I want to create a game in which I rotate a cube around 2 fixed axes(x and y) using my mouse.

Here is what I want to do. Just use the mouse to see what kind of rotation I want.

I calculated my yaw and pitch values according to mouse movement and they work fine when I try to rotate only around one axis(x or y), but when I try to rotate around both axes it doesn't work(because OpenGL rotates axes when you apply a rotation). How do I make them both work at the same time? Here my code:

glm::mat4 model;
glm::mat4 view;
glm::mat4 projection;

float cameraDistance=3.0;

glm::vec3 center=glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp    = glm::vec3(0.0f, 1.0f,  0.0f);
glm::vec3 modelDistance= glm::vec3(0.0,0.0,3.0);

int oldX,oldY;
GLfloat yaw   = 0.0f; // Yaw is initialized to -90.0 degrees since a yaw of 0.0 
                      // results in a direction vector pointing to the right (due 
                      // to how Euler angles work) so we initially rotate a bit 
                      // to the left.
GLfloat pitch =   0.0f;

while (running)


    projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 1.0f, 100.0f);

    view = glm::lookAt(center+modelDistance, center+modelDistance + cameraFront, cameraUp);

    model= glm::mat4();

    //Here is the problem,how do i use both at the same time?


    GLint modelLoc = glGetUniformLocation(ourShader.Program, "model");
    GLint viewLoc = glGetUniformLocation(ourShader.Program, "view");
    GLint projLoc = glGetUniformLocation(ourShader.Program, "projection");

    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

    glDrawArrays(GL_TRIANGLES, 0, 27*n*n);
  • 1
    \$\begingroup\$ You should store stuff like uniform locations somewhere instead of getting them each frame. It's a very costy operation. \$\endgroup\$
    – Bálint
    Dec 20 '16 at 8:18

You could do something like the following:

Instead of applying the delta rotation to the model matrix, try storing the total rotation, and create a new modelnmatrix each frame:

int yaw = 0;
int pitch = 0;

// ...

yaw += oldX * 0.1;  // Note the difference
pitch += oldY * 0.1;

model = glm::mat4(); // Set the matrix to identity each frame
model = glm::rotate(model, glm::radians(yaw), glm::vec3(0, 1, 0));
model = glm::rotate(model, glm::radians(pitch), glm::vec3(1, 0, 0));
  • \$\begingroup\$ Why do you think that would solve the problem? I think its the same thing. I want to rotate my cube just like in that exemple. (around x and y axis) \$\endgroup\$ Dec 20 '16 at 9:22
  • \$\begingroup\$ @rob let me try something \$\endgroup\$
    – Bálint
    Dec 20 '16 at 10:10
  • \$\begingroup\$ The idea is correct, but the code example does not illustrate it. What you should do is store the total rotation of the object, relative to a pre-defined world-space "zero rotation". You can store it as pitch and yaw values (and build a matrix from them, which you send to the shader as a Model matrix), or store it as a matrix that gets updated using glm::rotate(...) and sent to the shader as a Model matrix. What I suggest that you do is avoid Euler angles, and stick with a quaternion. \$\endgroup\$ Jul 18 '17 at 11:56

In the example, the cube is rotating first around the z axis based on the x position of the mouse, then it's rotated around the x axis based on the y position of the mouse. When the mouse is in the upper left corner, there is no rotation, in the bottom left corner, there is 90 degrees of rotation around the x axis, and in the top right corner there is 90 degrees of rotation around the z axis.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.