How do I render a 4D object in openGL utilizing homogenous transforms?

穿精又带淫゛_ 提交于 2020-06-29 06:42:20

问题


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.


回答1:


4D Reper

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 ...

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
//---------------------------------------------------------------------------

List<> template

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 ...

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
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

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.



来源:https://stackoverflow.com/questions/62460757/how-do-i-render-a-4d-object-in-opengl-utilizing-homogenous-transforms

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!