Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Game Development

Reply
 
LinkBack Thread Tools Display Modes
Old 08-19-2010, 07:03 AM   #1 (permalink)
Registered Member
 
god0fgod's Avatar
 
Join Date: Jul 2010
Posts: 278
god0fgod is on a distinguished road
Default OpenGL ES1 perspective with depth buffer fails. Clearing the colour is fine.

Hello. I'm trying to set up the projection matrix for 3D graphics. Easy enough in normal OpenGL programming but not here for some reason.

I've taken the default OpenGL template and I removed the ES2 code and transferred parts of the ES1 renderer class to the EAGLView class and that worked fine. Everything broke after trying to use the depth buffer. Clearing the colour works okay but the square wont render when using a viewing frustrum.

Here's the current EAGLView class. The code gives a red screen and no square:

Code:
//
//  EAGLView.m
//  iPhone Monkey Curling
//
//  Created by Matthew Mitchell on 18/08/2010.
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import "EAGLView.h"

@implementation EAGLView

@synthesize animating;
@dynamic animationFrameInterval;

// You must implement this method
+ (Class) layerClass{
	return [CAEAGLLayer class];
}

//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id) initWithCoder:(NSCoder*) coder{	
	if ((self = [super initWithCoder:coder])) 
	{
		// Get the layer
		CAEAGLLayer *eaglLayer = (CAEAGLLayer *) self.layer;

		eaglLayer.opaque = TRUE;
		eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
										[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

		animating = FALSE;
		displayLinkSupported = FALSE;
		displayLink = nil;
		animationTimer = nil;

		// A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
		// class is used as fallback when it isn't available.
		NSString *reqSysVer = @"3.1";
		NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
		if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) 
			displayLinkSupported = TRUE;
	}
	context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
	
	if (!context || ![EAGLContext setCurrentContext:context]) 
	{
		[self release];
		return nil;
	}
	
	// Create default framebuffer object.
	glGenFramebuffersOES(1, &defaultFramebuffer);
	glGenRenderbuffersOES(1, &colourRenderbuffer);
	glGenRenderbuffersOES(1, &depthRenderbuffer);
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colourRenderbuffer);
	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colourRenderbuffer);
	//Initialisation code for the game's graphics and to develop the scene
	//glEnable(GL_CULL_FACE);
	//glCullFace(GL_FRONT);
	glMatrixMode(GL_MODELVIEW); //Select The Modelview Matrix
	glLoadIdentity();
	glEnable(GL_DEPTH_TEST); //Enables Depth Testing
	glClearColor(1, 0, 0, 1);
	return self;
}

- (void) drawView:(id) sender{
	static const GLfloat squareVertices[] = {
		 5,   5,5,
		-5,   5,5,
		 5,  -5,5,
		-5, -5,5,
	};
	
	static const GLubyte squarecolours[] = {
		0,0,200,255,
		40,90,250,255,
		0,0,200,255,
		50,100,230,255,
	};
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glVertexPointer(3, GL_FLOAT, 0, squareVertices);
	glEnableClientState(GL_VERTEX_ARRAY);
	glColorPointer(4, GL_UNSIGNED_BYTE, 0, squarecolours);
	glEnableClientState(GL_COLOR_ARRAY);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

- (void) layoutSubviews{
	// Allocate colour buffer backing based on the current layer size
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colourRenderbuffer);
	[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*) self.layer];
	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
	glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
	//Setup projection matrix
	glViewport(0, 0, backingWidth, backingHeight);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	double xmax = 0.04142135624 * ((float) backingWidth)/backingHeight;
	glFrustumf(-xmax, xmax, -0.04142135624, 0.04142135624, 0.1, 2000); //The ymax and min have been precalculated
	//Re-bind colour buffer for rendering
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colourRenderbuffer);
	//Check framebuffer
	if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)  != GL_FRAMEBUFFER_COMPLETE_OES) 
	{
		NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) );
	}
	[self drawView:nil];
}

- (void) startAnimation{
	if (!animating) 
	{
		if (displayLinkSupported) 
		{
			// CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
			// if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
			// not be called in system versions earlier than 3.1.

			displayLink = [NSClassFromString(@"CADisplayLink")  displayLinkWithTarget:self selector:@selector(drawView:) ];
			[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
		}
		else
			animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)  0.03333333333 target:self selector:@selector(drawView:)  userInfo:nil repeats:TRUE];

		animating = TRUE;
	}
}

- (void) stopAnimation{
	if (animating) 
	{
		if (displayLinkSupported) 
		{
			[displayLink invalidate];
			displayLink = nil;
		}
		else
		{
			[animationTimer invalidate];
			animationTimer = nil;
		}

		animating = FALSE;
	}
}

- (void) dealloc{
	// Tear down GL
	if (defaultFramebuffer) 
	{
		glDeleteFramebuffersOES(1, &defaultFramebuffer);
		defaultFramebuffer = 0;
	}
	
	if (colourRenderbuffer) 
	{
		glDeleteRenderbuffersOES(1, &colourRenderbuffer);
		colourRenderbuffer = 0;
	}
	if (depthRenderbuffer) 
	{
		glDeleteRenderbuffersOES(1, &depthRenderbuffer);
		depthRenderbuffer = 0;
	}
	// Tear down context
	if ([EAGLContext currentContext] == context) 
		[EAGLContext setCurrentContext:nil];
	
	[context release];
	context = nil;

	[super dealloc];
}

@end
Thank you for any help on this problem.

Last edited by god0fgod; 08-21-2010 at 11:17 AM.
god0fgod is offline   Reply With Quote
Old 08-19-2010, 03:27 PM   #2 (permalink)
Registered Member
 
