调用返回数组的函数时出现问题

时间:2015-10-09 02:01:47

标签: c++ arrays pointers opengl glut

我试图在c ++中使用GLUT和OpenGL编写一个简单的动画。我已为此创建了三个功能:catSpline(), fillArray()fixedAngle()catSpline()返回GLfloat值,fillArray()是一个void函数,由一系列循环组成,这些循环使用catSpline生成GLfloat值,填充一系列数组,fixedAngle()将返回16-单元阵列。以下是这三种方法的代码:

GLfloat * fixedAngle(GLfloat initialX, GLfloat initialY, GLfloat initialZ, GLfloat rotX, GLfloat rotY, GLfloat rotZ)

{
      ArrayXXf z(4,4); //initializing the 4x4 rotation matrixes
      ArrayXXf y(4,4);
      ArrayXXf x(4,4);

      x<<1, 0, 0, 0,
          0, cos(rotX), -sin(rotX), 0,
          0, sin(rotX), cos(rotX), 0,
          0, 0, 0, 1;

      y<<cos(rotY), 0, sin(rotY), 0,
          0, 1, 0, 0,
          -sin(rotY), 0, cos(rotY), 0,
          0, 0, 0, 1;

      z<< cos(rotZ), -sin(rotZ), 0, 0,
          sin(rotZ), cos(rotZ), 0, 0,
          0, 0, 1, 0,
          0, 0, 0, 1;



      ArrayXXf fin(4,4);

      fin = x * y * z; 

      fin(0,3) = initialX;
      fin(1,3) = initialY;
      fin(2,3) = initialZ;
      //now we've moved the translational information into the final matrix
    // std::cout << fin;

     fin(3,3) = 1;

    GLfloat * arr;
    arr = (GLfloat *) malloc(16*sizeof(GLfloat));

          arr[0] = fin(0,0);
         arr[1] = fin(0,1);
         arr[2] = fin(0,2);
         arr[3] = fin(0,3);
        arr[4] = fin(1,0);
        arr[5] = fin(1,1);
            arr[6] = fin(1,2);
        arr[7] = fin(1,3);
                            arr[8] = fin(2,0);
                            arr[9] = fin(2,1);
                            arr[10] = fin(2,2);
                            arr[11] = fin(2,3);
                            arr[12] = fin(3,0);
                            arr[13] = fin(3,1);
                            arr[14] = fin(3,2);
                            arr[15] = fin(3,3);


      return arr; 

}

GLfloat catSpline(GLfloat x1, GLfloat x2, GLfloat x3, GLfloat x4, GLfloat t) 
{ 
    ArrayXXf M(4,4); //4x4 M matrix
    ArrayXXf P(4,1); //matrix to hold keyframe x values 

    P(0,0) = x1;
    P(1,0) = x2;
    P(2,0) = x3;
    P(3,0) = x4;
    //keyframe x values

    M(0,0) = -0.5;
    M(0,1) = 2-(-0.5);
    M(0,2) = -0.5-2;
    M(0,3) = 0.5;

    M(1,0) = 2*0.5;
    M(1,1) = 0.5-3;
    M(1,2) = 3-(2*0.5);
    M(1,3) = -0.5;

    M(2,0) = -0.5;
    M(2,1) = 0;
    M(2,2) = 0.5;
    M(2,3) = 0;

    M(3,0) = 0;
    M(3,1) = 1;
    M(3,2)=0;
    M(3,3)=0;

      ArrayXXf T(1,4);



         T(0,0) = t*t*t; //you can't cube a float, but you can get the same result by doing this
         T(0,1) = t*t;
         T(0,2) = t;
         T(0,3)=1;
         //now the T matrix is filled
         ArrayXXf TM(1,4);

        TM(0,0) = (T(0,0) * M(0,0)) + (T(0,1) * M(1,0)) + (T(0,2) * M(2,0)) + (T(0,3) * M(0,3));
        TM(0,1) = (T(0,0) * M(0,1)) + (T(0,1) * M(1,1)) + (T(0,2) * M(2,1)) + (T(0,3) * M(3,1));
        TM(0,2) = (T(0,0) * M(0,2)) + (T(0,1) * M(1,2)) + (T(0,2) * M(2,2)) + (T(0,3) * M(3,2));
        TM(0,3) = (T(0,0) * M(0,3)) + (T(0,1) * M(1,3)) + (T(0,2) * M(2,3)) + (T(0,3) * M(3,3));
        //first multiply T amd M




        GLfloat TMP;

        TMP = (TM(0,0) * P(0,0)) + (TM(0,1) *P(1,0)) + (TM(0,2) * P(2,0)) + (TM(0,3) * P(3,0));



      return TMP;
} 


