infraed
infraed

Reputation: 23

How to have multiple independently moving objects in OpenGL

I am trying to do some simple graphics processing with OpenGL, but I am having trouble having 2 objects where one of them is static and the other moves. The objects are a simple cube and a square that represents the floor. I want the cube to move down until it touches the floor (as if it were moving). I can render the falling cube on its own, and I can get the floor on its own. But when I want to have them both in the same scene I am having issues as they either both fall down (the cubes behaviour), or both stay in the same place (the floors behaviour). Which one of these two options occurs is due to whether I push and pop my model matrix - when I do pop and push, they stay static, when I don't, they fall down (I guess this makes sense as I draw the floor then the cube.

This is my code in the draw phase of the program:

//Clear the screen to the colour specified earlier, as well as the depth
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glUseProgram(programID); // Use our shader
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

//RENDER THE FLOOR
pushMat(Model); //PUSH - WHEN ACTIVE, CUBE AND FLOOR FALL. WHEN COMMENTED OUT, BOTH FLOOR AND CUBE ARE STATIC
    MVP = Projection * View * Model; //These are all matrices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, floorVertexBuffer);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    //FLOOR COLOURS
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, colorbuffer2);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glDrawArrays(GL_TRIANGLES, 0, 2*3); //2 triangles, of 3 vertices each

Model = popMat(); //POP - WHEN ACTIVE, CUBE AND FLOOR FALL. WHEN COMMENTED OUT, BOTH FLOOR AND CUBE ARE STATIC

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);


//RENDER THE CUBE
pushMat(Model); //PUSH - WHEN ACTIVE, CUBE AND FLOOR FALL. WHEN COMMENTED OUT, BOTH FLOOR AND CUBE ARE STATIC
    Model = translate(Model, vec3(0.0f, deltaY, 0.0f)); //deltaY is the change in the y position of the cube, it is calculated earlier in this draw loop
    MVP = Projection * View * Model;

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, cubeVertexBuffer);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    //CUBE COLOURS
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    //DRAW CUBE
    glDrawArrays(GL_TRIANGLES, 0, 12 * 3); //12 triangle, of 3 vertices each
Model = popMat(); //FINAL POP - WHEN ACTIVE, CUBE AND FLOOR FALL. WHEN COMMENTED OUT, BOTH FLOOR AND CUBE ARE STATIC

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

Code for my push and pop functions:

stack<mat4> modelViewStack; //This is initialised with the identity matrix in the main function

void pushMat(mat4 m)
{
    modelViewStack.push(m);
}

mat4 popMat()
{
    mat4 temp = modelViewStack.top();
    modelViewStack.pop();
    return temp;
}

Any clues as to how I get it so the floor stays in one place and the cube moves down? I'm happy to help explain any code, provide more of my code, or answer any questions in general. Thanks for any help.

Upvotes: 2

Views: 2794

Answers (1)

Xirema
Xirema

Reputation: 20396

glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

This call needs to appear before each call to glDrawArrays. Right now, it's only being called once, before you render everything, which means both objects are receiving the same MVP matrix.

Also, I would reconsider the logic of implementing this logic using a Matrix Stack. That was how it worked in Legacy OpenGL (because everything depended on Global State, and some other reasons) but it's not obvious that this is the best solution today, when we can simply associate Matrices with individual objects and simply bind them as needed.

Upvotes: 3

Related Questions