mesh.d 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. module three.mesh;
  2. import three.common;
  3. struct DrawArraysIndirectCommand {
  4. GLuint vertexCount;
  5. GLuint instanceCount;
  6. GLuint firstVertex;
  7. GLuint baseInstance;
  8. }
  9. struct DrawElementsIndirectCommand {
  10. GLuint count;
  11. GLuint instanceCount;
  12. GLuint firstIndex;
  13. GLuint baseVertex;
  14. GLuint baseInstance;
  15. }
  16. struct SOAMesh {
  17. SoA!GLuint vao;
  18. SoA!GLuint vboVertices;
  19. SoA!GLuint vboNormals;
  20. SoA!GLuint vboTexcoords;
  21. SoA!GLuint vboColors;
  22. SoA!GLuint vboIndices;
  23. SoA!GLuint cntIndices;
  24. size_t cnt;
  25. }
  26. void loadModel(ref SOAMesh mesh, string filePath) {
  27. import std.traits;
  28. import std.string : toStringz;
  29. auto scene = aiImportFile(filePath.toStringz(), aiProcess_Triangulate); scope(exit) aiReleaseImport(scene);
  30. for(uint m = 0; m < scene.mNumMeshes; ++m) {
  31. const(aiMesh*) meshData = scene.mMeshes[m];
  32. assert(meshData !is null);
  33. //-----------------------------
  34. // create mesh
  35. auto meshIdx = mesh.cnt;
  36. ++mesh.cnt;
  37. mesh.vao.length = mesh.cnt;
  38. mesh.vboVertices.length = mesh.cnt;
  39. mesh.vboNormals.length = mesh.cnt;
  40. mesh.vboTexcoords.length = mesh.cnt;
  41. mesh.vboIndices.length = mesh.cnt;
  42. mesh.cntIndices.length = mesh.cnt;
  43. //-----------------------------
  44. // upload data
  45. glCheck!glGenVertexArrays(1, &mesh.vao[meshIdx]);
  46. glCheck!glBindVertexArray(mesh.vao[meshIdx]); scope(exit) glCheck!glBindVertexArray(0);
  47. alias Vertex = float[3];
  48. alias Normal = float[3];
  49. alias TexCoord = float[2];
  50. alias Color = float[4];
  51. alias Index = uint[1];
  52. size_t cntIndices = 0;
  53. foreach(f; 0..meshData.mNumFaces) {
  54. cntIndices += meshData.mFaces[f].mNumIndices;
  55. }
  56. mesh.cntIndices[meshIdx] = cntIndices;
  57. {// upload vertex data
  58. Vertex[] vertexData;
  59. vertexData.length = meshData.mNumVertices;
  60. foreach(v; 0..meshData.mNumVertices) {
  61. vertexData[v] = [meshData.mVertices[v].x, meshData.mVertices[v].y, meshData.mVertices[v].z];
  62. }
  63. glCheck!glGenBuffers(1, &mesh.vboVertices[meshIdx]);
  64. glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboVertices[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0);
  65. glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Vertex.sizeof * vertexData.length) , vertexData.ptr, GL_STATIC_DRAW);
  66. GLuint attribIndex = 0;
  67. glCheck!glEnableVertexAttribArray(attribIndex);
  68. glCheck!glVertexAttribPointer(attribIndex, Vertex.sizeof / ForeachType!Vertex.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  69. }
  70. {// upload normal data
  71. Normal[] normalData;
  72. normalData.length = meshData.mNumVertices;
  73. foreach(v; 0..meshData.mNumVertices) {
  74. normalData[v] = [meshData.mNormals[v].x, meshData.mNormals[v].y, meshData.mNormals[v].z];
  75. }
  76. glCheck!glGenBuffers(1, &mesh.vboNormals[meshIdx]);
  77. glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboNormals[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0);
  78. glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Normal.sizeof * normalData.length) , normalData.ptr, GL_STATIC_DRAW);
  79. GLuint attribIndex = 1;
  80. glCheck!glEnableVertexAttribArray(attribIndex);
  81. glCheck!glVertexAttribPointer(attribIndex, Normal.sizeof / ForeachType!Normal.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  82. }
  83. if(meshData.mTextureCoords[0] !is null) {// upload texture data
  84. TexCoord[] textureData;
  85. textureData.length = meshData.mNumVertices;
  86. foreach(v; 0..meshData.mNumVertices) {
  87. textureData[v] = [meshData.mTextureCoords[0][v].x, meshData.mTextureCoords[0][v].y];
  88. }
  89. glCheck!glGenBuffers(1, &mesh.vboTexcoords[meshIdx]);
  90. glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboTexcoords[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0);
  91. glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(TexCoord.sizeof * textureData.length) , textureData.ptr, GL_STATIC_DRAW);
  92. GLuint attribIndex = 2;
  93. glEnableVertexAttribArray(attribIndex);
  94. glVertexAttribPointer(attribIndex, TexCoord.sizeof / ForeachType!TexCoord.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  95. }
  96. if(meshData.mColors[0] !is null) {// upload color data
  97. Color[] colorData;
  98. colorData.length = meshData.mNumVertices;
  99. foreach(v; 0..meshData.mNumVertices) {
  100. colorData[v] = [meshData.mColors[0][v].r, meshData.mColors[0][v].g, meshData.mColors[0][v].b, meshData.mColors[0][v].a];
  101. }
  102. glCheck!glGenBuffers(1, &mesh.vboTexcoords[meshIdx]);
  103. glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboTexcoords[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0);
  104. glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Color.sizeof * colorData.length) , colorData.ptr, GL_STATIC_DRAW);
  105. GLuint attribIndex = 3;
  106. glEnableVertexAttribArray(attribIndex);
  107. glVertexAttribPointer(attribIndex, Color.sizeof / ForeachType!Color.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  108. }
  109. {// upload index data
  110. Index[] indexData;
  111. indexData.length = cntIndices;
  112. size_t curIndexDataIdx = 0;
  113. foreach(f; 0..meshData.mNumFaces) {
  114. assert(meshData.mFaces !is null);
  115. foreach(i; 0..meshData.mFaces[f].mNumIndices) {
  116. assert(meshData.mFaces[f].mIndices !is null);
  117. indexData[curIndexDataIdx++] = meshData.mFaces[f].mIndices[i];
  118. }
  119. }
  120. glCheck!glGenBuffers(1, &mesh.vboIndices[meshIdx]);
  121. glCheck!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vboIndices[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  122. glCheck!glBufferData(GL_ELEMENT_ARRAY_BUFFER, cast(ptrdiff_t)(Index.sizeof * indexData.length) , indexData.ptr, GL_STATIC_DRAW);
  123. // GLuint attribIndex = 4;
  124. // glCheck!glEnableVertexAttribArray(attribIndex);
  125. // glCheck!glVertexAttribPointer(attribIndex, Index.sizeof / ForeachType!Index.sizeof, GL_UNSIGNED_INT, GL_FALSE, 0, cast(void*)0);
  126. }
  127. }
  128. }