如何使用同构变换在 openGL 中渲染 4D 对象? [英] How do I render a 4D object in openGL utilizing homogenous transforms?

查看:61
本文介绍了如何使用同构变换在 openGL 中渲染 4D 对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想尝试制作一款利用 4D 横截面移动的游戏.我反复查看,但找不到任何提供完整和清晰代码的答案 - 我找到的最接近的是 [我应该如何处理(变形)opengl 中的 4D 对象?其中包含我需要的内容,但是,在尝试使用代码时,并未清楚地描述所有架构,例如包含 5x5 矩阵的文件.

I want to try and make a game that utilises movement through 4D cross sections. I have looked repeatedly, but cannot find any answers that present complete and clear code - the closest i found was [how should i handle (morphing) 4D objects in opengl? which contains what I need, however, upon trying to utilise the code, not all of the architecture was described clearly, such as the file containing the 5x5 matrix.

推荐答案

4D Reper

我之前没有发布它,因为它不符合 30KByte 的限制以及我的其他答案......而且它只是矩阵的基本用法,这对于制作 3D 或更高维度向量 gfx 的任何人来说都应该是显而易见的...

I did not post it before as it would not fit into 30KByte limit along with the rest of my answers... And also its just basic use of matrices which should be obvious to anyone who make 3D or higher dimensionality vector gfx ...

它在内部使用 nd_math.h.并且根据我多年来获得的 4x4 同质变换矩阵的所有知识,基本上反映了我的 3D reper 类.reper本身是class,它存储单个累积齐次矩阵及其逆矩阵,并自我修复以保持基向量的正交正态性.

It uses nd_math.h internaly. And basically reflects my 3D reper class based on all the knowledge of 4x4 homogenous transform matrices I gain over the years. The reperitself is class that stores single cumulative homogenuous matrix along with its inverted counterpart and self repairs itself to maintain ortho-normality of basis vectors.

//---------------------------------------------------------------------------
//--- Reper 4D: ver 1.000 ---------------------------------------------------
//---------------------------------------------------------------------------
#ifndef _reper4D_h
#define _reper4D_h
//---------------------------------------------------------------------------
#include "nd_math.h"
//---------------------------------------------------------------------------
const double pi   =    M_PI;
const double pi2  =2.0*M_PI;
const double pipol=0.5*M_PI;
const double deg=M_PI/180.0;
const double rad=180.0/M_PI;
const int _reper_max_cnt=16;
//---------------------------------------------------------------------------
class reper4D
    {
/*  xx yx zx wx x0
    xy yy zy wy y0
    xz yz zz wz z0
    xw yw zw ww w0
     0  0  0  0  1  */

public:
    matrix<5> rep,inv;  // 4D uniform 5x5 transform matrix direct, inverse
    int     _rep,_inv;  // is actual ?
    int     cnt;        // dir operation counter

    reper4D()   { reset(); }
    reper4D(reper4D& a) { *this=a; }
    ~reper4D()  {}
    reper4D* operator = (const reper4D *a) { *this=*a; return this; }
    //reper4D* operator = (const reper4D &a) { ...copy... return this; }

    void reset() { rep.unit(); inv.unit(); _rep=1; _inv=1; cnt=0; orto(1); }
    void use_rep();
    void use_inv();
    void use_all();
    void orto(int test=0);                      // kolmost ak treba (podla cnt,alebo hned ak test!=0)
    void g2l    (vector<4> &l,vector<4> &g);    // global xyzw -> local xyzw
    void l2g    (vector<4> &g,vector<4> &l);    // global xyzw <- local xyzw
    void g2l_dir(vector<4> &l,vector<4> &g);    // global xyzw -> local xyzw  , only direction change
    void l2g_dir(vector<4> &g,vector<4> &l);    // global xyzw <- local xyzw  , only direction change
    void g2l_rep(reper4D &l,reper4D g);
    void l2g_rep(reper4D &g,reper4D l);
    void axisx_get(vector<4> &p);
    void axisx_set(vector<4> &p);
    void axisy_get(vector<4> &p);
    void axisy_set(vector<4> &p);
    void axisz_get(vector<4> &p);
    void axisz_set(vector<4> &p);
    void axisw_get(vector<4> &p);
    void axisw_set(vector<4> &p);
    void lpos_get (vector<4> &p);           // get origin in local xyzw (vzdy 0,0,0)
    void lpos_set (vector<4> &p);           // set origin in local xyzw
    void gpos_get (vector<4> &p);           // get origin in global xyzw
    void gpos_set (vector<4> &p);           // set origin in global xyzw
    void gpos_add (vector<4> &p);           // move origin in global xyzw
    void gpos_sub (vector<4> &p);           // move origin in global xyzw

    void rot_rnd();                             // random orientation
    // local rotations paralel to hyper plane
    void lrot_xy(double ang);
    void lrot_yz(double ang);
    void lrot_zx(double ang);
    void lrot_xw(double ang);
    void lrot_yw(double ang);
    void lrot_zw(double ang);
    // global rotations paralel to hyper plane
    void grot_xy(double ang);
    void grot_yz(double ang);
    void grot_zx(double ang);
    void grot_xw(double ang);
    void grot_yw(double ang);
    void grot_zw(double ang);

    void rep2rep(reper4D r0,reper4D r1);        // this=r1<<r0
    void rep_rep(reper4D r0,reper4D r1);        // this=r1>>r0

    void repset(matrix<5> &m);
    void invset(matrix<5> &m);
    void repget(matrix<5> &m);
    void invget(matrix<5> &m);

    void mul_rep_mat(matrix<5> &m) { use_rep(); rep=rep*m; _inv=0; cnt++; orto(); }
    void mul_inv_mat(matrix<5> &m) { use_inv(); inv=inv*m; _rep=0; cnt++; orto(); }
    void mul_mat_rep(matrix<5> &m) { use_rep(); rep=m*rep; _inv=0; cnt++; orto(); }
    void mul_mat_inv(matrix<5> &m) { use_inv(); inv=m*inv; _rep=0; cnt++; orto(); }
    vector<4> mul_mat_vec    (matrix<5> &m,vector<4> &v);
    vector<4> mul_mat_vec_dir(matrix<5> &m,vector<4> &v);
    };
//---------------------------------------------------------------------------
void reper4D::use_rep() { if (!_rep) { rep=inv.inverse(); _rep=1; _inv=1; cnt++; orto(); }
                          if (!_rep) { rep=inv.inverse(); _rep=1; _inv=1; } }
void reper4D::use_inv() { if (!_inv) { inv=rep.inverse(); _rep=1; _inv=1; cnt++; orto(); }
                          if (!_inv) { inv=rep.inverse(); _rep=1; _inv=1; } }
void reper4D::use_all() { use_rep(); use_inv(); }
//---------------------------------------------------------------------------
void reper4D::orto(int test)
    {
    if ((cnt>=_reper_max_cnt)||(test))
        {
        use_rep();
        rep.orthonormal();
        _rep=1; _inv=0; cnt=0;
        }
    }
//---------------------------------------------------------------------------
void reper4D::g2l    (vector<4> &l,vector<4> &g) { use_inv(); l=mul_mat_vec(inv,g); }
void reper4D::l2g    (vector<4> &g,vector<4> &l) { use_rep(); g=mul_mat_vec(rep,l); }
void reper4D::g2l_dir(vector<4> &l,vector<4> &g) { use_inv(); l=mul_mat_vec_dir(inv,g); }
void reper4D::l2g_dir(vector<4> &g,vector<4> &l) { use_rep(); g=mul_mat_vec_dir(rep,l); }
//---------------------------------------------------------------------------
void reper4D::g2l_rep(reper4D &l,reper4D g)
    {
    vector<4> p;
    g.gpos_get(p);  g2l(p,p);     l.gpos_set(p);
    g.axisx_get(p); g2l_dir(p,p); l.axisx_set(p);
    g.axisy_get(p); g2l_dir(p,p); l.axisy_set(p);
    g.axisz_get(p); g2l_dir(p,p); l.axisz_set(p);
    g.axisw_get(p); g2l_dir(p,p); l.axisw_set(p);
    }
//---------------------------------------------------------------------------
void reper4D::l2g_rep(reper4D &g,reper4D l)
    {
    vector<4> p;
    l.gpos_get(p);  l2g(p,p);     g.gpos_set(p);
    l.axisx_get(p); l2g_dir(p,p); g.axisx_set(p);
    l.axisy_get(p); l2g_dir(p,p); g.axisy_set(p);
    l.axisz_get(p); l2g_dir(p,p); g.axisz_set(p);
    l.axisw_get(p); l2g_dir(p,p); g.axisw_set(p);
    }
//---------------------------------------------------------------------------
void reper4D::axisx_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][0];
    p[1]=rep[1][0];
    p[2]=rep[2][0];
    p[3]=rep[3][0];
    }
