0
votes

I'm drawing a Pyramid made out of 3 Cubes (two side to side then one on top), then I try to rotate this pyramid on X, Y or Z axis and scale it up and down.

Problem is the three cubes do not scale correctly (different sizes), also rotating produces very strange results.

I have defined an array for my Cube, using a glm vec3 array:

const glm::vec3 cube[] = {
    glm::vec3(-1.0f,-1.0f,-1.0f),
    glm::vec3( -1.0f,-1.0f, 1.0f),
    glm::vec3(-1.0f, 1.0f, 1.0f),
    glm::vec3(1.0f, 1.0f,-1.0f), 
    glm::vec3(-1.0f,-1.0f,-1.0f),
    glm::vec3(-1.0f, 1.0f,-1.0f),
    glm::vec3(1.0f,-1.0f, 1.0f),
    glm::vec3(-1.0f,-1.0f,-1.0f),
    glm::vec3(1.0f,-1.0f,-1.0f),
    glm::vec3(1.0f, 1.0f,-1.0f),
    glm::vec3(1.0f,-1.0f,-1.0f),
    glm::vec3(-1.0f,-1.0f,-1.0f),
    glm::vec3(-1.0f,-1.0f,-1.0f),
    glm::vec3(-1.0f, 1.0f, 1.0f),
    glm::vec3(-1.0f, 1.0f,-1.0f),
    glm::vec3(1.0f,-1.0f, 1.0f),
    glm::vec3(-1.0f,-1.0f, 1.0f),
    glm::vec3(-1.0f,-1.0f,-1.0f),
    glm::vec3(-1.0f, 1.0f, 1.0f),
    glm::vec3(-1.0f,-1.0f, 1.0f),
    glm::vec3(1.0f,-1.0f, 1.0f),
    glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(1.0f,-1.0f,-1.0f),
    glm::vec3(1.0f, 1.0f,-1.0f),
    glm::vec3(1.0f,-1.0f,-1.0f),
    glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(1.0f,-1.0f, 1.0f),
    glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(1.0f, 1.0f,-1.0f),
    glm::vec3(-1.0f, 1.0f,-1.0f),
    glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-1.0f, 1.0f,-1.0f),
    glm::vec3(-1.0f, 1.0f, 1.0f),
    glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-1.0f, 1.0f, 1.0f),
    glm::vec3(1.0f,-1.0f, 1.0f)
};

I generate and link the buffers and the necessary stuff for OpenGL to work, then I draw the pyramid, which is made of the three cubes. I am almost certain this is the part of the code where it all goes wrong:

glm::mat4 P = glm::perspective(glm::radians(60.0f + zoom), float(width()) / height(), 0.01f, 1000.0f);

glm::mat4 V = glm::mat4(1);
V = glm::translate(V, glm::vec3(-3 + moveX, -1 + moveY, -6 + moveZ));


V = glm::rotate(V, glm::radians(rotateCamradX), glm::vec3(1.0, 0.0, 0.0));
V = glm::rotate(V, glm::radians(rotateCamradY), glm::vec3(0.0, 1.0, 0.0));
V = glm::rotate(V, glm::radians(rotateCamradZ), glm::vec3(0.0, 0.0, 1.0));


glm::mat4 M = glm::mat4(1);  
M = glm::translate(M, glm::vec3(-1, 0, 0));

M = glm::rotate(M, glm::radians(rotateradX), glm::vec3(1.0, 0.0, 0.0));
M = glm::rotate(M, glm::radians(rotateradY), glm::vec3(0.0, 1.0, 0.0));
M = glm::rotate(M, glm::radians(rotateradZ), glm::vec3(0.0, 0.0, 1.0));

M = glm::scale(M, glm::vec3(scaleVar, scaleVar, scaleVar));

glm::mat4 M1 = glm::mat4(1);
M1 = glm::translate(M, glm::vec3(2, 0, 0));

M1 = glm::rotate(M1, glm::radians(rotateradX), glm::vec3(1.0, 0.0, 0.0));
M1 = glm::rotate(M1, glm::radians(rotateradY), glm::vec3(0.0, 1.0, 0.0));
M1 = glm::rotate(M1, glm::radians(rotateradZ), glm::vec3(0.0, 0.0, 1.0));

M1 = glm::scale(M1, glm::vec3(scaleVar, scaleVar, scaleVar));


glm::mat4 M2 = glm::mat4(1);
M2 = glm::translate(M, glm::vec3(1, 2, 0));

M2 = glm::rotate(M2, glm::radians(rotateradX), glm::vec3(1.0, 0.0, 0.0));
M2 = glm::rotate(M2, glm::radians(rotateradY), glm::vec3(0.0, 1.0, 0.0));
M2 = glm::rotate(M2, glm::radians(rotateradZ), glm::vec3(0.0, 0.0, 1.0));

M2 = glm::scale(M2, glm::vec3(scaleVar, scaleVar, scaleVar));

glm::mat4 PVM = P * V * M;
glm::mat4 PVM1 = P * V * M1;
glm::mat4 PVM2 = P * V * M2;

gl->glUniformMatrix4fv(id_shader_program_PVM_uniform, 1, GL_FALSE, glm::value_ptr(PVM));
gl->glUniform3f(id_shader_program_Color_uniform, 0.3f ,0.1f, 0.2f);
gl->glDrawArrays(GL_TRIANGLES, 0, 3*12);
gl->glUniformMatrix4fv(id_shader_program_PVM_uniform, 1, GL_FALSE, glm::value_ptr(PVM1));
gl->glUniform3f(id_shader_program_Color_uniform, 0.8f ,0.2f, 0.7f);
gl->glDrawArrays(GL_TRIANGLES, 0, 3*12);
gl->glUniformMatrix4fv(id_shader_program_PVM_uniform, 1, GL_FALSE, glm::value_ptr(PVM2));
gl->glUniform3f(id_shader_program_Color_uniform, 0.1f ,0.2f, 0.1f);
gl->glDrawArrays(GL_TRIANGLES, 0, 3*12);

The variables in V matrix are used for camera movement, which works, then in M, M1 and M2 are the scaling variables and rotation variables. All of the variables are type float, which I change using buttons in an UI app.

1

1 Answers

0
votes

Try flipping the order of your transformations. Instead of [translate,rotate,scale] do [scale,rotate,translate].

As a side note, it's generally easier to use glm::lookAt to compute your V matrix then to use multiple steps.