Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: OpenGL rotate a cube with keyboard

  1. #1
    Newbie Newbie
    Join Date
    Dec 2017
    Posts
    2

    OpenGL rotate a cube with keyboard

    I try to rotate a cube with keyboard but I can't. The first rotation works correctly but the second rotation is broken.I understand why, but I can't figure out how to fix it. First glRotatef is for rotation on x.It works but the second glRotote that is for rotation on y is not working like first one.

    Think like I want to rotate on the camera axis.But when you click Left or Right,the cube turns on its own y axis

    NOTE.:: You need to press the arrows when it first work ///////////

    Code cpp:
     #include <GL/glut.h>
            #include <iostream>
            using namespace std;
     
            GLfloat rx = 0, ry = 0;
     
            void drawCube(void)
            {
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                glEnable(GL_DEPTH_TEST);
     
     
                glBegin(GL_QUADS);
                glColor3f(0.0, 1.0, 0.0);
                glVertex3f(1.0, 1.0, 1.0);
                glVertex3f(-1.0, 1.0, 1.0);
                glVertex3f(-1.0, 1.0, -1.0);
                glVertex3f(1.0, 1.0, -1.0);
     
                glColor3f(1.0, 0.0, 0.0);
                glVertex3f(1.0, -1.0, 1.0);
                glVertex3f(-1.0, -1.0, 1.0);
                glVertex3f(-1.0, -1.0, -1.0);
                glVertex3f(1.0, -1.0, -1.0);
     
                glColor3f(1.0, 1.0, 0.0);
                glVertex3f(1.0, 1.0, -1.0);
                glVertex3f(-1.0, 1.0, -1.0);
                glVertex3f(-1.0, -1.0, -1.0);
                glVertex3f(1.0, -1.0, -1.0);
     
                glColor3f(0.0, 0.0, 1.0);
                glVertex3f(1.0, 1.0, 1.0);
                glVertex3f(1.0, 1.0, -1.0);
                glVertex3f(1.0, -1.0, -1.0);
                glVertex3f(1.0, -1.0, 1.0);
     
                glColor3f(1.0, 0.5, 0.0);
                glVertex3f(-1.0, 1.0, 1.0);
                glVertex3f(-1.0, 1.0, -1.0);
                glVertex3f(-1.0, -1.0, -1.0);
                glVertex3f(-1.0, -1.0, 1.0);
     
                glColor3f(1.0, 0.5, 1.0);
                glVertex3f(1.0, 1.0, 1.0);
                glVertex3f(-1.0, 1.0, 1.0);
                glVertex3f(-1.0, -1.0, 1.0);
                glVertex3f(1.0, -1.0, 1.0);
                glEnd();
     
                glutSwapBuffers();
     
     
            }
            void arrows(int key, int x, int y)
            {
                glLoadIdentity();
                gluLookAt(0,0,5,0,0,0,0,1,0);
                switch (key) {
     
                case GLUT_KEY_LEFT:  ry += 5;
     
                    glRotatef(rx, 1, 0, 0);  // Up and down arrow keys 'tip' view.
                    glRotatef(ry, 0, 1, 0);  // Right/left arrow keys 'turn' view.
     
                    break;
                case GLUT_KEY_RIGHT:  ry -= 5;
                    glRotatef(rx, 1, 0, 0);  // Up and down arrow keys 'tip' view.
                    glRotatef(ry, 0, 1, 0);  // Right/left arrow keys 'turn' view.
                    break;
                case GLUT_KEY_UP:  rx += 5;
                    glRotatef(rx, 1, 0, 0);  // Up and down arrow keys 'tip' view.
                    glRotatef(ry, 0, 1, 0);  // Right/left arrow keys 'turn' view.
                    break;
                case GLUT_KEY_DOWN:  rx -= 5;
                    glRotatef(rx, 1, 0, 0);  // Up and down arrow keys 'tip' view.
                    glRotatef(ry, 0, 1, 0);  // Right/left arrow keys 'turn' view.
                    break;
     
                }
                cout << rx << " " << ry << "\n";
                drawCube();
            }
     
            int main(int argc, char **argv){
                glutInit(&argc, argv);
                glutInitWindowSize(640, 480);
                glutInitWindowPosition(300, 150);
                glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
     
     
                glutCreateWindow("");
                glutSpecialFunc(arrows);
     
                glClearColor(1.0, 1.0, 1.0, 1.0);
     
                glMatrixMode(GL_PROJECTION);
                gluPerspective(100, 1.5, 1, 10);
                glMatrixMode(GL_MODELVIEW);
     
                glPushMatrix();
                glutMainLoop();
                return 0;
            }
    Last edited by Dark Photon; 12-02-2017 at 09:04 AM.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,522
    You can't achieve what (I think) you're trying to do by accumulating X and Y angles; you need to accumulate matrices. E.g. using GLM:
    Code cpp:
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glut.h>
     
    glm::mat4 m(1.0f);
     
    void drawCube(void)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
     
     
        glBegin(GL_QUADS);
        glColor3f(0.0, 1.0, 0.0);
        glVertex3f(1.0, 1.0, 1.0);
        glVertex3f(-1.0, 1.0, 1.0);
        glVertex3f(-1.0, 1.0, -1.0);
        glVertex3f(1.0, 1.0, -1.0);
     
        glColor3f(1.0, 0.0, 0.0);
        glVertex3f(1.0, -1.0, 1.0);
        glVertex3f(-1.0, -1.0, 1.0);
        glVertex3f(-1.0, -1.0, -1.0);
        glVertex3f(1.0, -1.0, -1.0);
     
        glColor3f(1.0, 1.0, 0.0);
        glVertex3f(1.0, 1.0, -1.0);
        glVertex3f(-1.0, 1.0, -1.0);
        glVertex3f(-1.0, -1.0, -1.0);
        glVertex3f(1.0, -1.0, -1.0);
     
        glColor3f(0.0, 0.0, 1.0);
        glVertex3f(1.0, 1.0, 1.0);
        glVertex3f(1.0, 1.0, -1.0);
        glVertex3f(1.0, -1.0, -1.0);
        glVertex3f(1.0, -1.0, 1.0);
     
        glColor3f(1.0, 0.5, 0.0);
        glVertex3f(-1.0, 1.0, 1.0);
        glVertex3f(-1.0, 1.0, -1.0);
        glVertex3f(-1.0, -1.0, -1.0);
        glVertex3f(-1.0, -1.0, 1.0);
     
        glColor3f(1.0, 0.5, 1.0);
        glVertex3f(1.0, 1.0, 1.0);
        glVertex3f(-1.0, 1.0, 1.0);
        glVertex3f(-1.0, -1.0, 1.0);
        glVertex3f(1.0, -1.0, 1.0);
        glEnd();
     
        glutSwapBuffers();
     
     
    }
     
    void arrows(int key, int x, int y)
    {
        switch (key) {
        case GLUT_KEY_LEFT:
            m = glm::rotate(glm::mat4(1.0f), glm::radians( 5.0f), glm::vec3(0, 1.0f, 0)) * m;
            break;
        case GLUT_KEY_RIGHT:
            m = glm::rotate(glm::mat4(1.0f), glm::radians(-5.0f), glm::vec3(0, 1.0f, 0)) * m;
            break;
        case GLUT_KEY_UP:
            m = glm::rotate(glm::mat4(1.0f), glm::radians( 5.0f), glm::vec3(1.0f, 0, 0)) * m;
            break;
        case GLUT_KEY_DOWN:
            m = glm::rotate(glm::mat4(1.0f), glm::radians(-5.0f), glm::vec3(1.0f, 0, 0)) * m;
            break;
        }
     
        glutPostRedisplay();
    }
     
    void display(void)
    {
        glLoadIdentity();
        gluLookAt(0,0,5,0,0,0,0,1,0);
        glMultMatrixf(glm::value_ptr(m));
        drawCube();
    }
     
    int main(int argc, char **argv){
        glutInit(&argc, argv);
        glutInitWindowSize(640, 480);
        glutInitWindowPosition(300, 150);
        glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
     
     
        glutCreateWindow("test");
        glutSpecialFunc(arrows);
        glutDisplayFunc(display);
     
        glClearColor(1.0, 1.0, 1.0, 1.0);
     
     
        glMatrixMode(GL_PROJECTION);
        gluPerspective(100, 1.5, 1, 10);
        glMatrixMode(GL_MODELVIEW);
     
        glPushMatrix();
        glutMainLoop();
        return 0;
    }

    Also note that the rendering has been moved to the display callback; the keyboard callback simply updates the state then calls glutPostRedisplay().

  3. #3
    Newbie Newbie
    Join Date
    Dec 2017
    Posts
    2

    I cant use GLM

    Quote Originally Posted by GClements View Post
    You can't achieve what (I think) you're trying to do by accumulating X and Y angles; you need to accumulate matrices. E.g. using GLM:
    Code cpp:
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glut.h>
     
    glm::mat4 m(1.0f);
     
    void drawCube(void)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
     
     
        glBegin(GL_QUADS);
        glColor3f(0.0, 1.0, 0.0);
        glVertex3f(1.0, 1.0, 1.0);
        glVertex3f(-1.0, 1.0, 1.0);
        glVertex3f(-1.0, 1.0, -1.0);
        glVertex3f(1.0, 1.0, -1.0);
     
        glColor3f(1.0, 0.0, 0.0);
        glVertex3f(1.0, -1.0, 1.0);
        glVertex3f(-1.0, -1.0, 1.0);
        glVertex3f(-1.0, -1.0, -1.0);
        glVertex3f(1.0, -1.0, -1.0);
     
        glColor3f(1.0, 1.0, 0.0);
        glVertex3f(1.0, 1.0, -1.0);
        glVertex3f(-1.0, 1.0, -1.0);
        glVertex3f(-1.0, -1.0, -1.0);
        glVertex3f(1.0, -1.0, -1.0);
     
        glColor3f(0.0, 0.0, 1.0);
        glVertex3f(1.0, 1.0, 1.0);
        glVertex3f(1.0, 1.0, -1.0);
        glVertex3f(1.0, -1.0, -1.0);
        glVertex3f(1.0, -1.0, 1.0);
     
        glColor3f(1.0, 0.5, 0.0);
        glVertex3f(-1.0, 1.0, 1.0);
        glVertex3f(-1.0, 1.0, -1.0);
        glVertex3f(-1.0, -1.0, -1.0);
        glVertex3f(-1.0, -1.0, 1.0);
     
        glColor3f(1.0, 0.5, 1.0);
        glVertex3f(1.0, 1.0, 1.0);
        glVertex3f(-1.0, 1.0, 1.0);
        glVertex3f(-1.0, -1.0, 1.0);
        glVertex3f(1.0, -1.0, 1.0);
        glEnd();
     
        glutSwapBuffers();
     
     
    }
     
    void arrows(int key, int x, int y)
    {
        switch (key) {
        case GLUT_KEY_LEFT:
            m = glm::rotate(glm::mat4(1.0f), glm::radians( 5.0f), glm::vec3(0, 1.0f, 0)) * m;
            break;
        case GLUT_KEY_RIGHT:
            m = glm::rotate(glm::mat4(1.0f), glm::radians(-5.0f), glm::vec3(0, 1.0f, 0)) * m;
            break;
        case GLUT_KEY_UP:
            m = glm::rotate(glm::mat4(1.0f), glm::radians( 5.0f), glm::vec3(1.0f, 0, 0)) * m;
            break;
        case GLUT_KEY_DOWN:
            m = glm::rotate(glm::mat4(1.0f), glm::radians(-5.0f), glm::vec3(1.0f, 0, 0)) * m;
            break;
        }
     
        glutPostRedisplay();
    }
     
    void display(void)
    {
        glLoadIdentity();
        gluLookAt(0,0,5,0,0,0,0,1,0);
        glMultMatrixf(glm::value_ptr(m));
        drawCube();
    }
     
    int main(int argc, char **argv){
        glutInit(&argc, argv);
        glutInitWindowSize(640, 480);
        glutInitWindowPosition(300, 150);
        glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
     
     
        glutCreateWindow("test");
        glutSpecialFunc(arrows);
        glutDisplayFunc(display);
     
        glClearColor(1.0, 1.0, 1.0, 1.0);
     
     
        glMatrixMode(GL_PROJECTION);
        gluPerspective(100, 1.5, 1, 10);
        glMatrixMode(GL_MODELVIEW);
     
        glPushMatrix();
        glutMainLoop();
        return 0;
    }

    Also note that the rendering has been moved to the display callback; the keyboard callback simply updates the state then calls glutPostRedisplay().
    I cant Use GLM.I can just simple opengl functions like in my code

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,522
    Quote Originally Posted by ZuoKsrf View Post
    I cant Use GLM.I can just simple opengl functions like in my code
    In which case, you just need to write replacements for glm::rotate() and operator* (matrix multiplication).

    You can either copy the rotate() code from GLM or use the information in the glRotate reference page. Or you can write specialised versions for the X and Y axes.

  5. #5
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    10

    very nice start

    Quote Originally Posted by ZuoKsrf View Post
    I try to rotate a cube with keyboard but I can't. The first rotation works correctly but the second rotation is broken.I understand why, but I can't figure out how to fix it. First glRotatef is for rotation on x.It works but the second glRotote that is for rotation on y is not working like first one.

    Think like I want to rotate on the camera axis.But when you click Left or Right,the cube turns on its own y axis

    NOTE.:: You need to press the arrows when it first work ///////////
    [/highlight]
    The fact that you wait for a callback before drawing is good. However you should probably draw first and wait for another callback before redrawing. Secondly, I think this one was overlooked slightly in your design , you have global variables , meaning they can be used anywhere. I'm not a user of Glut so I can't say for sure when the glLoadIdentity() equivalent is called but is it possible that calling your draw from inside has somehow triggered such an event?

    Maybe Clement can tell me when such an event occurs?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •