NSOpenGLView depth isn't working correctly.

Started by
3 comments, last by thyrgle 12 years, 5 months ago
So I have the following class:

@implementation GameView

-(void)mainTimerFired:(id) sender { //Move the square based off arrow key states.
if (upPressed == YES) {
vertVec = 0.01;
}
if (downPressed == YES) {
vertVec = -0.01;
}
if (rightPressed == YES) {
horiVec = 0.01;
}
if (leftPressed == YES) {
horiVec = -0.01;
}


[ self setNeedsDisplay:YES];
}

//Needed, if you don't include it the keys wont work.
- (BOOL)acceptsFirstResponder
{
return YES;
}

- (void) prepareOpenGL {

upPressed = NO;
downPressed = NO;
leftPressed = NO;
rightPressed = NO;

vertVec = 0;
horiVec = 0;
rotY = 0;
rotX = 0;

glEnable(GL_DEPTH_TEST);
glClearDepth(1.0f);

mainTimer=[ [ NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(mainTimerFired:) userInfo:nil repeats:YES ] retain ] ;

return;
}

-(void) keyUp:(NSEvent *)theEvent { //Stop movement when the key is released.
switch( [theEvent keyCode] ) {
case 126: //Up arrow
upPressed = NO;
vertVec = 0.0;
break;
case 125: //Down arrow
downPressed = NO;
vertVec = 0.0;
break;
}
switch( [theEvent keyCode] ) {
case 124: //Right arrow
rightPressed = NO;
horiVec = 0.0;
break;
case 123: //Left arrow
leftPressed = NO;
horiVec = 0.0;
break;
}
}

//Key events.
-(void) keyDown:(NSEvent *)theEvent { //Tell the game loop that I want to move the square.
switch( [theEvent keyCode] ) {
case 126: //Up arrow
upPressed = YES;
break;
case 125: //Down arrow
downPressed = YES;
break;
}
switch( [theEvent keyCode] ) {
case 124: //Right arrow
rightPressed = YES;
break;
case 123: //Left arrow
leftPressed = YES;
break;
}
}

- (void)drawRect:(NSRect)rect { //In combination draw this is where the drawing happens.

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glViewport( 0,0,[self frame].size.width,[self frame].size.height );

glMatrixMode(GL_MODELVIEW);

[self draw];

glFlush();
}

- (void)draw {
glViewport( 0, 0, [self frame].size.width, [self frame].size.height );
glTranslatef(horiVec, 0, vertVec);

glBegin(GL_TRIANGLES);

{

glVertex3f( 0.0, 1.0, -1.0);

glVertex3f( -1.0, -1.0, -1.0);

glVertex3f( 1.0, -1.0 ,-1.0);

}

glEnd();
}

@end

A brief explanation of my code:

The keyUp:(NSEvent *) and keyDown:(NSEvent *) tell my game loop mainTimerFired:(id) to change horiVec or vertVec. Those are used in the 2 drawing methods to with glTranslatef to move a triangle.

So I am using an NSOpenGLView, a triangle does display, I can move it left and right, but when I try moving it forward and backward nothing happens until it suddenly disappears after holding either the up or down key for a while. I can then bring it back by holding the opposite arrow key. Also, I tried getting info about my GL_DEPTH_BITS by doing:

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

And I got 24 bits depth. Which is odd because in Interface Builder I set it up to be 32-bit in my NSOpenGLView.
Advertisement
I made a few changes to your code. One of your translation components was applied in the Z direction, which looks wrong. That explains why the triangle goes AWOL. You might want to check how the projection matrix is setup and make sure it's configured the way you want.

Also, calling [super drawRect:rect] is a good idea, but not essential. Flush buffers using [[self openGLContext] flushBuffer] is preferred.

I also removed the key state tracking stuff, because you can use the vertVec and horiVec for that.

Removed the second redundant glViewport() call in your draw method.
Code not tested :P


@implementation GameView

-(void)mainTimerFired:(id) sender {
[ self setNeedsDisplay:YES];
}

//Needed, if you don't include it the keys wont work.
- (BOOL)acceptsFirstResponder
{
return YES;
}

- (void) prepareOpenGL {

vertVec = 0;
horiVec = 0;
rotY = 0;
rotX = 0;

glEnable(GL_DEPTH_TEST);
glClearDepth(1.0f);

mainTimer=[ [ NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(mainTimerFired:) userInfo:nil repeats:YES ] retain ] ;

return;
}

-(void) keyUp:(NSEvent *)theEvent { //Stop movement when the key is released.
switch( [theEvent keyCode] ) {
case 126: //Up arrow
vertVec = 0.0;
break;
case 125: //Down arrow
vertVec = 0.0;
break;
case 124: //Right arrow
horiVec = 0.0;
break;
case 123: //Left arrow
horiVec = 0.0;
break;
}
}

//Key events.
-(void) keyDown:(NSEvent *)theEvent { //Tell the game loop that I want to move the square.
switch( [theEvent keyCode] ) {
case 126: //Up arrow
vertVec = 0.01;
break;
case 125: //Down arrow
vertVec = -0.01;
break;
case 124: //Right arrow
horiVec = 0.01;
break;
case 123: //Left arrow
horiVec = -0.01;
break;
}
}

- (void)drawRect:(NSRect)rect { //In combination draw this is where the drawing happens.

[super drawRect:rect];

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glViewport( 0,0,[self frame].size.width,[self frame].size.height );

glMatrixMode(GL_MODELVIEW);

[self draw];

[[self openGLContext] flushBuffer];
}

- (void)draw {
glTranslatef(horiVec, vertVec, 0);

glBegin(GL_TRIANGLES);

{

glVertex3f( 0.0, 1.0, -1.0);

glVertex3f( -1.0, -1.0, -1.0);

glVertex3f( 1.0, -1.0 ,-1.0);

}

glEnd();
}

@end

Latest project: Sideways Racing on the iPad
Thank you for the response but, I only see a white screen (for some reason I have trouble flushing the screen unless it is with glFlush()). Also, I have the vertVec in the z part of glTranlatef because I want the triangle to move forward and backward, not up and down. Sorry, maybe I should change vertVec because it is a little bit of a misnomer.

So I am using an NSOpenGLView, a triangle does display, I can move it left and right, but when I try moving it forward and backward nothing happens until it suddenly disappears after holding either the up or down key for a while. I can then bring it back by holding the opposite arrow key.

If I understand your issue correctly, the depth buffer isn't the problem.

You haven't set a projection matrix, which means you are using an identity matrix for the projection, which is an orthogonal projection - in other words, it doesn't have give you any perspective (size of objects varying with distance to the camera). If you want perspective projection, then you need to set the projection matrix, most likely using the gluPerspective function.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Ok, thank you! I put:


gluPerspective(45.0, //The camera angle
[self frame].size.width/[self frame].size.height, //The width-to-height ratio
1.0, //The near z clipping coordinate
200.0);


In my prepareOpenGL method and now I have depth.

Thanks!

This topic is closed to new replies.

Advertisement