0

I'm trying to program a simple animation using GLUT and OpenGL in c++. I've created three functions for this purpose: catSpline(), fillArray(), and fixedAngle(). catSpline() returns a GLfloat value, fillArray() is a void function that consists of a series of loops that fills a series of arrays with GLfloat values produced using catSpline, and fixedAngle() will return a 16-unit array. Here is the code for these three methods:

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;
    }


}

The way I use these three functions is in a loop called Render, I set up OpenGL for displaying an animation of a teapot model, call fillArrays(), and then attempt to store the result of a single fixedAngle call (using a few entries form the arrays filled in just before) in a new array called foo. This seems to be the cause of the errors, with foo only containing a pointer address rather than pointing to the actual array so I can use it. This is the code I'm using to call these functions:

fillArrays();

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

    foo = fixedAngle(xArr[tp], yArr[tp], zArr[tp], xRot[tp], yRot[tp], zRot[tp]);

    glLoadMatrixf(foo);

After having used multiple print statements to print out the results of my functions, I know that the problem has to be how I set up the pointers somewhere. Can anyone help me return the array correctly?

Please note: if some of the matrix syntax seems unfammiliar, it's because I'm using a c++ library called Eigen to do some of the matrix math. Once again, after having rigorously printed out the results of the functions, I know that the functions that use Eigen syntax are producing the right values.

8
  • 2
    You don't include enough information to even attempt to reproduce the problem you report. Random code snippets are very hard to analyze Commented Oct 9, 2015 at 2:27
  • 3
    One thing that seems odd to me is that you allocate memory for foo, then immediately assigned other allocated memory to foo. That's sure to be a memory leak one day. That's likely not the cause of your error, though. Commented Oct 9, 2015 at 2:37
  • Do you know how I can fix it? Commented Oct 9, 2015 at 2:46
  • I recommend you switch to using/returning a std::vector<GLfloat> - as long as you use push_back, or give the constructor an appropriate initial size or explicitly call resize() before indexing with [], you basically can't screw it up. Hmmm..... Commented Oct 9, 2015 at 2:47
  • Just curious. What does x<<1, 0, 0, 0,...; do? Commented Oct 9, 2015 at 2:57

1 Answer 1

1

You can replace...

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

...with...

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

...or even directly initialise it instead of copying elements afterwards...

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) };

...which - FWIW - could also be done like this...

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

With any of the above, you'll need to change the return type correspondingly...

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

...then you can call fixedAngle and use foo like this:

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...
Sign up to request clarification or add additional context in comments.

4 Comments

I just want to know how I should change the return type. (I'm still new to c++).
@Maria-Andersado: if you "just" want to change the return type, you're at a dead end: your function's already using a GLfloat* to address the malloced memory, and has the right return type to return that to the calling code. So changing "just" the return type will tend to stop your program compiling (unless you make a useless change like to void*). (My answer is trying to show you a way to avoid pointers so you can be productive writing robust code, despite being new to C++, and avoiding explicit application-level memory allocation is considered best practice even for C++ experts....)
No, it's just that you said that using your recommended sollutions would require me to change the return type. I'm still learning the C++ syntax and wanted to know how I could change the return type so it would match something like std::vector<GLfloat>
@Maria-Andersado: oh - with you now; where I said std::vector<GLfloat> fixedAngle(... - that's the text that should replace your old GLfloat * fixedAngle(.... The function return type appears before the function name and arguments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.