PDA

View Full Version : gluLookAt and other problems

Dum
11-09-2006, 02:26 AM
Please, help me with my problems. I need it for the real scientific work, so, I'll be very thankful. First of all let us assume that I'm rendering this stuff - http://camellab.spb.ru/pub/sample.GIF . Each small cube's edge length equals 1. Blue axis is Z, red is X, green is Y. So big cube consists of 9*9*9=729 small cubes. So big cubes lies from point (5,5,5) to (-4,-4,-4)

1) On this picture I'm looking to it using gluLookAt(2,2,2,0,0,0,0,0,1). If I understand everything rigth then point (2,2,2) lies inside the big cube, but it looks like I'm looking from outside the cube. Moreover it renders same picture if I do gluLookAt(3,3,3,0,0,0,0,0,1) or gluLookAt(4,4,4,0,0,0,0,0,1). Why? I don't understand how eyepoint's coordinates are measured...

2) You can see strange white horizontal strokes on light red small cubes in the bottom. I'm getting number of such deffects from time to time. What's the origin of them, I'm drawing solid small cubes?

3) At the very beggining, I was rendering to the memory. So, I started like this:

PIXELFORMATDESCRIPTOR pfd ;
...
pfd.dwFlags=PFD_DRAW_TO_BITMAP|PFD_SUPPORT_OPENGL| PFD_SUPPORT_GDI;
...

And my 729 small cubes were rendering for the very long lime. I have quite cool PC with NVidia video-card, but nevertheless it takes significant time to render (several seconds). The fact is that I have to render much bigger cubes (100x100x100), so it is close to impossible for now. As I learnt I was getting Microsoft's renderer when choosing pixel format. So, I tried to render on the live control and I got NVidia's renderer and it is much quicker. The question is how can I choose the renderer? Can I render using NVidia renderer to the memory bitmap?

P.S. Yes, it is all under Windows.

Thanks beforehand!

jide
11-09-2006, 02:58 AM
Well it's really hard to say like that. What I can say is that you should have a different view point when changing the first 3 parameters of gluLookAt.

If you could show us your code, it will help, you might have had misplaced some matrix calls.

k_szczech
11-09-2006, 03:09 AM
1.
Please show us what you exactly do with MODELVIEW and PROJECTION matrices.

2.
This is called z-fighting. Upper face of lower cube is at "exactly" the same location as lower face of upper cube. If you render each cube at it's exact coordinates (so you pass exaclty the same coordinates to both quads that should be at the same location) GPU draws two triangles instead of one quad. If you overlap such two quads:

+--+ +--+
| /| |\ |
|/ | | \|
+--+ +--+you will receive just a bit different depth values used during depth test.
The solution is to use glEnable(GL_CULL_FACE) and draw only one face (the one that should be visible from camera).

3.
I would suggest not to render directly to memory (to a bitmap). Render to a window and then just use glReadPixels to get rendered image.
There were some discussions about selecting pixel formats here. Look for DescribePixelFormat on forums.

Dum
11-10-2006, 01:09 PM
Here is the code (don't mind about unknown variables, I'll describe everything if you will find this significant, it is just small part of huge project with giant classes :) )

// Determine the limits of visualization
initcage=true;
xlo=(int)pUnion->Datum->z.a1;
xhi=(int)pUnion->Datum->z.b1;
ylo=(int)pUnion->Datum->z.a2;
yhi=(int)pUnion->Datum->z.b2;
zlo=(int)pUnion->Datum->z.a3;
zhi=(int)pUnion->Datum->z.b3;

// Resetup output
{
COLORTOBYTES(p_colBk.Get());
glClearColor((float)(r/255.0),(float)(g/255.0),(float)(b/255.0),0);
}
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glViewport(0,0,min(pDim->cx-1,pDim->cy-1),min(pDim->cx-1,pDim->cy-1));

