frustum problem

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(&argc, argv);
	glutCreateWindow("Chessboard");
	glutDisplayFunc(display);

	GLenum err = glewInit();
	if (GLEW_OK != err)
	{
		/* Problem: glewInit failed, something is seriously wrong. */
		fprintf(stderr, "Error: %s
", 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, &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
", errString);
		getchar();
	}

	// Set texture data
	glTexImage3D(GL_TEXTURE_3D,0,GL_RGB,32,32,3,0,GL_RGB,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();
}

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.

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…

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.

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?

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.

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…

Read this 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.

I see -Nico-, but why if I use 0 the program works and if I use a positive value I don’t see nothing?

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.

Maybe you’re better off using the gluPerspectivefunction, 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.

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);
}

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.

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… :frowning:

You have the same value for left and right in glFrustum.

ok I’m a stupid… THANKS Bob!!!