EAGLView.m
上传用户:datou2885
上传日期:2019-04-15
资源大小:162k
文件大小:9k
- //
- // EAGLView.m
- // AppleCoder-OpenGLES-00
- //
- // Created by Simon Maurice on 18/03/09.
- // Copyright Simon Maurice 2009. All rights reserved.
- //
- #import <QuartzCore/QuartzCore.h>
- #import <OpenGLES/EAGLDrawable.h>
- #import "EAGLView.h"
- #define USE_DEPTH_BUFFER 1
- #define DEGREES_TO_RADIANS(__ANGLE) ((__ANGLE) / 180.0 * M_PI)
- // A class extension to declare private methods
- @interface EAGLView ()
- @property (nonatomic, retain) EAGLContext *context;
- @property (nonatomic, assign) NSTimer *animationTimer;
- - (BOOL) createFramebuffer;
- - (void) destroyFramebuffer;
- @end
- @implementation EAGLView
- @synthesize context;
- @synthesize animationTimer;
- @synthesize animationInterval;
- // 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;
- }
-
- animationInterval = 1.0 / 60.0;
- rota = 0.0;
-
- [self setupView];
- [self loadTexture];
- }
- return self;
- }
- - (void)drawView {
- const GLfloat triangleVertices[] = {
- 0.0, 1.0, 0.0, // Triangle top centre
- 1.0, -1.0, 0.0, // bottom right
- -1.0, -1.0, 0.0 // bottom left
- };
-
- const GLfloat squareVertices[] = {
- -1.0, 1.0, 0.0, // Top left
- 1.0, 1.0, 0.0, // Top right
- 1.0, -1.0, 0.0, // Bottom right
- -1.0, -1.0, 0.0 // Bottom left
- };
-
- /*const GLfloat squareColours[] = {
- 1.0, 0.0, 0.0, 1.0, // Red - top left - the colour for squareVertices[0]
- 0.0, 1.0, 0.0, 1.0, // Green - top right - squareVertices[1]
- 0.0, 0.0, 1.0, 1.0, // Blue - bottom right - squareVerticies[2]
- 0.5, 0.5, 0.5, 1.0 // Grey - bottom left - squareVerticies[3]
- };*/
- const GLshort squareTextureCoords[] = {
- 0, 1, // top left
- 1, 1, // top right
- 1, 0, // bottom right
- 0, 0 // bottom left
- };
-
- [EAGLContext setCurrentContext:context];
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
- glViewport(0, 0, backingWidth, backingHeight);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glMatrixMode(GL_MODELVIEW);
-
- rota += 0.5;
-
- glLoadIdentity();
- glColor4f(0.0, 0.0, 0.8, 1.0);
- glTranslatef(-1.5, 0.0, -6.0);
- glRotatef(rota, 0.0, 0.0, 1.0);
- glVertexPointer(3, GL_FLOAT, 0, triangleVertices);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_TRIANGLES, 0, 3);
-
- glLoadIdentity();
- glColor4f(1.0, 1.0, 1.0, 1.0); // NEW
- glTranslatef(1.5, 0.0, -6.0);
- glRotatef(rota, 0.0, 0.0, 1.0);
- glVertexPointer(3, GL_FLOAT, 0, squareVertices);
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glTexCoordPointer(2, GL_SHORT, 0, squareTextureCoords); // NEW
- glEnableClientState(GL_TEXTURE_COORD_ARRAY); // NEW
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY); // NEW
-
- 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)setupView {
-
- const GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 60.0;
- GLfloat size;
-
- glEnable(GL_DEPTH_TEST);
- glMatrixMode(GL_PROJECTION);
- size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
-
- // This give us the size of the iPhone display
- CGRect rect = self.bounds;
- glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / (rect.size.width / rect.size.height), zNear, zFar);
- glViewport(0, 0, rect.size.width, rect.size.height);
-
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- }
- - (void)loadTexture {
- CGImageRef textureImage = [UIImage imageNamed:@"checkerplate.png"].CGImage;
- if (textureImage == nil) {
- NSLog(@"Failed to load texture image");
- return;
- }
-
- NSInteger texWidth = CGImageGetWidth(textureImage);
- NSInteger texHeight = CGImageGetHeight(textureImage);
-
- GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
-
- CGContextRef textureContext = CGBitmapContextCreate(textureData,
- texWidth, texHeight,
- 8, texWidth * 4,
- CGImageGetColorSpace(textureImage),
- kCGImageAlphaPremultipliedLast);
- CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), textureImage);
- CGContextRelease(textureContext);
-
- glGenTextures(1, &textures[0]);
- glBindTexture(GL_TEXTURE_2D, textures[0]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
-
- free(textureData);
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glEnable(GL_TEXTURE_2D);
- //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- //glEnable(GL_BLEND);
- }
- - (void)destroyFramebuffer {
-
- glDeleteFramebuffersOES(1, &viewFramebuffer);
- viewFramebuffer = 0;
- glDeleteRenderbuffersOES(1, &viewRenderbuffer);
- viewRenderbuffer = 0;
-
- if(depthRenderbuffer) {
- glDeleteRenderbuffersOES(1, &depthRenderbuffer);
- depthRenderbuffer = 0;
- }
- }
- - (void)startAnimation {
- self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
- }
- - (void)stopAnimation {
- self.animationTimer = nil;
- }
- - (void)setAnimationTimer:(NSTimer *)newTimer {
- [animationTimer invalidate];
- animationTimer = newTimer;
- }
- - (void)setAnimationInterval:(NSTimeInterval)interval {
-
- animationInterval = interval;
- if (animationTimer) {
- [self stopAnimation];
- [self startAnimation];
- }
- }
- - (void)checkGLError:(BOOL)visibleCheck {
- GLenum error = glGetError();
-
- switch (error) {
- case GL_INVALID_ENUM:
- NSLog(@"GL Error: Enum argument is out of range");
- break;
- case GL_INVALID_VALUE:
- NSLog(@"GL Error: Numeric value is out of range");
- break;
- case GL_INVALID_OPERATION:
- NSLog(@"GL Error: Operation illegal in current state");
- break;
- case GL_STACK_OVERFLOW:
- NSLog(@"GL Error: Command would cause a stack overflow");
- break;
- case GL_STACK_UNDERFLOW:
- NSLog(@"GL Error: Command would cause a stack underflow");
- break;
- case GL_OUT_OF_MEMORY:
- NSLog(@"GL Error: Not enough memory to execute command");
- break;
- case GL_NO_ERROR:
- if (visibleCheck) {
- NSLog(@"No GL Error");
- }
- break;
- default:
- NSLog(@"Unknown GL Error");
- break;
- }
- }
- - (void)dealloc {
-
- [self stopAnimation];
-
- if ([EAGLContext currentContext] == context) {
- [EAGLContext setCurrentContext:nil];
- }
-
- [context release];
- [super dealloc];
- }
- @end