[关闭]
@cxm-2016 2017-04-05T06:28:22.000000Z 字数 12767 阅读 5298

NDK开发OpenGL ES 3.0(五)——一个立方体

OpenGL-ES

版本:2
作者:陈小默
声明:禁止商用,禁止转载

文章仅发布于 作业部落简书开源中国


上一篇:NDK开发OpenGL ES 3.0(四)——旋转的彩色方块


本章参考书:
[1]Dan Ginsburg,Budirjanto Purnomo.OpenGL ES 3.0 编程指南 第二版(姚军 译).北京:机械工业出版社


本篇主要介绍OpenGL ES中的图元装配和一些光栅化过程。学完本篇内容之后我们将会建造一个简单的旋转的立方体,就像下图所示。
最终效果图


九、图元装配和光栅化

本章主要内容是介绍基本图元,以及图元的装配和最终显示之前的光栅化。


9.1 基本图元

图元是由一组顶点描述的几何形状对象。在OpenGL中,任何图元都可以被绘制,但是在OpenGL ES中,由于其性能被精简(毕竟移动端CPU和GPU不比桌面设备),所以只能绘制三种最基本的图元,但所有的图形都可以使用这三个基本图元来表示:

  • 点精灵
  • 直线
  • 三角形

9.1.1 点精灵

在OpenGL中,点精灵是指定位置和半径的屏幕对其的正方形,常用作粒子效果。

图元枚举GL_POINTS
注意:默认情况下,点精灵的坐标原点是屏幕左上角。当我们决定绘制点的时候,需要在着色器中设置点的尺寸,否则,可能会造成绘图错误。在着色器中表示点精灵尺寸的变量是gl_PointSize

9.1.2 直线

图元枚举GL_LINESGL_LINE_STRIPGL_LINE_LOOP

说明:假设现在有[0,1,2,3,4]共5个点组成的数组,我们使用下列类型绘制的结果:

  • GL_LINES:绘制出[0,1]和[2,3]两条线,第五个点由于没有匹配点而被忽略。
  • GL_LINE_STRIP:绘制出[0,1],[1,2],[2,3],[3,4]两两相连的四条线组成的折现。
  • GL_LINE_LOOP:绘制出[0,1],[1,2],[2,3],[3,4],[4,1]首尾相连的封闭图形。

其他函数

void glLineWidth(GLfloat width);

  • width:指定线宽,默认为1.0

9.1.3 三角形

将一个图形分解为若干三角形是几何渲染最常用的方式

图元枚举GL_TRIANGLESGL_TRIANGLE_STRIPGL_TRIANGLE_FAN

说明:假设有[0,1,2,3,4,5,6]共7个点组成的数组,我们使用下列类型的绘制结果:

  • GL_TRIANGLES:绘制出[0,1,2]和[3,4,5]两个三角形,第7个点由于没有匹配点而被忽略。
  • GL_TRIANGLE_STRIP:绘制出[0,1,2],[2,1,3],[2,3,4],[4,3,5],[4,5,6]共5个三角形(绘制出偶数下标[n,n+1,n+2]和奇数下标[n+1,n,n+2]共n-2个三角形)
  • GL_TRIANGLE_FAN:绘制出[0,1,2],[0,2,3],[0,3,4],[0,4,5],[0,5,6]等共享顶点的5个三角形(绘制出[0,n+1,n+2]共n-2个三角形)

9.2 绘制图元

OpenGL ES提供了五种绘制图元的函数,分别是glDrawArrays、glDrawElements、glDrawRangeElement、glDrawArraysInstanced和glDrawElementsInstanced。接下来分别介绍这几种方法。

9.2.1 glDrawArrays

void glDrawArrays (GLenum mode, GLint first, GLsizei count);

  • mode:指定图元枚举,9.1节中的任意一个。
  • first:指定从顶点数组中的何处开始绘制。
  • count:需要绘制的顶点数量。

示例代码:

  1. #define VERTEX_IND 0
  2. GLfloat VERTICES[]={...};
  3. glEnableVertexAttribArray(VERTEX_IND);
  4. glVertexAttribPointer(VERTEX_IND,3,GL_FLOAT,GL_FALSE,0,VERTICES);
  5. glDrawArrays(GL_TRIANGLES,0,3);

9.2.2 glDrawElements

该函数用来绘制图元,使用前需要创建图元索引列表。

void glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);

  • mode:指定图元枚举,9.1节中的任意一个。
  • count:指定要绘制的索引数量。
  • type:指定索引类型。
  • indices:索引数组。