// Setup matrixes
glMatrixMode(GL_PROJECTION);
glOrtho(2*xlo,2*xhi,2*ylo,2*yhi,3*zlo,3*zhi);
glMatrixMode(GL_MODELVIEW);
gluLookAt(p_dEyeX.Get(),p_dEyeY.Get(),p_dEyeZ.Get( ),(xlo+xhi)/2,(ylo+yhi)/2,(zlo+zhi)/2,0.0,0.0,1.0);
// Actually, now this is the same as
// gluLookAt(2,2,2,0,0,0,0,0,1);

if (rotx!=0.0) glRotatef((float)rotx,1.0,0.0,0.0);
if (roty!=0.0) glRotatef((float)roty,0.0,1.0,0.0);
if (rotz!=0.0) glRotatef((float)rotz,0.0,0.0,1.0);
glTranslatef((float)transx,(float)transy,(float)tr ansz);

// Enter the coloring mode
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,p_bBlend.Get()?G L_AMBIENT_AND_DIFFUSE:GL_AMBIENT);

.......................................
....... Drawing, drawing, drawing .....
.......................................

P.S. Thanks a lot for the advise with culling! Question 2 is closed for now.

Dum
11-10-2006, 01:20 PM
Yes, and question 3 is also closed. I just overcame rendering to memory, but your advise about glReadPixels I now have taken into consideration. Thanks.

songho
11-10-2006, 06:43 PM
Originally posted by Dum:
1) On this picture I'm looking to it using gluLookAt(2,2,2,0,0,0,0,0,1). If I understand everything rigth then point (2,2,2) lies inside the big cube, but it looks like I'm looking from outside the cube. Moreover it renders same picture if I do gluLookAt(3,3,3,0,0,0,0,0,1) or gluLookAt(4,4,4,0,0,0,0,0,1). Why? I don't understand how eyepoint's coordinates are measured...Because you are using orthographic projection, the object should look same no matter how far the eye is away from the object. Switch the projection to perspective, then you will see the difference.

If you want to keep orthographic view, then change the params of glOrtho(), too.

Relic
11-11-2006, 06:56 AM
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,p_bBlend.Get()?G L_AMBIENT_AND_DIFFUSE:GL_AMBIENT);Beware of OpenGL pitfall #14!
http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/
Set OpenGL state before you enable it, that avoids this problem and maybe more.

Dum
11-12-2006, 03:30 PM
After songho's replic:

But in any case, point (2,2,2), eyepoint, is to be in the big cube, not outside of it. Is not it? If I undersand a thing, coordinates are measured the same way in all functions, are not they?

It seems that you are right about orthographic projection. So after glOrthe gluLookAt jus determines the direction and... what? Actually, if from (2,2,2), ..., (n,n,n) the look is the same, then from (2,3,2), (4,5,6) etc. if is different.

What is the secret with glFrustum, as I understant, with the same parameters as glOrtho it is to draw the same area of scene in the different projection, but it clips the majority of rendered cubes. Do I have to see bit modifiedm but the same picture after replacing glOrtho with glFrustum?

4Relic:

Thank you. Very significant, unexpected and useful comment.

songho
11-12-2006, 07:09 PM
Dum,
gluLookAt() indeed transforms GL_MODELVIEW matrix (both the position of eyepoint and lookat direction), however, it does not affect on orthographic projection. The reason is that you have exactly same parameters in glOrtho(), more spefically, left, right, bottom and top clipping planes are not changed.

Even if the eyepoint is inside of the cube, the viewing frustum is almost identical except near and far clipping planes. Therefore, OpenGL renders from 2*xlo to 2*xhi as width, and from 2*ylo to 2*yhi as height. In other words, you have same projected 2D window no matter where your eyepoint is placed.

Near and far clipping planes are a little different. If you move the eyepoint far away from the cube, let's say 10*zhi, then the cube is finally disappeared from the window. (clipped)

If you want to have zoom in/out effects in orthographic, change the params of glOrtho(), For example, for zoom-in effect, decrease left, right, bottom, and top values. So you will have a smaller frustum, and it is streched up to fit to the window.

