EAGLView.m
上传用户:datou2885
上传日期:2019-04-15
资源大小:162k
文件大小:9k
源码类别:

MacOS编程

开发平台:

Objective-C

  1. //
  2. //  EAGLView.m
  3. //  AppleCoder-OpenGLES-00
  4. //
  5. //  Created by Simon Maurice on 18/03/09.
  6. //  Copyright Simon Maurice 2009. All rights reserved.
  7. //
  8. #import <QuartzCore/QuartzCore.h>
  9. #import <OpenGLES/EAGLDrawable.h>
  10. #import "EAGLView.h"
  11. #define USE_DEPTH_BUFFER 1
  12. #define DEGREES_TO_RADIANS(__ANGLE) ((__ANGLE) / 180.0 * M_PI)
  13. // A class extension to declare private methods
  14. @interface EAGLView ()
  15. @property (nonatomic, retain) EAGLContext *context;
  16. @property (nonatomic, assign) NSTimer *animationTimer;
  17. - (BOOL) createFramebuffer;
  18. - (void) destroyFramebuffer;
  19. @end
  20. @implementation EAGLView
  21. @synthesize context;
  22. @synthesize animationTimer;
  23. @synthesize animationInterval;
  24. // You must implement this method
  25. + (Class)layerClass {
  26.     return [CAEAGLLayer class];
  27. }
  28. //The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
  29. - (id)initWithCoder:(NSCoder*)coder {
  30.     
  31.     if ((self = [super initWithCoder:coder])) {
  32.         // Get the layer
  33.         CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
  34.         
  35.         eaglLayer.opaque = YES;
  36.         eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
  37.                                         [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
  38.         
  39.         context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
  40.         
  41.         if (!context || ![EAGLContext setCurrentContext:context]) {
  42.             [self release];
  43.             return nil;
  44.         }
  45.         
  46.         animationInterval = 1.0 / 60.0;
  47. rota = 0.0;
  48. [self setupView];
  49. [self loadTexture];
  50.     }
  51.     return self;
  52. }
  53. - (void)drawView {
  54. const GLfloat triangleVertices[] = {
  55.         0.0, 1.0, 0.0, // Triangle top centre
  56.         1.0, -1.0, 0.0, // bottom right
  57.         -1.0, -1.0, 0.0 // bottom left
  58.     };
  59. const GLfloat squareVertices[] = {
  60.         -1.0, 1.0, 0.0,            // Top left
  61.         1.0, 1.0, 0.0,             // Top right
  62.         1.0, -1.0, 0.0,            // Bottom right
  63.         -1.0, -1.0, 0.0            // Bottom left
  64.     };
  65. /*const GLfloat squareColours[] = {
  66. 1.0, 0.0, 0.0, 1.0, // Red - top left - the colour for squareVertices[0]
  67.         0.0, 1.0, 0.0, 1.0,   // Green - top right - squareVertices[1]
  68.         0.0, 0.0, 1.0, 1.0,   // Blue - bottom right - squareVerticies[2]
  69.         0.5, 0.5, 0.5, 1.0    // Grey - bottom left - squareVerticies[3]
  70.     };*/
  71.     const GLshort squareTextureCoords[] = {
  72.         0, 1,       // top left
  73.         1, 1,       // top right
  74.         1, 0,       // bottom right
  75.         0, 0        // bottom left
  76.     };
  77.     [EAGLContext setCurrentContext:context];    
  78.     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
  79.     glViewport(0, 0, backingWidth, backingHeight);
  80. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  81. glMatrixMode(GL_MODELVIEW);
  82. rota += 0.5;
  83. glLoadIdentity();
  84.     glColor4f(0.0, 0.0, 0.8, 1.0);
  85. glTranslatef(-1.5, 0.0, -6.0);
  86. glRotatef(rota, 0.0, 0.0, 1.0);
  87. glVertexPointer(3, GL_FLOAT, 0, triangleVertices);
  88. glEnableClientState(GL_VERTEX_ARRAY);
  89. glDrawArrays(GL_TRIANGLES, 0, 3);
  90.     
  91.     glLoadIdentity();
  92.     glColor4f(1.0, 1.0, 1.0, 1.0);      // NEW
  93.     glTranslatef(1.5, 0.0, -6.0);
  94.     glRotatef(rota, 0.0, 0.0, 1.0);
  95.     glVertexPointer(3, GL_FLOAT, 0, squareVertices);
  96.     glEnableClientState(GL_VERTEX_ARRAY);
  97.     
  98.     glTexCoordPointer(2, GL_SHORT, 0, squareTextureCoords);     // NEW
  99.     glEnableClientState(GL_TEXTURE_COORD_ARRAY);                // NEW
  100.     
  101.     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  102.     glDisableClientState(GL_TEXTURE_COORD_ARRAY);               // NEW
  103.     glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
  104.     [context presentRenderbuffer:GL_RENDERBUFFER_OES];
  105. }
  106. - (void)layoutSubviews {
  107.     [EAGLContext setCurrentContext:context];
  108.     [self destroyFramebuffer];
  109.     [self createFramebuffer];
  110.     [self drawView];
  111. }
  112. - (BOOL)createFramebuffer {
  113.     
  114.     glGenFramebuffersOES(1, &viewFramebuffer);
  115.     glGenRenderbuffersOES(1, &viewRenderbuffer);
  116.     
  117.     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
  118.     glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
  119.     [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
  120.     glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
  121.     
  122.     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
  123.     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
  124.     
  125.     if (USE_DEPTH_BUFFER) {
  126.         glGenRenderbuffersOES(1, &depthRenderbuffer);
  127.         glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
  128.         glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
  129.         glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
  130.     }
  131.     
  132.     if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
  133.         NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
  134.         return NO;
  135.     }
  136.     
  137.     return YES;
  138. }
  139. - (void)setupView {
  140.     const GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 60.0;
  141.     GLfloat size;
  142.     glEnable(GL_DEPTH_TEST);
  143.     glMatrixMode(GL_PROJECTION);
  144.     size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
  145. // This give us the size of the iPhone display
  146.     CGRect rect = self.bounds;
  147.     glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / (rect.size.width / rect.size.height), zNear, zFar);
  148.     glViewport(0, 0, rect.size.width, rect.size.height);
  149.     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  150. }
  151. - (void)loadTexture {
  152.     CGImageRef textureImage = [UIImage imageNamed:@"checkerplate.png"].CGImage;
  153.     if (textureImage == nil) {
  154.         NSLog(@"Failed to load texture image");
  155. return;
  156.     }
  157.     NSInteger texWidth = CGImageGetWidth(textureImage);
  158.     NSInteger texHeight = CGImageGetHeight(textureImage);
  159. GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
  160.     CGContextRef textureContext = CGBitmapContextCreate(textureData,
  161.                                                          texWidth, texHeight,
  162.                                                          8, texWidth * 4,
  163.                                                          CGImageGetColorSpace(textureImage),
  164.                                                          kCGImageAlphaPremultipliedLast);
  165. CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), textureImage);
  166. CGContextRelease(textureContext);
  167. glGenTextures(1, &textures[0]);
  168. glBindTexture(GL_TEXTURE_2D, textures[0]);
  169. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
  170. free(textureData);
  171. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  172. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  173. glEnable(GL_TEXTURE_2D);
  174. //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  175. //glEnable(GL_BLEND);
  176. }
  177. - (void)destroyFramebuffer {
  178.     
  179.     glDeleteFramebuffersOES(1, &viewFramebuffer);
  180.     viewFramebuffer = 0;
  181.     glDeleteRenderbuffersOES(1, &viewRenderbuffer);
  182.     viewRenderbuffer = 0;
  183.     
  184.     if(depthRenderbuffer) {
  185.         glDeleteRenderbuffersOES(1, &depthRenderbuffer);
  186.         depthRenderbuffer = 0;
  187.     }
  188. }
  189. - (void)startAnimation {
  190.     self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
  191. }
  192. - (void)stopAnimation {
  193.     self.animationTimer = nil;
  194. }
  195. - (void)setAnimationTimer:(NSTimer *)newTimer {
  196.     [animationTimer invalidate];
  197.     animationTimer = newTimer;
  198. }
  199. - (void)setAnimationInterval:(NSTimeInterval)interval {
  200.     
  201.     animationInterval = interval;
  202.     if (animationTimer) {
  203.         [self stopAnimation];
  204.         [self startAnimation];
  205.     }
  206. }
  207. - (void)checkGLError:(BOOL)visibleCheck {
  208.     GLenum error = glGetError();
  209.     
  210.     switch (error) {
  211.         case GL_INVALID_ENUM:
  212.             NSLog(@"GL Error: Enum argument is out of range");
  213.             break;
  214.         case GL_INVALID_VALUE:
  215.             NSLog(@"GL Error: Numeric value is out of range");
  216.             break;
  217.         case GL_INVALID_OPERATION:
  218.             NSLog(@"GL Error: Operation illegal in current state");
  219.             break;
  220.         case GL_STACK_OVERFLOW:
  221.             NSLog(@"GL Error: Command would cause a stack overflow");
  222.             break;
  223.         case GL_STACK_UNDERFLOW:
  224.             NSLog(@"GL Error: Command would cause a stack underflow");
  225.             break;
  226.         case GL_OUT_OF_MEMORY:
  227.             NSLog(@"GL Error: Not enough memory to execute command");
  228.             break;
  229.         case GL_NO_ERROR:
  230.             if (visibleCheck) {
  231.                 NSLog(@"No GL Error");
  232.             }
  233.             break;
  234.         default:
  235.             NSLog(@"Unknown GL Error");
  236.             break;
  237.     }
  238. }
  239. - (void)dealloc {
  240.     
  241.     [self stopAnimation];
  242.     
  243.     if ([EAGLContext currentContext] == context) {
  244.         [EAGLContext setCurrentContext:nil];
  245.     }
  246.     
  247.     [context release];  
  248.     [super dealloc];
  249. }
  250. @end