I have openGL code

#include <iostream> #include <glut.h> #include <math.h> #include <QDebug> using namespace std; #define WIDTH 1024 #define HEIGHT 600 void display(); void reshape(int width, int height); void keyboard(unsigned char key, int x, int y); void moveCamera(); void init(); void mkList(); //double z(const double &x, const double &y); //void enableLight(); //void idle(); GLuint idList = 0; double e_x = 0; double e_y = 0; double e_z = 0; double r = 300; double phi = 0; double theta = 1.5; int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(WIDTH, HEIGHT); glutInitWindowPosition(30, 100); glutCreateWindow("Lab#2"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); // glutIdleFunc(idle); glEnable(GL_DEPTH_TEST); init(); mkList(); // enableLight(); glutMainLoop(); return 0; } void display() { glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); moveCamera(); glCallList(idList); glFinish(); } void reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // glOrtho(-width/2, width/2, -height/2, height/2, -width/2, width/2); gluPerspective(45, 2, 100, 2000); // glFrustum(-width/2, width/2, -height/2, height/2, 100, 500); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { #define ESCAPE '\033' switch (key) { case ESCAPE: exit(0); break; case 's': theta += 0.1; break; case 'w': theta -= 0.1; break; case 'a': phi += 0.1; break; case 'd': phi -= 0.1; break; case 'q': r-=5; break; case 'e': r+=5; break; default: break; } e_x = r * sin(theta) * cos(phi); e_z = r * sin(theta) * sin(phi); e_y = r * cos(theta); glutPostRedisplay(); } void moveCamera() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); int vec = ceil(theta / 3.1415); int y; if (vec%2) y = 1; else y = -1; gluLookAt(e_x, e_y, e_z, 0, 0, 0, 0, y, 0); } void init() { e_x = r * sin(theta) * cos(phi); e_z = r * sin(theta) * sin(phi); e_y = r * cos(theta); } void mkList() { int idInnerList = glGenLists(1); glNewList(idInnerList, GL_COMPILE); glColor3ub(255, 0, 0); glPushMatrix(); glTranslatef(-200, 0, 0); glutWireSphere(50, 10, 10); glPopMatrix(); glColor3ub(0, 255, 0); glPushMatrix(); glTranslatef(200, 0, 0); glutSolidCube(100); glPopMatrix(); glEndList(); idList = glGenLists(1); glNewList(idList, GL_COMPILE); glCallList(idInnerList); glPushMatrix(); glTranslatef(0, 0, 200); glCallList(idInnerList); glPopMatrix(); glPushMatrix(); glTranslatef(0, 0, -200); glCallList(idInnerList); glPopMatrix(); glEndList(); } 

Let's look at the display () function.

 void display() { glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); moveCamera(); glCallList(idList); glFinish(); } 

The display function has a moveCamera () function.

 void moveCamera() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); int vec = ceil(theta / 3.1415); int y; if (vec%2) y = 1; else y = -1; gluLookAt(e_x, e_y, e_z, 0, 0, 0, 0, y, 0); } 

With the above arrangement of the moveCamera function in the display function, everything works fine. But it is worth moving the moveCamera function to the end of the display () function, like this:

 void display() { glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCallList(idList); moveCamera(); glFinish(); } 

Then the rotation is late for the last key. That is, I press right-right-left-left and the camera rotates right-right-right-left

I do not understand what's the matter. Who can explain?

    1 answer 1

    When moving the function moveCamera (); The new camera settings are applied only to the next frame. In other words glCallList (idList); will use "previous camera settings".

    You should understand how moving objects and cameras in OpenGL work. These functions change the current matrix (transformation) of objects that will be used in the next render. If you rendered the object in the backbuffer or in the frontbuffer, the camera changes after that will not change the current frame drawn earlier. The glFinish command all synchronizes the execution of commands on the video card with the CPU.

    • I did not understand anything. Why is this setting going to be applied to the next frame and not the current one? gluLookAt is also a multiplication of matrices, similar to rotate, scale, translate. Why multiplication will be applied to the following? - van9petryk
    • Because for the function where moveCamera (); at the end the drawing has already happened and the setting will apply only to the next display () call. - Unick