//---------------------------------------------------------------------------
void reper4D::axisx_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][0]=p[0];
    rep[1][0]=p[1];
    rep[2][0]=p[2];
    rep[3][0]=p[3];
    cnt=_reper_max_cnt;
    }
//---------------------------------------------------------------------------
void reper4D::axisy_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][1];
    p[1]=rep[1][1];
    p[2]=rep[2][1];
    p[3]=rep[3][1];
    }
//---------------------------------------------------------------------------
void reper4D::axisy_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][1]=p[0];
    rep[1][1]=p[1];
    rep[2][1]=p[2];
    rep[3][1]=p[3];
    cnt=_reper_max_cnt;
    }
//---------------------------------------------------------------------------
void reper4D::axisz_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][2];
    p[1]=rep[1][2];
    p[2]=rep[2][2];
    p[3]=rep[3][2];
    }
//---------------------------------------------------------------------------
void reper4D::axisz_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][2]=p[0];
    rep[1][2]=p[1];
    rep[2][2]=p[2];
    rep[3][2]=p[3];
    cnt=_reper_max_cnt;
    }
//---------------------------------------------------------------------------
void reper4D::axisw_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][3];
    p[1]=rep[1][3];
    p[2]=rep[2][3];
    p[3]=rep[3][3];
    }
