[关闭]
@cxm-2016 2016-11-03T10:38:11.000000Z 字数 13033 阅读 2057

NDK开发OpenGL ES 3.0——工具类代码

OpenGL-ES

版本:1
作者:陈小默

ESUtil.h


  1. #ifndef GLES_ESUTIL_H
  2. #define GLES_ESUTIL_H
  3. #include <GLES3/gl3.h>
  4. #include <android/log.h>
  5. #include <jni.h>
  6. #ifndef LOG_TAG
  7. #define LOG_TAG "ES_LIB"
  8. #endif
  9. #define STR(s) #s
  10. #define STRV(s) STR(s)
  11. #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
  12. #define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
  13. #include <cstdlib>
  14. #include <cmath>
  15. #define PI 3.1415
  16. //检查当前程序错误
  17. bool checkGlError(const char *funcName);
  18. //获取并编译着色器对象
  19. GLuint createShader(GLenum shaderType, const char *src);
  20. //使用着色器生成着色器程序对象
  21. GLuint createProgram(const char *vtxSrc, const char *fragSrc);
  22. //产生一个立方体
  23. int createCube(float scale, GLfloat **vertices, GLfloat **normals,
  24. GLfloat **texCoords, GLuint **indices);
  25. int createSquareGrid ( int size, GLfloat **vertices, GLuint **indices );
  26. //生成一个球
  27. int createSphere(int numSlices, float radius, GLfloat **vertices, GLfloat **normals,
  28. GLfloat **texCoords, GLuint **indices);
  29. typedef struct {
  30. GLfloat m[4][4];
  31. } Matrix;
  32. //初始化一个矩阵
  33. void matrixLoadIdentity(Matrix *result);
  34. //矩阵变换
  35. void translate(Matrix *result, GLfloat tx, GLfloat ty, GLfloat tz);
  36. //矩阵旋转
  37. void rotate(Matrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
  38. //矩阵相乘
  39. void matrixMultiply(Matrix *result, Matrix *srcA, Matrix *srcB);
  40. //矩阵截取
  41. void frustum(Matrix *result, float w, float h, float nearZ, float farZ);
  42. //矩阵透视变换
  43. void perspective(Matrix *result, float fovy, float aspect, float nearZ, float farZ);
  44. void ortho(Matrix *result, float left, float right, float bottom, float top, float nearZ,
  45. float farZ);
  46. void scale(Matrix *result, GLfloat sx, GLfloat sy, GLfloat sz);
  47. void matrixLookAt(Matrix *result, float posX, float posY, float posZ, float lookAtX, float lookAtY,
  48. float lookAtZ, float upX, float upY, float upZ);
  49. #endif

ESUtil.cpp


  1. #include "esUtil.h"
  2. bool checkGlError(const char *funcName) {
  3. GLint err = glGetError();
  4. if (err != GL_NO_ERROR) {
  5. ALOGE("GL error after %s(): 0x%08x\n", funcName, err);
  6. return true;
  7. }
  8. return false;
  9. }
  10. GLuint createShader(GLenum shaderType, const char *src) {
  11. GLuint shader = glCreateShader(shaderType);
  12. if (!shader) {
  13. checkGlError("glCreateShader");
  14. return 0;
  15. }
  16. glShaderSource(shader, 1, &src, NULL);
  17. GLint compiled = GL_FALSE;
  18. glCompileShader(shader);
  19. glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
  20. if (!compiled) {
  21. GLint infoLogLen = 0;
  22. glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
  23. if (infoLogLen > 0) {
  24. GLchar *infoLog = (GLchar *) malloc(infoLogLen);
  25. if (infoLog) {
  26. glGetShaderInfoLog(shader, infoLogLen, NULL, infoLog);
  27. ALOGE("Could not compile %s shader:\n%s\n",
  28. shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment",
  29. infoLog);
  30. free(infoLog);
  31. }
  32. }
  33. glDeleteShader(shader);
  34. return 0;
  35. }
  36. return shader;
  37. }
  38. GLuint createProgram(const char *vtxSrc, const char *fragSrc) {
  39. GLuint vtxShader = 0;
  40. GLuint fragShader = 0;
  41. GLuint program = 0;
  42. GLint linked = GL_FALSE;
  43. vtxShader = createShader(GL_VERTEX_SHADER, vtxSrc);
  44. if (!vtxShader)
  45. goto exit;
  46. fragShader = createShader(GL_FRAGMENT_SHADER, fragSrc);
  47. if (!fragShader)
  48. goto exit;
  49. program = glCreateProgram();
  50. if (!program) {
  51. checkGlError("glCreateProgram");
  52. goto exit;
  53. }
  54. glAttachShader(program, vtxShader);
  55. glAttachShader(program, fragShader);
  56. glLinkProgram(program);
  57. glGetProgramiv(program, GL_LINK_STATUS, &linked);
  58. if (!linked) {
  59. ALOGE("Could not link program");
  60. GLint infoLogLen = 0;
  61. glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen);
  62. if (infoLogLen) {
  63. GLchar *infoLog = (GLchar *) malloc(infoLogLen);
  64. if (infoLog) {
  65. glGetProgramInfoLog(program, infoLogLen, NULL, infoLog);
  66. ALOGE("Could not link program:\n%s\n", infoLog);
  67. free(infoLog);
  68. }
  69. }
  70. glDeleteProgram(program);
  71. program = 0;
  72. }
  73. exit:
  74. glDeleteShader(vtxShader);
  75. glDeleteShader(fragShader);
  76. return program;
  77. }
  78. void
  79. matrixMultiply(Matrix *result, Matrix *srcA, Matrix *srcB) {
  80. Matrix tmp;
  81. int i;
  82. for (i = 0; i < 4; i++) {
  83. tmp.m[i][0] = (srcA->m[i][0] * srcB->m[0][0]) +
  84. (srcA->m[i][1] * srcB->m[1][0]) +
  85. (srcA->m[i][2] * srcB->m[2][0]) +
  86. (srcA->m[i][3] * srcB->m[3][0]);
  87. tmp.m[i][1] = (srcA->m[i][0] * srcB->m[0][1]) +
  88. (srcA->m[i][1] * srcB->m[1][1]) +
  89. (srcA->m[i][2] * srcB->m[2][1]) +
  90. (srcA->m[i][3] * srcB->m[3][1]);
  91. tmp.m[i][2] = (srcA->m[i][0] * srcB->m[0][2]) +
  92. (srcA->m[i][1] * srcB->m[1][2]) +
  93. (srcA->m[i][2] * srcB->m[2][2]) +
  94. (srcA->m[i][3] * srcB->m[3][2]);
  95. tmp.m[i][3] = (srcA->m[i][0] * srcB->m[0][3]) +
  96. (srcA->m[i][1] * srcB->m[1][3]) +
  97. (srcA->m[i][2] * srcB->m[2][3]) +
  98. (srcA->m[i][3] * srcB->m[3][3]);
  99. }
  100. memcpy(result, &tmp, sizeof(Matrix));
  101. }
  102. int createSquareGrid(int size, GLfloat **vertices, GLuint **indices) {
  103. GLuint i, j;
  104. int numIndices = (size - 1) * (size - 1) * 2 * 3;
  105. // Allocate memory for buffers
  106. if (vertices != NULL) {
  107. int numVertices = size * size;
  108. float stepSize = (float) size - 1;
  109. *vertices = (GLfloat *) malloc(sizeof(GLfloat) * 3 * numVertices);
  110. for (i = 0; i < size; ++i) // row
  111. {
  112. for (j = 0; j < size; ++j) // column
  113. {
  114. (*vertices)[3 * (j + i * size)] = i / stepSize;
  115. (*vertices)[3 * (j + i * size) + 1] = j / stepSize;
  116. (*vertices)[3 * (j + i * size) + 2] = 0.0f;
  117. }
  118. }
  119. }
  120. // Generate the indices
  121. if (indices != NULL) {
  122. *indices = (GLuint *) malloc(sizeof(GLuint) * numIndices);
  123. for (i = 0; i < size - 1; ++i) {
  124. for (j = 0; j < size - 1; ++j) {
  125. // two triangles per quad
  126. (*indices)[6 * (j + i * (size - 1))] = j + (i) * (size);
  127. (*indices)[6 * (j + i * (size - 1)) + 1] = j + (i) * (size) + 1;
  128. (*indices)[6 * (j + i * (size - 1)) + 2] = j + (i + 1) * (size) + 1;
  129. (*indices)[6 * (j + i * (size - 1)) + 3] = j + (i) * (size);
  130. (*indices)[6 * (j + i * (size - 1)) + 4] = j + (i + 1) * (size) + 1;
  131. (*indices)[6 * (j + i * (size - 1)) + 5] = j + (i + 1) * (size);
  132. }
  133. }
  134. }
  135. return numIndices;
  136. }
  137. void
  138. frustum(Matrix *result, float w, float h, float nearZ,
  139. float farZ) {
  140. float left = -w;
  141. float right = w;
  142. float bottom = -h;
  143. float top = h;
  144. float deltaX = right - left;
  145. float deltaY = top - bottom;
  146. float deltaZ = farZ - nearZ;
  147. Matrix frust;
  148. if ((nearZ <= 0.0f) || (farZ <= 0.0f) ||
  149. (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f)) {
  150. return;
  151. }
  152. frust.m[0][0] = 2.0f * nearZ / deltaX;
  153. frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f;
  154. frust.m[1][1] = 2.0f * nearZ / deltaY;
  155. frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f;
  156. frust.m[2][0] = (right + left) / deltaX;
  157. frust.m[2][1] = (top + bottom) / deltaY;
  158. frust.m[2][2] = -(nearZ + farZ) / deltaZ;
  159. frust.m[2][3] = -1.0f;
  160. frust.m[3][2] = -2.0f * nearZ * farZ / deltaZ;
  161. frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f;
  162. matrixMultiply(result, &frust, result);
  163. }
  164. void
  165. rotate(Matrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
  166. GLfloat sinAngle, cosAngle;
  167. GLfloat mag = sqrtf(x * x + y * y + z * z);
  168. sinAngle = sinf(float(angle * PI / 180.0f));
  169. cosAngle = cosf(float(angle * PI / 180.0f));
  170. if (mag > 0.0f) {
  171. GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs;
  172. GLfloat oneMinusCos;
  173. Matrix rotMat;
  174. x /= mag;
  175. y /= mag;
  176. z /= mag;
  177. xx = x * x;
  178. yy = y * y;
  179. zz = z * z;
  180. xy = x * y;
  181. yz = y * z;
  182. zx = z * x;
  183. xs = x * sinAngle;
  184. ys = y * sinAngle;
  185. zs = z * sinAngle;
  186. oneMinusCos = 1.0f - cosAngle;
  187. rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle;
  188. rotMat.m[0][1] = (oneMinusCos * xy) - zs;
  189. rotMat.m[0][2] = (oneMinusCos * zx) + ys;
  190. rotMat.m[0][3] = 0.0F;
  191. rotMat.m[1][0] = (oneMinusCos * xy) + zs;
  192. rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle;
  193. rotMat.m[1][2] = (oneMinusCos * yz) - xs;
  194. rotMat.m[1][3] = 0.0F;
  195. rotMat.m[2][0] = (oneMinusCos * zx) - ys;
  196. rotMat.m[2][1] = (oneMinusCos * yz) + xs;
  197. rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle;
  198. rotMat.m[2][3] = 0.0F;
  199. rotMat.m[3][0] = 0.0F;
  200. rotMat.m[3][1] = 0.0F;
  201. rotMat.m[3][2] = 0.0F;
  202. rotMat.m[3][3] = 1.0F;
  203. matrixMultiply(result, &rotMat, result);
  204. }
  205. }
  206. void
  207. translate(Matrix *result, GLfloat tx, GLfloat ty, GLfloat tz) {
  208. result->m[3][0] += (result->m[0][0] * tx + result->m[1][0] * ty + result->m[2][0] * tz);
  209. result->m[3][1] += (result->m[0][1] * tx + result->m[1][1] * ty + result->m[2][1] * tz);
  210. result->m[3][2] += (result->m[0][2] * tx + result->m[1][2] * ty + result->m[2][2] * tz);
  211. result->m[3][3] += (result->m[0][3] * tx + result->m[1][3] * ty + result->m[2][3] * tz);
  212. }
  213. void
  214. matrixLoadIdentity(Matrix *result) {
  215. memset(result, 0, sizeof(Matrix));
  216. result->m[0][0] = 1.0f;
  217. result->m[1][1] = 1.0f;
  218. result->m[2][2] = 1.0f;
  219. result->m[3][3] = 1.0f;
  220. }
  221. int
  222. createCube(float scale, GLfloat **vertices, GLfloat **normals,
  223. GLfloat **texCoords, GLuint **indices) {
  224. int i;
  225. int numVertices = 24;
  226. int numIndices = 36;
  227. GLfloat cubeVerts[] =
  228. {
  229. -0.5f, -0.5f, -0.5f,
  230. -0.5f, -0.5f, 0.5f,
  231. 0.5f, -0.5f, 0.5f,
  232. 0.5f, -0.5f, -0.5f,
  233. -0.5f, 0.5f, -0.5f,
  234. -0.5f, 0.5f, 0.5f,
  235. 0.5f, 0.5f, 0.5f,
  236. 0.5f, 0.5f, -0.5f,
  237. -0.5f, -0.5f, -0.5f,
  238. -0.5f, 0.5f, -0.5f,
  239. 0.5f, 0.5f, -0.5f,
  240. 0.5f, -0.5f, -0.5f,
  241. -0.5f, -0.5f, 0.5f,
  242. -0.5f, 0.5f, 0.5f,
  243. 0.5f, 0.5f, 0.5f,
  244. 0.5f, -0.5f, 0.5f,
  245. -0.5f, -0.5f, -0.5f,
  246. -0.5f, -0.5f, 0.5f,
  247. -0.5f, 0.5f, 0.5f,
  248. -0.5f, 0.5f, -0.5f,
  249. 0.5f, -0.5f, -0.5f,
  250. 0.5f, -0.5f, 0.5f,
  251. 0.5f, 0.5f, 0.5f,
  252. 0.5f, 0.5f, -0.5f,
  253. };
  254. GLfloat cubeNormals[] =
  255. {
  256. 0.0f, -1.0f, 0.0f,
  257. 0.0f, -1.0f, 0.0f,
  258. 0.0f, -1.0f, 0.0f,
  259. 0.0f, -1.0f, 0.0f,
  260. 0.0f, 1.0f, 0.0f,
  261. 0.0f, 1.0f, 0.0f,
  262. 0.0f, 1.0f, 0.0f,
  263. 0.0f, 1.0f, 0.0f,
  264. 0.0f, 0.0f, -1.0f,
  265. 0.0f, 0.0f, -1.0f,
  266. 0.0f, 0.0f, -1.0f,
  267. 0.0f, 0.0f, -1.0f,
  268. 0.0f, 0.0f, 1.0f,
  269. 0.0f, 0.0f, 1.0f,
  270. 0.0f, 0.0f, 1.0f,
  271. 0.0f, 0.0f, 1.0f,
  272. -1.0f, 0.0f, 0.0f,
  273. -1.0f, 0.0f, 0.0f,
  274. -1.0f, 0.0f, 0.0f,
  275. -1.0f, 0.0f, 0.0f,
  276. 1.0f, 0.0f, 0.0f,
  277. 1.0f, 0.0f, 0.0f,
  278. 1.0f, 0.0f, 0.0f,
  279. 1.0f, 0.0f, 0.0f,
  280. };
  281. GLfloat cubeTex[] =
  282. {
  283. 0.0f, 0.0f,
  284. 0.0f, 1.0f,
  285. 1.0f, 1.0f,
  286. 1.0f, 0.0f,
  287. 1.0f, 0.0f,
  288. 1.0f, 1.0f,
  289. 0.0f, 1.0f,
  290. 0.0f, 0.0f,
  291. 0.0f, 0.0f,
  292. 0.0f, 1.0f,
  293. 1.0f, 1.0f,
  294. 1.0f, 0.0f,
  295. 0.0f, 0.0f,
  296. 0.0f, 1.0f,
  297. 1.0f, 1.0f,
  298. 1.0f, 0.0f,
  299. 0.0f, 0.0f,
  300. 0.0f, 1.0f,
  301. 1.0f, 1.0f,
  302. 1.0f, 0.0f,
  303. 0.0f, 0.0f,
  304. 0.0f, 1.0f,
  305. 1.0f, 1.0f,
  306. 1.0f, 0.0f,
  307. };
  308. if (vertices != NULL) {
  309. *vertices = (GLfloat *) malloc(sizeof(GLfloat) * 3 * numVertices);
  310. memcpy(*vertices, cubeVerts, sizeof(cubeVerts));
  311. for (i = 0; i < numVertices * 3; i++) {
  312. (*vertices)[i] *= scale;
  313. }
  314. }
  315. if (normals != NULL) {
  316. *normals = (GLfloat *) malloc(sizeof(GLfloat) * 3 * numVertices);
  317. memcpy(*normals, cubeNormals, sizeof(cubeNormals));
  318. }
  319. if (texCoords != NULL) {
  320. *texCoords = (GLfloat *) malloc(sizeof(GLfloat) * 2 * numVertices);
  321. memcpy(*texCoords, cubeTex, sizeof(cubeTex));
  322. }
  323. if (indices != NULL) {
  324. GLuint cubeIndices[] =
  325. {
  326. 0, 2, 1,
  327. 0, 3, 2,
  328. 4, 5, 6,
  329. 4, 6, 7,
  330. 8, 9, 10,
  331. 8, 10, 11,
  332. 12, 15, 14,
  333. 12, 14, 13,
  334. 16, 17, 18,
  335. 16, 18, 19,
  336. 20, 23, 22,
  337. 20, 22, 21
  338. };
  339. *indices = (GLuint *) malloc(sizeof(GLuint) * numIndices);
  340. memcpy(*indices, cubeIndices, sizeof(cubeIndices));
  341. }
  342. return numIndices;
  343. }
  344. void
  345. perspective(Matrix *result, float fovy, float aspect, float nearZ, float farZ) {
  346. GLfloat frustumW, frustumH;
  347. frustumH = tanf(float(fovy / 360.0f * PI)) * nearZ;
  348. frustumW = frustumH * aspect;
  349. frustum(result, frustumW, frustumH, nearZ, farZ);
  350. }
  351. void
  352. scale(Matrix *result, GLfloat sx, GLfloat sy, GLfloat sz) {
  353. result->m[0][0] *= sx;
  354. result->m[0][1] *= sx;
  355. result->m[0][2] *= sx;
  356. result->m[0][3] *= sx;
  357. result->m[1][0] *= sy;
  358. result->m[1][1] *= sy;
  359. result->m[1][2] *= sy;
  360. result->m[1][3] *= sy;
  361. result->m[2][0] *= sz;
  362. result->m[2][1] *= sz;
  363. result->m[2][2] *= sz;
  364. result->m[2][3] *= sz;
  365. }
  366. void
  367. matrixLookAt(Matrix *result,
  368. float posX, float posY, float posZ,
  369. float lookAtX, float lookAtY, float lookAtZ,
  370. float upX, float upY, float upZ) {
  371. float axisX[3], axisY[3], axisZ[3];
  372. float length;
  373. // axisZ = lookAt - pos
  374. axisZ[0] = lookAtX - posX;
  375. axisZ[1] = lookAtY - posY;
  376. axisZ[2] = lookAtZ - posZ;
  377. // normalize axisZ
  378. length = sqrtf(axisZ[0] * axisZ[0] + axisZ[1] * axisZ[1] + axisZ[2] * axisZ[2]);
  379. if (length != 0.0f) {
  380. axisZ[0] /= length;
  381. axisZ[1] /= length;
  382. axisZ[2] /= length;
  383. }
  384. // axisX = up X axisZ
  385. axisX[0] = upY * axisZ[2] - upZ * axisZ[1];
  386. axisX[1] = upZ * axisZ[0] - upX * axisZ[2];
  387. axisX[2] = upX * axisZ[1] - upY * axisZ[0];
  388. // normalize axisX
  389. length = sqrtf(axisX[0] * axisX[0] + axisX[1] * axisX[1] + axisX[2] * axisX[2]);
  390. if (length != 0.0f) {
  391. axisX[0] /= length;
  392. axisX[1] /= length;
  393. axisX[2] /= length;
  394. }
  395. // axisY = axisZ x axisX
  396. axisY[0] = axisZ[1] * axisX[2] - axisZ[2] * axisX[1];
  397. axisY[1] = axisZ[2] * axisX[0] - axisZ[0] * axisX[2];
  398. axisY[2] = axisZ[0] * axisX[1] - axisZ[1] * axisX[0];
  399. // normalize axisY
  400. length = sqrtf(axisY[0] * axisY[0] + axisY[1] * axisY[1] + axisY[2] * axisY[2]);
  401. if (length != 0.0f) {
  402. axisY[0] /= length;
  403. axisY[1] /= length;
  404. axisY[2] /= length;
  405. }
  406. memset(result, 0x0, sizeof(Matrix));
  407. result->m[0][0] = -axisX[0];
  408. result->m[0][1] = axisY[0];
  409. result->m[0][2] = -axisZ[0];
  410. result->m[1][0] = -axisX[1];
  411. result->m[1][1] = axisY[1];
  412. result->m[1][2] = -axisZ[1];
  413. result->m[2][0] = -axisX[2];
  414. result->m[2][1] = axisY[2];
  415. result->m[2][2] = -axisZ[2];
  416. // translate (-posX, -posY, -posZ)
  417. result->m[3][0] = axisX[0] * posX + axisX[1] * posY + axisX[2] * posZ;
  418. result->m[3][1] = -axisY[0] * posX - axisY[1] * posY - axisY[2] * posZ;
  419. result->m[3][2] = axisZ[0] * posX + axisZ[1] * posY + axisZ[2] * posZ;
  420. result->m[3][3] = 1.0f;
  421. }
  422. void
  423. ortho(Matrix *result, float left, float right, float bottom, float top, float nearZ,
  424. float farZ) {
  425. float deltaX = right - left;
  426. float deltaY = top - bottom;
  427. float deltaZ = farZ - nearZ;
  428. Matrix ortho;
  429. if ((deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f)) {
  430. return;
  431. }
  432. matrixLoadIdentity(&ortho);
  433. ortho.m[0][0] = 2.0f / deltaX;
  434. ortho.m[3][0] = -(right + left) / deltaX;
  435. ortho.m[1][1] = 2.0f / deltaY;
  436. ortho.m[3][1] = -(top + bottom) / deltaY;
  437. ortho.m[2][2] = -2.0f / deltaZ;
  438. ortho.m[3][2] = -(nearZ + farZ) / deltaZ;
  439. matrixMultiply(result, &ortho, result);
  440. }
  441. int
  442. createSphere(int numSlices, float radius, GLfloat **vertices, GLfloat **normals,
  443. GLfloat **texCoords, GLuint **indices) {
  444. int i;
  445. int j;
  446. int numParallels = numSlices / 2;
  447. int numVertices = (numParallels + 1) * (numSlices + 1);
  448. int numIndices = numParallels * numSlices * 6;
  449. float angleStep = (float) (2.0f * PI) / numSlices;
  450. // Allocate memory for buffers
  451. if (vertices != NULL) {
  452. *vertices = (GLfloat *) malloc(sizeof(GLfloat) * 3 * numVertices);
  453. }
  454. if (normals != NULL) {
  455. *normals = (GLfloat *) malloc(sizeof(GLfloat) * 3 * numVertices);
  456. }
  457. if (texCoords != NULL) {
  458. *texCoords = (GLfloat *) malloc(sizeof(GLfloat) * 2 * numVertices);
  459. }
  460. if (indices != NULL) {
  461. *indices = (GLuint *) malloc(sizeof(GLuint) * numIndices);
  462. }
  463. for (i = 0; i < numParallels + 1; i++) {
  464. for (j = 0; j < numSlices + 1; j++) {
  465. int vertex = (i * (numSlices + 1) + j) * 3;
  466. if (vertices) {
  467. (*vertices)[vertex + 0] = radius * sinf(angleStep * (float) i) *
  468. sinf(angleStep * (float) j);
  469. (*vertices)[vertex + 1] = radius * cosf(angleStep * (float) i);
  470. (*vertices)[vertex + 2] = radius * sinf(angleStep * (float) i) *
  471. cosf(angleStep * (float) j);
  472. }
  473. if (normals) {
  474. (*normals)[vertex + 0] = (*vertices)[vertex + 0] / radius;
  475. (*normals)[vertex + 1] = (*vertices)[vertex + 1] / radius;
  476. (*normals)[vertex + 2] = (*vertices)[vertex + 2] / radius;
  477. }
  478. if (texCoords) {
  479. int texIndex = (i * (numSlices + 1) + j) * 2;
  480. (*texCoords)[texIndex + 0] = (float) j / (float) numSlices;
  481. (*texCoords)[texIndex + 1] = (1.0f - (float) i) / (float) (numParallels - 1);
  482. }
  483. }
  484. }
  485. // Generate the indices
  486. if (indices != NULL) {
  487. GLuint *indexBuf = (*indices);
  488. for (i = 0; i < numParallels; i++) {
  489. for (j = 0; j < numSlices; j++) {
  490. *indexBuf++ = (GLuint) (i * (numSlices + 1) + j);
  491. *indexBuf++ = (GLuint) (i + 1) * (numSlices + 1) + j;
  492. *indexBuf++ = (GLuint) (i + 1) * (numSlices + 1) + (j + 1);
  493. *indexBuf++ = (GLuint) i * (numSlices + 1) + j;
  494. *indexBuf++ = (GLuint) (i + 1) * (numSlices + 1) + (j + 1);
  495. *indexBuf++ = (GLuint) i * (numSlices + 1) + (j + 1);
  496. }
  497. }
  498. }
  499. return numIndices;
  500. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注