OpenGl ES iPhone, strange line - iphone

I have a strange problem. Sometimes it happens, sometimes it doesn't.
I have an array of GLfloat with 8 items. When EAGLView draw it, it shows the two lines of the array, but also an additional line.
EAGLView.m
+ (Class)layerClass {
return [CAEAGLLayer class];
}
- (id)initWithCoder:(NSCoder*)coder {
if ((self = [super initWithCoder:coder])) {
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
eaglLayer.opaque = NO;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!context || ![EAGLContext setCurrentContext:context]) {
[self release];
return nil;
}
}
return self;
}
- (void)drawView {
int numero=malloc_size(puntosPintar)/sizeof(GLfloat);
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glClear(GL_COLOR_BUFFER_BIT);
glVertexPointer(2, GL_FLOAT, 0, puntosPintar);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(1,1,1,1);
glDrawArrays(GL_LINES, 0, numero);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
free(puntosPintar);
}
- (void)layoutSubviews {
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
[self drawView];
}
- (BOOL)createFramebuffer {
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if (USE_DEPTH_BUFFER) {
glGenRenderbuffersOES(1, &depthRenderbuffer);
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);
}
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(#"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
- (void)destroyFramebuffer {
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0;
if(depthRenderbuffer) {
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
}
- (void)dealloc {
if ([EAGLContext currentContext] == context) {
[EAGLContext setCurrentContext:nil];
}
[context release];
[super dealloc];
}
#end
puntosPintar
puntosPintar=(GLfloat*)malloc(sizeof(GLfloat)*8);
puntosPintar[0] = -0.25f;
puntosPintar[1] = -1.49f;
puntosPintar[2] = -0.1f;
puntosPintar[3] = 0.0f;
puntosPintar[4] = 0.25f;
puntosPintar[5] = -1.49f;
puntosPintar[6] = 0.1f;
puntosPintar[7] = 0.0f;

You should be passing '4' into the count argument of glDrawArrays, not 8 (this is the count of vertexes, not the count of floats).

Related

OpenGL + Camera View (iPhone)

I have been 2 days trying to show an OpenGLES view over the camera View preview on the iPhone.
The camera preview alone, works.
The EAGLView(OpenGLES) alone, works.
The problem is when i try to place the EAGLView over the camera preview.
I am able to place both UIViews at the same time, but the camera preview is always over the EAGLView (wrong!). When i set alpha to 0.5 of the camera preview, i can see both UIViews just as i want, but both are blurred (it's normal).
I have tried [self.view bringSubviewToFront:(EAGLView)], but nothing changes.
The EAGLView is on the IB as a class.
The CameraView is added as a subview by code.
Here i put some code, i can upload more if you need it.
Thanks!!!
EAGLView
+ (Class)layerClass {
return [CAEAGLLayer class];
}
//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder {
puntosPintar=(GLfloat*)malloc(sizeof(GLfloat)*8);
puntosPintar[0] = -0.25f;
puntosPintar[1] = -1.22f;
puntosPintar[2] = -0.41f;
puntosPintar[3] = 0.0f;
puntosPintar[4] = 0.35f;
puntosPintar[5] = -1.69f;
puntosPintar[6] = 0.15f;
puntosPintar[7] = 0.0f;
if ((self = [super initWithCoder:coder])) {
// Get the layer
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
eaglLayer.opaque = NO;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!context || ![EAGLContext setCurrentContext:context]) {
[self release];
return nil;
}
}
return self;
}
- (void)drawView {
const GLubyte squareColors[] = {
255, 255, 0, 255,
0, 255, 255, 255,
0, 0, 0, 0,
255, 0, 255, 255,
};
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT);
glVertexPointer(2, GL_FLOAT, 0, puntosPintar);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
- (void)layoutSubviews {
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
[self drawView];
}
- (BOOL)createFramebuffer {
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if (USE_DEPTH_BUFFER) {
glGenRenderbuffersOES(1, &depthRenderbuffer);
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);
}
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(#"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
UIViewController where i want to show both
Load of the view of the Camera
[CameraImageHelper startRunning];
UIView *fafa;
fafa= [[UIView alloc]initWithFrame:self.view.bounds]; //returns a UIView with the cameraview as a layer of that view. It works well (checked)
fafa = [CameraImageHelper previewWithBounds:self.view.bounds];
fafa.alpha=0.5; //Only way to show both
[self.view addSubview:fafa];
[self.view bringSubviewToFront:fafa];
Load of the EAGLView
On the .h i have created
IBOutlet EAGLView *openGLVista
In the view did load:
openGLVista=[[EAGLView alloc]init];
CameraImageHelper.h
#interface CameraImageHelper : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>
{
AVCaptureSession *session;
}
#property (retain) AVCaptureSession *session;
+ (void) startRunning;
+ (void) stopRunning;
+ (UIView *) previewWithBounds: (CGRect) bounds;
#end
CameraImageHelper.m
- (void) initialize
{
NSError *error;
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:&error];
if (!captureInput)
{
NSLog(#"Error: %#", error);
return;
}
self.session = [[[AVCaptureSession alloc] init] autorelease];
[self.session addInput:captureInput];
}
- (id) init
{
if (self = [super init]) [self initialize];
return self;
}
- (UIView *) previewWithBounds: (CGRect) bounds
{
UIView *view = [[[UIView alloc] initWithFrame:bounds] autorelease];
AVCaptureVideoPreviewLayer *preview = [AVCaptureVideoPreviewLayer layerWithSession: self.session];
preview.frame = bounds;
preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
[view.layer addSublayer: preview];
return view;
}
- (void) dealloc
{
self.session = nil;
[super dealloc];
}
#pragma mark Class Interface
+ (id) sharedInstance // private
{
if(!sharedInstance) sharedInstance = [[self alloc] init];
return sharedInstance;
}
+ (void) startRunning
{
[[[self sharedInstance] session] startRunning];
}
+ (void) stopRunning
{
[[[self sharedInstance] session] stopRunning];
}
+ (UIView *) previewWithBounds: (CGRect) bounds
{
return [[self sharedInstance] previewWithBounds: (CGRect) bounds];
}
#end
I see that in IB you are using the EAGLView as the view of the view controller, and in the code snippet you add the preview view as a subview of that view. In other words, your view hierarchy looks something like this:
*- EAGLView
+- Preview view
Thus, Preview view is always on top of the EAGLView because it is a subview of the EAGLView. If you want to be able to display either one on top of the other, you will instead have to lay things out like this:
*- some generic UIView
+- EAGLView
+- Preview view
In other words, in IB you should have a generic UIView bound to the view property, and then drag the EAGLView so it is inside that generic UIView. Then your code for adding the preview view should work right.
BTW, this does not do what you seem to think:
fafa= [[UIView alloc]initWithFrame:self.view.bounds]; //returns a UIView with the cameraview as a layer of that view. It works well (checked)
fafa = [CameraImageHelper previewWithBounds:self.view.bounds];
The first line creates a generic UIView. Then the second throws it away (leaking the memory!), replacing it with the preview view. You should just delete the first line.

My "drawView" function is being called only once?

I'm new to OpenGL ES and having a simple kind of problem in my project. I've successfully drawn a square on my screen but the problem is that my "drawView" function in my EAGLView is
only called once however I wrote code to call it again n again as in Xcode's OpenGL ES Template.
Do anyone have clue where's the mistake?
Following is the code of my EAGLView.m file:
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>
#import "EAGLView.h"
#define USE_DEPTH_BUFFER 0
// A class extension to declare private methods
#interface EAGLView ()
#property (nonatomic, retain) EAGLContext *context;
- (BOOL) createFramebuffer;
- (void) destroyFramebuffer;
#end
#implementation EAGLView
#synthesize context;
#synthesize animating;
#dynamic animationFrameInterval;
// You must implement this method
+ (Class)layerClass {
return [CAEAGLLayer class];
}
//The GL 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 = YES;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!context || ![EAGLContext setCurrentContext:context]) {
[self release];
return nil;
}
animating = FALSE;
displayLinkSupported = FALSE;
animationFrameInterval = 1;
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;
}
return self;
}
- (void)drawView {
NSLog(#"In EAGLView's drawView func");
static const GLfloat squareVertices[] = {
-0.5f, -0.33f,
0.5f, -0.33f,
-0.5f, 0.33f,
0.5f, 0.33f,
};
static const GLubyte squareColors[] = {
255, 0, 0, 255,
0, 255, 0, 255,
0, 0, 255, 255,
0, 0, 0, 0,
};
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(10.0f, 0.0f, 0.0f, 1.0f);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
- (void)layoutSubviews {
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
[self drawView];
}
- (BOOL)createFramebuffer {
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if (USE_DEPTH_BUFFER) {
glGenRenderbuffersOES(1, &depthRenderbuffer);
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);
}
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(#"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
- (void)destroyFramebuffer {
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0;
if(depthRenderbuffer) {
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
}
- (NSInteger)animationFrameInterval
{
return animationFrameInterval;
}
- (void)setAnimationFrameInterval:(NSInteger)frameInterval
{
// Frame interval defines how many display frames must pass between each time the
// display link fires. The display link will only fire 30 times a second when the
// frame internal is two on a display that refreshes 60 times a second. The default
// frame interval setting of one will fire 60 times a second when the display refreshes
// at 60 times a second. A frame interval setting of less than one results in undefined
// behavior.
if (frameInterval >= 1)
{
animationFrameInterval = frameInterval;
if (animating)
{
[self stopAnimation];
[self startAnimation];
}
}
}
- (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 setFrameInterval:animationFrameInterval];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
else
animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) 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 {
if ([EAGLContext currentContext] == context) {
[EAGLContext setCurrentContext:nil];
}
[context release];
[super dealloc];
}
#end
Check to see if your method:
- (void)startAnimation
is actually being called.

iPhone OpenGL ES Contexts and Framebuffers

I'm attempting to setup a framebuffer properly in order to support depth and correct perspective. I'm using the OpenGL ES Application template in XCode and I have been following the guidelines in the OpenGL ES Programming Guide.
I have my renderer set to ES1 manually since I just want to get something rendering with depth using the FFP.
This is my current code:
#import "ES1Renderer.h"
#import "water.h"
//#import "EAGLError.h"
#define PRINT_GLERR(error) ((error == GL_NO_ERROR) ? NSLog(#"No error") : NSLog(#"GL Error: %d", (error)))
//#define GLE(X) {X; eglGetError(); }
#implementation ES1Renderer
// Create an OpenGL ES 1.1 context
- (id)init
{
if ((self = [super init]))
{
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!context || ![EAGLContext setCurrentContext:context])
{
[self release];
return nil;
}
glGenFramebuffersOES(1, &framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glGenRenderbuffersOES(1, &colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
glViewport(0, 0, backingWidth, backingHeight);
// Start in projection mode.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double xmin, xmax, ymin, ymax;
ymax = NEAR_PLANE * tanf(DEGREES_TO_RADIANS(FOV) / 2.0f);
ymin = -ymax;
xmin = ymin * ((float)backingWidth / (float)backingHeight);
xmax = ymax * ((float)backingWidth / (float)backingHeight);
glFrustumf(xmin, xmax, ymin, ymax, NEAR_PLANE, FAR_PLANE);
glViewport(0, 0, backingWidth, backingHeight);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthRangef(0.0f, 1.0f);
glDepthMask(TRUE);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
return self;
}
- (void)render
{
static const GLfloat squareVertices[] = {
-0.5f, -0.33f, -1.0f,
0.5f, -0.33f, -1.0f,
-0.5f, 0.33f, -1.0f,
0.5f, 0.33f, -1.0f,
};
static const GLubyte squareColors[] = {
255, 255, 0, 255,
0, 255, 255, 255,
0, 0, 0, 0,
255, 0, 255, 255,
};
static float transY = 0.0f;
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f);
transY += 0.075f;
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glVertexPointer(3, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
- (BOOL)resizeFromLayer:(CAEAGLLayer *)layer
{
glGenFramebuffersOES(1, &framebuffer);
glGenRenderbuffersOES(1, &colorRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
glGenRenderbuffersOES(1, &depthRenderbuffer);
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);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
{
NSLog(#"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
- (void)dealloc
{
if (framebuffer)
{
glDeleteFramebuffersOES(1, &framebuffer);
framebuffer = 0;
}
if (colorRenderbuffer)
{
glDeleteRenderbuffersOES(1, &colorRenderbuffer);
colorRenderbuffer = 0;
}
if (depthRenderbuffer)
{
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
if ([EAGLContext currentContext] == context)
[EAGLContext setCurrentContext:nil];
[context release];
context = nil;
[super dealloc];
}
#end
When I commend out this part of the code:
glGenRenderbuffersOES(1, &depthRenderbuffer);
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);
I get a quad that bounces up and down and renders correctly. Any help on the depth issue would be awesome!

Implement iphone MSAA using Unity build

I want to implement MSAA into the Unity build of a game. Currently I am using this code I got from the Unity forums and it compiles but I can clearly see that it is having no effect in game. Any help would be appreciated.
bool msaaEnabled = false;
CGSize globalSize;
struct MyEAGLSurface
{
GLuint format;
GLuint depthFormat;
GLuint framebuffer;
GLuint renderbuffer;
GLuint msaaFrameBuffer;
GLuint msaaRenderBuffer;
GLuint msaaDepthBuffer;
GLuint depthBuffer;
CGSize size;
};
typedef EAGLContext* MyEAGLContext;
#interface EAGLView : UIView {}
#end
MyEAGLContext _context;
MyEAGLSurface _surface;
UIWindow * _window;
NSTimer* _timer;
id _displayLink;
BOOL _accelerometerIsActive = NO;
extern "C" void MSAA_Enabled( bool enabled )
{
if( enabled && !msaaEnabled )
{
// Create MSAA buffers!
glGenFramebuffersOES(1, &_surface.msaaFrameBuffer );
glGenRenderbuffersOES(1, &_surface.msaaRenderBuffer );
glBindFramebufferOES(GL_FRAMEBUFFER_OES, _surface.msaaFrameBuffer );
glBindRenderbufferOES(GL_RENDERBUFFER_OES, _surface.msaaRenderBuffer );
// Samples is the amount of pixels the MSAA buffer uses to make one pixel on the render
// buffer. Use a small number like 2 for the 3G and below and 4 or more for newer models
int samples = 4;
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, samples, GL_RGB5_A1_OES, globalSize.width, globalSize.height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, _surface.msaaRenderBuffer);
// MSAA Depth buffer
glGenRenderbuffersOES(1, &_surface.msaaDepthBuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, _surface.msaaDepthBuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, samples, _surface.depthFormat, globalSize.width, globalSize.height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, _surface.msaaDepthBuffer);
}
else
{
}
msaaEnabled = enabled;
}
extern "C" void MSAA_BindTarget()
{
if( _surface.msaaFrameBuffer && msaaEnabled )
{
glBindFramebufferOES(GL_FRAMEBUFFER_OES, _surface.msaaFrameBuffer); //Bind MSAA
}
}
bool CreateWindowSurface(EAGLView *view, GLuint format, GLuint depthFormat, bool retained, MyEAGLSurface* surface)
{
CGSize newSize;
GLuint oldRenderbuffer;
GLuint oldFramebuffer;
CAEAGLLayer* eaglLayer = (CAEAGLLayer*)[view layer];
surface->format = format;
surface->depthFormat = depthFormat;
surface->msaaFrameBuffer = 0;
surface->msaaRenderBuffer = 0;
surface->msaaDepthBuffer = 0;
surface->depthBuffer = 0;
surface->renderbuffer = 0;
surface->framebuffer = 0;
eaglLayer.opaque = YES;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
newSize = [eaglLayer bounds].size;
newSize.width = roundf(newSize.width);
newSize.height = roundf(newSize.height);
globalSize = newSize;
glGetIntegerv(GL_RENDERBUFFER_BINDING_OES, (GLint *) &oldRenderbuffer);
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *) &oldFramebuffer);
// Create the main frame and render buffers
glGenFramebuffersOES(1, &surface->framebuffer);
glGenRenderbuffersOES(1, &surface->renderbuffer);
// Bind the frame and render buffer
glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->framebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->renderbuffer);
// Set storage for render buffer
if(![_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer])
{
glDeleteRenderbuffersOES(1, &surface->renderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_BINDING_OES, oldRenderbuffer);
return false;
}
// Attach the renderbuffer
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, surface->renderbuffer);
if (depthFormat)
{
// Regular depth buffer
glGenRenderbuffersOES(1, &surface->depthBuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->depthBuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, surface->depthFormat, newSize.width, newSize.height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, surface->depthBuffer);
}
surface->size = newSize;
glBindRenderbufferOES(GL_RENDERBUFFER_OES, oldRenderbuffer);
CHECK_GL_ERROR();
return true;
}
void DestroySurface(MyEAGLSurface* surface)
{
EAGLContext *oldContext = [EAGLContext currentContext];
if (oldContext != _context)
[EAGLContext setCurrentContext:_context];
if(surface->msaaDepthBuffer)
{
glDeleteRenderbuffersOES(1, &surface->msaaDepthBuffer);
surface->msaaDepthBuffer = 0;
}
if(surface->depthBuffer)
{
glDeleteRenderbuffersOES(1, &surface->depthBuffer);
surface->depthBuffer = 0;
}
glDeleteRenderbuffersOES(1, &surface->msaaRenderBuffer);
surface->msaaRenderBuffer = 0;
glDeleteFramebuffersOES(1, &surface->msaaFrameBuffer);
surface->msaaFrameBuffer = 0;
glDeleteRenderbuffersOES(1, &surface->renderbuffer);
surface->renderbuffer = 0;
glDeleteFramebuffersOES(1, &surface->framebuffer);
surface->framebuffer = 0;
if (oldContext != _context)
[EAGLContext setCurrentContext:oldContext];
}
void PresentSurface(MyEAGLSurface& surface)
{
EAGLContext *oldContext = [EAGLContext currentContext];
GLuint oldRenderbuffer;
if (oldContext != _context)
[EAGLContext setCurrentContext:_context];
CHECK_GL_ERROR();
glGetIntegerv(GL_RENDERBUFFER_BINDING_OES, (GLint *) &oldRenderbuffer);
if( msaaEnabled )
{
glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, surface.msaaFrameBuffer);
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, surface.framebuffer);
// Call a resolve to combine buffers
glResolveMultisampleFramebufferAPPLE();
}
glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface.renderbuffer);
if(![_context presentRenderbuffer:GL_RENDERBUFFER_OES])
EAGL_ERROR("swap renderbuffer");
if(oldContext != _context)
[EAGLContext setCurrentContext:oldContext];
}
void PresentContext_UnityCallback(struct UnityFrameStats const* unityFrameStats)
{
#if ENABLE_INTERNAL_PROFILER
_unityFrameStats = *unityFrameStats;
if (_frameId % BLOCK_ON_GPU_EACH_NTH_FRAME == (BLOCK_ON_GPU_EACH_NTH_FRAME-1))
{
Prof_Int64 gpuTime0 = mach_absolute_time();
#if ENABLE_BLOCK_ON_GPU_PROFILER
UnityFinishRendering();
#endif
Prof_Int64 gpuTime1 = mach_absolute_time();
_gpuDelta = gpuTime1 - gpuTime0;
}
else
_gpuDelta = 0;
#endif
#if ENABLE_INTERNAL_PROFILER
Prof_Int64 swapTime0 = mach_absolute_time();
#endif
PresentSurface(_surface);
#if ENABLE_INTERNAL_PROFILER
Prof_Int64 vblankTime = mach_absolute_time();
if (_lastVBlankTime < 0) _lastVBlankTime = vblankTime;
_frameDelta = vblankTime - _lastVBlankTime; _lastVBlankTime = vblankTime;
Prof_Int64 swapTime1 = vblankTime;
_swapDelta = swapTime1 - swapTime0;
#endif
}
int OpenEAGL_UnityCallback(UIWindow** window, int* screenWidth, int* screenHeight)
{
CGRect rect = [[UIScreen mainScreen] bounds];
// Create a full-screen window
_window = [[UIWindow alloc] initWithFrame:rect];
EAGLView* view = [[EAGLView alloc] initWithFrame:rect];
[_window addSubview:view];
//CAEAGLLayer* eaglLayer = (CAEAGLLayer*)[view layer];
_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
MSAA_Enabled(true);
MSAA_BindTarget();
if (!_context)
return false;
if (![EAGLContext setCurrentContext:_context]) {
_context = 0;
return false;
}
if (!CreateWindowSurface(view, GL_RGB565_OES, GL_DEPTH_COMPONENT16_OES, NO, &_surface)) {
return false;
}
glViewport(0, 0, _surface.size.width, _surface.size.height);
[_window makeKeyAndVisible];
[view release];
*window = _window;
*screenWidth = _surface.size.width;
*screenHeight = _surface.size.height;
return true;
}
Got it working with some help from the Unity forums. If anyone wants to know how to implement, take a look at the thread here: http://forum.unity3d.com/threads/60785-iPhone-4-MSAA-Test-Results
The code provided at the bottom of the thread only seemed to compile using a Unity 3.0 build, btw.

OpenGL ES - purple or black screen

I'm using OpenGL ES in my iPhone application and sometimes during startup the screen goes purple or black - in one case from twenty. This happens only during initialization and if the screen became black or purple it will remain in such a color - only restarting the application helps.
Also I found out that when this bug happens, application is running (I can see the game loop working through console), but the iPhone stops responding to touches (touchesBegan method is not being invoked).
Here's my code:
#define USE_DEPTH_BUFFER FALSE
#implementation EAGLView
#synthesize context;
+ (Class)layerClass {
return [CAEAGLLayer class];
}
- (id)initWithFrame: (CGRect)frame {
NSLog(#"init EAGLView");
if ( (self = [super initWithFrame: frame]) ) {
NSLog(#"initializing CAEAGLLayer and EAGLContext");
// Get the layer
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
eaglLayer.opaque = YES;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!context || ![EAGLContext setCurrentContext:context]) {
NSLog(#"!context || ![EAGLContext setCurrentContext:context]");
[self release];
return nil;
}
}
return self;
}
- (void)layoutSubviews {
[EAGLContext setCurrentContext: context];
[self destroyFramebuffer];
[self createFramebuffer];
}
- (BOOL)createFramebuffer {
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if (USE_DEPTH_BUFFER) {
glGenRenderbuffersOES(1, &depthRenderbuffer);
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);
}
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(#"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
- (void)destroyFramebuffer {
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0;
if(depthRenderbuffer) {
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
}
-(void) startDrawing: (GLfloat) viewWidth andHeight: (GLfloat) viewHeight
{
[EAGLContext setCurrentContext: context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glRotatef(-90.0f, 0.0f , 0.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
-(void) endDrawing
{
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer: GL_RENDERBUFFER_OES];
}
- (void)dealloc {
if ([EAGLContext currentContext] == context) {
[EAGLContext setCurrentContext:nil];
}
[context release];
[super dealloc];
}
...touches processing...
#end
What may be the problem and how can I fix it?
Thank you in advance,
Ilya.
That sounds similar to a problem I had on another phone.
What happened there was that sometimes we would get "out of memory" when trying to allocate a texture and from then on, OpenGL would simply not render, with the non-visual part of the application still running normally.
Make sure to call glGetError often and trace a message / break every time it reports something else than GL_NO_ERROR. (We have a macro for that, so that, while debugging, we call glGetError after every OpenGL call.)