mesh.d 5.2 KB

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