Hidden Surface Removal

Started by
9 comments, last by mbanghart 15 years, 9 months ago
Hi, I was wondering if anyone knows of a good easy tutorial on enabling hidden surface removal in a program. Thanks Marc
Advertisement
Hello,

Try here - they're culling about determining visiblity of object. GL_NV_occlusion_query, GL_HP_occlusion_query and their own occlusion - these are sources with IMHO pretty well commented code.
http://www.ultimategameprogramming.com/demoDownload.php?category=OpenGL&page=4

If you want just basic hidden surface removal - I mean F.e. backface culling - then call before rendering VBOs, calling glBegin/glEnd legacy, or calling display list:
// parameter might be GL_FRONT or GL_FRONT_AND_BACK tooglCullFace(GL_BACK);// Enable culling, don't forget disabling it after rendering geometryglEnable(GL_CULL_FACE);

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

I tried that but it didn't work. Here is all my code (prior to trying that):

#include <windows.h>
#include <stdlib.h>
#include <gl\gl.h>
#include <fstream>
#include <iostream>
#include <list>
#include <gl\glut.h>
#include <gl\glu.h> /* GLU extention library */

#define EXIT 1
#define RESET 2

using namespace std;

GLfloat worldx = 0;
GLfloat worldy = 0;
GLfloat worldxBegin = 0;
GLfloat worldyBegin = 0;
GLfloat worldxEnd = 0;
GLfloat worldyEnd = 0;
GLfloat wc1 = 0.5;
GLfloat wc2 = 0.5;
GLfloat wc3 = 0.5;

//Global movement variables
GLfloat moveY = 0;
GLfloat moveZ = 0;
GLfloat rotateArrow = 0;
GLfloat arrowPosX = 0;
GLfloat arrowPosY = 0;



list<char> commandList; //List that stores command operations from file
list<GLfloat> dataList; //List that stores transformations/scalings/color changes of objects

void init(void);
void display(void);
void keyboard(unsigned char, int, int);
void resize(int, int);
void drawObjects();
void readFile(string);
void createDisplayLists(void);
void createMenu(void);
void processMenuEvents(int);
void myTimer(int);
void reset(void);
void displayMap(void);
void specialKeyboard(int key, int x, int y);

int is_depth; /* depth testing flag */
GLint window3D,windowMap;



int main (int argc, char **argv)
{
glutInit(&argc, argv);
init();
string filename = "su08_world2.dat";
readFile(filename);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

glutInitWindowSize(600, 600);
glutInitWindowPosition(1,1);

//Create First 3D world window
window3D = glutCreateWindow("jkjk");
createDisplayLists();
glutCreateMenu(processMenuEvents);
glutAddMenuEntry("Exit",EXIT);
glutAddMenuEntry("Reset",RESET);
glutAttachMenu(GLUT_RIGHT_BUTTON);
int n = 30;
glutTimerFunc(100,myTimer,n);
glutSpecialFunc(specialKeyboard);
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutIdleFunc(display);
//Set initial position
glTranslatef(0.0, -4.0, 0.0);

glutMainLoop();
return 0;

}

void init(void)
{
glEnable(GL_DEPTH_TEST);
is_depth = 1;
glMatrixMode(GL_MODELVIEW);
}

//Function that creates 3D world
void display(void)
{
glutSetWindow(window3D);
glTranslatef(0.0, moveY, moveZ);

glClearColor(0, 0, 1, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);



/* draw 3D world */
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();

gluLookAt(0,0,0,worldxBegin-200,worldyBegin-200,1,1,1,1);
/* draw the floor */
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();
glRotatef(90,1,0,0);
glScalef(worldx+10,1,worldy+10);
glBegin(GL_QUADS);
glColor3f(wc1, wc2, wc3);
glVertex3f( 0.5f,-0.5f, 0.5f); // Top Right Of The Quad (Bottom)
glVertex3f(-0.5f,-0.5f, 0.5f); // Top Left Of The Quad (Bottom)
glVertex3f(-0.5f,-0.5f,-0.5f); // Bottom Left Of The Quad (Bottom)
glVertex3f( 0.5f,-0.5f,-0.5f); // Bottom Right Of The Quad (Bottom)
glEnd();
glPopAttrib();
glPopMatrix();


drawObjects();
glPopAttrib();
glPopMatrix();
glutSwapBuffers();

}



