Clarification regarding the use of OpenGL matrix and matrix transformation

I was able to use the viewview matrix and functions like glTranslatef() and gluLookAt() to transform the object or point of view of the whole scene, but when I try to do both, I run into problems.

It seems that regardless of the parameters I use for gluLookAt() , the objects I draw are displayed from the same angle. I tried calling functions in various other applications using glPushMatrix() and glPopMatrix based on what I read in other threads, no luck. Here is what I have now. Objects move, they should, but I can make them appear from only one point of view.

For example, since they should move along the xy plane and circle counterclockwise, I think changing z_0 to -30 will make them move clockwise, but that doesn't seem to make any difference. Before him is a long list of constants that I leave. The ultimate goal is to make a simple model of our solar system.

  GLfloat time = 0.0; GLfloat inc = 0.01; // viewing parameters GLint winWidth = 600, winHeight = 600; GLfloat x_0 = 0.0, y_0 = 0.0, z_0 = 30.0; GLfloat xref = 0.0, yref = 0.0, zref = 0.0; GLfloat Vx = 0.0, Vy= 1.0, Vz = 0.0; GLfloat xwMin = -50.0, ywMin = -50.0, xwMax = 50.0, ywMax = 50.0; GLfloat dnear = .3, dfar = 10.0; void view(void) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(x_0, y_0, z_0, xref, yref, zref, Vx, Vy, Vz); } void init(void) { view(); glEnable(GL_DEPTH_TEST); } void drawPlanet(GLfloat maj, GLfloat min, GLfloat x0, GLfloat theta, GLfloat size) { GLfloat x = maj * cosf(theta) + x0; GLfloat y = min * sinf(theta); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glTranslatef(x, y, 0); glutSolidSphere(size, 25, 25); glPopMatrix(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); drawPlanet(MERCURY_MAJOR, MERCURY_MINOR, MERCURY_CENTER, time / MERCURY_YEAR, MERCURY_SIZE); drawPlanet(MARS_MAJOR, MARS_MINOR, MARS_CENTER, time / MARS_YEAR, MARS_SIZE); drawPlanet(URANUS_MAJOR, URANUS_MINOR, URANUS_CENTER, time / URANUS_YEAR, URANUS_SIZE); glFlush(); } void idle(void) { time += inc; display(); glutSwapBuffers(); } int main (int argc, char **argv) { glutInit(&argc, argv); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH); glutCreateWindow(""); init(); glutDisplayFunc(display); glutIdleFunc(idle); glutMainLoop(); } 

If someone sees what I am missing, I would really persuade an explanation or guide to some additional reading that will help me fix this problem.

+4
source share
1 answer

You make a typical OpenGL newbie mistake and scatter matrix manipulations all over the place. You never initialize the state of an OpenGL matrix. Always set it when entering the display function. This greatly facilitates the determination of the location.

You may also mistakenly accept OpenGL for the scene graph, while glPush / PopMatrix will β€œmagically” establish the transformation hierarchy.

glPushMatrix - as you probably know - copies the current top of the stack matrix and pushes it onto the stack. The idea is to make temporary copies that you can multiply by further transformations.

Now let's look at your code in a slightly different form:

 void display(void) { glViewport(…); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(x_0, y_0, z_0, xref, yref, zref, Vx, Vy, Vz); glColor3f(1.0, 1.0, 1.0); { GLfloat x = maj * cosf(theta) + x0; GLfloat y = min * sinf(theta); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // <<<<<<<<< glTranslatef(x, y, 0); glutSolidSphere(size, 25, 25); glPopMatrix(); } 

Do you see what is going on here? You redirect your model matrix to a personality, and then translate it. The look matrix you created earlier is completely discarded and does not affect the drawing of the sphere.

Remove this glLoadIdentity() I noted, and everything should work fine.

+4
source

All Articles