god0fgod's Avatar
 
Join Date: Jul 2010
Posts: 278
god0fgod is on a distinguished road
Default

I added this line:

glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);

to the layoutSubviews method after making the depth buffer and now I can clear the colour but the square will still not show.
god0fgod is offline   Reply With Quote
Old 08-20-2010, 03:06 PM   #3 (permalink)
Registered Member
 
god0fgod's Avatar
 
Join Date: Jul 2010
Posts: 278
god0fgod is on a distinguished road
Default

This is annoying me now, because there's absolutely nothing on the internet with proper instructions on this.

The old template for OpenGL ES in xcode looked easier. Can I get that anywhere?

Thank you.
god0fgod is offline   Reply With Quote
Old 08-20-2010, 04:06 PM   #4 (permalink)
Registered Member
 
Join Date: Apr 2010
Posts: 138
wahness is on a distinguished road
Default

Quote:
Originally Posted by god0fgod View Post
Code:
- (void) layoutSubviews{
...
	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
	glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
...
}
i don't have this code in "layoutSubviews" i have it in "resizeFromLayer" and those two lines are swapped in my code. if you think about it, you need your storage before you attach it! i don't know if this will solve all your problems, but it should help.
wahness is offline   Reply With Quote
Old 08-20-2010, 05:50 PM   #5 (permalink)
Registered Member
 
god0fgod's Avatar
 
Join Date: Jul 2010
Posts: 278
god0fgod is on a distinguished road
Default

Thank you for the reply. I have noticed and changed that myself but I still can't get it working.

I have changed quite a bit since. I will update my code on the first post and change the information to reflect the current situation.

I didn't want to use ES2 which is why I moved all the rendering code into the EAGLView class because the rendering classes aren't needed if I'm just to have one ES version.

Remember, the code worked when I moved the code into the EAGLView class, it s just the depth which is the problem at the moment.

Thank you again.
god0fgod is offline   Reply With Quote
Old 08-21-2010, 01:21 AM   #6 (permalink)
Registered Member
 
Join Date: Apr 2010
Posts: 138
wahness is on a distinguished road
Default

Quote:
Originally Posted by god0fgod View Post
Thank you for the reply. I have noticed and changed that myself but I still can't get it working.

I have changed quite a bit since. I will update my code on the first post and change the information to reflect the current situation.

I didn't want to use ES2 which is why I moved all the rendering code into the EAGLView class because the rendering classes aren't needed if I'm just to have one ES version.

Remember, the code worked when I moved the code into the EAGLView class, it s just the depth which is the problem at the moment.

Thank you again.
i don't use es 2.0, just 1.1. and i take the part out of the template which tries to instantiate an es 2.0 renderer and just make the 1.1 renderer. i know that gives a whole nother stack frame and like 30+ cycles per frame as well as a small, annoying, permanent little memory hole on the heap (which may eventually cause fragmentation, but hasn't yet caused me any problems), but i think it's just easier and i'm too lazy to write my own gl context allocator template from scratch. and you're right, it should work, but to me, the lack of solid documentation makes me feel like it's black magic. so...i try to stay out of its way as much as possible. maybe if apple was better at documenting things like this, it would be significantly less painful. to be fair, i've seen (but can't remember where now) where people DO write up their own gl context templates from scratch for the iphone. i've never done it myself, and have definitely shied away from it on all platforms (i've used GLUT almost exclusively for desktop platforms), but it might be considered a requisite skill for any graphics programmer.

oh, btw, 16-bit depth is cheesey beyond all reason: you'll get floating point round off error based artifacts like crazy if you stick with that. 24-bit isn't MUCH better, but it IS available and will still cut down your fp round-off artifacts by a significant amount. i use it exclusively on the iphone. you might consider the same once you get your buffer working.

sorry i wasn't much help. you may find that the problem is really elsewhere anyway.
wahness is offline   Reply With Quote
Old 08-21-2010, 10:19 AM   #7 (permalink)
Registered Member
 
god0fgod's Avatar
 
Join Date: Jul 2010
Posts: 278
god0fgod is on a distinguished road
Default

Well the problem must be with the code I posted somewhere. I just can't figure it out.

I will look into the 24 bot depth buffer, thank you.

The most annoying thing, is there are no full (All code required) examples anywhere.

Edit: Also, I recommend using Cocoa for OpenGL programming over GLUT, especially if you only want to programme for OSX anyway. Cocoa is quite easy, especially if you are used to Objective-C for iphone. It's powerful and fast. It should be considering it's an operating system API but it's also high-level and rather easy.

Shame the same can't be said for iOS.

Last edited by god0fgod; 08-21-2010 at 06:26 PM.
god0fgod is offline   Reply With Quote
Old 08-22-2010, 08:08 PM   #8 (permalink)
Registered Member
 
god0fgod's Avatar
 
Join Date: Jul 2010
Posts: 278
god0fgod is on a distinguished road
Default

It turns out my new code does work after moving the square around and finding it eventually.

Thank you wahness for your input.

Here is proof of my working code so far:



I'll have to post it on here once I'm done completely. That screenshot is some of the scene being rendered on the simulator.
god0fgod is offline   Reply With Quote
Reply

Bookmarks

Tags
eaglview, ios, opengl, opengl es

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 401
11 members and 390 guests
7twenty7, ChrisYates, djohnson, Duncan C, gmarro, hussain1982, Kirkout, Retouchable, SLIC, walex, xzoonxoom
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,679
Threads: 94,128
Posts: 402,921
Top Poster: BrianSlick (7,990)
Welcome to our newest member, xzoonxoom
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 08:06 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0