示例代码:

  1. #define VERTEX_IND 0
  2. GLfloat VERTICES[]={
  3. 0.1f,0.3f,0.4f,//0
  4. 0.2f,0.5f,0.7f,//1
  5. 0.9f,-0.3f,0.8f,//2
  6. 0.4f,0.5f,-0.2f//3
  7. };
  8. GLubyte INDICES[]={
  9. 0,1,2,
  10. 3,2,1
  11. };
  12. glEnableVertexAttribArray(VERTEX_IND);
  13. glVertexAttribPointer(VERTEX_IND,3,GL_FLOAT,GL_FALSE,0,VERTICES);
  14. glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_BYTE,INDICES);

9.2.3 glDrawRangeElement

void glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);

  • mode:指定图元枚举,9.1节中的任意一个。
  • start:指定图元索引列表中最小值(从顶点数组何处开始)。
  • end:指定图元索引列表中的最大值(从顶点数组何处结束)。
  • count:指定要绘制的索引数量。
  • type:指定索引类型。
  • indices:索引数组。

示例代码(本例限定了仅顶点坐标中1-6有效,那么此次就只会绘制[3,4,5]这个三角形):

  1. #define VERTEX_IND 0
  2. GLfloat VERTICES[] = {};//10个顶点
  3. GLubyte INDICES[] = {
  4. 0, 1, 2,
  5. 0, 2, 3,
  6. 3, 4, 5,
  7. 7, 8, 9
  8. };
  9. glEnableVertexAttribArray(VERTEX_IND);
  10. glVertexAttribPointer(VERTEX_IND, 3, GL_FLOAT, GL_FALSE, 0, VERTICES);
  11. glDrawRangeElements(GL_TRIANGLES, 1, 6, 12, GL_UNSIGNED_BYTE, INDICES);
  12. }

9.3 图元装配光栅化过程

在图形经过顶点着色器处理之后,便进入了图元装配和光栅化的过程。其流程如下:

Created with Raphaël 2.1.2顶点着色器输出裁剪透视分割窗口变换剔除片元着色器输入

9.3.1 裁剪

在某些时候,我们的图元肯能超出了屏幕能够显示的范围。这时候,就需要对这些图元进行裁剪。

9.3.2 透视分割

透视分割取得裁剪坐标指定的点,并将其投影到屏幕或者是视图上。在过程中坐标将被转换为规范化坐标,即[-1.0..1.0]区间。

9.3.3 视口变换

视口是一个二维矩形窗口区域,是所有OpenGL ES渲染操作最终显示的地方。
void glViewport(GLint x,GLint y,GLsizei w,GLsizei h);
这个常用的方法指定了一个视口的区域。

9.4 剔除

在图形被光栅化之前,我们需要确定它是正面或者反面,这样可以剔除掉不需要显示的图形,仅保留可见部分。在剔除之前我们需要告诉OpenGL正反面的标准是什么。对于三角形图元,我们仅仅需要注明当前已逆时针为正还是逆时针。

void glFrontFace (GLenum mode);

  • mode:旋转方向GL_CW顺时针,GL_CCW逆时针

当我们指定了区分正反的方法之后,接下来可以调用下列方法剔除特定的面。

void glCullFace (GLenum mode);

  • mode:指定我们需要剔除的方向GL_FRONT剔除正面、GL_BACK剔除背面、GL_FRONT_AND_BACK剔除正面和背面

9.5 光栅化

在进行完以上操作之后,光栅化管线取得了单独的图元,并为该图元生成相应的片元(具体的像素点)。然后每个像素点都会经过片元着色器处理。

十、绘制一个旋转立方体

