PDA

View Full Version : undefined behavior and gluLookAt()



akashiraffee
04-22-2009, 05:18 PM
Where should I be calling gluLookAt()? I currently use it at the end of my display function, right before glFlush() or glSwapBuffers().

I'm asking because I have some example code where the scene "disappears" immediately depending on the presence of gluLookAt() BUT NOT ALWAYS. As in, I don't even have to recompile. If I run the SAME executable over and over, about 60-70% of the time the scene disappears, the rest it does not. I am not a novice to C and I have *never* seen this happen happen (an executable with random runtime behavior).

scratt
04-22-2009, 08:16 PM
gluLookAt alters your current viewing matrix..


...gluLookAt is equivalent to
glMultMatrixf(M);
glTranslated (-eyex, -eyey, -eyez);

Look very carefully at your code to see what Matrix mode you are in, if any conditions in your code are altering this differently on a frame by frame basis, or your current matrix mode...

Also perhaps try wrapping some code in a few glGetError().
I would expect most likely you either have some logic that is messing up your maths or a stack underflow / overflow..

dletozeun
04-23-2009, 04:45 AM
I think you misunderstand 3D transformations in OpengGL. Read this to better understand the concepts of Propejction, ModelView, ... matrices:
http://www.opengl.org/wiki/Viewing_and_Transformations

akashiraffee
04-23-2009, 06:11 AM
gluLookAt alters your current viewing matrix..

Look very carefully at your code to see what Matrix mode you are in, if any conditions in your code are altering this differently on a frame by frame basis, or your current matrix mode...


I know what gluLookAt is for and what it generally does; this is not my first openGL program. I have learned lighting and movement and can make little scenes with orbiting objects, pattern materials, move the camera, etc. I sat down the day before yesterday to learn textures and after getting nowhere despite a wealth of reference material (see my other thread (http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=256490#Post256490), I decided to just take some working code from the redbook and slowly modify it to meet my needs and hopefully figure out why my textures fail to appear.

The first thing I did was add gluLookAt, and that's when I noticed this peculiarity. So I did not actually write this code, it is from exercise 9-1 of the 6th addition. I tried moving gluLookAt to the beginning of the "display" function, before the objects are rendered, and that consistently produces the same result: no scene at all, although the "camera" is at (0,0,50), looking at the origin, and the scene is drawn at the origin. Since there are no pop/push Matrix calls, it would be hard to see where in these 75 simple lines I could have become confused about that. It's single buffered, but I haven't found any caveats against using glLookAt single buffered; basically I would much rather have someone who understands GL from practice explain to me what is wrong with this incredibly simple example rather than just start plugging away changing things hoping something will make it better.

If I put glLookAt at the end of the display function (which is where I left it here, about half way down), we get the undefined behavior. I just tested this again; I compiled using -Wall and I get one warning for the redbook authors, "suggest parentheses around comparison in operand of ^"; this does not look significant to me, but I have marked that line for the curious. Anyway, after compiling ONCE and running the same executable 10 times, the scene appeared properly 6 times, and the other four times it appears for an instant and then disappears.


#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

#define checkImageWidth 64
#define checkImageHeight 64

void change (int w, int h);
void display(void);
void init(void);
void makeCheckImage(void);

static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLuint texName;

int main(int argc, char** argv) {
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1200,800);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(change);
glutMainLoop();
return 0;
}

void change (int w, int h) {
float aspect=(float)w/(float)h;
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f,aspect,1.0f,30.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.6);
}

void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texName);

/* move gluLookAt to here and the scene never appears */
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);

glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
gluLookAt(0.0f,0.0f,50.0f,0.0f,0.0f,0.0f,0.0f,1.0f ,0.0f);
glFlush();
glDisable(GL_TEXTURE_2D);
}

void init(void) {
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);

makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glGenTextures(1, &amp;texName);
glBindTexture(GL_TEXTURE_2D, texName);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
}

void makeCheckImage(void) {
int i, j, c;

for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
/* gcc wants even more parantheses here...*/
c = ((((i&amp;0x8)==0)^((j&amp;0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
}

dletozeun
04-23-2009, 08:03 AM
I know what gluLookAt is for and what it generally does


It seems that you do not know well. Put gluLookAt before drawing the scene geometry and call glLoadIdentity before, otherwise it is like each frame you "concatenate" the gluLookAt transformation on the modelview matrix.

akashiraffee
04-23-2009, 08:28 AM
[quote]
It seems that you do not know well. Put gluLookAt before drawing the scene geometry and call glLoadIdentity before, otherwise it is like each frame you "concatenate" the gluLookAt transformation on the modelview matrix.

Please read more carefully. I said in the post that I did try it at the beginning (it was originally at the beginning, I moved it to the end). I tried adding "glLoadIdentity" before that (it does not make any difference and I don't see why it would, either):


/* move gluLookAt to here and the scene never appears */
glLoadIdentity();
gluLookAt(0.0f,0.0f,50.0f,0.0f,0.0f,0.0f,0.0f,1.0f ,0.0f);

The comment is from my 2nd post. So we are kind of going backward with this; what I really need is someone to look at the original code (it's all there), and tell me DECISIVELY what needs to change to make it work. I understand if you do not have time, however, I am sure if you have any amount of serious experience with GL it will be DEAD SIMPLE.
I've compiled other peoples code in other forums, tested my solution TO MAKE SURE IT WORKS (instead of just issuing vague statements), and explained in concrete terms what I have just PROVEN. That's a "solution". I do that almost everyday, in fact. Hopefully there is someone else out there with the same level of commitment to the forum concept ;) If not, I guess I am on my own.

akashiraffee
04-23-2009, 11:08 AM
For posterity, this was solved at cboard (http://cboard.cprogramming.com/game-programming/115188-opengl-textures-glulookat-undefined-behavior.html) (much love!) which to be fair certianly has a much larger user base.

Have a nice day y'all...

dletozeun
04-23-2009, 11:22 AM
Sorry I must admit a read a bit fastly your post.

I tested the code you provided in the second post and worked fine for me.
I have been mistaken in my last post because I though the window was constantly updated and it is not, so the display function is only called once.
Moreover in case of window reshape you actually do the glLoadIdentity call.

When you put gluLookAt at the end, the modelview matrix is not affected by this one when drawing the quads so you can see them.

When you put the gluLookAt before drawing the quads, these ones are affected by the view transformation. The problem, is that you go 50 units (along z axis) further from the quads whereas you set the [znear, zfar] clip interval to [1 30].
This is not sufficient and the geometry is clipped. Try to enlarge this interval, e.g with zfar = 100 and you will see something.