- - (void)renderLayer
- {
- //设置窗口背景颜色
- glClearColor(0.0, 0.0, 0.0, 1.0);
- //清空颜色缓存
- glClear(GL_COLOR_BUFFER_BIT);
- //设置视口大小
- 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);
-
- //读取顶点和片元着色器程序
- NSString *vertFile = [[NSBundle mainBundle] pathForResource:@"shaderv" ofType:@"glsl"];
- NSString *fragFile = [[NSBundle mainBundle] pathForResource:@"shaderf" ofType:@"glsl"];
- NSLog(@"vertFile:%@", vertFile);
- NSLog(@"fragFile:%@", fragFile);
-
- //判断myProgram是否存在,存在则清空
- if (self.myProgram) {
- glDeleteProgram(self.myProgram);
- self.myProgram = 0;
- }
-
- //加载着色器到myProgram中
- self.myProgram = [self loadShader:vertFile frag:fragFile];
-
- //创建链接
- glLinkProgram(self.myProgram);
- GLint linkSuccess;
-
- //获取链接状态
- glGetProgramiv(self.myProgram, GL_LINK_STATUS, &linkSuccess);
-
- //判断链接是否成功
- if (linkSuccess == GL_FALSE) {
- //获取失败信息
- GLchar message[256];
- glGetProgramInfoLog(self.myProgram, sizeof(message), 0, &message[0]);
- //c字符串转换成oc字符串
- NSString *messageString = [NSString stringWithUTF8String:message];
- NSLog(@"error:%@", messageString);
- return;
- } else {
- //使用myProgram
- glUseProgram(self.myProgram);
- }
-
- //创建绘制索引数组
- GLuint indices[] = {
- 0, 3, 2,
- 0, 1, 3,
- 0, 2, 4,
- 0, 4, 1,
- 2, 3, 4,
- 1, 4, 3
- };
-
- //判断顶点缓存区是否为空,为空则申请一个缓存区标志符
- if (self.myVertices == 0) {
- glGenBuffers(1, &_myVertices);
- }
-
- //----------处理顶点坐标---------
-
- /*顶点数据
- 1.前3个坐标值(x、y、z),后3个颜色值(RGB);
- 2.有先后顺序,否则绘制形状完全不同
- */
- GLfloat attrArr[] =
- {
- -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, //左上
- 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, //右上
- -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, //左下
- 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, //右下
- 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, //顶点
- };
-
- //将_myVertices绑定到GL_ARRAY_BUFFER标志符上
- glBindBuffer(GL_ARRAY_BUFFER, _myVertices);
- //把顶点坐标数据从CPU复制到GPU上
- glBufferData(GL_ARRAY_BUFFER, sizeof(attrArr), attrArr, GL_DYNAMIC_DRAW);
-
- //将顶点坐标数据通过myProgram传递到顶点着色器程序的position
-
- //获取顶点属性入口
- GLuint position = glGetAttribLocation(self.myProgram, "position");
- /*传递数据
- 1.一行6个数据,前3个为坐标,后3个为颜色;
- 2.NULL开始位置:默认为0,指向数组首地址;
- */
- glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*6, NULL);
- //设置合适的格式从缓存区中读取数据
- glEnableVertexAttribArray(position);
-
- //处理顶点颜色数据:传递到顶点着色器的positionColor
- GLuint positionColor = glGetAttribLocation(self.myProgram, "positionColor");
- glVertexAttribPointer(positionColor, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*6, (float *)NULL +3);
- glEnableVertexAttribArray(positionColor);
-
- //在myProgram中找到透视投影矩阵和模型视图矩阵
- GLuint projectionMatrixSlot = glGetUniformLocation(self.myProgram, "projectionMatrix");
- GLuint modelViewMatrixSlot = glGetUniformLocation(self.myProgram, "modelViewMatrix");
-
- //创建透视投影矩阵并初始化
- 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);
-
- //设置glsl里面的投影矩阵
- glUniformMatrix4fv(projectionMatrixSlot, 1, GL_FALSE, (GLfloat *)&_projectionMatrix.m[0][0]);
-
- //开启剔除功能
- glEnable(GL_CULL_FACE);
-
- //创建平移矩阵:Z轴平移-10
- KSMatrix4 _modelViewMatrix;
- ksMatrixLoadIdentity(&_modelViewMatrix);
- ksTranslate(&_modelViewMatrix, 0.0, 0.0, -10.0);
-
- //创建旋转矩阵
- 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);
-
- //将平移矩阵和旋转矩阵相乘,结果放到模型视图矩阵中
- ksMatrixMultiply(&_modelViewMatrix, &_rotationMatrix, &_modelViewMatrix);
-
- //设置glsl里面的模型视图矩阵
- glUniformMatrix4fv(modelViewMatrixSlot, 1, GL_FALSE, (GLfloat *)&_modelViewMatrix.m[0][0]);
-
- //设置绘制参数:片元、个数、索引数组
- glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_INT, indices);
-
- //由顶点着色器将缓存区中的数据渲染到显示涂层上
- [self.myContext presentRenderbuffer:GL_RENDERBUFFER];
- }