PDA

View Full Version : How to draw front- and back-scene by GL_DEPTH_TEST



charmingzuo
03-31-2008, 09:03 AM
Hello, my friends,

I tried to draw a simple cube, and wanted to show
the front-scene and back-scene by the switch,


// front-scene
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glClear(GL_DEPTH_BUFFER_BIT);
// back-scene
glClearDepth(0.0);
glDepthFunc(GL_GREATER);
glClear(GL_DEPTH_BUFFER_BIT);


But I failed! There appears some garbages in one scene.


The full test code is as following,



#include <GL/glut.h>

float hQuadSize = 3.28;
float R = 96.0;
float halfCone = 6.8;

#define width 500
#define height 500


// The following function is from INTERNET,
// although I forgot where it was.
void renderCube(void)
{

# define V(a,b,c) glColor3f(0.5 a 0.5, 0.5 b 0.5, 0.5 c 0.5 ); \
glVertex3f( a hQuadSize, b hQuadSize, c hQuadSize );
# define N(a,b,c) glNormal3d( a, b, c );

/*
* PWO: I dared to convert the code to use macros...
*/
glBegin( GL_QUADS );
//N( 1.0, 0.0, 0.0);

//glEnd();
//glBegin( GL_QUADS );
//N(-1.0, 0.0, 0.0);
V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-);
//glEnd();
//glBegin( GL_QUADS );
//N( 0.0,-1.0, 0.0);
V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+);
//glEnd();

//glBegin( GL_QUADS );
//N( 0.0, 0.0,-1.0);
V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-);

V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+);
//glEnd();

//glBegin( GL_QUADS );
//N( 0.0, 1.0, 0.0);
V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+);
//glEnd();
//glBegin( GL_QUADS );
//N( 0.0, 0.0, 1.0);
V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+);
glEnd();

# undef V
# undef N

}


void myDisplay(void)
{
// Init the env
glEnable(GL_DEPTH_TEST);
glClearColor(0,0,0,0);
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthFunc(GL_LESS);

glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(R,R, R, 0,0,0, 0,0,1);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(0.8*halfCone, 1.0, 0.001, 200);

// Back-scene
glClearDepth(0.0);
glDepthFunc(GL_GREATER);
glClear(GL_DEPTH_BUFFER_BIT);
glViewport(0,0, width/2, height/2);
renderCube();

// Front-scene
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glClear(GL_DEPTH_BUFFER_BIT);
glViewport(width/2, height/2, width/2, height/2);
renderCube();


glutSwapBuffers();

}


int main(int argc, char *argv[])
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE| GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(width, height);
glutCreateWindow("Render A Cube");

glutDisplayFunc(myDisplay);

glutMainLoop();

return 0;
}

Zengar
03-31-2008, 09:58 AM
Define "back-scene". If you want to see the scene from behind, set the camera to an appropriate position.

-NiCo-
03-31-2008, 11:50 AM
Your far/near ratio is too large.
e.g. Artifacts are not visible for
gluPerspective(0.8*halfCone, 1.0, 0.1, 200);

charmingzuo
03-31-2008, 07:23 PM
Your far/near ratio is too large.
e.g. Artifacts are not visible for
gluPerspective(0.8*halfCone, 1.0, 0.1, 200);

Thanks to Zengar and NiCo for helping me out.

For the "gluPerspective" function, it seems the "zNear" parameter takes effect, not the ratio zNear/zFar. Because when I set [zNear, zFar]=[0.001, 200], it works bad (with garbage); But the other set [zNear, zFar]=[0.01, 2000], with the same ratio, it works well. Currently I don't know yet the principle that gluPerspective is working, although I know it map the constrained box to a normal cube.

Many thanks again,

charmingzuo

charmingzuo
03-31-2008, 10:45 PM
My initial problem is to render a cube by a Framebuffer Object. And now I encounter the error to use the GL_LESS and GL_GREATER. For simplicity, I have put the front-scene and back-scene in the same window. Then I imported the drawn data by glReadPixels(...) into a DATA file to test whether it was correctly drawn. Unfortunately it can only show the front-scene.

The full test code is following:



/*
* Simply to render a cube into a FBO.
* We try to render the front-scene and back-scene
* by the switch of GL_LESS and GL_GREATER.
*
* CAUTION: This code is ONLY tested on NVIDIA 8600GT
* graphics card, most of which is from internet.
*
* April 1, 2008, by Charmingzuo, a user of OpenGL Forum,
* http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=postlist&amp;Board=2
*/

//#pragma comment (lib, "opengl32.lib")
//#pragma comment (lib, "glut32.lib")
#pragma comment (lib, "glew32.lib")

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

float hQuadSize = 3.28;

int width = 500;
int height = 500;

void renderCube(void);
bool CheckFBOStatus();

bool CheckFBOStatus()
{
GLenum status = (GLenum) glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
return true;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
//printf("Framebuffer incomplete, incomplete attachment\n");
return false;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
//printf("Unsupported framebuffer format\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
//printf("Framebuffer incomplete, missing attachment\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
//printf("Framebuffer incomplete, attached images must have same dimensions\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
//printf("Framebuffer incomplete, attached images must have same format\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
//printf("Framebuffer incomplete, missing draw buffer\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
//printf("Framebuffer incomplete, missing read buffer\n");
return false;
}
return false;
}


void myDisplay(void)
{
glEnable(GL_DEPTH_TEST);

glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(96,96, 96, 0,0,0, 0,0,1);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(5, 1.0, 1, 200);

GLuint fb;
glGenFramebuffersEXT(1,&amp;fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fb);

GLuint fboTex;
glGenTextures (1, &amp;fboTex);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB,fboTex);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_WRAP_T, GL_CLAMP);

// Assign the memory in GPU for Tex;
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,0,GL_RGB32F_ ARB,
width,height,0,GL_RGB, GL_FLOAT,0);

//Bind the current FBO to a Texture Object;
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB,fboTex,0);

// Determine the FBO status;
if (CheckFBOStatus() != true) return;

// Draw the front-scene of the Cube in the FBO;
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glClear(GL_DEPTH_BUFFER_BIT);
glViewport(0,0, width/2, height/2);
renderCube();

// Draw the back-scene of the Cube in the FBO;
glClearDepth(0.0);
glDepthFunc(GL_GREATER);
glClear(GL_DEPTH_BUFFER_BIT);
glViewport(width/2, height/2, width/2, height/2);
renderCube();


//glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
GLubyte * readPixel = new GLubyte [3*height*width];
glReadPixels(0,0, width, height, GL_RGB, GL_UNSIGNED_BYTE, readPixel);

FILE *pFile = fopen("readPixel.dat", "wb");
if(!pFile) return ;
fwrite(readPixel, 3*height*width, sizeof(GLubyte), pFile);
fclose(pFile);

delete readPixel;

glDeleteFramebuffersEXT(1, &amp;fb);
glDeleteTexturesEXT(1, &amp;fboTex);

}

void renderCube(void)
{

# define V(a,b,c) glColor3f(0.5 a 0.5, 0.5 b 0.5, 0.5 c 0.5 ); \
glVertex3f( a hQuadSize, b hQuadSize, c hQuadSize );
# define N(a,b,c) glNormal3d( a, b, c );

/*
* PWO: I dared to convert the code to use macros...
*/
glBegin( GL_QUADS );
//N( 1.0, 0.0, 0.0);

//glEnd();
//glBegin( GL_QUADS );
//N(-1.0, 0.0, 0.0);
V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-);
//glEnd();
//glBegin( GL_QUADS );
//N( 0.0,-1.0, 0.0);
V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+);
//glEnd();

//glBegin( GL_QUADS );
//N( 0.0, 0.0,-1.0);
V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-);

V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+);
//glEnd();

//glBegin( GL_QUADS );
//N( 0.0, 1.0, 0.0);
V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+);
//glEnd();
//glBegin( GL_QUADS );
//N( 0.0, 0.0, 1.0);
V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+);
glEnd();

# undef V
# undef N

}



int main(int argc, char *argv[])
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE| GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(width, height);
glutCreateWindow("Render Cube Demo");

glewInit();

glutDisplayFunc(myDisplay);

glutMainLoop();

return 0;
}



Sorry for my boring questions, I have failed to find any other ideas.

Thank you,
Charmingzuo