The preparatory work
- Introduce the #import
header file
#import <GLKit/GLKit.h>
Copy the code
- Declare vertex data structures
3. Property Settings
#import <GLKit/GLKit.h> #import "dnCubeViewController.h" typedef struct { GLKVector3 positionCoord; GLKVector2 textureCoord; // Texture coordinates GLKVector3 normal; // normal} DNCubeVertex; // The cube has 36 vertices static NSInteger const kCoordCount = 36; @interface dnCubeViewController () <GLKViewDelegate> @property (nonatomic, assign) DNCubeVertex * vertices; @property (nonatomic, strong) GLKView * GLKView; // View@property (nonatomic, strong) GLKBaseEffect * baseEffect; @property (nonatomic, assign) GLuint vertexBuffer; @property (nonatomic, assign) NSInteger Angle; // Rotate Angle @property (nonatomic, strong) CADisplayLink * displayLink; // Timer more Angle redraw to achieve rotation effect @endCopy the code
Lazy loading of vertices data
- (DNCubeVertex*)vertices{ if (! _vertices) { _vertices = malloc(sizeof(DNCubeVertex) * kCoordCount); / / the front _vertices [0] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {0, 0, 1}}; _vertices [1] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 0}, {0, 0, 1}}; _vertices [2] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 1}, {0, 0, 1}}; _vertices [3] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 0}, {0, 0, 1}}; _vertices [4] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 1}, {0, 0, 1}}; _vertices [5] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {0, 0, 1}}; / / the above _vertices [6] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 1}, {0, 1, 0}}; _vertices [7] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {0, 1, 0}}; _vertices [8] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {0, 1, 0}}; _vertices [9] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {0, 1, 0}}; _vertices [10] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {0, 1, 0}}; _vertices [11] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 0}, {0, 1, 0}}; / / the following _vertices [12] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 1}, {0, 1, 0}}; _vertices [13] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {0, 1, 0}}; _vertices [14] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {0, 1, 0}}; _vertices [15] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {0, 1, 0}}; _vertices [16] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {0, 1, 0}}; _vertices [17] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 0}, {0, 1, 0}}; / / the left _vertices [18] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 1}, {1, 0, 0}}; _vertices [19] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {1, 0, 0}}; _vertices [20] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {1, 0, 0}}; _vertices [21] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {1, 0, 0}}; _vertices [22] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {1, 0, 0}}; _vertices [23] (DNCubeVertex) = {{0.5, 0.5, 0.5}, {0, 0}, {1, 0, 0}}; / / right _vertices [24] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 1}, {1, 0, 0}}; _vertices [25] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {1, 0, 0}}; _vertices [26] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {1, 0, 0}}; _vertices [27] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {1, 0, 0}}; _vertices [28] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {1, 0, 0}}; _vertices [29] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 0}, {1, 0, 0}}; / / behind _vertices [30] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 1}, {0, 0, 1}}; _vertices [31] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 0}, {0, 0, 1}}; _vertices [32] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 1}, {0, 0, 1}}; _vertices [33] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {0, 0}, {0, 0, 1}}; _vertices [34] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 1}, {0, 0, 1}}; _vertices [35] = (DNCubeVertex) {{0.5, 0.5, 0.5}, {1, 0}, {0, 0, 1}}; } return _vertices; }Copy the code
CommonInit function environment Settings
Get the current contenxt GLKBaseEffect Settings to open caches and bind textures to load
- (void) commonInit {/ / 1. Create the context EAGLContext * context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2]; / / set the current context [EAGLContext setCurrentContext: context]; / / 2. Create GLKView and set up the proxy CGRect frame = CGRectMake (0, 100, the self. View. Frame. The size, width, and the self. The frame. The size, width); self.glkView = [[GLKView alloc] initWithFrame:frame context:context]; self.glkView.backgroundColor = [UIColor clearColor]; self.glkView.delegate = self; / / 3. Self using the depth buffer. GlkView. DrawableDepthFormat = GLKViewDrawableDepthFormat24; GlDepthRangef (1, 0); glDepthRangef(1, 0); glDepthRangef(1, 0); // add GLKView to self.view [self.view addSubview:self.glkView]; / / 5. For texture image nsstrings * imagePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: @ "kunkun. JPG"]. UIImage *image = [UIImage imageWithContentsOfFile:imagePath]; / / 6. Set the texture parameters NSDictionary * options = @ {GLKTextureLoaderOriginBottomLeft: @ (YES)}; GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:[image CGImage] options:options error:NULL]; Self. BaseEffect = [[GLKBaseEffect alloc] init]; self.baseEffect.texture2d0.name = textureInfo.name; self.baseEffect.texture2d0.target = textureInfo.target; / / open the lighting effects self. BaseEffect. Light0. Enabled = YES; / / diffuse color self. BaseEffect. Light0. DiffuseColor = GLKVector4Make (1, 1, 1, 1); / / the source self. BaseEffect. Light0. Position = GLKVector4Make (0.5, 0.5, 5, 1); / * explain: here we don't reuse vertices, using every three by drawing a triangle, it takes about 12 triangles, then you will need the following 36 vertex data used to draw on (0, 0), length of 1 cube * / / / 8. Buffers(1, &_vertexBuffer); // Buffers(1, &_vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); GLsizeiptr bufferSizeBytes = sizeof(DNCubeVertex) * kCoordCount; glBufferData(GL_ARRAY_BUFFER, bufferSizeBytes, self.vertices, GL_STATIC_DRAW); / / vertex data glEnableVertexAttribArray (GLKVertexAttribPosition); NSLog(@"offsetof(DNCubeVertex, positionCoord): %lu",offsetof(DNCubeVertex, positionCoord)); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(DNCubeVertex), NULL + offsetof(DNCubeVertex, positionCoord)); / / texture data glEnableVertexAttribArray (GLKVertexAttribTexCoord0); glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(DNCubeVertex), NULL + offsetof(DNCubeVertex, textureCoord)); NSLog(@"offsetof(DNCubeVertex, textureCoord): %lu",offsetof(DNCubeVertex, textureCoord)); / / normal data glEnableVertexAttribArray (GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(DNCubeVertex), NULL + offsetof(DNCubeVertex, normal)); NSLog(@"offsetof(DNCubeVertex, normal): %lu",offsetof(DNCubeVertex, normal)); }Copy the code
Adding a timer
-(void) addCADisplayLink{//CADisplayLink is like a timer and provides a periodic call. . Belong to the QuartzCore framework. / / specific can refer to the blog https://www.cnblogs.com/panyangjun/p/4421904.html self. The Angle = 0; self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)]; [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; }Copy the code
Update the Angle
#pragma mark - update - (void)update { //1. Self. Angle = (self. Angle + 5) % 360; self. Angle = (self. Angle + 5) % 360; / / 2. Modify baseEffect. Transform. ModelviewMatrix self. BaseEffect. Transform. ModelviewMatrix = GLKMatrix4MakeRotation (GLKMathDegreesToRadians (self Angle), 0.3, 1, 0.7); //3. Re-render [self.glkView display]; }Copy the code
GLKView proxy method implementation
#pragma mark - GLKViewDelegate - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { //1. Enable the depth test glEnable(GL_DEPTH_TEST); / / 2. Remove the color buffer & depth buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //3. PrepareToDraw [self. BaseEffect prepareToDraw]; //4. Say glDrawArrays(Say, GL_TRIANGLES, 0, kCoordCount); }Copy the code
ViewDidLoad function
- (void)viewDidLoad { [super viewDidLoad]; / / 1. The self View background. The backgroundColor = [UIColor blackColor]; //2. OpenGL ES related initialization [self commonInit]; //3. AddCADisplayLink [self addCADisplayLink]; }Copy the code
Dealloc function
- (void)dealloc { if ([EAGLContext currentContext] == self.glkView.context) { [EAGLContext setCurrentContext:nil]; } if (_vertices) { free(_vertices); _vertices = nil; } if (_vertexBuffer) { glDeleteBuffers(1, &_vertexBuffer); _vertexBuffer = 0; } //displayLink invalidate [self.displayLink invalidate]; }Copy the code