//---------------------------------------------------------------------------
void reper4D::axisw_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][3]=p[0];
    rep[1][3]=p[1];
    rep[2][3]=p[2];
    rep[3][3]=p[3];
    cnt=_reper_max_cnt;
    }
//---------------------------------------------------------------------------
void reper4D::lpos_get(vector<4> &p)
    {
    p[0]=0;
    p[1]=0;
    p[2]=0;
    p[3]=0;
    }
//---------------------------------------------------------------------------
void reper4D::lpos_set(vector<4> &p)
    {
    vector<4> q;
    l2g(q,p);
    gpos_set(q);
    }
//---------------------------------------------------------------------------
void reper4D::gpos_get(vector<4> &p)
    {
    use_rep();
    p[0]=rep[0][4];
    p[1]=rep[1][4];
    p[2]=rep[2][4];
    p[3]=rep[3][4];
    orto();
    }
//---------------------------------------------------------------------------
void reper4D::gpos_set(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][4]=p[0];
    rep[1][4]=p[1];
    rep[2][4]=p[2];
    rep[3][4]=p[3];
    orto();
    }
//---------------------------------------------------------------------------
void reper4D::gpos_add(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][4]+=p[0];
    rep[1][4]+=p[1];
    rep[2][4]+=p[2];
    rep[3][4]+=p[3];
    orto();
    }
//---------------------------------------------------------------------------
void reper4D::gpos_sub(vector<4> &p)
    {
    use_rep();
    _rep=1; _inv=0;
    rep[0][4]-=p[0];
    rep[1][4]-=p[1];
    rep[2][4]-=p[2];
    rep[3][4]-=p[3];
    orto();
    }