Dum
11-14-2006, 09:12 AM
In other words, you have same projected 2D window no matter where your eyepoint is placed.
You are not quite right. I got the same picture if I'm looking from point (n,n,n), but when I'm looking from (n,m,k), where (n!=m && n!=k) the picture is different. Moreover, if I'll not call gluLookAt at all - I'll be looking from (0,0,0) to the negative direction of Z. Conclusion: even in orthographical projection gluLookAt has the influence, it defines something, but what? That is my question? Help please.

If you want to have zoom in/out effects in orthographic, change the params of glOrtho(), For example, for zoom-in effect, decrease left, right, bottom, and top values. So you will have a smaller frustum, and it is streched up to fit to the window.
I've done exactly this way after you previous post. Thanx.

songho
11-14-2006, 01:20 PM
Originally posted by Dum:
You are not quite right. I got the same picture if I'm looking from point (n,n,n), but when I'm looking from (n,m,k), where (n!=m && n!=k) the picture is different. Moreover, if I'll not call gluLookAt at all - I'll be looking from (0,0,0) to the negative direction of Z. Conclusion: even in orthographical projection gluLookAt has the influence, it defines something, but what? That is my question? Help please.Sorry for making you confused. I didn't mean you will have a same view all the time. But, in only case of the eyepoint is (ax, ay, az), where a is scale factor. You already knew the view is different in the other cases.

gluLookAt() simply modifies only GL_MODELVIEW matrix. That's it.

Please write something about my question, concerning glFrustum in previous post.Frustum defines a viewing area. The frustum in orthographic is a shape of a rectangular box. In perspective, the frustum is pyramid shape.

If the eyepoint is too close to the near clipping plane in perspective projection, the scene might be cropped off a lot because of narrow FOV (Field of View). You can increase FOV value in gluPerspective(), or increase left,right, bottom and top clipping plane values in glFrustum() in order to see wider area.

It is better using glPerspective() and glFrustum() instead modifying manually GL_PROJECTION matrix.

Dum
11-14-2006, 03:32 PM
gluLookAt() simply modifies only GL_MODELVIEW matrix. That's it.
But what is the applied meaning of such modification? As we can seem it defines the vector of our stare. But what is the point of this vector's application? Minimum along all axis from the glOrtho's parameters? Ok, probably, but we can determine minimum along X and Y, but what with Z? It is not so clear. How renderer determines the eyepoint to use?

songho
11-14-2006, 06:46 PM
The man page of gluLookAt() describes what elements are changed. It basically computes 3 axis vectors; side, forward, up vector, plus translation.

a b c d
ModelView matrix = e f g h
i j k l
m n o p
side axis = (a,b,c)
up axis = (e,f,g)
forward axis = (i,j,k)

translation x = d
translation y = h
translation z = l

Others are not changed by gluLookAt().Here is a simple example. I assume the up vector is always straight up which is (0,1,0) to make it simple. If the eyepoint is at (0,0,1) and is looking at (0,0,0), then the matrix will be;

1 0 0 0
0 1 0 0
0 0 1 -1
0 0 0 1The side, up, forward axis are same as the default value (identity matrix), but only translation-z is changed. Moving -1 along Z-axis. Notice the value is negated. (I think you know why it is reversed.)

What if the eye is at (0,0,-1) and looking at (0,0,0)? Now the eye is moved to the back of an object, so you need to rotate 180 degree.

Visualize yourself with your right hand and 3 fingers open. When you turn your hand along your index finger, which is up axis, you realize the thumb and the 3rd finger are flipped to the opposite side. The side axis (1,0,0) is now (-1,0,0), and the forward axis is flipped from (0,0,1) to (0,0,-1). Therefore the final matrix is;

-1 0 0 0
0 1 0 0
0 0 -1 1
0 0 0 1You don't even need math to figure out above 2 examples. But for arbitrary cases, you need vector subtraction, cross product and normalization in order to calculate side, up and forward axis. It is all in the gluLookAt() man page.

Again, gluLookAt() does not modify GL_PROJECTION matrix.

Dum
11-15-2006, 05:00 AM
Thank you