Mesh.cpp 8.7 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()
  10. : _vertexFormat(NULL), _vertexCount(0), _vertexBuffer(0), _primitiveType(TRIANGLES),
  11. _partCount(0), _parts(NULL), _dynamic(false)
  12. {
  13. }
  14. Mesh::Mesh(const Mesh& copy)
  15. {
  16. // hidden
  17. }
  18. Mesh::~Mesh()
  19. {
  20. for (unsigned int i = 0; i < _partCount; ++i)
  21. {
  22. SAFE_DELETE(_parts[i]);
  23. }
  24. SAFE_DELETE_ARRAY(_parts);
  25. if (_vertexBuffer)
  26. {
  27. glDeleteBuffers(1, &_vertexBuffer);
  28. _vertexBuffer = 0;
  29. }
  30. SAFE_RELEASE(_vertexFormat);
  31. }
  32. Mesh* Mesh::createMesh(VertexFormat* vertexFormat, unsigned int vertexCount, bool dynamic)
  33. {
  34. GLuint vbo;
  35. GL_ASSERT( glGenBuffers(1, &vbo) );
  36. if (GL_LAST_ERROR())
  37. {
  38. return NULL;
  39. }
  40. GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, vbo) );
  41. if (GL_LAST_ERROR())
  42. {
  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. glBindBuffer(GL_ARRAY_BUFFER, 0);
  50. glDeleteBuffers(1, &vbo);
  51. return NULL;
  52. }
  53. Mesh* mesh = new Mesh();
  54. mesh->_vertexFormat = vertexFormat;
  55. mesh->_vertexCount = vertexCount;
  56. mesh->_vertexBuffer = vbo;
  57. mesh->_dynamic = dynamic;
  58. vertexFormat->addRef();
  59. return mesh;
  60. }
  61. Mesh* Mesh::createQuad(float x, float y, float width, float height)
  62. {
  63. float x2 = x + width;
  64. float y2 = y + height;
  65. float vertices[] =
  66. {
  67. x, y2, 0, 0, 0, 1, 0, 0,
  68. x, y, 0, 0, 0, 1, 0, 1,
  69. x2, y2, 0, 0, 0, 1, 1, 0,
  70. x2, y, 0, 0, 0, 1, 1, 1
  71. };
  72. VertexFormat::Element elements[] =
  73. {
  74. VertexFormat::Element(VertexFormat::POSITION, 3),
  75. VertexFormat::Element(VertexFormat::NORMAL, 3),
  76. VertexFormat::Element(VertexFormat::TEXCOORD0, 2)
  77. };
  78. VertexFormat* format = VertexFormat::create(elements, 3);
  79. Mesh* mesh = Mesh::createMesh(format, 4, false);
  80. SAFE_RELEASE(format);
  81. if (mesh == NULL)
  82. {
  83. return NULL;
  84. }
  85. mesh->_primitiveType = TRIANGLE_STRIP;
  86. mesh->setVertexData(vertices, 0, 4);
  87. return mesh;
  88. }
  89. Mesh* Mesh::createQuadFullscreen()
  90. {
  91. float x = -1.0f;
  92. float y = -1.0f;
  93. float x2 = 1.0f;
  94. float y2 = 1.0f;
  95. float vertices[] =
  96. {
  97. x, y2, 0, 0,
  98. x, y, 0, 1,
  99. x2, y2, 1, 0,
  100. x2, y, 1, 1
  101. };
  102. VertexFormat::Element elements[] =
  103. {
  104. VertexFormat::Element(VertexFormat::POSITION, 2),
  105. VertexFormat::Element(VertexFormat::TEXCOORD0, 2)
  106. };
  107. VertexFormat* format = VertexFormat::create(elements, 2);
  108. Mesh* mesh = Mesh::createMesh(format, 4, false);
  109. SAFE_RELEASE(format);
  110. if (mesh == NULL)
  111. {
  112. return NULL;
  113. }
  114. mesh->_primitiveType = TRIANGLE_STRIP;
  115. mesh->setVertexData(vertices, 0, 4);
  116. return mesh;
  117. }
  118. Mesh* Mesh::createQuad(const Vector3& p1, const Vector3& p2, const Vector3& p3, const Vector3& p4)
  119. {
  120. // Calculate the normal vector of the plane.
  121. Vector3 v1, v2, n;
  122. Vector3::subtract(p2, p1, &v1);
  123. Vector3::subtract(p3, p2, &v2);
  124. Vector3::cross(v1, v2, &n);
  125. n.normalize();
  126. float vertices[] =
  127. {
  128. p1.x, p1.y, p1.z, n.x, n.y, n.z, 0, 1,
  129. p2.x, p2.y, p2.z, n.x, n.y, n.z, 0, 0,
  130. p3.x, p3.y, p3.z, n.x, n.y, n.z, 1, 1,
  131. p4.x, p4.y, p4.z, n.x, n.y, n.z, 1, 0
  132. };
  133. VertexFormat::Element elements[] =
  134. {
  135. VertexFormat::Element(VertexFormat::POSITION, 3),
  136. VertexFormat::Element(VertexFormat::NORMAL, 3),
  137. VertexFormat::Element(VertexFormat::TEXCOORD0, 2)
  138. };
  139. VertexFormat* format = VertexFormat::create(elements, 3);
  140. Mesh* mesh = Mesh::createMesh(format, 4, false);
  141. SAFE_RELEASE(format);
  142. if (mesh == NULL)
  143. {
  144. return NULL;
  145. }
  146. mesh->_primitiveType = TRIANGLE_STRIP;
  147. mesh->setVertexData(vertices, 0, 4);
  148. return mesh;
  149. }
  150. Mesh* Mesh::createLines(Vector3* points, unsigned int pointCount)
  151. {
  152. float* vertices = new float[pointCount*3];
  153. memcpy(vertices, points, pointCount*3*sizeof(float));
  154. VertexFormat::Element elements[] =
  155. {
  156. VertexFormat::Element(VertexFormat::POSITION, 3)
  157. };
  158. VertexFormat* format = VertexFormat::create(elements, 1);
  159. Mesh* mesh = Mesh::createMesh(format, pointCount, false);
  160. SAFE_RELEASE(format);
  161. if (mesh == NULL)
  162. {
  163. SAFE_DELETE_ARRAY(vertices);
  164. return NULL;
  165. }
  166. mesh->_primitiveType = LINE_STRIP;
  167. mesh->setVertexData(vertices, 0, pointCount);
  168. SAFE_DELETE_ARRAY(vertices);
  169. return mesh;
  170. }
  171. Mesh* Mesh::createBoundingBox(const BoundingBox& box)
  172. {
  173. Vector3 corners[8];
  174. box.getCorners(corners);
  175. float vertices[] =
  176. {
  177. corners[7].x, corners[7].y, corners[7].z,
  178. corners[6].x, corners[6].y, corners[6].z,
  179. corners[1].x, corners[1].y, corners[1].z,
  180. corners[0].x, corners[0].y, corners[0].z,
  181. corners[7].x, corners[7].y, corners[7].z,
  182. corners[4].x, corners[4].y, corners[4].z,
  183. corners[3].x, corners[3].y, corners[3].z,
  184. corners[0].x, corners[0].y, corners[0].z,
  185. corners[0].x, corners[0].y, corners[0].z,
  186. corners[1].x, corners[1].y, corners[1].z,
  187. corners[2].x, corners[2].y, corners[2].z,
  188. corners[3].x, corners[3].y, corners[3].z,
  189. corners[4].x, corners[4].y, corners[4].z,
  190. corners[5].x, corners[5].y, corners[5].z,
  191. corners[2].x, corners[2].y, corners[2].z,
  192. corners[1].x, corners[1].y, corners[1].z,
  193. corners[6].x, corners[6].y, corners[6].z,
  194. corners[5].x, corners[5].y, corners[5].z
  195. };
  196. VertexFormat::Element elements[] =
  197. {
  198. VertexFormat::Element(VertexFormat::POSITION, 3)
  199. };
  200. VertexFormat* format = VertexFormat::create(elements, 1);
  201. Mesh* mesh = Mesh::createMesh(format, 18, false);
  202. SAFE_RELEASE(format);
  203. if (mesh == NULL)
  204. {
  205. return NULL;
  206. }
  207. mesh->_primitiveType = LINE_STRIP;
  208. mesh->setVertexData(vertices, 0, 18);
  209. return mesh;
  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. VertexBuffer 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(void* 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. return _parts[index];
  281. }
  282. const BoundingBox& Mesh::getBoundingBox() const
  283. {
  284. return _boundingBox;
  285. }
  286. void Mesh::setBoundingBox(const BoundingBox& box)
  287. {
  288. _boundingBox = box;
  289. }
  290. const BoundingSphere& Mesh::getBoundingSphere() const
  291. {
  292. return _boundingSphere;
  293. }
  294. void Mesh::setBoundingSphere(const BoundingSphere& sphere)
  295. {
  296. _boundingSphere = sphere;
  297. }
  298. }