First, preparation

Second, the analysis process

Three, notes

  • To use GLKViewController, you must create a GLKView and implement the GLKView proxy method
  • Because multiple contexts can occur, be sure to set the current context
  • To make the GPU more efficient, we need to create a vertex buffer and copy an array of vertices into it
  • Attributes is off by default. It is enabled by API and needs to be enabled twice, passing in vertex data and texture data respectively
  • The origin of texture coordinates is in the lower left corner, but the image shows the origin in the upper left corner. Note the mapping

Fourth, code analysis

1. Initialize the configuration

- (void) SetUpConfig {/ / 1, the initial context context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES3]; // check if(! context){ NSLog(@"context failed !!!" ); } / / 3, set the current context (because context can have multiple, but only one current context) [EAGLContext setCurrentContext: context]; GLKView *view = (GLKView *)self.view; view.context = context; //5, set the background color glClearColor(0.9f, 0.2f, 0.0f, 1.0f); /* drawableColorFormat: /* drawableColorFormat: It is used to store colors that will be displayed on the screen. You can use its properties to set the color format of each pixel in the buffer. GLKViewDrawableColorFormatRGBA8888 = 0, the default. The minimum component of each pixel of the cache (RGBA) uses 8 bits, (so 4 bytes per pixel, 4*8 bits). GLKViewDrawableColorFormatRGB565, if your APP allows a smaller range of color, can set this. Will make your APP consumes less resources (memory and processing time) GLKViewDrawableColorFormatSRGBA8888 * / the drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; /* drawableDepthFormat: Depth buffer format GLKViewDrawableDepthFormatNone = 0 means no depth buffer GLKViewDrawableDepthFormat16, this will consume less than 24 resource GLKViewDrawableDepthFormat24, commonly used in 3 d game * / the drawableDepthFormat = GLKViewDrawableDepthFormat16; // Also remember the GLKView proxy}Copy the code

2. Set vertex data and texture coordinates

-(void)SetUpVertexData{//1, set vertex array /* 1) 0) * / GLfloat vertexData [] = {0.5, 0.5, 0.0 f, f 1.0, 0.0, f / / lower 0.5, 0.5, 0.0 f, f 1.0, 1.0, f / / upper right - 0.5, 0.5, 0.0, f F 0.0, 1.0, f / / upper left 0.5, 0.5, 0.0 f, f 1.0, 0.0, f / / right - 0.5, 0.5, 0.0 f, f 0.0, 1.0, f / / upper left - 0.5, 0.5, 0.0 f, f 0.0, 0.0, f / / lower left}; //1) create vertex buffer identifier id GLuint vbufferId; 2) create vertex buffer identifier id GLuint vbufferId; glGenBuffers(1, &vbufferId); //2) Bind vertex buffer glBindBuffer(GL_ARRAY_BUFFER, vbufferId); GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); Attributes is off by default. (1) In iOS, all vertex shader Attribute variables are turned off by default for performance reasons. Meaning that vertex data is not available on the shader side (server side). Even if you already use the glBufferData method to copy vertex data from memory to the vertex cache (GPU memory). So, must open the channel by glEnableVertexAttribArray method. Specify access properties to allow vertex shaders to access data copied from CPU to GPU. Note: data on the GPU is visible, that is, to the shader can read data, is determined by whether to enable the corresponding attribute, that's the function of glEnableVertexAttribArray, allowed to read the vertex shader GPU (server) data. GlVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, Const GLvoid* PTR) function: upload vertex data to memory (set the appropriate way to read data from buffer) parameter list: index, specify the index value of the vertex property to be modified, such as size, the number of reads each time. (For example, position is composed of three (x,y,z), color is four (R, G, B,a), and texture is two.) Type, specifying the data type of each component in the array. Available symbolic constants are GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, and GL_FLOAT, starting with GL_FLOAT. Normalized, specifies whether the fixed point data value should be normalized (GL_TRUE) or converted to a fixed point value (GL_FALSE) stride when accessed, specifies the offset between consecutive vertex attributes. If 0, the vertex attributes are understood to mean that they are tightly packed together. PTR specifies a pointer to the first component of the first vertex property in the array. The initial value of 0 * / / / vertex data glEnableVertexAttribArray (GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) *5, (GLfloat *)NULL + 0); / / texture data glEnableVertexAttribArray (GLKVertexAttribTexCoord0); glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3); }Copy the code

3. Load texture data

NSBundle *filePath = [[NSBundle mainBundle]pathForResource:@"mark" ofType:@"jpeg"]; NSBundle *filePath = [NSBundle mainBundle]pathForResource:@"mark" ofType:@"jpeg"]; // Set the texture parameters. But the picture shows the origin is in the upper left corner NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys: @ (1), GLKTextureLoaderOriginBottomLeft, nil]; GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil]; YEffect = [[GLKBaseEffect alloc]init]; yEffect.texture2d0.enabled = GL_TRUE; yEffect.texture2d0.name = textureInfo.name; // Notice that the drawing is done in the GLKView proxy method}Copy the code

4. Proxy method

Void glkView:(glkView *)view drawInRect:(CGRect)rect{void glkView:(glkView *)view drawInRect:(CGRect)rect{ //2, prepareToDraw [yEffect prepareToDraw]; // Triangles (GL_TRIANGLES, 0, 6); }Copy the code