iDevGames Forums
glLookAt problem - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: glLookAt problem (/thread-3242.html)



glLookAt problem - Tekkan - Jun 12, 2007 11:07 PM

Hello iDevGames!

I have started using C++, SDL, and OpenGL recently to try to setup a basic game. I have run into a problem with the gluLookAt function, which seems to be that it just... doesn't do anything. After reviewing someone else's similar problem, here: http://www.idevgames.com/forum/showthread.php?t=2345 I feel positive that my code is correct, yet for some reason it's not working. I figured the only possible explanation for this might be that I might need to change some SDL-specific options for my code to work.

In any event, here is my basic OpenGL setup:
Code:
void initOpenGL(int WIDTH, int HEIGHT)
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0);
    glDepthFunc(GL_LESS);
    glShadeModel(GL_SMOOTH);
    
    glEnable(GL_DEPTH_TEST | GL_DOUBLE);
    
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // Really Nice Perspective Calculations
    
    glViewport(0, 0, WIDTH, HEIGHT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    float ASPECT_RATIO = (float) (WIDTH / HEIGHT);
    gluPerspective(WINDOW_PERSPECTIVE, ASPECT_RATIO, 0.1f, 100.0f);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    // this clears the screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

and here is my render function

Code:
void render()
{
    // Clear the color and depth buffers.
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    /*
     gluLookAt:
     the camera is AT the position EYE
     the camera is LOOKING TOWARD the CENTER
    
     the current values are just arbitrary, for testing purposes
     */
    gluLookAt(0.0, 50.0, -100.0,
              0.0, 5.0, 0.0,
              0.0, 7.0, 0.0);  
    
    
    glLoadIdentity();
    
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_LINES);
        glVertex3f(0, 50, -100);
        glVertex3f(100, 200, -100);
    glEnd();



    /*
    * Swap the buffers. This this tells the driver to
    * render the next frame from the contents of the
    * back-buffer, and to set all rendering operations
    * to occur on what was the front-buffer.
    *
    * Double buffering prevents nasty visual tearing
    * from the application drawing on areas of the
    * screen that are being updated at the same time.
    *
    * If it's not double-buffered, it will just flush
    * the pipeline to screen.
    */
    SDL_GL_SwapBuffers();
    //glFlush();
}

No matter what arguments I try for gluLookAt, nothing happens. It doesn't do anything. My line always looks the same.

I have the glMatrixMode set to MODELVIEW, not PROJECTION, so glLookAt should work, right? Have I enabled something I should not have, or done something else wrong?

Thanks in advance for the help,
Tekkan


glLookAt problem - Fenris - Jun 13, 2007 02:48 AM

Just after your gluLookAt call, you have glLoadIdentity() - that resets the model view matrix. Remove that line and you should be fine. Smile


glLookAt problem - longjumper - Jun 13, 2007 09:28 AM

And now for the reason why:

gluLookAt creates a matrix to multiply onto the current model view matrix. It's basically a "human readable" way of setting up a camera, which is no more than apply a transformation to the entire world as far as OpenGL see its. It creates this idea of a "camera" to be more intuitive to the user. When you first call glLoadIdentity, you set the model view matrix to the identity matrix. Which means any vertex you pass into OpenGL, it comes out the same. When you set up your model view matrix, every vertex is transformed by that matrix to produce a point in world space that is transformed so that it looks as though you are viewing it from the parameters you supplied to gluLookAt. Calling glLoadIdentity again afterwards just returns it to the identity matrix. A similar situation would be doing something like: x = 1; x = someCrazyCalculation(); x = 1; in that order. In fact, the scalar number 1 is the identity for scalars, just as the identity matrix is the identity for matrices. Wink


glLookAt problem - Tekkan - Jun 13, 2007 10:40 AM

It works! Thanks so much, both of you... but I'm still running into one minor problem. It seems like I need to call glLoadIdentity before drawing objects outside of the "main.cpp" file.

For example, assume this is TileMap.cpp

Code:
#include <stdio.h>

#include <OpenGL/gl.h>
#include <OpenGL/glu.h>

#include "TileMap.h"
#include "Tile.h"

// other stuff ignored....

//draws a grid
void TileMap::render()
{
    //glLoadIdentity(); // this will not be drawn at all without glLoadIdentity() ??  
    glColor3f(0.5f, 0.5f, 0.5f);
    glBegin(GL_LINES);
    for (int i = 0; i <= WIDTH; i++)
    {
        glVertex3f(i*TILERAD, HEIGHT*TILERAD, -100);
        glVertex3f(i*TILERAD, 0, -100);
    }
    
    for (int i = 0; i <= HEIGHT; i++)
    {
        glVertex3f(0, i*TILERAD, -100);
        glVertex3f(WIDTH*TILERAD, i*TILERAD, -100);
    }
    glEnd();
}

Now, back to main.cpp, in the render function

Code:
// assume i've already created TILEMAP as a TileMap object
    
    
    gluLookAt(0, 0, 0,
              0, 0, -100,
              0, 1, 0);
    
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_LINES);
        glVertex3f(10, 50, -100);
        glVertex3f(-50, 37, -100);
    glEnd();
    
    
    TILEMAP.render();

TILEMAP.render will only draw something if I call glLoadIdentity in the function itself... otherwise it does not get drawn at all. The only problem is that if I do include glLoadIdentity in TILEMAP.render, it doesn't get transformed by my glLookAt function.

Do I simply have to recall glLookAt after calling glLoadIdentity each time, or is there a simpler solution I can't see here?


glLookAt problem - longjumper - Jun 13, 2007 11:01 AM

You should only need to call glLoadIdentity and gluLookAt once per frame, in that order.

Let's look at your LookAt function, it says you are at the origin looking down the -z axis, so you are 100 units away from where you are drawing these lines. Your gluPerspective function is specifiying that you only want to see 100 units away. Therefore, your lines are being culled because they are too far away. Increase the "far" parameter in gluPerspective to something like 1000, you should be able to see the lines then.


glLookAt problem - Tekkan - Jun 13, 2007 11:56 AM

That makes sense. I had also run into problems because I was using glTranslate for some objects, and not using it with others (I had reset the position with glLoadIdentity).


glLookAt problem - longjumper - Jun 14, 2007 10:57 AM

Call glTranslate(as well as glRotate, glScale, and glMultMatrix) from within push/pop blocks. That way, when you pop, you are back to the matrix you had before you had called the last push. You don't reset matrices with glLoadIdentity - you are loading the identity. The only efficient way of "reset"ing your matrix to the previous matrix is to use push/pop commands.