Mesh.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. #include "Base.h"
  2. #include "Mesh.h"
  3. #include "MeshPart.h"
  4. #include "Effect.h"
  5. #include "Model.h"
  6. #include "Material.h"
  7. namespace gameplay
  8. {
  9. Mesh::Mesh(const VertexFormat& vertexFormat)
  10. : _vertexFormat(vertexFormat), _vertexCount(0), _vertexBuffer(0), _primitiveType(TRIANGLES),
  11. _partCount(0), _parts(NULL), _dynamic(false)
  12. {
  13. }
  14. Mesh::~Mesh()
  15. {
  16. if (_parts)
  17. {
  18. for (unsigned int i = 0; i < _partCount; ++i)
  19. {
  20. SAFE_DELETE(_parts[i]);
  21. }
  22. SAFE_DELETE_ARRAY(_parts);
  23. }
  24. if (_vertexBuffer)
  25. {
  26. glDeleteBuffers(1, &_vertexBuffer);
  27. _vertexBuffer = 0;
  28. }
  29. }
  30. Mesh* Mesh::createMesh(const VertexFormat& vertexFormat, unsigned int vertexCount, bool dynamic)
  31. {
  32. GLuint vbo;
  33. GL_ASSERT( glGenBuffers(1, &vbo) );
  34. if (GL_LAST_ERROR())
  35. {
  36. GP_ERROR("Failed to create VBO for mesh with OpenGL error %d.", GL_LAST_ERROR());
  37. return NULL;
  38. }
  39. GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, vbo) );
  40. if (GL_LAST_ERROR())
  41. {
  42. GP_ERROR("Failed to bind VBO for mesh with OpenGL error %d.", GL_LAST_ERROR());
  43. glDeleteBuffers(1, &vbo);
  44. return NULL;
  45. }
  46. GL_CHECK( glBufferData(GL_ARRAY_BUFFER, vertexFormat.getVertexSize() * vertexCount, NULL, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW) );
  47. if (GL_LAST_ERROR())
  48. {
  49. GP_ERROR("Failed to load VBO with vertex data with OpenGL error %d.", GL_LAST_ERROR());
  50. glBindBuffer(GL_ARRAY_BUFFER, 0);
  51. glDeleteBuffers(1, &vbo);
  52. return NULL;
  53. }
  54. Mesh* mesh = new Mesh(vertexFormat);
  55. mesh->_vertexCount = vertexCount;
  56. mesh->_vertexBuffer = vbo;
  57. mesh->_dynamic = dynamic;
  58. return mesh;
  59. }
  60. Mesh* Mesh::createQuad(float x, float y, float width, float height, float s1, float t1, float s2, float t2)
  61. {
  62. float x2 = x + width;
  63. float y2 = y + height;
  64. float vertices[] =
  65. {
  66. x, y2, 0, 0, 0, 1, s1, t2,
  67. x, y, 0, 0, 0, 1, s1, t1,
  68. x2, y2, 0, 0, 0, 1, s2, t2,
  69. x2, y, 0, 0, 0, 1, s2, t1,
  70. };
  71. VertexFormat::Element elements[] =
  72. {
  73. VertexFormat::Element(VertexFormat::POSITION, 3),
  74. VertexFormat::Element(VertexFormat::NORMAL, 3),
  75. VertexFormat::Element(VertexFormat::TEXCOORD0, 2)
  76. };
  77. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 3), 4, false);
  78. if (mesh == NULL)
  79. {
  80. GP_ERROR("Failed to create mesh.");
  81. return NULL;
  82. }
  83. mesh->_primitiveType = TRIANGLE_STRIP;
  84. mesh->setVertexData(vertices, 0, 4);
  85. return mesh;
  86. }
  87. Mesh* Mesh::createQuadFullscreen()
  88. {
  89. float x = -1.0f;
  90. float y = -1.0f;
  91. float x2 = 1.0f;
  92. float y2 = 1.0f;
  93. float vertices[] =
  94. {
  95. x, y2, 0, 1,
  96. x, y, 0, 0,
  97. x2, y2, 1, 1,
  98. x2, y, 1, 0
  99. };
  100. VertexFormat::Element elements[] =
  101. {
  102. VertexFormat::Element(VertexFormat::POSITION, 2),
  103. VertexFormat::Element(VertexFormat::TEXCOORD0, 2)
  104. };
  105. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), 4, false);
  106. if (mesh == NULL)
  107. {
  108. GP_ERROR("Failed to create mesh.");
  109. return NULL;
  110. }
  111. mesh->_primitiveType = TRIANGLE_STRIP;
  112. mesh->setVertexData(vertices, 0, 4);
  113. return mesh;
  114. }
  115. Mesh* Mesh::createQuad(const Vector3& p1, const Vector3& p2, const Vector3& p3, const Vector3& p4)
  116. {
  117. // Calculate the normal vector of the plane.
  118. Vector3 v1, v2, n;
  119. Vector3::subtract(p2, p1, &v1);
  120. Vector3::subtract(p3, p2, &v2);
  121. Vector3::cross(v1, v2, &n);
  122. n.normalize();
  123. float vertices[] =
  124. {
  125. p1.x, p1.y, p1.z, n.x, n.y, n.z, 0, 1,
  126. p2.x, p2.y, p2.z, n.x, n.y, n.z, 0, 0,
  127. p3.x, p3.y, p3.z, n.x, n.y, n.z, 1, 1,
  128. p4.x, p4.y, p4.z, n.x, n.y, n.z, 1, 0
  129. };
  130. VertexFormat::Element elements[] =
  131. {
  132. VertexFormat::Element(VertexFormat::POSITION, 3),
  133. VertexFormat::Element(VertexFormat::NORMAL, 3),
  134. VertexFormat::Element(VertexFormat::TEXCOORD0, 2)
  135. };
  136. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 3), 4, false);
  137. if (mesh == NULL)
  138. {
  139. GP_ERROR("Failed to create mesh.");
  140. return NULL;
  141. }
  142. mesh->_primitiveType = TRIANGLE_STRIP;
  143. mesh->setVertexData(vertices, 0, 4);
  144. return mesh;
  145. }
  146. Mesh* Mesh::createLines(Vector3* points, unsigned int pointCount)
  147. {
  148. GP_ASSERT(points);
  149. GP_ASSERT(pointCount);
  150. float* vertices = new float[pointCount*3];
  151. memcpy(vertices, points, pointCount*3*sizeof(float));
  152. VertexFormat::Element elements[] =
  153. {
  154. VertexFormat::Element(VertexFormat::POSITION, 3)
  155. };
  156. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 1), pointCount, false);
  157. if (mesh == NULL)
  158. {
  159. GP_ERROR("Failed to create mesh.");
  160. SAFE_DELETE_ARRAY(vertices);
  161. return NULL;
  162. }
  163. mesh->_primitiveType = LINE_STRIP;
  164. mesh->setVertexData(vertices, 0, pointCount);
  165. SAFE_DELETE_ARRAY(vertices);
  166. return mesh;
  167. }
  168. Mesh* Mesh::createBoundingBox(const BoundingBox& box)
  169. {
  170. Vector3 corners[8];
  171. box.getCorners(corners);
  172. float vertices[] =
  173. {
  174. corners[7].x, corners[7].y, corners[7].z,
  175. corners[6].x, corners[6].y, corners[6].z,
  176. corners[1].x, corners[1].y, corners[1].z,
  177. corners[0].x, corners[0].y, corners[0].z,
  178. corners[7].x, corners[7].y, corners[7].z,
  179. corners[4].x, corners[4].y, corners[4].z,
  180. corners[3].x, corners[3].y, corners[3].z,
  181. corners[0].x, corners[0].y, corners[0].z,
  182. corners[0].x, corners[0].y, corners[0].z,
  183. corners[1].x, corners[1].y, corners[1].z,
  184. corners[2].x, corners[2].y, corners[2].z,
  185. corners[3].x, corners[3].y, corners[3].z,
  186. corners[4].x, corners[4].y, corners[4].z,
  187. corners[5].x, corners[5].y, corners[5].z,
  188. corners[2].x, corners[2].y, corners[2].z,
  189. corners[1].x, corners[1].y, corners[1].z,
  190. corners[6].x, corners[6].y, corners[6].z,
  191. corners[5].x, corners[5].y, corners[5].z
  192. };
  193. VertexFormat::Element elements[] =
  194. {
  195. VertexFormat::Element(VertexFormat::POSITION, 3)
  196. };
  197. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 1), 18, false);
  198. if (mesh == NULL)
  199. {
  200. GP_ERROR("Failed to create mesh.");
  201. return NULL;
  202. }
  203. mesh->_primitiveType = LINE_STRIP;
  204. mesh->setVertexData(vertices, 0, 18);
  205. return mesh;
  206. }
  207. const char* Mesh::getUrl() const
  208. {
  209. return _url.c_str();
  210. }
  211. const VertexFormat& Mesh::getVertexFormat() const
  212. {
  213. return _vertexFormat;
  214. }
  215. unsigned int Mesh::getVertexCount() const
  216. {
  217. return _vertexCount;
  218. }
  219. unsigned int Mesh::getVertexSize() const
  220. {
  221. return _vertexFormat.getVertexSize();
  222. }
  223. VertexBufferHandle Mesh::getVertexBuffer() const
  224. {
  225. return _vertexBuffer;
  226. }
  227. bool Mesh::isDynamic() const
  228. {
  229. return _dynamic;
  230. }
  231. Mesh::PrimitiveType Mesh::getPrimitiveType() const
  232. {
  233. return _primitiveType;
  234. }
  235. void Mesh::setPrimitiveType(PrimitiveType type)
  236. {
  237. _primitiveType = type;
  238. }
  239. void Mesh::setVertexData(const float* vertexData, unsigned int vertexStart, unsigned int vertexCount)
  240. {
  241. GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer) );
  242. if (vertexStart == 0 && vertexCount == 0)
  243. {
  244. GL_ASSERT( glBufferData(GL_ARRAY_BUFFER, _vertexFormat.getVertexSize() * _vertexCount, vertexData, _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW) );
  245. }
  246. else
  247. {
  248. if (vertexCount == 0)
  249. {
  250. vertexCount = _vertexCount - vertexStart;
  251. }
  252. GL_ASSERT( glBufferSubData(GL_ARRAY_BUFFER, vertexStart * _vertexFormat.getVertexSize(), vertexCount * _vertexFormat.getVertexSize(), vertexData) );
  253. }
  254. }
  255. MeshPart* Mesh::addPart(PrimitiveType primitiveType, IndexFormat indexFormat, unsigned int indexCount, bool dynamic)
  256. {
  257. MeshPart* part = MeshPart::create(this, _partCount, primitiveType, indexFormat, indexCount, dynamic);
  258. if (part)
  259. {
  260. // Increase size of part array and copy old subets into it.
  261. MeshPart** oldParts = _parts;
  262. _parts = new MeshPart*[_partCount + 1];
  263. for (unsigned int i = 0; i < _partCount; ++i)
  264. {
  265. _parts[i] = oldParts[i];
  266. }
  267. // Add new part to array.
  268. _parts[_partCount++] = part;
  269. // Delete old part array.
  270. SAFE_DELETE_ARRAY(oldParts);
  271. }
  272. return part;
  273. }
  274. unsigned int Mesh::getPartCount() const
  275. {
  276. return _partCount;
  277. }
  278. MeshPart* Mesh::getPart(unsigned int index)
  279. {
  280. GP_ASSERT(_parts);
  281. return _parts[index];
  282. }
  283. const BoundingBox& Mesh::getBoundingBox() const
  284. {
  285. return _boundingBox;
  286. }
  287. void Mesh::setBoundingBox(const BoundingBox& box)
  288. {
  289. _boundingBox = box;
  290. }
  291. const BoundingSphere& Mesh::getBoundingSphere() const
  292. {
  293. return _boundingSphere;
  294. }
  295. void Mesh::setBoundingSphere(const BoundingSphere& sphere)
  296. {
  297. _boundingSphere = sphere;
  298. }
  299. }