k123

HelloGLKitViewController.m

May 30th, 2012
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #import "HelloGLKitViewController.h"
  2. #import "Objects.h"
  3.  
  4. GLKMatrix4 modelViewMatrix;
  5. GLKMatrix4 projectionMatrix;
  6.  
  7. Drawable cube;
  8.  
  9. GLKTextureInfo * info;
  10. GLKTextureInfo * info2;
  11.  
  12. // THIS IS THE STRUCTURE FOR THE CUBE IN THE TUTORIAL.
  13. // THIS IS NOT BEING RENDERED.
  14. typedef struct {
  15.     float Position[3];
  16.     float Color[4];
  17.     float TexCoord[2];
  18. } Vertex;
  19.  
  20. const Vertex Vertices[] = {
  21.     // Front
  22.     {{1, -1, 1}, {1, 0, 0, 1}, {1, 0}},
  23.     {{1, 1, 1}, {0, 1, 0, 1}, {1, 1}},
  24.     {{-1, 1, 1}, {0, 0, 1, 1}, {0, 1}},
  25.     {{-1, -1, 1}, {0, 0, 0, 1}, {0, 0}},
  26.     // Back
  27.     {{1, 1, -1}, {1, 0, 0, 1}, {0, 1}},
  28.     {{-1, -1, -1}, {0, 1, 0, 1}, {1, 0}},
  29.     {{1, -1, -1}, {0, 0, 1, 1}, {0, 0}},
  30.     {{-1, 1, -1}, {0, 0, 0, 1}, {1, 1}},
  31.     // Left
  32.     {{-1, -1, 1}, {1, 0, 0, 1}, {1, 0}},
  33.     {{-1, 1, 1}, {0, 1, 0, 1}, {1, 1}},
  34.     {{-1, 1, -1}, {0, 0, 1, 1}, {0, 1}},
  35.     {{-1, -1, -1}, {0, 0, 0, 1}, {0, 0}},
  36.     // Right
  37.     {{1, -1, -1}, {1, 0, 0, 1}, {1, 0}},
  38.     {{1, 1, -1}, {0, 1, 0, 1}, {1, 1}},
  39.     {{1, 1, 1}, {0, 0, 1, 1}, {0, 1}},
  40.     {{1, -1, 1}, {0, 0, 0, 1}, {0, 0}},
  41.     // Top
  42.     {{1, 1, 1}, {1, 0, 0, 1}, {1, 0}},
  43.     {{1, 1, -1}, {0, 1, 0, 1}, {1, 1}},
  44.     {{-1, 1, -1}, {0, 0, 1, 1}, {0, 1}},
  45.     {{-1, 1, 1}, {0, 0, 0, 1}, {0, 0}},
  46.     // Bottom
  47.     {{1, -1, -1}, {1, 0, 0, 1}, {1, 0}},
  48.     {{1, -1, 1}, {0, 1, 0, 1}, {1, 1}},
  49.     {{-1, -1, 1}, {0, 0, 1, 1}, {0, 1}},
  50.     {{-1, -1, -1}, {0, 0, 0, 1}, {0, 0}}
  51. };
  52.  
  53. const GLubyte Indices[] = {
  54.     // Front
  55.     0, 1, 2,
  56.     2, 3, 0,
  57.     // Back
  58.     4, 6, 5,
  59.     4, 5, 7,
  60.     // Left
  61.     8, 9, 10,
  62.     10, 11, 8,
  63.     // Right
  64.     12, 13, 14,
  65.     14, 15, 12,
  66.     // Top
  67.     16, 17, 18,
  68.     18, 19, 16,
  69.     // Bottom
  70.     20, 21, 22,
  71.     22, 23, 20
  72. };
  73.  
  74. #endif
  75.  
  76. @interface HelloGLKitViewController () {
  77.     GLuint _vertexBuffer;
  78.     GLuint _indexBuffer;
  79.     float _rotation;
  80. }
  81.  
  82. @end
  83.  
  84. @implementation HelloGLKitViewController
  85.  
  86. @synthesize context = _context;
  87. @synthesize effect = _effect;
  88.  
  89. #pragma mark - View lifecycle
  90.  
  91. - (void)setupGL {
  92.     [EAGLContext setCurrentContext:self.context];
  93.     glEnable(GL_CULL_FACE);
  94.    
  95.     self.effect = [[GLKBaseEffect alloc] init];
  96.    
  97.     NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
  98.                               [NSNumber numberWithBool:YES],
  99.                               GLKTextureLoaderOriginBottomLeft,
  100.                               nil];
  101.     NSError * error;    
  102.     NSString *path = [[NSBundle mainBundle] pathForResource:@"tile_floor" ofType:@"png"];
  103.     info = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
  104.     if (info == nil) {
  105.         NSLog(@"Error loading file: %@", [error localizedDescription]);
  106.     }
  107.  
  108.     NSString *path2 = [[NSBundle mainBundle] pathForResource:@"stopButton" ofType:@"png"];
  109.     info2 = [GLKTextureLoader textureWithContentsOfFile:path2 options:options error:&error];
  110.     if (info2 == nil) {
  111.         NSLog(@"Error loading file: %@", [error localizedDescription]);
  112.     }
  113.    
  114.     cube = [self createDrawable:@"Cube.obj"];
  115.    
  116.     // Old stuff
  117.     glGenBuffers(1, &_vertexBuffer);
  118.     glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
  119.     glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
  120.    
  121.     glGenBuffers(1, &_indexBuffer);
  122.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
  123.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
  124. }
  125.  
  126. - (void) tearDownGL {
  127.    
  128.     [EAGLContext setCurrentContext:self.context];
  129.    
  130.     glDeleteBuffers(1, &_vertexBuffer);
  131.     glDeleteBuffers(1, &_indexBuffer);
  132.    
  133.     self.effect = nil;    
  134.    
  135. }
  136.  
  137. #pragma mark - GLKViewDelegateiew loading and unloading
  138.  
  139. - (void)viewDidLoad {
  140.     [super viewDidLoad];
  141.    
  142.     self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
  143.    
  144.     if (!self.context) {
  145.         NSLog(@"Failed to create ES context");
  146.     }
  147.    
  148.     GLKView *view = (GLKView *)self.view;
  149.     view.context = self.context;
  150.     view.drawableMultisample = GLKViewDrawableMultisample4X;
  151.     [self setupGL];
  152. }
  153.  
  154. - (void)viewDidUnload {
  155.     [super viewDidUnload];
  156.    
  157.     [self tearDownGL];
  158.    
  159.     if ([EAGLContext currentContext] == self.context) {
  160.         [EAGLContext setCurrentContext:nil];
  161.     }
  162.     self.context = nil;
  163. }
  164.  
  165. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  166. {
  167.     // Return YES for supported orientations
  168.     return (interfaceOrientation == UIInterfaceOrientationPortrait);
  169. }
  170.  
  171. #pragma mark - GLKViewDelegate
  172.  
  173. - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
  174.    
  175.     glClearColor(1.0f, 1.0, 1.0, 1.0);
  176.     glClear(GL_COLOR_BUFFER_BIT);
  177.    
  178.     [self.effect prepareToDraw];    
  179.    
  180.     self.effect.texture2d0.name = info.name;
  181.     self.effect.texture2d0.enabled = true;
  182.    
  183.     glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
  184.     glEnableVertexAttribArray(GLKVertexAttribPosition);        
  185.     glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
  186.     glEnableVertexAttribArray(GLKVertexAttribColor);
  187.     glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Color));
  188.     glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
  189.     glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, TexCoord));
  190.    
  191.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
  192.     // NOT RENDERING THE DEFAULT CUBE.
  193.     //glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);  
  194.    
  195.     self.effect.texture2d0.name = info2.name;
  196.     self.effect.texture2d0.enabled = true;
  197.     [self renderDrawable:cube];
  198.    
  199.     glFlush();
  200. }
  201.  
  202. #pragma mark - GLKViewControllerDelegate
  203.  
  204. - (void)update {
  205.     float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
  206.     projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 2.0f, 20.0f);    
  207.     self.effect.transform.projectionMatrix = projectionMatrix;
  208.    
  209.     modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -10.0f);  
  210.     _rotation += 45 * self.timeSinceLastUpdate;
  211.     modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(25), 1, 0, 0);
  212.     modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(_rotation), 0, 1, 0);    
  213.     self.effect.transform.modelviewMatrix = modelViewMatrix;
  214. }
  215.  
  216. # pragma mark - Create and render Drawable functions
  217.  
  218. - (Drawable)createDrawable: (NSString *)objFileName {
  219.     NSError * error;
  220.    
  221.     // Get obj contents.
  222.     NSArray *objFile              = [objFileName componentsSeparatedByString:@"."];
  223.     NSString *name                = [objFile objectAtIndex:0];
  224.     NSString *extension           = [objFile objectAtIndex:1];
  225.     NSString *objFilePath         = [[NSBundle mainBundle] pathForResource:name ofType:extension];
  226.     NSString *objFileContents     = [[NSString alloc] init];
  227.     objFileContents               = [NSString stringWithContentsOfFile:objFilePath encoding: NSASCIIStringEncoding error: &error];
  228.     if (objFileContents == nil) {
  229.         NSLog(@"Error loading file %@.obj: %@", name, [error localizedDescription]);
  230.     }
  231.     NSArray *individualLinesInObj = [objFileContents componentsSeparatedByString:@"\n"];
  232.    
  233.     // Specifications/arrays of individual things for this object. The array for
  234.     // faces can (and will) be directly used for the indexbuffer. For the
  235.     // vertexbuffer we'll need another array that will hold all three vertices,
  236.     // texture uvs and normals togather.
  237.     int  numVerts = 0;
  238.     int  numTex = 0;
  239.     int  numNormals = 0;
  240.     int  numFaces = 0;
  241.     float *vertices;
  242.     float *tex;
  243.     float *normals;
  244.     uint  *indices;
  245.    
  246.     // We will be returning this Drawable.
  247.     Drawable _drawable;
  248.    
  249.     // Get specifications (i.e. # of everything).
  250.     for(NSString *line in individualLinesInObj) {
  251.         if([line hasPrefix:@"v "])
  252.             numVerts++;
  253.         else if([line hasPrefix:@"vt "])
  254.             numTex++;
  255.         else if([line hasPrefix:@"vn "])
  256.             numNormals++;
  257.         else if([line hasPrefix:@"f "])
  258.             numFaces++;
  259.     }
  260.    
  261.     // Initialize object arrays with values from the obj file.
  262.     vertices = malloc(sizeof(GL_FLOAT) * numVerts * 3);       // x, y, z: 3 values per vertex.
  263.     tex      = malloc(sizeof(GL_FLOAT) * numTex * 2);         // u, v: 2 values per texture point.
  264.     normals  = malloc(sizeof(GL_FLOAT) * numNormals * 3);     // nx, ny, nz: 3 values per normal.
  265.     indices  = malloc(sizeof(GL_UNSIGNED_INT) * numFaces * 3);// 3 vertices per (triangle) face.
  266.    
  267.     // Copy obj file data to arrays. v, n, t, f: counters.
  268.     int v = 0;
  269.     int t = 0;
  270.     int n = 0;
  271.     int f = 0;
  272.     for(NSString *line in individualLinesInObj) {
  273.         if([line hasPrefix:@"v "]) {
  274.             NSArray *tempV = [line componentsSeparatedByString:@" "];
  275.            
  276.             // The first string is the prefix 'v', which we are to ignore.
  277.             BOOL prefixPassed = NO;
  278.             for(NSString *tempString in tempV) {
  279.                 if(prefixPassed) {
  280.                     vertices[v] = [tempString floatValue];
  281.                     v++;
  282.                 }
  283.                 else {
  284.                     prefixPassed = YES;
  285.                 }
  286.             }
  287.         }
  288.         else if([line hasPrefix:@"vt "]) {
  289.             NSArray *tempT = [line componentsSeparatedByString:@" "];
  290.            
  291.             // The first string is the prefix 'vt', which we are to ignore.
  292.             BOOL prefixPassed = NO;
  293.             for(NSString *tempString in tempT) {
  294.                 if(prefixPassed) {
  295.                     tex[t] = [tempString floatValue];
  296.                     t++;
  297.                 }
  298.                 else {
  299.                     prefixPassed = YES;
  300.                 }
  301.             }
  302.         }
  303.         else if([line hasPrefix:@"vn "]) {
  304.             NSArray *tempN = [line componentsSeparatedByString:@" "];
  305.            
  306.             // The first string is the prefix 'vn', which we are to ignore.
  307.             BOOL prefixPassed = NO;
  308.             for(NSString *tempString in tempN) {
  309.                 if(prefixPassed) {
  310.                     normals[n] = [tempString floatValue];
  311.                     n++;
  312.                 }
  313.                 else {
  314.                     prefixPassed = YES;
  315.                 }
  316.             }
  317.         }
  318.         else if([line hasPrefix:@"f "]) {
  319.             NSArray *tempF = [line componentsSeparatedByString:@" "];
  320.            
  321.             // The first string is the prefix 'f', which we are to ignore.
  322.             BOOL prefixPassed = NO;
  323.            
  324.             for(NSString *tempString in tempF) {
  325.                 int iTemp[3] = {0, 0, 0};
  326.                 NSArray *singleFaceData = [tempString componentsSeparatedByString:@" "];
  327.                 for(NSString *singleVertexData in singleFaceData) {
  328.                     if(prefixPassed) {
  329.                         // Break this vertex's data into V#, T# and N#. For now,
  330.                         // we need only vertex number.
  331.                         NSArray *brokenVertex = [singleVertexData componentsSeparatedByString:@"/"];
  332.                        
  333.                         int i = 0;
  334.                         for(NSString *vertexNumber in brokenVertex) {
  335.                             iTemp[i] = [vertexNumber intValue] - 1;
  336.                             i++;
  337.                         }
  338.                        
  339.                         indices[f] = iTemp[0];
  340.                         f++;
  341.                     }
  342.                     else {
  343.                         prefixPassed = YES;
  344.                     }
  345.                 }
  346.             }
  347.         }
  348.     }
  349.    
  350.     // Create an array for vertex data. This array will contain 3 vertex data
  351.     // sets, each having 8 float values for each vertex. Something like:
  352.     // (Vx, Vy, Vz, u, v, Nx, Ny, Nz).
  353.     // This ordering will come from the indexbuffer (*faces array).  An indexbuffer
  354.     // triplet a/b/c means a-th vertex, b-th uv and in the .obj file.
  355.     GLfloat *vertexData = malloc(sizeof(GL_FLOAT) * (3 + 2 + 3) * numFaces * 3);
  356.     int vdCount = 0;
  357.     for(NSString *line in individualLinesInObj) {
  358.         if([line hasPrefix:@"f "]) {
  359.             NSArray *tempF = [line componentsSeparatedByString:@" "];
  360.            
  361.             // The first string is the prefix 'f', which we are to ignore.
  362.             BOOL prefixPassed = NO;
  363.            
  364.             for(NSString *tempString in tempF) {
  365.                 NSArray *singleFaceData = [tempString componentsSeparatedByString:@" "];
  366.                 for(NSString *singleVertexData in singleFaceData) {
  367.                     if(prefixPassed) {
  368.                         // Break this vertex's data into V#, T# and N#.
  369.                         NSArray *brokenVertex = [singleVertexData componentsSeparatedByString:@"/"];
  370.                        
  371.                         int i = 0;
  372.                         int iTemp[3] = {0, 0, 0};
  373.                         for(NSString *string in brokenVertex) {
  374.                             iTemp[i] = [string intValue];
  375.                             iTemp[i] -= 1;
  376.                             i++;
  377.                         }
  378.                        
  379.                         // Copy data into vertex-array (not vertexarray) from
  380.                         // vertices, texture (uvs) and normals.
  381.                         // vertices
  382.                         vertexData[vdCount + 0] = vertices[iTemp[0] * 3 + 0];
  383.                         vertexData[vdCount + 1] = vertices[iTemp[0] * 3 + 1];
  384.                         vertexData[vdCount + 2] = vertices[iTemp[0] * 3 + 2];
  385.                         // texture
  386.                         vertexData[vdCount + 3] = tex[iTemp[1] * 3 + 0];
  387.                         vertexData[vdCount + 4] = tex[iTemp[1] * 3 + 1];
  388.                         // normals
  389.                         vertexData[vdCount + 5] = normals[iTemp[2] * 3 + 0];
  390.                         vertexData[vdCount + 6] = normals[iTemp[2] * 3 + 1];
  391.                         vertexData[vdCount + 7] = normals[iTemp[2] * 3 + 2];
  392.                        
  393.                         // increment vertex count
  394.                         vdCount += 8;
  395.                     }
  396.                     else {
  397.                         prefixPassed = YES;
  398.                     }
  399.                 }
  400.             }
  401.         }
  402.     }
  403.    
  404.     _drawable.numFaces = numFaces;
  405.    
  406.     glGenBuffers(1, &_drawable.vertexBuffer);
  407.     glBindBuffer(GL_ARRAY_BUFFER, _drawable.vertexBuffer);
  408.     glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData) * numFaces * 8, vertexData, GL_STATIC_DRAW);
  409.    
  410.     glGenBuffers(1, &_drawable.indexBuffer);
  411.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _drawable.indexBuffer);
  412.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices) * numFaces * 3, indices, GL_STATIC_DRAW);
  413.    
  414.     _drawable.matrix = GLKMatrix4Identity;
  415.     //_drawable.matrix = GLKMatrix4Scale(_drawable.matrix, 5.0f, 5.0f, 5.0f);
  416.     _drawable.matrix = GLKMatrix4Translate(_drawable.matrix, 0.0f, 0.0f, 10.0f);
  417.    
  418.     return _drawable;
  419. }
  420.  
  421. - (void) renderDrawable: (Drawable)object {
  422.     glBindBuffer(GL_ARRAY_BUFFER, object.vertexBuffer);
  423.     glEnableVertexAttribArray(GLKVertexAttribPosition);        
  424.     glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) 0);
  425.     glEnableVertexAttribArray(GLKVertexAttribTexCoord1);
  426.     glVertexAttribPointer(GLKVertexAttribTexCoord1, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) 3);
  427.     glEnableVertexAttribArray(GLKVertexAttribNormal);
  428.     glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) 5);
  429.    
  430.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object.indexBuffer);
  431.     glDrawElements(GL_LINES, sizeof(object.indexBuffer) * 3 * object.numFaces, GL_UNSIGNED_BYTE, (const GLvoid *) object.indexBuffer);
  432. }
  433.  
  434. # pragma mark - Touch events
  435.  
  436. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  437.     self.paused = !self.paused;
  438.    
  439.     NSLog(@"timeSinceLastUpdate: %f", self.timeSinceLastUpdate);
  440.     NSLog(@"timeSinceLastDraw: %f", self.timeSinceLastDraw);
  441.     NSLog(@"timeSinceFirstResume: %f", self.timeSinceFirstResume);
  442.     NSLog(@"timeSinceLastResume: %f", self.timeSinceLastResume);
  443. }
  444.  
  445. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  446.    
  447. }
  448.  
  449. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  450.    
  451. }
  452.  
  453. - (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
  454.    
  455. }
  456.  
  457. @end
Advertisement
Add Comment
Please, Sign In to add comment