PDA

View Full Version : Tricks from the Culling Gurus



camoguard
01-30-2006, 10:44 AM
First the code:

// from the create method
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);

// TODO: Add your specialized creation code here
static PIXELFORMATDESCRIPTOR pfd = {
sizeof (PIXELFORMATDESCRIPTOR), // strcut size
1, // Version number
PFD_DRAW_TO_WINDOW | // Flags, draw to a window,
PFD_SUPPORT_OPENGL, // use OpenGL
PFD_TYPE_RGBA, // RGBA pixel values
24, // 24-bit color
0, 0, 0, // RGB bits & shift sizes.
0, 0, 0, // Don't care about them
0, 0, // No alpha buffer info
0, 0, 0, 0, 0, // No accumulation buffer
32, // 32-bit depth buffer
0, // No stencil buffer
0, // No auxiliary buffers
PFD_MAIN_PLANE, // Layer type
0, // Reserved (must be 0)
0, // No layer mask
0, // No visible mask
0 // No damage mask
};

int nMyPixelFormatID;
HGLRC hRC;

CDC *pDC = GetDC();
nMyPixelFormatID = ChoosePixelFormat(pDC->m_hDC, &pfd );

// catch errors here.
if(pfd.dwFlags & PFD_NEED_PALETTE)
{
int what = 1;
}
// If nMyPixelFormat is zero, then there's
// something wrong... most likely the window's
// style bits are incorrect (in CreateWindow() )
// or OpenGl isn't installed on this machine

SetPixelFormat( pDC->m_hDC, nMyPixelFormatID, &pfd );

hRC = wglCreateContext( pDC->m_hDC );
ReleaseDC(pDC );

m_hrc = hRC;

glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

// From the Draw routine
BOOL bResult = wglMakeCurrent (pDC->m_hDC, m_hrc);
if (!bResult)
{
TRACE("wglMakeCurrent Failed %x\r\n", GetLastError() ) ;
}

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

glFrustum(5,5,5,5,5,100);

// move the viewpoint
glTranslatef( (float)m_x, (float)m_y, (float)m_z );

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_TRIANGLE_STRIP );
{
// front face
glColor3f(1.0f, 0.0f, 0.0f);// blue
Vector2Vertex(cubelist[3]);
Vector2Vertex(cubelist[0]);
Vector2Vertex(cubelist[2]);
Vector2Vertex(cubelist[1]);
// bottom face
glColor3f(1.0f, 1.0f, 0.0f);
Vector2Vertex(cubelist[0]);
Vector2Vertex(cubelist[4]);
Vector2Vertex(cubelist[1]);
Vector2Vertex(cubelist[5]);
//right face
glColor3f(0.0f, 1.0f, 0.0f);
Vector2Vertex(cubelist[2]);
Vector2Vertex(cubelist[1]);
Vector2Vertex(cubelist[6]);
Vector2Vertex(cubelist[5]);

}// glBegin

glEnd();

Now the synopsis:

I am trying to test culling with half a cube, one plane in each direction and culling makes the lines look right on the corners where planes intersect. I haven't succeeded in getting culling to do anything.

I have six keys that move my x, y, and z on my viewpoint so I see sides and such.

The ideal solution would define an entire cube each face with its own color and from above, below, left, or right, the cube would look correct.

All suggestions welcome,
cam

Jan
01-30-2006, 12:06 PM
I don't know what the heck you are talking about.

camoguard
01-30-2006, 12:20 PM
Given three faces of a cube: front side, right side, bottom side. I want to move the camera around and have the three faces drawn correctly. Essentially from some angles the faces are drawn out of order so that the screen shot doesn't look properly 3d.

I'm trying to fix that.

Aeluned
01-30-2006, 12:33 PM
If your cube is opaque setup the following states before rendering it:

glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);

you may also need to ensure that your polygon winding is correct and that you can write to the depth buffer:

glFrontFace(GL_CCW) or GL_CW if your vertices are defined clockwise.
glDepthMask(GL_TRUE)

if your cube is translucent:

glEnable(GL_BLEND);

glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
//Render cube

glCullFace(GL_BACK);
//Render cube again.

This ensures that blending will work properly regardless of the order you draw your faces in.

Using that setup, the cube should look correct no matter what angle it's viewed from.

-cheers.

camoguard
01-31-2006, 06:01 AM
Thank you for your reply.

However, I'm still missing something in the culling process. So I simplified the project. I am drawing a single triangle that runs on the YZ plane. I can move the view left/right up/down in/out so I figure from the left side if I see the triangle, then on the right side I shouldn't see the triangle at all. Or vice versa depending on the winding.

I have enabled the commands mentioned in the previous post. Is there something else that needs to be in order to cull properly?

I'm sure this is all going to seem naive once I figure out what is missing.

Cam

camoguard
01-31-2006, 06:45 AM
I finally succeeded in getting a triangle culled. I was wondering if GL_MODEL_VIEW broke culling. Does anyone know?

camoguard
01-31-2006, 07:11 AM
Okay, here's my guess as to what happened. I am using MFCs and OpenGL. I declared all the state variables I wanted in OnCreate(...) but the states didn't persist.

Now that I'm calling the state variables in the OnDraw(), the whole project is working as expected.

Thanks to all repliers,
cam

Jan
01-31-2006, 02:27 PM
Is it possible, that you set the states, before you created the window? In that case, your states will be reset, because there actually is no OpenGL present, before the window creation.

Other than that, states won't be magically reset, you need to set them yourself to screw up ;)

Jan.