0
\$\begingroup\$

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)
{
    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?
    model=glm::rotate(model,glm::radians(yaw),glm::vec3(0.0,1.0,0.0));
    model=glm::rotate(model,glm::radians(pitch),glm::vec3(1.0,0.0,0.0));
    //
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    ourShader.Use();

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

    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 27*n*n);
\$\endgroup\$
1
  • 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, 2016 at 8:18

2 Answers 2

1
\$\begingroup\$

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));
\$\endgroup\$
3
  • \$\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, 2016 at 9:22
  • \$\begingroup\$ @rob let me try something \$\endgroup\$
    – Bálint
    Dec 20, 2016 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, 2017 at 11:56
0
\$\begingroup\$

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.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .