views:

1654

answers:

4

Hi there.

I just ported a .obj loader to objective-C and so far, it works, I can get my vertices and normals and stuff. Every normal is good, pointing in the right direction, all my faces are in CCW winding, but I have some issues with the depth test.

float rotX = 0;
float rotY = 0;
objModel* o = [[objModel alloc] initWithPath:@"/model.obj"]

glClearColor(0,0,0,0);

glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW);
glCullFace(GL_BACK); 
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();   
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0, -1, 0);
glRotatef(90,0,0,1);
glRotatef(90,0,1,0);
glRotatef(rotX,0,0,-1);
glRotatef(rotY,0,1,0);

[o drawObjWithArrays]

glFlush();

I have 2 different ways of drawing my object, one uses glBegin() / glEnd(), the other uses vertex and normal arrays with a call to glDrawArrays(). Both of them result in the same problem : faces that should be hidden by faces in front of them are displayed, because the depth test isn't working. The faces are drawn in the order they come in the .obj file.

You'll find an image here : http://img524.imageshack.us/img524/994/image2jgq.png

I quite new to OpenGL and objective-C, so I guess my problem comes from a setting that I forgot. Here they are :

-(id) initWithFrame:(NSRect) frame {
NSLog(@"INIT GL VIEW\n");

GLuint attributes[] = {
 NSOpenGLPFANoRecovery,
 NSOpenGLPFAWindow,
 NSOpenGLPFAAccelerated,
 NSOpenGLPFADoubleBuffer,
 NSOpenGLPFAColorSize, 24,
 NSOpenGLPFAAlphaSize, 8,
 NSOpenGLPFADepthSize, 24,
 NSOpenGLPFAStencilSize, 8,
 NSOpenGLPFAAccumSize, 0,
 0
};

NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:(NSOpenGLPixelFormatAttribute*) attributes];
if (!fmt)
 NSLog(@"No OpenGL pixel format");

GLfloat   mat_ambient[]  = {0.0, 0.0, 1.0, 1.0};
GLfloat   mat_flash[]  = {0.0, 0.0, 1.0, 1.0};
GLfloat   mat_flash_shiny[] = {50.0};
GLfloat   light_position[]  = {100.0,-200.0,-200.0,0.0};
GLfloat   ambi[]            = {0.1, 0.1, 0.1, 0.1};
GLfloat   lightZeroColor[]  = {0.9, 0.9, 0.9, 0.1};

/* set the material */
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);

glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny); 
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

return self = [super initWithFrame:frame pixelFormat:[fmt autorelease]]; 
}

Anyone can help me ? I've tried everyone glDepthFunc, glCullFace, glFrontFace combination possible, nothing works...

Thanks ^^

A: 

I'm not sure how the appropriate AGL calls should look like but you should make sure you actually allocate bit planes for the depth buffer.

shoosh
A: 

Make sure you call glDepthFunc() to set the depth buffer comparison function. Most applications use GL_LEQUAL or GL_LESS for the depth function. Also make sure you call glClearDepth() to set the value that the depth buffer gets cleared to; you should probably use a parameter of 1.0 for this to clear to maximum depth.

Adam Rosenfield
I just tried it, with other parameters for glDepthFunc, nothing new... :/
melka
+5  A: 

what do you get when you add this to your draw method?

int depth;
glGetIntegerv(GL_DEPTH_BITS, &depth);
NSLog(@"%i bits depth", depth)

A few more things to try:

  • make sure initWithFrame is being called
  • if you're using an NSOpenGLView subclass from IB, set the depth buffer in IB, and move all your openGL initialization into - (void)prepareOpenGL
cobbal
Added it to the drawRect function, returns "0 bits depth". Does not seem right...
melka
so there's your problem.
shoosh
Wow, thanks, it worked.I didn't know you had to set the params in IB.Now I have a 24 bits depth and no more problem in my view ^^
melka
if you need code to do this without a NIB, I posted it below (cannot format code in comments).
Gaspard Bucher
I'd been struggling with this problem for a while. This led me to the correct solution.
Daniel Wood
+2  A: 

In case someone wonders how to set this without IB:

NSOpenGLPixelFormatAttribute attrs[] = {
    // NSOpenGLPFADoubleBuffer,
    NSOpenGLPFADepthSize, 32,
    0
};
NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
NSOpenGLView *view = [[NSOpenGLView alloc] initWithFrame:frame pixelFormat:format];
Gaspard Bucher