PDA

View Full Version : frustum problem



arthas
02-16-2008, 01:08 AM
Hi! my program creates a chessboard using 3d texture; the program creates 3 different chessboard and display the blending. When I use an Ortho projection is all ok,( if I change the visible plane it works perfectly). The problem is with glFrustum: if I move znear or zfar the chessboard is /isn't visible but if I change left/right I always see the chessboard ( that shouldn't be correct!). Suggestions?



#include <windows.h>
#include <stdio.h>
#include "glew.h"
#include "glut.h"

static void display(void);

int main(int argc, char **argv)
{
int Err=0;

glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInit(&amp;argc, argv);
glutCreateWindow("Chessboard");
glutDisplayFunc(display);

GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));

}
glutMainLoop();

return Err;
}

static void display(void)
{
// Create texture data
float *pData = new float[32*32*3*3];
int nx,ny,nz,nIndex;
for (nIndex=0; nIndex<32*32*3*3; nIndex++)
pData[nIndex]=0;
nIndex=0;
for (nz=0; nz<3; nz++)
for (nx=0; nx<32; nx++)
for (ny=0; ny<32; ny++)
{
if (((nx+ny)%((nz+1)*2))==0)
pData[nIndex]=0.0;
else
pData[nIndex]=0.3;
nIndex+=3;
}

// Enable texture, declare and init texture
glEnable(GL_TEXTURE_3D);
GLuint tex;
glGenTextures (1, &amp;tex);

// Activate texture mapping
glBindTexture(GL_TEXTURE_3D,tex);

// Set dimension
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);

GLenum errCode;
const GLubyte *errString;
if ((errCode = glGetError()) != GL_NO_ERROR) //check for glut errors
{
errString = gluErrorString(errCode);
fprintf (stderr, "OpenGL Error: %s\n", errString);
getchar();
}

// Set texture data
glTexImage3D(GL_TEXTURE_3D,0,GL_RGB,32,32,3,0,GL_R GB,GL_FLOAT,pData);

// Clear buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Set geometry
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0,1.0,-1.0,1.0);


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//set blending
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_CONSTANT_COLOR,GL_ONE);
glBlendColor(1.0,1.0,1.0,1.0);


// Draw quad
glBegin(GL_QUADS);
for (nz=0; nz<3; nz++)
{
glTexCoord3f(0.0,0.0,nz); glVertex3f(-0.8, -0.8, 0.1+0.1*nz);
glTexCoord3f(1.0,0.0,nz); glVertex3f(0.8, -0.8, 0.1+0.1*nz);
glTexCoord3f(1.0,1.0,nz); glVertex3f(0.8, 0.8, 0.1+0.1*nz);
glTexCoord3f(0.0,1.0,nz); glVertex3f(-0.8, 0.8, 0.1+0.1*nz);
}
glEnd();

// Disable texture
glDisable(GL_TEXTURE_3D);

glDisable(GL_BLEND);

delete [] pData;


glutSwapBuffers();
}

Bob
02-16-2008, 03:56 AM
Can't answer what you did wrong since you never said how you tried to use it.

I can, however, point out that you should never recreate the texture every time you're drawing something. Your display function leaks resources as it allocates a new texture object every time the display function is called, but it is never deleted. And don't stick a glDeleteTextures at the end of the display function. Put the texture code outside the display function and reuse the texture object.

arthas
02-16-2008, 04:25 AM
Thanks Bob, but the resources isn't a problem because this code is not the final program; what i want to do is not display the result but calculate it and then create a file ( with c++ classes that i wrote..).
What I've tried to do is, using glFrustum instead of ortho. As I sad, setting f.e znear=10 and zfar=20 I don't see the chessboard ( that is right because the z coordinate of the quad, is at most 0.1+0.1*3=0.4) but, if I set f.e left = 20 and right =30 I see the chessboard ( that is wrong bacause the quad left coordinate is -0.8). I hope to be clear..

Bob
02-16-2008, 06:11 AM
Not clear what parameters you use in the second case. Do you leave near and far at 20 and 30 from the first case, or do you use -1 and 1 from the gluOrtho-case?

Or just show the exact code for each test case and describe the result. Describing code changes in words is too ambiguous.

arthas
02-16-2008, 06:57 AM
ok, sorry... f.e. if I use all the code... and instead of the ortho, this:
glFrustum(-90.0,-80.0,-1.0,1.0,0.0,0.4);
I shouldn't see the chessboard, because I'm watching in a frustum with left=-90 and right=-80, and being the min X coordinate of the quad =-0.8, how is it possible?

Bob
02-16-2008, 09:44 AM
What you should and shouldn't see in that case is not important, becuase the near clip plane is wrong. The near clip plane must be a positive value.

arthas
02-16-2008, 10:00 AM
are you sure that it can't be 0.0? because if I write: glFrustum(-1.0,1.0,-1.0,1.0,0.0,1.0); I see the chessboard blended
but if I use:
glFrustum(-1.0,1.0,-1.0,1.0,0.1,1.0); I don't see anything..

-NiCo-
02-16-2008, 12:33 PM
Read this (http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/frustum.html) document if you want to understand the inner workings of glFrustum. Take a look at the Notes section:



NOTES
Depth buffer precision is affected by the values specified
for zNear and zFar...
Because r approaches infinity as zNear approaches 0, zNear
must never be set to 0.


N.

arthas
02-16-2008, 12:59 PM
I see -Nico-, but why if I use 0 the program works and if I use a positive value I don't see nothing?

Bob
02-16-2008, 01:05 PM
If you use zero for near clip plane, the driver probably handles it in one of two cases. Either it reports an error and ignores the command (effectively leaving you with identity matrix), or the driver assumes you pass correct values and attempts to divide by zero. Either case, the matrix is undefined and useless and no conclusions can be drawn from using it.

This is not only a limitation in OpenGL, it's how projections in general works. Projection is about projecting the volume onto a plane (although depth information is preserved for the depth buffer), and this plane is then mapped to the screen. But with a near plane of 0, you're projecting everyting into a single point, and a single point cannot uniquely map to a surface on the screen. It's a mathematical impossibility.

-NiCo-
02-16-2008, 01:32 PM
Maybe you're better off using the gluPerspective (http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/perspective.html)function, it's easier to understand intuitively. When using glFrustum it's important to understand that the left, right, top, bottom and znear values are intertwined. Changing the znear value does not perform a simple shift of the near clipping plane but also changes the opening angle of your perspective camera.

N.

arthas
02-17-2008, 02:26 AM
gluPerspective is certainly simpler to use, but I must use glfrustum because what I need is asymmetrical frustum.. and please explain me this:
I changed quad coordinates and frustum values, now I don't use zeros and what I should see is my chessboard; I don't see nothing!
WHY?? (If I use gluOrtho2D(-2.0,2.0,-2.0,2.0); it works but it's not what I need )


glFrustum(-2.0,2.0,-2.0,2.0,1.0,3.0);
...
glBegin(GL_QUADS);
for (nz=0; nz<3; nz++) {
glTexCoord3f(0.0,0.0,nz); glVertex3f(-1.5, -1.5, 1+0.1*nz);
glTexCoord3f(1.0,0.0,nz); glVertex3f(1.5,-1.5, 1+0.1*nz);
glTexCoord3f(1.0,1.0,nz); glVertex3f(1.5, 1.5, 1+0.1*nz);
glTexCoord3f(0.0,1.0,nz); glVertex3f(-1.5, 1.5, 1+0.1*nz);
}

Bob
02-17-2008, 03:55 AM
The near and far clip plane parameters defines the distance along the negative Z-axis where you want the clip planes to be positioned. So clip planes at 1 and 3 makes the valid depth range -1 to -3.

arthas
02-17-2008, 05:38 AM
So, if I used

glFrustum(-2.0,-2.0,-2.0,2.0,1.0,3.0); and

glBegin(GL_QUADS);
for (nz=0; nz<3; nz++)
{
glTexCoord3f(0.0,0.0,nz); glVertex3f(-1.5, -1.5, -1.5+0.1*nz);
glTexCoord3f(1.0,0.0,nz); glVertex3f(1.5,-1.5, -1.5+0.1*nz);
glTexCoord3f(1.0,1.0,nz); glVertex3f(1.5, 1.5, -1.5+0.1*nz);
glTexCoord3f(0.0,1.0,nz); glVertex3f(-1.5, 1.5, -1.5+0.1*nz);
I should see the chessboard correctly? because I don't see nothing.. :-(

Bob
02-17-2008, 09:39 AM
You have the same value for left and right in glFrustum.

arthas
02-17-2008, 10:39 AM
ok I'm a stupid....... THANKS Bob!!!!!!!!