# Opengl rotate around global axis

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;

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)
{
oldX=sf::Mouse::getPosition(window).x;
oldY=sf::Mouse::getPosition(window).y;

yaw=oldX*0.1;
pitch=oldY*0.1;

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

view=glm::mat4();
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?
//
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 27*n*n);

• You should store stuff like uniform locations somewhere instead of getting them each frame. It's a very costy operation. – 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));

• 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) – robertooverflow97 Dec 20 '16 at 9:22
• @rob let me try something – Bálint Dec 20 '16 at 10:10
• 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. – curious student 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.