void resize(int width, int height)
{
if (height == 0) height = 1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(45.0, width / height, 1.0, 400.0);

/* set initial position */
glTranslatef(0.0, -4.0, 0.0);
glMatrixMode(GL_MODELVIEW);

}

void drawObjects()
{
list<GLfloat>::iterator di=dataList.begin();

for(list<char>::iterator ai=commandList.begin(); ai!=commandList.end(); ++ai)
{
GLfloat x,y,z;
switch (*ai)
{
case 'c' :
x = *di;
di++;
y = *di;
di++;
z = *di;
di++;
glColor3f(x,y,z);
break;


case 'b' :
x = *di;
di++;
y = *di;
di++;
z = *di;
di++;
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();
glTranslatef(x,y,z);
x = *di;
di++;
y = *di;
di++;
z = *di;
di++;
glScalef(x,y,z);
glCallList(2);
glPopAttrib();
glPopMatrix();
break;

case 's' :
x = *di;
di++;
y = *di;
di++;
z = *di;
di++;
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();
glTranslatef(x,y,z);
z = *di;
di++;
glScalef(1.0,1.0,z);
glCallList(3);
glPopAttrib();
glPopMatrix();
break;

case 'a' :
//ignore advance 3
di++;
di++;
di++;
break;

case 'l' :
//ignore advance 6
di++;
di++;
di++;
di++;
di++;
di++;
break;
}//switch
}//for
}//void



//Function that creates Display lists of a block and a sphere
void createDisplayLists()
{
//Block defined with 6 polygons
glNewList(2, GL_COMPILE);
glBegin(GL_QUADS);
glVertex3f( 0.5f, 0.5f,-0.5f); // Top Right Of The Quad (Top)
glVertex3f(-0.5f, 0.5f,-0.5f); // Top Left Of The Quad (Top)
glVertex3f(-0.5f, 0.5f, 0.5f); // Bottom Left Of The Quad (Top)
glVertex3f( 0.5f, 0.5f, 0.5f); // Bottom Right Of The Quad (Top)

glVertex3f( 0.5f,-0.5f, 0.5f); // Top Right Of The Quad (Bottom)
glVertex3f(-0.5f,-0.5f, 0.5f); // Top Left Of The Quad (Bottom)
glVertex3f(-0.5f,-0.5f,-0.5f); // Bottom Left Of The Quad (Bottom)
glVertex3f( 0.5f,-0.5f,-0.5f); // Bottom Right Of The Quad (Bottom)

glVertex3f( 0.5f, 0.5f, 0.5f); // Top Right Of The Quad (Front)
glVertex3f(-0.5f, 0.5f, 0.5f); // Top Left Of The Quad (Front)
glVertex3f(-0.5f,-0.5f, 0.5f); // Bottom Left Of The Quad (Front)
glVertex3f( 0.5f,-0.5f, 0.5f); // Bottom Right Of The Quad (Front)

glVertex3f( 0.5f,-0.5f,-0.5f); // Bottom Left Of The Quad (Back)
glVertex3f(-0.5f,-0.5f,-0.5f); // Bottom Right Of The Quad (Back)
glVertex3f(-0.5f, 0.5f,-0.5f); // Top Right Of The Quad (Back)
glVertex3f( 0.5f, 0.5f,-0.5f); // Top Left Of The Quad (Back)

glVertex3f(-0.5f, 0.5f, 0.5f); // Top Right Of The Quad (Left)
glVertex3f(-0.5f, 0.5f,-0.5f); // Top Left Of The Quad (Left)
glVertex3f(-0.5f,-0.5f,-0.5f); // Bottom Left Of The Quad (Left)
glVertex3f(-0.5f,-0.5f, 0.5f); // Bottom Right Of The Quad (Left)

glVertex3f( 0.5f, 0.5f,-0.5f); // Top Right Of The Quad (Right)
glVertex3f( 0.5f, 0.5f, 0.5f); // Top Left Of The Quad (Right)
glVertex3f( 0.5f,-0.5f, 0.5f); // Bottom Left Of The Quad (Right)
glVertex3f( 0.5f,-0.5f,-0.5f); // Bottom Right Of The Quad (Right)
glEnd(); // Done Drawing The Quad

glEnd();
glEndList();

//Unit sphere centered at origin
glNewList(3, GL_COMPILE);
GLUquadricObj *p;
p = gluNewQuadric();
gluSphere(p,1,100,100);
glEndList();
}


void myTimer(int v)
{
glutPostRedisplay();
glutTimerFunc(1000/v,myTimer,v);
}

