mesh.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. #include "mesh.h"
  2. #include <stdint.h>
  3. #include <math.h>
  4. #include "geometry.h"
  5. #include "program.h"
  6. #include <glplatform/glplatform-glcore.h>
  7. #include <glplatform/math3d.h>
  8. #include "lua.h"
  9. #include "texture.h"
  10. static void delete_mesh(struct mesh *m)
  11. {
  12. glDeleteBuffers(1, &m->vertex_array);
  13. glDeleteBuffers(1, &m->index_array);
  14. glDeleteBuffers(MAX_UV_LAYERS, m->uv_array);
  15. }
  16. static int mesh_gc(lua_State *L)
  17. {
  18. struct mesh *m = lua_touserdata(L, -1);
  19. if (m)
  20. delete_mesh(m);
  21. return 0;
  22. }
  23. static struct buffer_type buffer_type_mesh[2][32];
  24. void create_mesh(struct mesh *m, lua_State *L, const uint8_t *blob)
  25. {
  26. lua_getfield(L, -1, "num_triangles");
  27. m->num_triangles = lua_tointeger(L, -1);
  28. lua_pop(L, 1);
  29. lua_getfield(L, -1, "num_verticies");
  30. m->num_verticies = lua_tointeger(L, -1);
  31. lua_pop(L, 1);
  32. int has_uv_layers = false;
  33. lua_getfield(L, -1, "uv_layers");
  34. lua_pushnil(L);
  35. if (lua_next(L, -2)) {
  36. has_uv_layers = true;
  37. lua_pop(L, 3);
  38. } else {
  39. lua_pop(L, 1);
  40. }
  41. m->has_uv_layers = true;
  42. lua_getfield(L, -1, "weights_per_vertex");
  43. int weights_per_vertex = lua_tointeger(L, -1);
  44. lua_pop(L, 1);
  45. lua_getfield(L, -1, "submeshes");
  46. lua_len(L, -1);
  47. int num_submesh = lua_tointeger(L, -1);
  48. lua_pop(L, 1);
  49. m->num_submesh = num_submesh;
  50. int i;
  51. for (i = 1; i <= num_submesh; i++) {
  52. struct submesh *submesh = m->submesh + i - 1;
  53. lua_rawgeti(L, -1, i);
  54. lua_getfield(L, -1, "material_name");
  55. submesh->material_name = strdup(lua_tostring(L, -1));
  56. lua_pop(L, 1);
  57. lua_getfield(L, -1, "triangle_no");
  58. submesh->triangle_no = lua_tointeger(L, -1);
  59. lua_pop(L, 1);
  60. lua_getfield(L, -1, "triangle_count");
  61. submesh->triangle_count = lua_tointeger(L, -1);
  62. lua_pop(L, 1);
  63. lua_pop(L, 1);
  64. }
  65. lua_pop(L, 1);
  66. struct attribute attribute[NUM_ATTRIBUTES];
  67. memset(attribute, 0, sizeof(attribute));
  68. struct buffer_type *type = &(buffer_type_mesh[(has_uv_layers > 0) ? 1 : 0][weights_per_vertex]);
  69. if (!type->valid) {
  70. int fcount = 0;
  71. int scount = 0;
  72. attribute[ATTRIBUTE_VERTEX].integer = false;
  73. attribute[ATTRIBUTE_VERTEX].size = 3;
  74. attribute[ATTRIBUTE_VERTEX].type = GL_FLOAT;
  75. attribute[ATTRIBUTE_VERTEX].offset = 0;
  76. attribute[ATTRIBUTE_VERTEX].binding_index = 0;
  77. fcount += 3;
  78. attribute[ATTRIBUTE_NORMAL].integer = false;
  79. attribute[ATTRIBUTE_NORMAL].size = 3;
  80. attribute[ATTRIBUTE_NORMAL].type = GL_FLOAT;
  81. attribute[ATTRIBUTE_NORMAL].offset = sizeof(float) * fcount;
  82. attribute[ATTRIBUTE_NORMAL].binding_index = 0;
  83. fcount += 3;
  84. if (has_uv_layers) {
  85. attribute[ATTRIBUTE_UV].integer = false;
  86. attribute[ATTRIBUTE_UV].size = 2;
  87. attribute[ATTRIBUTE_UV].type = GL_FLOAT;
  88. attribute[ATTRIBUTE_UV].offset = 0;
  89. attribute[ATTRIBUTE_UV].binding_index = 1;
  90. attribute[ATTRIBUTE_TANGENT].integer = false;
  91. attribute[ATTRIBUTE_TANGENT].size = 4;
  92. attribute[ATTRIBUTE_TANGENT].type = GL_FLOAT;
  93. attribute[ATTRIBUTE_TANGENT].offset = sizeof(float) * 2;
  94. attribute[ATTRIBUTE_TANGENT].binding_index = 1;
  95. }
  96. for (i = 0; i < weights_per_vertex && i < MAX_VERTEX_WEIGHTS; i++) {
  97. attribute[ATTRIBUTE_WEIGHT0 + i].integer = true;
  98. attribute[ATTRIBUTE_WEIGHT0 + i].size = 2;
  99. attribute[ATTRIBUTE_WEIGHT0 + i].type = GL_UNSIGNED_SHORT;
  100. attribute[ATTRIBUTE_WEIGHT0 + i].offset = sizeof(float) * fcount + sizeof(uint16_t) * scount;
  101. attribute[ATTRIBUTE_WEIGHT0 + i].binding_index = 0;
  102. scount += 2;
  103. }
  104. type->element_size[0] = sizeof(float) * fcount + sizeof(uint16_t) * scount;
  105. type->element_size[1] = sizeof(float) * 6;
  106. buffer_type_init(type, attribute, NUM_ATTRIBUTES);
  107. }
  108. m->weights_per_vertex = weights_per_vertex;
  109. m->type = type;
  110. lua_getfield(L, -1, "vertex_co_array_offset");
  111. float *vertex_ptr = (float *)(blob + lua_tointeger(L, -1));
  112. lua_pop(L, 1);
  113. lua_getfield(L, -1, "vertex_normal_array_offset");
  114. float *normal_ptr = (float *)(blob + lua_tointeger(L, -1));
  115. lua_pop(L, 1);
  116. lua_getfield(L, -1, "weights_array_offset");
  117. uint16_t *weights_ptr = (uint16_t *)(blob + lua_tointeger(L, -1));
  118. lua_pop(L, 1);
  119. glGenBuffers(1, &m->vertex_array);
  120. glGenBuffers(1, &m->index_array);
  121. glGenBuffers(MAX_UV_LAYERS, m->uv_array);
  122. glBindBuffer(GL_ARRAY_BUFFER, m->vertex_array);
  123. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->index_array);
  124. glBufferStorage(GL_ARRAY_BUFFER,
  125. m->type->element_size[0] * m->num_verticies,
  126. NULL,
  127. GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
  128. glBufferStorage(GL_ELEMENT_ARRAY_BUFFER,
  129. sizeof(uint16_t) * 3 * m->num_triangles,
  130. NULL,
  131. GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
  132. uint8_t *ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
  133. uint16_t *index_buffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
  134. int j;
  135. for (i = 0; i < m->num_verticies; i++) {
  136. float *f = (float *)ptr;
  137. *(f++) = *(vertex_ptr++);
  138. *(f++) = *(vertex_ptr++);
  139. *(f++) = *(vertex_ptr++);
  140. *(f++) = *(normal_ptr++);
  141. *(f++) = *(normal_ptr++);
  142. *(f++) = *(normal_ptr++);
  143. uint16_t *s = (uint16_t *)f;
  144. for (j = 0; j < weights_per_vertex && j < MAX_VERTEX_WEIGHTS; j++) {
  145. s[2*j] = weights_ptr[2*j];
  146. s[2*j + 1] = weights_ptr[2*j + 1];
  147. }
  148. s += 2 * j;
  149. weights_ptr += 2 * weights_per_vertex;
  150. ptr += m->type->element_size[0];
  151. }
  152. lua_getfield(L, -1, "index_array_offset");
  153. memcpy(index_buffer, blob + lua_tointeger(L, -1), sizeof(uint16_t) * 3 * m->num_triangles);
  154. lua_pop(L, 1);
  155. glUnmapBuffer(GL_ARRAY_BUFFER);
  156. glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
  157. lua_getfield(L, -1, "uv_layers");
  158. lua_pushnil(L);
  159. i = 0;
  160. while (lua_next(L, -2)) {
  161. lua_pushinteger(L, i);
  162. lua_setfield(L, -2, "idx");
  163. lua_getfield(L, -1, "uv_array_offset");
  164. int uv_array_offset = lua_tointeger(L, -1);
  165. lua_pop(L, 1);
  166. lua_getfield(L, -1, "tangent_array_offset");
  167. int tangent_array_offset = lua_tointeger(L, -1);
  168. lua_pop(L, 1);
  169. float *uv_ptr = (float *)(blob + uv_array_offset);
  170. float *tangent_ptr = (float *)(blob + tangent_array_offset);
  171. glBindBuffer(GL_ARRAY_BUFFER, m->uv_array[i]);
  172. glBufferStorage(GL_ARRAY_BUFFER, sizeof(float) * 6 * m->num_verticies, NULL, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
  173. ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
  174. for (j = 0; j < m->num_verticies; j++) {
  175. float *f = (float *)ptr;
  176. *(f++) = *(uv_ptr++);
  177. *(f++) = *(uv_ptr++);
  178. *(f++) = *(tangent_ptr++);
  179. *(f++) = *(tangent_ptr++);
  180. *(f++) = *(tangent_ptr++);
  181. *(f++) = *(tangent_ptr++);
  182. ptr += m->type->element_size[1];
  183. }
  184. glUnmapBuffer(GL_ARRAY_BUFFER);
  185. lua_pop(L, 1);
  186. i++;
  187. }
  188. lua_pop(L, 2);
  189. }
  190. void render_mesh(lua_State *L, int b2l_data_idx, int materials_idx, const uint8_t *blob,
  191. const char *scene_name,
  192. const char *object_name,
  193. double frame,
  194. struct math3d_mat4 *model,
  195. struct math3d_mat4 *view,
  196. struct math3d_mat4 *proj)
  197. {
  198. int top_idx = lua_gettop(L);
  199. lua_getfield(L, b2l_data_idx, "objects");
  200. lua_getfield(L, -1, object_name);
  201. if (lua_isnil(L, -1)) {
  202. goto end;
  203. }
  204. int object_idx = lua_gettop(L);
  205. lua_getfield(L, object_idx, "type");
  206. if (strcmp(lua_tostring(L, -1), "MESH")) {
  207. goto end;
  208. }
  209. lua_getfield(L, object_idx, "data");
  210. lua_getfield(L, b2l_data_idx, "meshes");
  211. lua_getfield(L, -1, lua_tostring(L, -2));
  212. if (lua_isnil(L, -1)) {
  213. goto end;
  214. }
  215. int mesh_idx = lua_gettop(L);
  216. lua_getfield(L, mesh_idx, "mesh");
  217. struct mesh *m = (struct mesh *)lua_touserdata(L, -1);
  218. if (!m) {
  219. lua_getfield(L, mesh_idx, "submeshes");
  220. lua_len(L, -1);
  221. int num_submesh = lua_tointeger(L, -1);
  222. size_t mesh_size = offsetof(struct mesh, submesh[num_submesh]);
  223. m = (struct mesh *)lua_newuserdata(L, mesh_size);
  224. memset(m, 0, mesh_size);
  225. lua_newtable(L);
  226. lua_pushcfunction(L, mesh_gc);
  227. lua_setfield(L, -2, "__gc");
  228. lua_setmetatable(L, -2);
  229. lua_setfield(L, mesh_idx, "mesh");
  230. lua_pushvalue(L, mesh_idx);
  231. create_mesh(m, L, blob);
  232. }
  233. lua_getfield(L, object_idx, "vertex_groups");
  234. int num_vertex_groups;
  235. if (lua_isnil(L, -1)) {
  236. num_vertex_groups = 0;
  237. } else {
  238. lua_len(L, -1);
  239. num_vertex_groups = lua_tointeger(L, -1);
  240. }
  241. int i;
  242. for (i = 0; i < m->num_submesh; i++) {
  243. lua_getfield(L, materials_idx, m->submesh[i].material_name);
  244. int material_idx = lua_gettop(L);
  245. lua_getfield(L, material_idx, "program");
  246. struct program *program = lua_touserdata(L, -1);
  247. glUseProgram(program->program);
  248. glUniformMatrix4fv(glGetUniformLocation(program->program, "model"), 1, GL_FALSE, (GLfloat *)model);
  249. glUniformMatrix4fv(glGetUniformLocation(program->program, "proj"), 1, GL_FALSE, (GLfloat *)proj);
  250. glUniformMatrix4fv(glGetUniformLocation(program->program, "view"), 1, GL_FALSE, (GLfloat *)view);
  251. //
  252. // Compute armature matrix transforms
  253. //
  254. GLint groups_index = glGetUniformLocation(program->program, "groups");
  255. if (groups_index >= 0 && m->weights_per_vertex) {
  256. static int render_count = 0;
  257. render_count++;
  258. int prev_top = lua_gettop(L);
  259. int frame_i = floorf(frame);
  260. double frame_fract = frame - frame_i;
  261. lua_getfield(L, b2l_data_idx, "scenes");
  262. lua_getfield(L, -1, scene_name);
  263. if (!lua_istable(L, -1)) {
  264. goto end;
  265. }
  266. lua_getfield(L, -1, "objects");
  267. lua_getfield(L, -1, object_name);
  268. lua_getfield(L, -1, "vertex_group_transform_array_offset");
  269. int offset = lua_tointeger(L, -1);
  270. int stride = sizeof(float) * 4 * 4 * num_vertex_groups;
  271. int j;
  272. for (j = 0; j < num_vertex_groups; j++) {
  273. struct math3d_mat4 res;
  274. struct math3d_mat4 *base = (struct math3d_mat4 *)(blob + offset + (j * sizeof(float) * 4 * 4) + frame_i * stride);
  275. struct math3d_mat4 *next = (struct math3d_mat4 *)(blob + offset + (j * sizeof(float) * 4 * 4) + (frame_i + 1) * stride);
  276. #if USE_SLERP
  277. struct math3d_mat4 M1;
  278. struct math3d_mat4 M2;
  279. struct math3d_mat4 temp;
  280. math3d_mat4_zero(&temp);
  281. temp.v[3][3] = 1;
  282. M1 = *base;
  283. M2 = *next;
  284. spherical_lerp(M1.v[0], M2.v[0], frame_fract, temp.v[0]);
  285. spherical_lerp(M1.v[1], M2.v[1], frame_fract, temp.v[1]);
  286. spherical_lerp(M1.v[2], M2.v[2], frame_fract, temp.v[2]);
  287. struct math3d_vec3 v1[3];
  288. struct math3d_vec3 v2[3];
  289. v1[0] = M1.v[0][3];
  290. v1[1] = M1.v[1][3];
  291. v1[2] = M1.v[2][3];
  292. v2[0] = M2.v[0][3];
  293. v2[1] = M2.v[1][3];
  294. v2[2] = M2.v[2][3];
  295. math3d_vec3_lerp(&v1, &v2, frame_fract, temp.v[3]);
  296. #else
  297. math3d_mat4_lerp(base, next, frame_fract, &res);
  298. #endif
  299. glUniformMatrix4fv(groups_index + j,
  300. 1,
  301. GL_FALSE,
  302. (GLfloat *)&res);
  303. }
  304. lua_settop(L, prev_top);
  305. }
  306. int texunit = 0;
  307. //
  308. // Grab material state
  309. //
  310. lua_getfield(L, material_idx, "uv_layer");
  311. int uv_idx = 0;
  312. if (!lua_isnil(L, -1)) {
  313. lua_getfield(L, mesh_idx, "uv_layers");
  314. if (!lua_isnil(L, -1)) {
  315. lua_getfield(L, -1, lua_tostring(L, -2));
  316. if (!lua_isnil(L, -1)) {
  317. lua_getfield(L, -1, "idx");
  318. uv_idx = lua_tointeger(L , -1);
  319. }
  320. }
  321. }
  322. lua_getfield(L, material_idx, "params");
  323. lua_pushnil(L); /* first key */
  324. while (lua_next(L, -2)) {
  325. int variable_idx = lua_gettop(L);
  326. const char *variable_name = lua_tostring(L, variable_idx - 1);
  327. int uniform_loc = glGetUniformLocation(program->program, variable_name);
  328. if (uniform_loc == -1) {
  329. lua_pop(L, 1);
  330. continue;
  331. }
  332. lua_getfield(L, variable_idx, "value");
  333. int value_idx = variable_idx + 1;
  334. lua_getfield(L, variable_idx, "datatype");
  335. const char *datatype = lua_tostring(L, -1);
  336. if (!strcmp(datatype, "bool")) {
  337. int bool_value = lua_toboolean(L, value_idx);
  338. glUniform1i(uniform_loc, bool_value);
  339. } else if (!strcmp(datatype, "vec3")) {
  340. lua_rawgeti(L, value_idx, 1);
  341. lua_rawgeti(L, value_idx, 2);
  342. lua_rawgeti(L, value_idx, 3);
  343. float val[3];
  344. val[0] = (float)lua_tonumber(L, -3);
  345. val[1] = (float)lua_tonumber(L, -2);
  346. val[2] = (float)lua_tonumber(L, -1);
  347. glUniform3fv(uniform_loc, 1, val);
  348. } else if (!strcmp(datatype, "float")) {
  349. float fval = lua_tonumber(L, value_idx);
  350. glUniform1f(uniform_loc, fval);
  351. } else if (!strcmp(datatype, "sampler2D")) {
  352. //
  353. // Bind texture
  354. //
  355. lua_getfield(L, variable_idx, "_texture");
  356. if (lua_isuserdata(L, -1)) {
  357. struct texture *t = lua_touserdata(L, -1);
  358. glActiveTexture(GL_TEXTURE0 + texunit);
  359. glBindTexture(GL_TEXTURE_2D, t->texid);
  360. glUniform1i(uniform_loc, texunit);
  361. }
  362. texunit++;
  363. }
  364. lua_settop(L, variable_idx - 1);
  365. }
  366. render_submesh(m, i, uv_idx);
  367. lua_pop(L, 1);
  368. }
  369. end:
  370. lua_settop(L, top_idx);
  371. }
  372. void render_submesh(struct mesh *m, int submesh, int uvmap)
  373. {
  374. glBindVertexArray(m->type->vao);
  375. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->index_array);
  376. glBindVertexBuffer(0, m->vertex_array, 0, m->type->element_size[0]);
  377. if (m->has_uv_layers)
  378. glBindVertexBuffer(1, m->uv_array[uvmap], 0, m->type->element_size[1]);
  379. glDrawElements(GL_TRIANGLES,
  380. m->submesh[submesh].triangle_count * 3,
  381. GL_UNSIGNED_SHORT,
  382. (void *)(m->submesh[submesh].triangle_no * 3 * sizeof(uint16_t)));
  383. }