Search code examples
openglglulookat

OpenGL - wrong objects positioning - gluLookAt()


I've got a taks from university and have to make a small example of solar system, the objects have to rotate etc. The problem is that when I do not call GluLookAt() everything looks fine, but I would like to change the view and when I call the function, there occurs that one orbit renders completely strangely. I do not know if problem is with wrong creation of the first orbit, or with the proper values in gluLookAt parameters. Can anyone help?

Here's how it looks without calling gluLookAt():

Here's how it looks after gluLookAt():

Here's the code:

#include "stdafx.h"
#include  <GL\glut.h>
#include <math.h>

GLfloat yRotated=1;
GLfloat movement = 0;


void drawCircle(float r) { // radius

    glBegin(GL_LINE_LOOP);
    for (int i = 0; i <= 300; i++) {
        double angle = 2 * 3.14 * i / 300;
        double x = r*cos(angle);
        double y = r*sin(angle);
        glVertex3d(x, y, -5.5);
    }
    glEnd();

}



void display(void) {
    glMatrixMode(GL_MODELVIEW);
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    //gluLookAt(5, 5, 5, 0, 0, -8, 0, 1, 0); // 3rd coordinate - depth

    float radius1 = 6;
    float radius2 = 1;

    //first orbit
    glColor3f(1, 1, 1);
    glPushMatrix();
    glTranslatef(0, 0, -5.5);
    drawCircle(radius1);
    glPopMatrix();


    //second orbit with rotation
    glPushMatrix();
    glRotatef(yRotated, 0, 0, 1);
    glPushMatrix();
    glTranslatef(radius1 / 2, 0, 0);
    drawCircle(radius2);
    glPopMatrix();
    glPopMatrix();


    //first czajnik
    glColor3f(0.8, 0.2, 0.1);
    glPushMatrix();
    glTranslatef(0.0, 0.0, -5.5);
//  glScalef(1.0, 1.0, 1.0);
    glRotatef(yRotated, 0, 0, 1);
    glRotatef(90, 1, 0, 0);
    glutSolidSphere(1,20,20);


    //second czajnik
    glPushMatrix();
    glColor3f(0, 0, 1);
    glTranslatef(radius1/2, 0, 0);
    glRotatef(yRotated, 0, 1, 0);
    glutSolidSphere(0.5, 20, 20);

    //third czajnik
    glPushMatrix();
    glTranslatef(radius2, 0, 0);
    glColor3f(1, 1, 0);
    glRotatef(yRotated, 0, 1, 0);
    glutSolidSphere(0.2, 20, 20);
    glPopMatrix();


    //second czajnik pop
    glPopMatrix();


    //first czajnik pop
    glPopMatrix();





    glFlush();
}

void idle() {

        yRotated += 0.1;
        Sleep(2);
        display();

}

void myReshape(int w, int h) {

    if (w == 0 || h == 0) return;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(70.0, (GLdouble)w / (GLdouble)h, 0.5, 20.0); 

    glViewport(0, 0, w, h);
}



int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(900, 600);
    glutCreateWindow("Solar system");
    //window with a title
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glClearColor(0, 0, 0, 1.0);
    glutDisplayFunc(display);
    glutReshapeFunc(myReshape);
    glutIdleFunc(idle);
    glutMainLoop();
    return 0;
}

Solution

  • Some of your objects are at different z values, e.g. 1st orbit at -5.5, second at 0, because you "popped" the matrix.

    In general, do not do so many push\pops nested into each other, matrix stack isn't made of rubber.

    There is more efficient circle drawing procedure than to calculate sine and cosine for each step, e.g. to get advantage of circle being a figure of rotation:

    inline void circle(F32 r, U32 quality)
    {
        if (r < F_ALMOST_ZERO) return;
    
        F32 th = M_PI /(quality-1);
        F32 s = sinf(th);
        F32 c = cosf(th);
        F32 t;
    
        F32  x = r;
        F32  y = 0;
    
        ::glBegin (GL_LINE_LOOP);
        for(U32 i = 0; i < quality; i++)
        {
            glVertex2f(x, y);
            t = x;
            x = c*x + s*y;
            y = -s*t + c*y;
        }
        ::glEnd();
    }
    

    it can be optimized further by using symmetry, but this one is the basis.