//---------------------------------------------------------------------------
void reper4D::rot_rnd()
    {
    int i,j;
    matrix<4> a;
    a.rnd();
    a.orthonormal();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_xy(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld( c , s ,0.0,0.0);
    b[1].ld(-s , c ,0.0,0.0);
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_yz(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0, c , s ,0.0);
    b[2].ld(0.0,-s , c ,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_zx(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld( c ,0.0,-s ,0.0);
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld( s ,0.0, c ,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_xw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld( c ,0.0,0.0, s );
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(-s ,0.0,0.0, c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_yw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0, c ,0.0,-s );
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(0.0, s ,0.0, c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::lrot_zw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_rep();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=rep[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld(0.0,0.0, c ,-s );
    b[3].ld(0.0,0.0, s , c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      rep[i][j]=a[i][j];
    _rep=1; _inv=0; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_xy(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld( c , s ,0.0,0.0);
    b[1].ld(-s , c ,0.0,0.0);
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_yz(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0, c , s ,0.0);
    b[2].ld(0.0,-s , c ,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_zx(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld( c ,0.0,-s ,0.0);
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld( s ,0.0, c ,0.0);
    b[3].ld(0.0,0.0,0.0,1.0);
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_xw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld( c ,0.0,0.0, s );
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(-s ,0.0,0.0, c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_yw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0, c ,0.0,-s );
    b[2].ld(0.0,0.0,1.0,0.0);
    b[3].ld(0.0, s ,0.0, c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::grot_zw(double ang)
    {
    int i,j;
    matrix<4> a,b;
    double c=cos(ang),s=sin(ang);
    use_inv();
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      a[i][j]=inv[i][j];
    b[0].ld(1.0,0.0,0.0,0.0);
    b[1].ld(0.0,1.0,0.0,0.0);
    b[2].ld(0.0,0.0, c ,-s );
    b[3].ld(0.0,0.0, s , c );
    a*=b;
    for (i=0;i<4;i++)
     for (j=0;j<4;j++)
      inv[i][j]=a[i][j];
    _rep=0; _inv=1; orto();
    }
//---------------------------------------------------------------------------
void reper4D::rep2rep(reper4D r0,reper4D r1)
    {
    reset();
    r0.use_inv();
    r1.use_inv();
    inv=r0.inv*r1.inv;
    rep=inv.inverse();
    _rep=1; _inv=1; orto(1);
    }
//---------------------------------------------------------------------------
void reper4D::rep_rep(reper4D r0,reper4D r1)
    {
    reset();
    r0.use_rep();
    r1.use_inv();
    inv=r0.rep*r1.inv;
    rep=inv.inverse();
    _rep=1; _inv=1; orto(1);
    }
//---------------------------------------------------------------------------
void reper4D::repset(matrix<5> &m) { rep=m; _rep=1; _inv=0; }
void reper4D::invset(matrix<5> &m) { inv=m; _rep=0; _inv=1; }
void reper4D::repget(matrix<5> &m) { use_rep(); m=rep; }
void reper4D::invget(matrix<5> &m) { use_inv(); m=inv; }
//---------------------------------------------------------------------------
vector<4> reper4D::mul_mat_vec(matrix<5> &m,vector<4> &v)
    {
    vector<4> p;
    p[0]=(m[0][0]*v[0])+(m[0][1]*v[1])+(m[0][2]*v[2])+(m[0][3]*v[3])+(m[0][4]);
    p[1]=(m[1][0]*v[0])+(m[1][1]*v[1])+(m[1][2]*v[2])+(m[1][3]*v[3])+(m[1][4]);
    p[2]=(m[2][0]*v[0])+(m[2][1]*v[1])+(m[2][2]*v[2])+(m[2][3]*v[3])+(m[2][4]);
    p[3]=(m[3][0]*v[0])+(m[3][1]*v[1])+(m[3][2]*v[2])+(m[3][3]*v[3])+(m[3][4]);
    return p;
    }
//---------------------------------------------------------------------------
vector<4> reper4D::mul_mat_vec_dir(matrix<5> &m,vector<4> &v)
    {
    vector<4> p;
    p[0]=(m[0][0]*v[0])+(m[0][1]*v[1])+(m[0][2]*v[2])+(m[0][3]*v[3]);
    p[1]=(m[1][0]*v[0])+(m[1][1]*v[1])+(m[1][2]*v[2])+(m[1][3]*v[3]);
    p[2]=(m[2][0]*v[0])+(m[2][1]*v[1])+(m[2][2]*v[2])+(m[2][3]*v[3]);
    p[3]=(m[3][0]*v[0])+(m[3][1]*v[1])+(m[3][2]*v[2])+(m[3][3]*v[2]);
    return p;
    }
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------

列表<>模板

它只是一个线性数组容器模板,具有自分配属性,专为多线程和快速列表操作而开发.我不能分享它的源代码,因为它是公司代码的一部分......

Its just a linear array container template with self allocating properties specially developed for multithreading and fast list operations. I can not share its source code however because its part of corporate code ...

取而代之的是一个模拟 API 的静态模板,因此您可以使用您可以使用的任何线性存储对其进行重新编码,例如 std::vector<> 或其他任何内容,或者仅将其与静态分配一起使用相反...

Instead Here a static template that mimics the API so you can recode it using any linear storage you got at your disposal like std::vector<> or whatever or just use this with static allocation as is instead...

//---------------------------------------------------------------------------
//--- static list template class ver 3.00 ----------------------------------
//---------------------------------------------------------------------------
#ifndef _list_static_h
#define _list_static_h
/*---------------------------------------------------------------------------
    Template class/struct must contain these operators/functions to work properly:

    // all inline
    T(){}; T(T& a){ *this=a; }; ~T(){}; T* operator = (const T *a) { *this=*a; return this; }; /*T* operator = (const T &a) { ...copy... return this; };*/
/*
    // inline
    T()     {}
    T(T& a) { *this=a; }
    ~T()    {}
    T* operator = (const T *a) { *this=*a; return this; }
    //T* operator = (const T &a) { ...copy... return this; }

    // header
    T();
    T(T& a);
    ~T();
    T* operator = (const T *a);
    //T* operator = (const T &a);

    // body
T::T()      {}
T::T(T& a)  { *this=a; }
T::~T()     {}
T* T::operator = (const T *a) { *this=*a; return this; }
//T* T::operator = (const T &a) { ..copy... return this; }
//-------------------------------------------------------------------------*/
template <class T,int N=16> class List_static
        {
public: T       dat[N];                 // items array
        int     num,siz;                // items count,allocated size

        int     minsiz;                 // minimal array size
        int     element_size;           // initiate in constructor
        bool    enable_auto_shrink;     // automatic shrink after delete operation ?

        void (__closure *onrealloc)();  // realloc event

        List_static(int _allocate=N);
        ~List_static() { free(); }

        void operator = (const List_static<T> &a);
        T& operator[] (int i);

        void free();
        int  allocate(int _allocate);
        int  reallocate(int _allocate);
        int  shrink();                  // down alloc if possible

        int  ins(int ix);
        int  ins(int ix,T &a);
        int  ins(int ix,const T &a);
        int  del(int ix);
        int  qdel(int ix);
        int  ins_block(int ix,int sz);
        int  del_block(int ix,int sz);
        void shl(int d=1);
        void shr(int d=1);
        int  add() { return ins(num); }
        int  add(T &a) { return ins(num,a); }
        int  add(const T &a) { return ins(num,a); }
        int  add(List_static<T> &a);
        void reset();
        int  save_size();
        void save(int hnd);
        void load(int hnd);
        };
//---------------------------------------------------------------------------
template <class T,int N> List_static<T>::List_static(int _allocate)
        {
        onrealloc=NULL;
        element_size=sizeof(T);
        enable_auto_shrink=false;
        num=0;
        siz=N;
        minsiz=siz;
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::operator = (const List_static<T> &a)
        {
        int     i;
        reset();
        element_size       =a.element_size;
        enable_auto_shrink =a.enable_auto_shrink;
        minsiz             =a.minsiz;
        for (i=0;i<a.num;i++) add(a.dat[i]);
        }
//---------------------------------------------------------------------------
template <class T,int N> T& List_static<T>::operator[] (int i)
        {
        static T empty;
        if (i<   0) return empty;
        if (i>=num) return empty;
        return dat[i];
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::free()
        {
        num=0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::allocate(int _allocate)
        {
        if (_allocate<=siz) return 1; else return 0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::reallocate(int _allocate)
        {
        if (_allocate<=siz) return 1;
        else return 0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::shrink()
        {
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins(int ix)
        {
        int     i;
        if (num<0) num=0;
        if (ix<0) return 0;
        if (ix>num) return 0;
        if (num>=siz) return 0;
        if (ix<num)
         for (i=num;i>ix;i--)
          dat[i]=dat[i-1];
//      dat[ix]=;
        num++;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins(int ix,T &a)
        {
        int     i;
        if (num<0) num=0;
        if (ix<0) return 0;
        if (ix>num) return 0;
        if (num>=siz) return 0;
        if (ix<num)
         for (i=num;i>ix;i--)
          dat[i]=dat[i-1];
        dat[ix]=a;
        num++;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins(int ix,const T &a)
        {
        int     i;
        if (num<0) num=0;
        if (ix<0) return 0;
        if (ix>num) return 0;
        if (num>=siz) return 0;
        if (ix<num)
         for (i=num;i>ix;i--)
          dat[i]=dat[i-1];
        dat[ix]=a;
        num++;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::del(int ix)
        {
        int     i;
        if (num<=0) { num=0; return 0; }
        if (ix<0) return 0;
        if (ix>=num) return 0;
        num--;
        for (i=ix;i<num;i++)
         dat[i]=dat[i+1];
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::qdel(int ix)
        {
        int     i;
        if (num<=0) { num=0; return 0; }
        if (ix<0) return 0;
        if (ix>=num) return 0;
        if (ix<num-1)
         dat[ix]=dat[num-1];
        num--;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins_block(int ix,int sz)
        {
        int     i;
        if (num<0) num=0;
        if (sz<=0) return 0;
        if (ix<0) return 0;
        if (ix>num) return 0;
        if (num+sz>=siz) return 0;
        if (ix<num)
         for (i=num;i>ix;i--)
          dat[i+sz-1]=dat[i-1];
        num+=sz;
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::del_block(int ix,int sz)
        {
        int     i;
        if (num<=0) { num=0; return 0; }
        if (sz<=0) return 0;
        if (ix<0) return 0;
        if (ix+sz>num) return 0;
        num-=sz;
        for (i=ix;i<num;i++)
         dat[i]=dat[i+sz];
        return 1;
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::shl(int d)
        {
        int     i;
        if (num<0) num=0;
        if (num<=d) return;
        if (siz<=d) return;
        for (i=0;i<num-d;i++)
         dat[i]=dat[i+d];
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::shr(int d)
        {
        int     i;
        if (num<0) num=0;
        if (num<=d) return;
        if (siz<=d) return;
        for (i=num-d-1;i>=0;i--)
         dat[i+d]=dat[i];
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::reset()
        {
        num=0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::add(List_static<T> &a)
        {
        int     i,n,q;
        q=num;
        n=a.num;
        for (i=0;i<n;i++) add(a.dat[i]);
        if (num==n+q) return 1;
        return 0;
        }
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>:: save_size()
        {
        return 4+(num*element_size);
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>:: save(int hnd)
        {
        if (hnd<0) return;
        FileWrite(hnd,&num,4);
        FileWrite(hnd,dat,num*element_size);
        }
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>:: load(int hnd)
        {
        int     i,n;
        if (hnd<0) return;
        FileRead(hnd,&n,4); if (n<0) n=0;
        allocate(n); num=n; if (num>siz) num=siz; if (num<0) num=0;
        FileRead(hnd,dat,num*element_size);
        n=n-num;
        if (n>0) FileSeek(hnd,n*element_size,1);
        }
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

并非所有内容都被使用,因此要么忽略您不需要的内容,要么将 VCL 相关内容(文件访问)移植到您的环境中.

Not all stuff from that is used so either ignore what you do not need or port the VCL related stuff (file access) to your environment.

这篇关于如何使用同构变换在 openGL 中渲染 4D 对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