本章内容为绘制一个旋转的立方体的教程。本章只展示JNI部分的编写(暂不详解),其他部分和之前相同,请自行实现。示例改编自OpenGL ES 3.0 编程指南 第七章示例代码目录结构如下:
10-1 目录部分


  1. #define LOG_TAG "cube-lib"
  2. #include "esUtil.h"
  3. #include <cmath>
  4. #include <ctime>
  5. #define PI 3.14
  6. #define POSITION_IND 0
  7. #define COLOR_IND 1
  8. #define MVP_IND 2
  9. #define VERTEX_NUM 108
  10. #define INDICES_NUM 36
  11. #define MATRIX_COLUMN 4
  12. #define MATRIX_ROW 4
  13. GLuint program;
  14. GLuint positionVBO;
  15. GLuint colorVBO;
  16. GLuint mvpVBO;
  17. GLuint indicesIBO;
  18. GLfloat aspect;
  19. uint64_t lastFrameNs;
  20. GLfloat angle;
  21. const char VERTEX_SHADER[] =
  22. "#version 300 es\n"
  23. "layout(location = " STRV(POSITION_IND) ") in vec4 a_position;\n"
  24. "layout(location = " STRV(COLOR_IND) ") in vec4 a_color;\n"
  25. "layout(location = " STRV(MVP_IND) ") in mat4 a_mvpMatrix;\n"
  26. "out vec4 v_color;\n"
  27. "void main()\n"
  28. "{\n"
  29. " v_color = a_color;\n"
  30. " gl_Position = a_mvpMatrix * a_position;\n"
  31. "}\n";
  32. const char FRAGMENT_SHADER[] =
  33. "#version 300 es\n"
  34. "precision mediump float;\n"
  35. "in vec4 v_color;\n"
  36. "layout(location = 0) out vec4 outColor;\n"
  37. "void main()\n"
  38. "{\n"
  39. " outColor = v_color;\n"
  40. "}\n";
  41. GLfloat VERTEX_POS[VERTEX_NUM] =
  42. {
  43. -0.5f, -0.5f, -0.5f,//0
  44. 0.5f, -0.5f, 0.5f,//2
  45. -0.5f, -0.5f, 0.5f,//1
  46. -0.5f, -0.5f, -0.5f,//0
  47. 0.5f, -0.5f, -0.5f,//3
  48. 0.5f, -0.5f, 0.5f,//2
  49. -0.5f, 0.5f, -0.5f,//4
  50. -0.5f, 0.5f, 0.5f,//5
  51. 0.5f, 0.5f, 0.5f,//6
  52. -0.5f, 0.5f, -0.5f,//4
  53. 0.5f, 0.5f, 0.5f,//6
  54. 0.5f, 0.5f, -0.5f,//7
  55. -0.5f, -0.5f, -0.5f,//0
  56. -0.5f, 0.5f, -0.5f,//4
  57. 0.5f, 0.5f, -0.5f,//7
  58. -0.5f, -0.5f, -0.5f,//0
  59. 0.5f, 0.5f, -0.5f,//7
  60. 0.5f, -0.5f, -0.5f,//3
  61. -0.5f, -0.5f, 0.5f,//1
  62. 0.5f, -0.5f, 0.5f,//2
  63. 0.5f, 0.5f, 0.5f,//6
  64. -0.5f, -0.5f, 0.5f,//1
  65. 0.5f, 0.5f, 0.5f,//6
  66. -0.5f, 0.5f, 0.5f,//5
  67. -0.5f, -0.5f, -0.5f,//0
  68. -0.5f, -0.5f, 0.5f,//1
  69. -0.5f, 0.5f, 0.5f,//5
  70. -0.5f, -0.5f, -0.5f,//0
  71. -0.5f, 0.5f, 0.5f,//5
  72. -0.5f, 0.5f, -0.5f,//4
  73. 0.5f, -0.5f, -0.5f,//3
  74. 0.5f, 0.5f, -0.5f,//7
  75. 0.5f, 0.5f, 0.5f,//6
  76. 0.5f, -0.5f, -0.5f,//3
  77. 0.5f, 0.5f, 0.5f,//6
  78. 0.5f, -0.5f, 0.5f//2
  79. };
  80. const GLfloat cubeColor[] =
  81. {
  82. 1.0f, 0.0f, 0.0f, 0.0f,
  83. 1.0f, 0.0f, 0.0f, 0.0f,
  84. 1.0f, 0.0f, 0.0f, 0.0f,
  85. 1.0f, 0.0f, 0.0f, 0.0f,
  86. 1.0f, 0.0f, 0.0f, 0.0f,
  87. 1.0f, 0.0f, 0.0f, 0.0f,
  88. 0.0f, 0.0f, 1.0f, 0.0f,
  89. 0.0f, 0.0f, 1.0f, 0.0f,
  90. 0.0f, 0.0f, 1.0f, 0.0f,
  91. 0.0f, 0.0f, 1.0f, 0.0f,
  92. 0.0f, 0.0f, 1.0f, 0.0f,
  93. 0.0f, 0.0f, 1.0f, 0.0f,
  94. 0.0f, 1.0f, 0.0f, 0.0f,
  95. 0.0f, 1.0f, 0.0f, 0.0f,
  96. 0.0f, 1.0f, 0.0f, 0.0f,
  97. 0.0f, 1.0f, 0.0f, 0.0f,
  98. 0.0f, 1.0f, 0.0f, 0.0f,
  99. 0.0f, 1.0f, 0.0f, 0.0f,
  100. 1.0f, 1.0f, 0.0f, 0.0f,
  101. 1.0f, 1.0f, 0.0f, 0.0f,
  102. 1.0f, 1.0f, 0.0f, 0.0f,
  103. 1.0f, 1.0f, 0.0f, 0.0f,
  104. 1.0f, 1.0f, 0.0f, 0.0f,
  105. 1.0f, 1.0f, 0.0f, 0.0f,
  106. 0.0f, 1.0f, 1.0f, 0.0f,
  107. 0.0f, 1.0f, 1.0f, 0.0f,
  108. 0.0f, 1.0f, 1.0f, 0.0f,
  109. 0.0f, 1.0f, 1.0f, 0.0f,
  110. 0.0f, 1.0f, 1.0f, 0.0f,
  111. 0.0f, 1.0f, 1.0f, 0.0f,
  112. 1.0f, 0.0f, 1.0f, 0.0f,
  113. 1.0f, 0.0f, 1.0f, 0.0f,
  114. 1.0f, 0.0f, 1.0f, 0.0f,
  115. 1.0f, 0.0f, 1.0f, 0.0f,
  116. 1.0f, 0.0f, 1.0f, 0.0f,
  117. 1.0f, 0.0f, 1.0f, 0.0f
  118. };
  119. typedef struct {
  120. GLfloat m[MATRIX_ROW][MATRIX_COLUMN];
  121. } Matrix;
  122. bool
  123. init() {
  124. program = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
  125. if (!program)
  126. return false;
  127. glGenBuffers(1, &positionVBO);
  128. glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
  129. glBufferData(GL_ARRAY_BUFFER, VERTEX_NUM * sizeof(GLfloat), VERTEX_POS, GL_STATIC_DRAW);
  130. glGenBuffers(1, &colorVBO);
  131. glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
  132. glBufferData(GL_ARRAY_BUFFER, INDICES_NUM * 4 * sizeof(GLfloat), cubeColor, GL_STATIC_DRAW);
  133. glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
  134. glVertexAttribPointer(COLOR_IND, 4, GL_FLOAT,
  135. GL_FALSE, 0, (const void *) NULL);
  136. glEnableVertexAttribArray(COLOR_IND);
  137. angle = float(drand48() * 360.0f);
  138. glGenBuffers(1, &mvpVBO);
  139. glBindBuffer(GL_ARRAY_BUFFER, mvpVBO);
  140. glBufferData(GL_ARRAY_BUFFER, sizeof(Matrix), NULL, GL_DYNAMIC_DRAW);
  141. glBindBuffer(GL_ARRAY_BUFFER, 0);
  142. glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
  143. glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
  144. glVertexAttribPointer(POSITION_IND, 3, GL_FLOAT,
  145. GL_FALSE, 3 * sizeof(GLfloat), (const void *) NULL);
  146. glEnableVertexAttribArray(POSITION_IND);
  147. glBindBuffer(GL_ARRAY_BUFFER, mvpVBO);
  148. glVertexAttribPointer(MVP_IND + 0, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix),
  149. (const void *) NULL);
  150. glVertexAttribPointer(MVP_IND + 1, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix),
  151. (const void *) (sizeof(GLfloat) * 4));
  152. glVertexAttribPointer(MVP_IND + 2, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix),
  153. (const void *) (sizeof(GLfloat) * 8));
  154. glVertexAttribPointer(MVP_IND + 3, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix),
  155. (const void *) (sizeof(GLfloat) * 12));
  156. glEnableVertexAttribArray(MVP_IND + 0);
  157. glEnableVertexAttribArray(MVP_IND + 1);
  158. glEnableVertexAttribArray(MVP_IND + 2);
  159. glEnableVertexAttribArray(MVP_IND + 3);
  160. glVertexAttribDivisor(MVP_IND + 0, 1);
  161. glVertexAttribDivisor(MVP_IND + 1, 1);
  162. glVertexAttribDivisor(MVP_IND + 2, 1);
  163. glVertexAttribDivisor(MVP_IND + 3, 1);
  164. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesIBO);
  165. glUseProgram(program);
  166. glFrontFace(GL_CCW);
  167. glCullFace(GL_BACK);
  168. glEnable(GL_CULL_FACE);
  169. return true;
  170. }
  171. void
  172. matrixLoadIdentity(Matrix *result) {
  173. memset(result, 0, sizeof(Matrix));
  174. result->m[0][0] = 1.0f;
  175. result->m[1][1] = 1.0f;
  176. result->m[2][2] = 1.0f;
  177. result->m[3][3] = 1.0f;
  178. }
  179. void
  180. matrixMultiply(Matrix *result, Matrix *srcA, Matrix *srcB) {
  181. Matrix tmp;
  182. int i;
  183. for (i = 0; i < 4; i++) {
  184. tmp.m[i][0] = (srcA->m[i][0] * srcB->m[0][0]) +
  185. (srcA->m[i][1] * srcB->m[1][0]) +
  186. (srcA->m[i][2] * srcB->m[2][0]) +
  187. (srcA->m[i][3] * srcB->m[3][0]);
  188. tmp.m[i][1] = (srcA->m[i][0] * srcB->m[0][1]) +
  189. (srcA->m[i][1] * srcB->m[1][1]) +
  190. (srcA->m[i][2] * srcB->m[2][1]) +
  191. (srcA->m[i][3] * srcB->m[3][1]);
  192. tmp.m[i][2] = (srcA->m[i][0] * srcB->m[0][2]) +
  193. (srcA->m[i][1] * srcB->m[1][2]) +
  194. (srcA->m[i][2] * srcB->m[2][2]) +
  195. (srcA->m[i][3] * srcB->m[3][2]);
  196. tmp.m[i][3] = (srcA->m[i][0] * srcB->m[0][3]) +
  197. (srcA->m[i][1] * srcB->m[1][3]) +
  198. (srcA->m[i][2] * srcB->m[2][3]) +
  199. (srcA->m[i][3] * srcB->m[3][3]);
  200. }
  201. memcpy(result, &tmp, sizeof(Matrix));
  202. }
  203. void
  204. frustum(Matrix *result, float w, float h, float nearZ,
  205. float farZ) {
  206. float left = -w;
  207. float right = w;
  208. float bottom = -h;
  209. float top = h;
  210. float deltaX = right - left;
  211. float deltaY = top - bottom;
  212. float deltaZ = farZ - nearZ;
  213. Matrix frust;
  214. if ((nearZ <= 0.0f) || (farZ <= 0.0f) ||
  215. (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f)) {
  216. return;
  217. }
  218. frust.m[0][0] = 2.0f * nearZ / deltaX;
  219. frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f;
  220. frust.m[1][1] = 2.0f * nearZ / deltaY;
  221. frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f;
  222. frust.m[2][0] = (right + left) / deltaX;
  223. frust.m[2][1] = (top + bottom) / deltaY;
  224. frust.m[2][2] = -(nearZ + farZ) / deltaZ;
  225. frust.m[2][3] = -1.0f;
  226. frust.m[3][2] = -2.0f * nearZ * farZ / deltaZ;
  227. frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f;
  228. matrixMultiply(result, &frust, result);
  229. }
  230. void
  231. translate(Matrix *result, GLfloat tx, GLfloat ty, GLfloat tz) {
  232. result->m[3][0] += (result->m[0][0] * tx + result->m[1][0] * ty + result->m[2][0] * tz);
  233. result->m[3][1] += (result->m[0][1] * tx + result->m[1][1] * ty + result->m[2][1] * tz);
  234. result->m[3][2] += (result->m[0][2] * tx + result->m[1][2] * ty + result->m[2][2] * tz);
  235. result->m[3][3] += (result->m[0][3] * tx + result->m[1][3] * ty + result->m[2][3] * tz);
  236. }
  237. void
  238. rotate(Matrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
  239. GLfloat sinAngle, cosAngle;
  240. GLfloat mag = sqrtf(x * x + y * y + z * z);
  241. sinAngle = sinf(float(angle * PI / 180.0f));
  242. cosAngle = cosf(float(angle * PI / 180.0f));
  243. if (mag > 0.0f) {
  244. GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs;
  245. GLfloat oneMinusCos;
  246. Matrix rotMat;
  247. x /= mag;
  248. y /= mag;
  249. z /= mag;
  250. xx = x * x;
  251. yy = y * y;
  252. zz = z * z;
  253. xy = x * y;
  254. yz = y * z;
  255. zx = z * x;
  256. xs = x * sinAngle;
  257. ys = y * sinAngle;
  258. zs = z * sinAngle;
  259. oneMinusCos = 1.0f - cosAngle;
  260. rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle;
  261. rotMat.m[0][1] = (oneMinusCos * xy) - zs;
  262. rotMat.m[0][2] = (oneMinusCos * zx) + ys;
  263. rotMat.m[0][3] = 0.0F;
  264. rotMat.m[1][0] = (oneMinusCos * xy) + zs;
  265. rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle;
  266. rotMat.m[1][2] = (oneMinusCos * yz) - xs;
  267. rotMat.m[1][3] = 0.0F;
  268. rotMat.m[2][0] = (oneMinusCos * zx) - ys;
  269. rotMat.m[2][1] = (oneMinusCos * yz) + xs;
  270. rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle;
  271. rotMat.m[2][3] = 0.0F;
  272. rotMat.m[3][0] = 0.0F;
  273. rotMat.m[3][1] = 0.0F;
  274. rotMat.m[3][2] = 0.0F;
  275. rotMat.m[3][3] = 1.0F;
  276. matrixMultiply(result, &rotMat, result);
  277. }
  278. }
  279. void
  280. update(float deltaTime) {
  281. Matrix *matrixBuf;
  282. Matrix perspective;
  283. matrixLoadIdentity(&perspective);
  284. GLfloat frustumW, frustumH;
  285. frustumH = tanf(float(60.0f / 360.0f * PI)) * 1.5f;
  286. frustumW = frustumH * aspect;
  287. frustum(&perspective, frustumW, frustumH, 1.0f, 20.0f);
  288. glBindBuffer(GL_ARRAY_BUFFER, mvpVBO);
  289. matrixBuf = (Matrix *) glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(Matrix),
  290. GL_MAP_WRITE_BIT);
  291. Matrix modelview;
  292. matrixLoadIdentity(&modelview);
  293. translate(&modelview, 0, 0, -2.0f);
  294. angle += (deltaTime * 40.0f);
  295. if (angle >= 360.0f) {
  296. angle -= 360.0f;
  297. }
  298. rotate(&modelview, angle, 1.0, 0.0, 1.0);
  299. matrixMultiply(&matrixBuf[0], &modelview, &perspective);
  300. glUnmapBuffer(GL_ARRAY_BUFFER);
  301. }
  302. extern "C" {
  303. JNIEXPORT jboolean JNICALL Java_com_github_cccxm_gles_model_CubeLib_init(JNIEnv *env, jclass type);
  304. JNIEXPORT void JNICALL Java_com_github_cccxm_gles_model_CubeLib_resize(JNIEnv *env, jclass type,
  305. jint width, jint height);
  306. JNIEXPORT void JNICALL Java_com_github_cccxm_gles_model_CubeLib_render(JNIEnv *env, jclass type);
  307. JNIEXPORT void JNICALL Java_com_github_cccxm_gles_model_CubeLib_destroy(JNIEnv *env, jclass type);
  308. }
  309. jboolean
  310. Java_com_github_cccxm_gles_model_CubeLib_init(JNIEnv *env, jclass type) {
  311. if (init())return JNI_TRUE;
  312. return JNI_FALSE;
  313. }
  314. void
  315. Java_com_github_cccxm_gles_model_CubeLib_resize(JNIEnv *env, jclass type,
  316. jint width, jint height) {
  317. aspect = (GLfloat) width / (GLfloat) height;
  318. glViewport(0, 0, width, height);
  319. glClearColor(0, 0, 0, 0);
  320. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  321. }
  322. void
  323. Java_com_github_cccxm_gles_model_CubeLib_render(JNIEnv *env, jclass type) {
  324. timespec now;
  325. clock_gettime(CLOCK_MONOTONIC, &now);
  326. auto nowNs = now.tv_sec * 1000000000ull + now.tv_nsec;
  327. if (lastFrameNs > 0) {
  328. float dt = float(nowNs - lastFrameNs) * 0.000000001f;
  329. update(dt);
  330. glDrawArrays(GL_TRIANGLES, 0, 36);
  331. }
  332. lastFrameNs = nowNs;
  333. }
  334. void
  335. Java_com_github_cccxm_gles_model_CubeLib_destroy(JNIEnv *env, jclass type) {
  336. glDeleteBuffers(1, &positionVBO);
  337. glDeleteBuffers(1, &colorVBO);
  338. glDeleteBuffers(1, &mvpVBO);
  339. glDeleteBuffers(1, &indicesIBO);
  340. glDeleteProgram(program);
  341. }
  342. #undef LOG_TAG

下一篇:NDK开发OpenGL ES 3.0(六)——2D纹理贴图

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注