I presume you tried backface culling - so here is your display function code with backface culling:
//Function that creates 3D worldvoid display(void){	glutSetWindow(window3D);	glTranslatef(0.0, moveY, moveZ);	glClearColor(0, 0, 1, 0.0);	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	//////////////////////////////////////////////////////////////	// Here will be the best place to enable backface culling	//////////////////////////////////////////////////////////////	// Enabling face culling	glEnable(GL_CULL_FACE);	// We will cull faces, which directs from camera	// If you're not seeing anything, try to switch mode to GL_FRONT instead of GL_BACK, 	// or you may try to add prior to this glFrontFace(GL_CW); respectively glFrontFace(GL_CCW);	// which describes how are you drawing faces - in clockwise or counter clockwise order	glCullFace(GL_BACK);	//////////////////////////////////////////////////////////////	/* draw 3D world */	glPushAttrib(GL_ALL_ATTRIB_BITS);	glPushMatrix();	gluLookAt(0,0,0,worldxBegin-200,worldyBegin-200,1,1,1,1);	/* draw the floor */	glPushAttrib(GL_ALL_ATTRIB_BITS);	glPushMatrix();	glRotatef(90,1,0,0);	glScalef(worldx+10,1,worldy+10);	glBegin(GL_QUADS);	glColor3f(wc1, wc2, wc3);	glVertex3f( 0.5f,-0.5f, 0.5f); // Top Right Of The Quad (Bottom)	glVertex3f(-0.5f,-0.5f, 0.5f); // Top Left Of The Quad (Bottom)	glVertex3f(-0.5f,-0.5f,-0.5f); // Bottom Left Of The Quad (Bottom)	glVertex3f( 0.5f,-0.5f,-0.5f); // Bottom Right Of The Quad (Bottom)	glEnd();	glPopAttrib();	glPopMatrix();	drawObjects();	glPopAttrib();	glPopMatrix();		//////////////////////////////////////////////////////////////	// Here will be the best place to disable backface culling	//////////////////////////////////////////////////////////////	glDisable(GL_CULL_FACE);	//////////////////////////////////////////////////////////////	glutSwapBuffers();}

And by the way - please use [sour.ce] and [/sour.ce] tags or [co.de] and [/co.de] tags (all without periods) next time you want to post your code ... because if you use them, it's much easier to orient in it ;-)

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

I tried it and it kind of works. SOme of my objects are drawn correctly but others still show up as if hidden surface removal is not enabled.

Thanks
Quote:Original post by Vilem Otte
Hello,

Try here - they're culling about determining visiblity of object. GL_NV_occlusion_query, GL_HP_occlusion_query and their own occlusion - these are sources with IMHO pretty well commented code.
http://www.ultimategameprogramming.com/demoDownload.php?category=OpenGL&page=4

If you want just basic hidden surface removal - I mean F.e. backface culling - then call before rendering VBOs, calling glBegin/glEnd legacy, or calling display list:
*** Source Snippet Removed ***


GL_NV_occlusion_query, GL_HP_occlusion_query are ancient.
Occlusion query became core in GL 1.5 and that`s what you should be using thse days. glBeginQuery, glEndQuery, etc. Check the documents for more info.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Quote:Original post by mbanghart
I tried it and it kind of works. SOme of my objects are drawn correctly but others still show up as if hidden surface removal is not enabled.

Thanks


If the surface are hidden, why would it "show up"?

It is not that hard to write a description that is logically correct. If it is going to take up a huge paragraph to describe, show us an image instead. Posting a long long not compile-able source code, while hoping for someone can guess what is in your mind, is a very bad option.
How do I attach an image to this post?

Good Example: Grey shapes in front of green ones display correctly.

Incorrect Ex: Behind the white rectangle there is a yellow object and some green objects. The green objects should appear in front of the yellow one.

Thanks
Use ordinary HTML img tags. If you need a place to upload the image use http://www.imageshack.us/.
int main (int argc, char **argv)
{
//...
window3D = glutCreateWindow("jkjk");

// In order for this command to be delivered,
// it should be called after a window was created.
glEnable(GL_DEPTH_TEST);

createDisplayLists();
//...


Quote:Original post by mbanghart
...
Good Example: Grey shapes in front of green ones display correctly.
Incorrect Ex: Behind the white rectangle there is a yellow object and some green objects. The green objects should appear in front of the yellow one.
...


By the way, do you really think there is someone can understand what you wrote by reading? If so, can you?

This topic is closed to new replies.

Advertisement