I. understanding
The vertex data is stored in the applied buffer, which is passed to the shader by the data bus (if it is a chip shader, the vertex must also be converted into a chip), and finally rendered to the coating by the shader;
Two, train of thought
1. Set the coating;
2. Create context;
3. Clear the cache;
4. Create render buffer and frame buffer;
Start drawing;
III. core code
//Final rendering
- (void)renderLayer { //Set window background color glClearColor(0.0, 0.0, 0.0, 1.0); //Clear color cache glClear(GL_COLOR_BUFFER_BIT); //Set viewport size CGFloat scale = [[UIScreen mainScreen] scale]; glViewport(self.frame.origin.x*scale, self.frame.origin.y*scale, self.frame.size.width*scale, self.frame.size.height*scale); //Read vertex and slice shader program NSString *vertFile = [[NSBundle mainBundle] pathForResource:@"shaderv" ofType:@"glsl"]; NSString *fragFile = [[NSBundle mainBundle] pathForResource:@"shaderf" ofType:@"glsl"]; NSLog(@"vertFile:%@", vertFile); NSLog(@"fragFile:%@", fragFile); //judge myProgram Whether it exists, empty if it exists if (self.myProgram) { glDeleteProgram(self.myProgram); self.myProgram = 0; } //Load shaders to myProgram in self.myProgram = [self loadShader:vertFile frag:fragFile]; //create link glLinkProgram(self.myProgram); GLint linkSuccess; //Get link status glGetProgramiv(self.myProgram, GL_LINK_STATUS, &linkSuccess); //Judge whether the link is successful if (linkSuccess == GL_FALSE) { //Get failure information GLchar message[256]; glGetProgramInfoLog(self.myProgram, sizeof(message), 0, &message[0]); //c String to oc Character string NSString *messageString = [NSString stringWithUTF8String:message]; NSLog(@"error:%@", messageString); return; } else { //Use myProgram glUseProgram(self.myProgram); } //Create a drawing index array GLuint indices[] = { 0, 3, 2, 0, 1, 3, 0, 2, 4, 0, 4, 1, 2, 3, 4, 1, 4, 3 }; //Determine whether the vertex cache is empty. If it is empty, a cache flag will be applied if (self.myVertices == 0) { glGenBuffers(1, &_myVertices); } //----------Work with vertex coordinates--------- /*vertex data 1.The first three coordinate values (x, y, z) and the last three color values (RGB); 2.There is an order, otherwise the drawing shape is completely different */ GLfloat attrArr[] = { -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, //Left upper 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, //Right upper -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, //Left lower 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, //lower right 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, //vertex }; //take_myVertices Bound to GL_ARRAY_BUFFER Logo glBindBuffer(GL_ARRAY_BUFFER, _myVertices); //Transfer vertex coordinate data from CPU Copy to GPU upper glBufferData(GL_ARRAY_BUFFER, sizeof(attrArr), attrArr, GL_DYNAMIC_DRAW); //Passing vertex coordinate data through myProgram Passed to the position //Get vertex attribute entry GLuint position = glGetAttribLocation(self.myProgram, "position"); /*Transmit data 1.There are six data in a row, the first three are coordinates and the last three are colors; 2.NULL Start position: 0 by default, pointing to the array first address; */ glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*6, NULL); //Set the appropriate format to read data from the cache glEnableVertexAttribArray(position); //Processing vertex color data: passed to the positionColor GLuint positionColor = glGetAttribLocation(self.myProgram, "positionColor"); glVertexAttribPointer(positionColor, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*6, (float *)NULL +3); glEnableVertexAttribArray(positionColor); //stay myProgram Find perspective projection matrix and model view matrix in GLuint projectionMatrixSlot = glGetUniformLocation(self.myProgram, "projectionMatrix"); GLuint modelViewMatrixSlot = glGetUniformLocation(self.myProgram, "modelViewMatrix"); //Create perspective projection matrix and initialize float width = self.frame.size.width; float height = self.frame.size.height; KSMatrix4 _projectionMatrix; ksMatrixLoadIdentity(&_projectionMatrix); float aspect = width/height; ksPerspective(&_projectionMatrix, 30.0, aspect, 5.0f, 20.0f); //Set up glsl Projection matrix inside glUniformMatrix4fv(projectionMatrixSlot, 1, GL_FALSE, (GLfloat *)&_projectionMatrix.m[0][0]); //Enable rejection function glEnable(GL_CULL_FACE); //To create a translation matrix: Z Axis translation-10 KSMatrix4 _modelViewMatrix; ksMatrixLoadIdentity(&_modelViewMatrix); ksTranslate(&_modelViewMatrix, 0.0, 0.0, -10.0); //Create rotation matrix KSMatrix4 _rotationMatrix; ksMatrixLoadIdentity(&_rotationMatrix); ksRotate(&_rotationMatrix, xDegree, 1.0, 0.0, 0.0); ksRotate(&_rotationMatrix, yDegree, 0.0, 1.0, 0.0); ksRotate(&_rotationMatrix, zDegree, 0.0, 0.0, 1.0); //Multiply the translation matrix and rotation matrix, and put the result into the model view matrix ksMatrixMultiply(&_modelViewMatrix, &_rotationMatrix, &_modelViewMatrix); //Set up glsl Model view matrix inside glUniformMatrix4fv(modelViewMatrixSlot, 1, GL_FALSE, (GLfloat *)&_modelViewMatrix.m[0][0]); //Set drawing parameters: slice element, number, index array glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_INT, indices); //Render the data in the cache to the display layer by vertex shaders [self.myContext presentRenderbuffer:GL_RENDERBUFFER]; }
Four, effect