void fillArrays()
{


    /*  zRot = catSpline(2, 4, 5, 6);
        yRot = catSpline(1, 4, 6, 7);
        xRot = catSpline(6, 3, 2, 6);

        xArr = catSpline(9, 4, 3, 10);
        yArr = catSpline(1, 2, 4, 8);
        zArr = catSpline(8, 3, 1, 3);*/

    for(int j=0; j>=100; j++)
    {
        xArr[j] = catSpline(2, 4, 5, 6, t);
        t+=0.1;
    }
    for(int i=0; i>=100; i++)
    {
        yArr[i] = catSpline(2, 4, 5, 6, ty);
        ty+=0.1;
    }
    for(int k=0; k>=100; k++)
    {
        xArr[k] = catSpline(2, 4, 5, 6, tz);
        tz += 0.1;
    }

    for(int a=0; a>=100; a++)
    {
        xRot[a] = catSpline(2, 4, 5, 6, rx);
        rx += 0.1;
    }

    for(int b=0; b>=100; b++)
    {
        yRot[b] = catSpline(2, 4, 5, 6, ry);
        rz += 0.1;
    }

    for(int c=0; c>=100; c++)
    {
        zRot[c] = catSpline(2, 4, 5, 6, rz);
        rz += 0.1;
    }


}

我使用这三个函数的方式是在一个名为Render的循环中,我设置OpenGL来显示茶壶模型的动画,调用fillArrays(),然后尝试存储单个{{1的结果在一个名为foo的新数组中调用(使用几个条目组成前面填充的数组)。这似乎是错误的原因,foo只包含一个指针地址,而不是指向实际的数组,所以我可以使用它。这是我用来调用这些函数的代码:

fixedAngle

在使用多个print语句打印出我的函数结果后,我知道问题必须是我在某处设置指针的方法。任何人都可以帮我正确地返回阵列吗?

请注意:如果某些矩阵语法似乎不熟悉,那是因为我使用名为Eigen的c ++库来完成一些矩阵数学运算。再一次,在严格打印出函数的结果之后,我知道使用Eigen语法的函数正在产生正确的值。

1 个答案:

答案 0 :(得分:1)

你可以替换......

GLfloat * arr;
arr = (GLfloat *) malloc(16*sizeof(GLfloat));

...与...

std::vector<GLfloat> arr(16);

...或者甚至直接初始化它而不是之后复制元素......

std::vector<GLfloat> arr { fin(0,0), fin(0,1), fin(0,2), fin(0,3),
                           fin(1,0), fin(1,1), fin(1,2), fin(1,3),
                           fin(2,0), fin(2,1), fin(2,2), fin(2,3),
                           fin(3,0), fin(3,1), fin(3,2), fin(3,3) };

......哪个 - FWIW - 也可以这样做......

std::vector<GLfloat> arr;
for (int a = 0; a <= 3; ++a)
    for (int b = 0; b <= 3; ++b)
        arr.push_back(fin(a,b));

使用上述任何一项,您需要相应地更改返回类型...

std::vector<GLfloat> fixedAngle(
    GLfloat initialX, GLfloat initialY, GLfloat initialZ,
    GLfloat rotX, GLfloat rotY, GLfloat rotZ)
{
    ...

...然后你可以拨打fixedAngle并像这样使用foo

fillArrays();
std::vector<GLfloat> foo = fixedAngle(xArr[tp], yArr[tp], zArr[tp],
                                     xRot[tp], yRot[tp], zRot[tp]);
glLoadMatrixf(foo.data()); // or `&foo[0]` if you prefer...