mesh.d 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. {// upload vertex data
  44. Vertex[] vertexData;
  45. vertexData.length = meshData.mNumVertices;
  46. foreach(v; 0..meshData.mNumVertices) {
  47. vertexData[v] = [meshData.mVertices[v].x, meshData.mVertices[v].y, meshData.mVertices[v].z];
  48. }
  49. glCheck!glGenBuffers(1, &mesh.vboVertices[meshIdx]);
  50. glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboVertices[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0);
  51. GLuint attribIndex = 0;
  52. glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Vertex.sizeof * vertexData.length) , vertexData.ptr, GL_STATIC_DRAW);
  53. glCheck!glEnableVertexAttribArray(attribIndex);
  54. glCheck!glVertexAttribPointer(attribIndex, Vertex.sizeof / ForeachType!Vertex.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  55. }
  56. {// upload normal data
  57. Normal[] normalData;
  58. normalData.length = meshData.mNumVertices;
  59. foreach(v; 0..meshData.mNumVertices) {
  60. normalData[v] = [meshData.mNormals[v].x, meshData.mNormals[v].y, meshData.mNormals[v].z];
  61. }
  62. glCheck!glGenBuffers(1, &mesh.vboNormals[meshIdx]);
  63. glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboNormals[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0);
  64. GLuint attribIndex = 1;
  65. glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Normal.sizeof * normalData.length) , normalData.ptr, GL_STATIC_DRAW);
  66. glCheck!glEnableVertexAttribArray(attribIndex);
  67. glCheck!glVertexAttribPointer(attribIndex, Normal.sizeof / ForeachType!Normal.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  68. }
  69. if(meshData.mTextureCoords[0] !is null) {// upload texture data
  70. TexCoord[] textureData;
  71. textureData.length = meshData.mNumVertices;
  72. foreach(v; 0..meshData.mNumVertices) {
  73. textureData[v] = [meshData.mTextureCoords[0][v].x, meshData.mTextureCoords[0][v].y];
  74. }
  75. glCheck!glGenBuffers(1, &mesh.vboTexcoords[meshIdx]);
  76. glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboTexcoords[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0);
  77. GLuint attribIndex = 2;
  78. glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(TexCoord.sizeof * textureData.length) , textureData.ptr, GL_STATIC_DRAW);
  79. glEnableVertexAttribArray(attribIndex);
  80. glVertexAttribPointer(attribIndex, TexCoord.sizeof / ForeachType!TexCoord.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  81. }
  82. if(meshData.mColors[0] !is null) {// upload color data
  83. Color[] colorData;
  84. colorData.length = meshData.mNumVertices;
  85. foreach(v; 0..meshData.mNumVertices) {
  86. colorData[v] = [meshData.mColors[0][v].r, meshData.mColors[0][v].g, meshData.mColors[0][v].b, meshData.mColors[0][v].a];
  87. }
  88. glCheck!glGenBuffers(1, &mesh.vboTexcoords[meshIdx]);
  89. glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboTexcoords[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0);
  90. GLuint attribIndex = 2;
  91. glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Color.sizeof * colorData.length) , colorData.ptr, GL_STATIC_DRAW);
  92. glEnableVertexAttribArray(attribIndex);
  93. glVertexAttribPointer(attribIndex, Color.sizeof / ForeachType!Color.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
  94. }
  95. {// upload index data
  96. Index[] indexData;
  97. indexData.length = cntIndices;
  98. size_t curIndexDataIdx = 0;
  99. foreach(f; 0..meshData.mNumFaces) {
  100. assert(meshData.mFaces !is null);
  101. foreach(i; 0..meshData.mFaces[f].mNumIndices) {
  102. assert(meshData.mFaces[f].mIndices !is null);
  103. indexData[curIndexDataIdx++] = meshData.mFaces[f].mIndices[i];
  104. }
  105. }
  106. glCheck!glGenBuffers(1, &mesh.vboIndices[meshIdx]);
  107. glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboIndices[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0);
  108. GLuint attribIndex = 3;
  109. glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Index.sizeof * indexData.length) , indexData.ptr, GL_STATIC_DRAW);
  110. glCheck!glEnableVertexAttribArray(attribIndex);
  111. glCheck!glVertexAttribPointer(attribIndex, Index.sizeof / ForeachType!Index.sizeof, GL_UNSIGNED_INT, GL_FALSE, 0, cast(void*)0);
  112. }
  113. }
  114. }