经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
OpenGL ES 渲染立体图形
来源:cnblogs  作者:春天里的花骨朵  时间:2018/12/6 10:18:32  对本文有异议

一、理解

顶点数据存储在申请的缓冲区中,其由数据总线传递给着色器(如果是片元着色器,还须将顶点转换成片元),再由着色器最终渲染到涂层上;

二、思路

1.设置涂层;

 2.创建上下文;

 3.清空缓存区;

 4.创建渲染缓存区和帧缓存区;

 5.开始绘制;

三、核心代码

//最终渲染

  1. - (void)renderLayer
  2. {
  3. //设置窗口背景颜色
  4. glClearColor(0.0, 0.0, 0.0, 1.0);
  5. //清空颜色缓存
  6. glClear(GL_COLOR_BUFFER_BIT);
  7. //设置视口大小
  8. CGFloat scale = [[UIScreen mainScreen] scale];
  9. glViewport(self.frame.origin.x*scale, self.frame.origin.y*scale, self.frame.size.width*scale, self.frame.size.height*scale);
  10. //读取顶点和片元着色器程序
  11. NSString *vertFile = [[NSBundle mainBundle] pathForResource:@"shaderv" ofType:@"glsl"];
  12. NSString *fragFile = [[NSBundle mainBundle] pathForResource:@"shaderf" ofType:@"glsl"];
  13. NSLog(@"vertFile:%@", vertFile);
  14. NSLog(@"fragFile:%@", fragFile);
  15. //判断myProgram是否存在,存在则清空
  16. if (self.myProgram) {
  17. glDeleteProgram(self.myProgram);
  18. self.myProgram = 0;
  19. }
  20. //加载着色器到myProgram中
  21. self.myProgram = [self loadShader:vertFile frag:fragFile];
  22. //创建链接
  23. glLinkProgram(self.myProgram);
  24. GLint linkSuccess;
  25. //获取链接状态
  26. glGetProgramiv(self.myProgram, GL_LINK_STATUS, &linkSuccess);
  27. //判断链接是否成功
  28. if (linkSuccess == GL_FALSE) {
  29. //获取失败信息
  30. GLchar message[256];
  31. glGetProgramInfoLog(self.myProgram, sizeof(message), 0, &message[0]);
  32. //c字符串转换成oc字符串
  33. NSString *messageString = [NSString stringWithUTF8String:message];
  34. NSLog(@"error:%@", messageString);
  35. return;
  36. } else {
  37. //使用myProgram
  38. glUseProgram(self.myProgram);
  39. }
  40. //创建绘制索引数组
  41. GLuint indices[] = {
  42. 0, 3, 2,
  43. 0, 1, 3,
  44. 0, 2, 4,
  45. 0, 4, 1,
  46. 2, 3, 4,
  47. 1, 4, 3
  48. };
  49. //判断顶点缓存区是否为空,为空则申请一个缓存区标志符
  50. if (self.myVertices == 0) {
  51. glGenBuffers(1, &_myVertices);
  52. }
  53. //----------处理顶点坐标---------
  54. /*顶点数据
  55. 1.前3个坐标值(x、y、z),后3个颜色值(RGB);
  56. 2.有先后顺序,否则绘制形状完全不同
  57. */
  58. GLfloat attrArr[] =
  59. {
  60. -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, //左上
  61. 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, //右上
  62. -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, //左下
  63. 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, //右下
  64. 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, //顶点
  65. };
  66. //将_myVertices绑定到GL_ARRAY_BUFFER标志符上
  67. glBindBuffer(GL_ARRAY_BUFFER, _myVertices);
  68. //把顶点坐标数据从CPU复制到GPU上
  69. glBufferData(GL_ARRAY_BUFFER, sizeof(attrArr), attrArr, GL_DYNAMIC_DRAW);
  70. //将顶点坐标数据通过myProgram传递到顶点着色器程序的position
  71. //获取顶点属性入口
  72. GLuint position = glGetAttribLocation(self.myProgram, "position");
  73. /*传递数据
  74. 1.一行6个数据,前3个为坐标,后3个为颜色;
  75. 2.NULL开始位置:默认为0,指向数组首地址;
  76. */
  77. glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*6, NULL);
  78. //设置合适的格式从缓存区中读取数据
  79. glEnableVertexAttribArray(position);
  80. //处理顶点颜色数据:传递到顶点着色器的positionColor
  81. GLuint positionColor = glGetAttribLocation(self.myProgram, "positionColor");
  82. glVertexAttribPointer(positionColor, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*6, (float *)NULL +3);
  83. glEnableVertexAttribArray(positionColor);
  84. //在myProgram中找到透视投影矩阵和模型视图矩阵
  85. GLuint projectionMatrixSlot = glGetUniformLocation(self.myProgram, "projectionMatrix");
  86. GLuint modelViewMatrixSlot = glGetUniformLocation(self.myProgram, "modelViewMatrix");
  87. //创建透视投影矩阵并初始化
  88. float width = self.frame.size.width;
  89. float height = self.frame.size.height;
  90. KSMatrix4 _projectionMatrix;
  91. ksMatrixLoadIdentity(&_projectionMatrix);
  92. float aspect = width/height;
  93. ksPerspective(&_projectionMatrix, 30.0, aspect, 5.0f, 20.0f);
  94. //设置glsl里面的投影矩阵
  95. glUniformMatrix4fv(projectionMatrixSlot, 1, GL_FALSE, (GLfloat *)&_projectionMatrix.m[0][0]);
  96. //开启剔除功能
  97. glEnable(GL_CULL_FACE);
  98. //创建平移矩阵:Z轴平移-10
  99. KSMatrix4 _modelViewMatrix;
  100. ksMatrixLoadIdentity(&_modelViewMatrix);
  101. ksTranslate(&_modelViewMatrix, 0.0, 0.0, -10.0);
  102. //创建旋转矩阵
  103. KSMatrix4 _rotationMatrix;
  104. ksMatrixLoadIdentity(&_rotationMatrix);
  105. ksRotate(&_rotationMatrix, xDegree, 1.0, 0.0, 0.0);
  106. ksRotate(&_rotationMatrix, yDegree, 0.0, 1.0, 0.0);
  107. ksRotate(&_rotationMatrix, zDegree, 0.0, 0.0, 1.0);
  108. //将平移矩阵和旋转矩阵相乘,结果放到模型视图矩阵中
  109. ksMatrixMultiply(&_modelViewMatrix, &_rotationMatrix, &_modelViewMatrix);
  110. //设置glsl里面的模型视图矩阵
  111. glUniformMatrix4fv(modelViewMatrixSlot, 1, GL_FALSE, (GLfloat *)&_modelViewMatrix.m[0][0]);
  112. //设置绘制参数:片元、个数、索引数组
  113. glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_INT, indices);
  114. //由顶点着色器将缓存区中的数据渲染到显示涂层上
  115. [self.myContext presentRenderbuffer:GL_RENDERBUFFER];
  116. }

四、效果

 

 

GitHub

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号