Mesh.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "anki/resource/Mesh.h"
  2. #include "anki/resource/Material.h"
  3. #include "anki/resource/MeshLoader.h"
  4. #include "anki/gl/Vbo.h"
  5. #include "anki/util/Functions.h"
  6. namespace anki {
  7. //==============================================================================
  8. void Mesh::load(const char* filename)
  9. {
  10. MeshLoader loader(filename);
  11. // Set the non-VBO members
  12. vertsCount = loader.getPositions().size();
  13. ANKI_ASSERT(vertsCount > 0);
  14. indicesCount.push_back(loader.getLodsCount());
  15. for(U lod = 0; lod < indicesCount.size(); lod++)
  16. {
  17. indicesCount[lod] = loader.getIndices(lod).size();
  18. ANKI_ASSERT(indicesCount[lod] > 0);
  19. ANKI_ASSERT(indicesCount[lod] % 3 == 0 && "Expecting triangles");
  20. }
  21. weights = loader.getWeights().size() > 1;
  22. texChannelsCount = loader.getTextureChannelsCount();
  23. try
  24. {
  25. createVbos(loader);
  26. visibilityShape.set(loader.getPositions());
  27. }
  28. catch(std::exception& e)
  29. {
  30. throw ANKI_EXCEPTION("Mesh loading failed: " + filename) << e;
  31. }
  32. }
  33. //==============================================================================
  34. U32 Mesh::calcVertexSize() const
  35. {
  36. U32 a = sizeof(Vec3) + sizeof(Vec3) + sizeof(Vec4)
  37. + texChannelsCount * sizeof(Vec2);
  38. if(weights)
  39. {
  40. a += sizeof(MeshLoader::VertexWeight);
  41. }
  42. return a;
  43. }
  44. //==============================================================================
  45. void Mesh::createVbos(const MeshLoader& loader)
  46. {
  47. // Calculate VBO size
  48. U32 vertexsize = calcVertexSize();
  49. U32 vbosize = vertexsize * vertsCount;
  50. // Create a temp buffer and populate it
  51. Vector<U8> buff(vbosize, 0);
  52. U8* ptr = &buff[0];
  53. for(U i = 0; i < vertsCount; i++)
  54. {
  55. ANKI_ASSERT(ptr + vertexsize <= &buff[0] + vbosize);
  56. memcpy(ptr, &loader.getPositions()[i], sizeof(Vec3));
  57. ptr += sizeof(Vec3);
  58. memcpy(ptr, &loader.getNormals()[i], sizeof(Vec3));
  59. ptr += sizeof(Vec3);
  60. memcpy(ptr, &loader.getTangents()[i], sizeof(Vec4));
  61. ptr += sizeof(Vec4);
  62. for(U j = 0; j < texChannelsCount; j++)
  63. {
  64. memcpy(ptr, &loader.getTexureCoordinates(j)[i], sizeof(Vec2));
  65. ptr += sizeof(Vec2);
  66. }
  67. if(weights)
  68. {
  69. memcpy(ptr, &loader.getWeights()[i],
  70. sizeof(MeshLoader::VertexWeight));
  71. ptr += sizeof(MeshLoader::VertexWeight);
  72. }
  73. }
  74. // Create VBO
  75. vbo.create(
  76. GL_ARRAY_BUFFER,
  77. vbosize,
  78. &buff[0],
  79. GL_STATIC_DRAW);
  80. /// Create the indices VBOs
  81. indicesVbos.resize(loader.getLodsCount());
  82. U lod = 0;
  83. for(Vbo& v : indicesVbos)
  84. {
  85. v.create(
  86. GL_ELEMENT_ARRAY_BUFFER,
  87. getVectorSizeInBytes(loader.getIndices(lod)),
  88. &loader.getIndices(lod)[0],
  89. GL_STATIC_DRAW);
  90. ++lod;
  91. }
  92. }
  93. //==============================================================================
  94. void Mesh::getVboInfo(
  95. const VertexAttribute attrib, const U32 lod, const Vbo*& v, U32& size,
  96. GLenum& type, U32& stride, U32& offset) const
  97. {
  98. stride = calcVertexSize();
  99. // Set all to zero
  100. v = nullptr;
  101. size = 0;
  102. type = GL_NONE;
  103. offset = 0;
  104. switch(attrib)
  105. {
  106. case VA_POSITION:
  107. v = &vbo;
  108. size = 3;
  109. type = GL_FLOAT;
  110. offset = 0;
  111. break;
  112. case VA_NORMAL:
  113. v = &vbo;
  114. size = 3;
  115. type = GL_FLOAT;
  116. offset = sizeof(Vec3);
  117. break;
  118. case VA_TANGENT:
  119. v = &vbo;
  120. size = 4;
  121. type = GL_FLOAT;
  122. offset = sizeof(Vec3) * 2;
  123. break;
  124. case VA_TEXTURE_COORDS:
  125. if(texChannelsCount > 0)
  126. {
  127. v = &vbo;
  128. size = 2;
  129. type = GL_FLOAT;
  130. offset = sizeof(Vec3) * 2 + sizeof(Vec4);
  131. }
  132. break;
  133. case VA_TEXTURE_COORDS_1:
  134. if(texChannelsCount > 1)
  135. {
  136. v = &vbo;
  137. size = 2;
  138. type = GL_FLOAT;
  139. offset = sizeof(Vec3) * 2 + sizeof(Vec4) + sizeof(Vec2);
  140. }
  141. break;
  142. case VA_BONE_COUNT:
  143. if(weights)
  144. {
  145. v = &vbo;
  146. size = 1;
  147. type = GL_UNSIGNED_INT;
  148. offset = sizeof(Vec3) * 2 + sizeof(Vec4)
  149. + texChannelsCount * sizeof(Vec2);
  150. }
  151. break;
  152. case VA_BONE_IDS:
  153. if(weights)
  154. {
  155. v = &vbo;
  156. size = 4;
  157. type = GL_UNSIGNED_INT;
  158. offset = sizeof(Vec3) * 2 + sizeof(Vec4)
  159. + texChannelsCount * sizeof(Vec2) + sizeof(U32);
  160. }
  161. break;
  162. case VA_BONE_WEIGHTS:
  163. if(weights)
  164. {
  165. v = &vbo;
  166. size = 4;
  167. type = GL_FLOAT;
  168. offset = sizeof(Vec3) * 2 + sizeof(Vec4)
  169. + texChannelsCount * sizeof(Vec2) + sizeof(U32)
  170. + sizeof(U32) * 4;
  171. }
  172. case VA_INDICES:
  173. if(lod < indicesVbos.size())
  174. {
  175. v = &indicesVbos[lod];
  176. }
  177. break;
  178. default:
  179. ANKI_ASSERT(0);
  180. break;
  181. }
  182. }
  183. } // end namespace anki