MeshPrimitiveSample.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. #include "MeshPrimitiveSample.h"
  2. #include "SamplesGame.h"
  3. #if defined(ADD_SAMPLE)
  4. ADD_SAMPLE("Graphics", "Mesh Primitives", MeshPrimitiveSample, 2);
  5. #endif
  6. /**
  7. * Creates a triangle mesh with vertex colors.
  8. */
  9. static Mesh* createTriangleMesh()
  10. {
  11. // Calculate the vertices of the equilateral triangle.
  12. float a = 0.25f; // Length of side
  13. Vector2 p1(0.0f, a / sqrtf(3.0f));
  14. Vector2 p2(-a / 2.0f, -a / (2.0f * sqrtf(3.0f)));
  15. Vector2 p3( a / 2.0f, -a / (2.0f * sqrtf(3.0f)));
  16. // Create 3 vertices. Each vertex has position (x, y, z) and color (red, green, blue)
  17. float vertices[] =
  18. {
  19. p1.x, p1.y, 0.0f, 1.0f, 0.0f, 0.0f,
  20. p2.x, p2.y, 0.0f, 0.0f, 1.0f, 0.0f,
  21. p3.x, p3.y, 0.0f, 0.0f, 0.0f, 1.0f,
  22. };
  23. unsigned int vertexCount = 3;
  24. VertexFormat::Element elements[] =
  25. {
  26. VertexFormat::Element(VertexFormat::POSITION, 3),
  27. VertexFormat::Element(VertexFormat::COLOR, 3)
  28. };
  29. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), vertexCount, false);
  30. if (mesh == NULL)
  31. {
  32. GP_ERROR("Failed to create mesh.");
  33. return NULL;
  34. }
  35. mesh->setPrimitiveType(Mesh::TRIANGLES);
  36. mesh->setVertexData(vertices, 0, vertexCount);
  37. return mesh;
  38. }
  39. static Mesh* createTriangleStripMesh()
  40. {
  41. float scale = 0.02f;
  42. unsigned int vertexCount = 20;
  43. std::vector<float> vertices;
  44. vertices.reserve(vertexCount * 6);
  45. float x = -0.2f;
  46. float y = -0.05f;
  47. float step = fabs(x) * 2.0f / (float)vertexCount;
  48. for (unsigned int i = 0; i < vertexCount; ++i)
  49. {
  50. // x, y, z, r, g, b
  51. vertices.push_back(x);
  52. vertices.push_back(y + MATH_RANDOM_MINUS1_1() * scale);
  53. vertices.push_back(MATH_RANDOM_MINUS1_1() * scale * 2);
  54. vertices.push_back(MATH_RANDOM_0_1());
  55. vertices.push_back(MATH_RANDOM_0_1());
  56. vertices.push_back(MATH_RANDOM_0_1());
  57. x += step;
  58. y *= -1.0f;
  59. }
  60. VertexFormat::Element elements[] =
  61. {
  62. VertexFormat::Element(VertexFormat::POSITION, 3),
  63. VertexFormat::Element(VertexFormat::COLOR, 3)
  64. };
  65. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), vertexCount, false);
  66. if (mesh == NULL)
  67. {
  68. GP_ERROR("Failed to create mesh.");
  69. return NULL;
  70. }
  71. mesh->setPrimitiveType(Mesh::TRIANGLE_STRIP);
  72. //
  73. mesh->setVertexData(&vertices[0], 0, vertexCount);
  74. return mesh;
  75. }
  76. static Mesh* createLineStripMesh()
  77. {
  78. float a = 0.1f;
  79. float vertices[] =
  80. {
  81. 0, 0, 0, 1, 0, 0,
  82. a, 0, -a, 0, 1, 0,
  83. 0, -a, a, 0, 0, 1,
  84. -a, 0, -a, 1, 0, 1,
  85. 0, a, a, 0, 1, 1,
  86. };
  87. unsigned int vertexCount = 5;
  88. VertexFormat::Element elements[] =
  89. {
  90. VertexFormat::Element(VertexFormat::POSITION, 3),
  91. VertexFormat::Element(VertexFormat::COLOR, 3)
  92. };
  93. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), vertexCount, false);
  94. if (mesh == NULL)
  95. {
  96. GP_ERROR("Failed to create mesh.");
  97. return NULL;
  98. }
  99. mesh->setPrimitiveType(Mesh::LINE_STRIP);
  100. mesh->setVertexData(vertices, 0, vertexCount);
  101. return mesh;
  102. }
  103. static Mesh* createLinesMesh()
  104. {
  105. float scale = 0.2f;
  106. unsigned int vertexCount = 40;
  107. std::vector<float> vertices;
  108. vertices.reserve(vertexCount * 6);
  109. for (unsigned int i = 0; i < vertexCount; ++i)
  110. {
  111. // x, y, z, r, g, b
  112. vertices.push_back(MATH_RANDOM_MINUS1_1() * scale);
  113. vertices.push_back(MATH_RANDOM_MINUS1_1() * scale);
  114. vertices.push_back(MATH_RANDOM_MINUS1_1() * scale);
  115. vertices.push_back(MATH_RANDOM_0_1());
  116. vertices.push_back(MATH_RANDOM_0_1());
  117. vertices.push_back(MATH_RANDOM_0_1());
  118. }
  119. VertexFormat::Element elements[] =
  120. {
  121. VertexFormat::Element(VertexFormat::POSITION, 3),
  122. VertexFormat::Element(VertexFormat::COLOR, 3)
  123. };
  124. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), vertexCount, false);
  125. if (mesh == NULL)
  126. {
  127. GP_ERROR("Failed to create mesh.");
  128. return NULL;
  129. }
  130. mesh->setPrimitiveType(Mesh::LINES);
  131. //
  132. mesh->setVertexData(&vertices[0], 0, vertexCount);
  133. return mesh;
  134. }
  135. static Mesh* createPointsMesh()
  136. {
  137. float scale = 0.2f;
  138. unsigned int vertexCount = 100;
  139. std::vector<float> vertices;
  140. vertices.reserve(vertexCount * 6);
  141. for (unsigned int i = 0; i < vertexCount; ++i)
  142. {
  143. // x, y, z, r, g, b
  144. vertices.push_back(MATH_RANDOM_MINUS1_1() * scale);
  145. vertices.push_back(MATH_RANDOM_MINUS1_1() * scale);
  146. vertices.push_back(MATH_RANDOM_MINUS1_1() * scale);
  147. vertices.push_back(MATH_RANDOM_0_1());
  148. vertices.push_back(MATH_RANDOM_0_1());
  149. vertices.push_back(MATH_RANDOM_0_1());
  150. }
  151. VertexFormat::Element elements[] =
  152. {
  153. VertexFormat::Element(VertexFormat::POSITION, 3),
  154. VertexFormat::Element(VertexFormat::COLOR, 3)
  155. };
  156. Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), vertexCount, false);
  157. if (mesh == NULL)
  158. {
  159. GP_ERROR("Failed to create mesh.");
  160. return NULL;
  161. }
  162. mesh->setPrimitiveType(Mesh::POINTS);
  163. mesh->setVertexData(&vertices[0], 0, vertexCount);
  164. return mesh;
  165. }
  166. MeshPrimitiveSample::MeshPrimitiveSample()
  167. : _font(NULL), _triangles(NULL), _triangleStrip(NULL), _lineStrip(NULL), _lines(NULL), _points(NULL)
  168. {
  169. }
  170. void MeshPrimitiveSample::initialize()
  171. {
  172. // Create the font for drawing the framerate.
  173. _font = Font::create("res/common/arial18.gpb");
  174. // Create an orthographic projection matrix.
  175. float width = getWidth() / (float)getHeight();
  176. float height = 1.0f;
  177. Matrix::createOrthographic(width, height, -1.0f, 1.0f, &_viewProjectionMatrix);
  178. // Create a model for the triangle mesh. A model is an instance of a Mesh that can be drawn with a specified material.
  179. Mesh* triangleMesh = createTriangleMesh();
  180. _triangles = Model::create(triangleMesh);
  181. SAFE_RELEASE(triangleMesh);
  182. // Create a material from the built-in "colored-unlit" vertex and fragment shaders.
  183. // This sample doesn't use lighting so the unlit shader is used.
  184. // This sample uses vertex color so VERTEX_COLOR is defined. Look at the shader source files to see the supported defines.
  185. _triangles->setMaterial("res/shaders/colored-unlit.vert", "res/shaders/colored-unlit.frag", "VERTEX_COLOR");
  186. Mesh* triangleStripMesh = createTriangleStripMesh();
  187. _triangleStrip = Model::create(triangleStripMesh);
  188. SAFE_RELEASE(triangleStripMesh);
  189. Material* material = _triangleStrip->setMaterial("res/shaders/colored-unlit.vert", "res/shaders/colored-unlit.frag", "VERTEX_COLOR");
  190. material->getStateBlock()->setDepthTest(true);
  191. material->getStateBlock()->setDepthWrite(true);
  192. Mesh* lineStripMesh = createLineStripMesh();
  193. _lineStrip = Model::create(lineStripMesh);
  194. SAFE_RELEASE(lineStripMesh);
  195. _lineStrip->setMaterial("res/shaders/colored-unlit.vert", "res/shaders/colored-unlit.frag", "VERTEX_COLOR");
  196. Mesh* lineMesh = createLinesMesh();
  197. _lines = Model::create(lineMesh);
  198. SAFE_RELEASE(lineMesh);
  199. _lines->setMaterial("res/shaders/colored-unlit.vert", "res/shaders/colored-unlit.frag", "VERTEX_COLOR");
  200. }
  201. void MeshPrimitiveSample::finalize()
  202. {
  203. // Model and font are reference counted and should be released before closing this sample.
  204. SAFE_RELEASE(_triangles);
  205. SAFE_RELEASE(_triangleStrip);
  206. SAFE_RELEASE(_lineStrip);
  207. SAFE_RELEASE(_lines);
  208. SAFE_RELEASE(_points);
  209. SAFE_RELEASE(_font);
  210. for (std::list<Font::Text*>::iterator it = _text.begin(); it != _text.end(); ++it)
  211. {
  212. SAFE_DELETE(*it);
  213. }
  214. _text.clear();
  215. }
  216. void MeshPrimitiveSample::update(float elapsedTime)
  217. {
  218. if (_touchPoint.x == -1.0f && _touchPoint.y == -1.0f)
  219. {
  220. _tilt.x *= powf(0.99f, elapsedTime);
  221. _tilt.y *= powf(0.99f, elapsedTime);
  222. }
  223. }
  224. void MeshPrimitiveSample::render(float elapsedTime)
  225. {
  226. // Clear the color and depth buffers
  227. clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);
  228. Matrix wvp;
  229. wvp.rotateY(_tilt.x * 0.01f);
  230. wvp.rotateX(_tilt.y * 0.01f);
  231. Matrix::multiply(wvp, _viewProjectionMatrix, &wvp);
  232. Matrix m;
  233. float offset = 0.5f;
  234. // Bind the view projection matrix to the model's paramter. This will transform the vertices when the model is drawn.
  235. m.setIdentity();
  236. m.translate(-offset, offset, 0);
  237. Matrix::multiply(m, wvp, &m);
  238. _triangles->getMaterial()->getParameter("u_worldViewProjectionMatrix")->setValue(m);
  239. _triangles->draw();
  240. m.setIdentity();
  241. m.translate(0, offset, 0);
  242. Matrix::multiply(m, wvp, &m);
  243. _triangleStrip->getMaterial()->getParameter("u_worldViewProjectionMatrix")->setValue(m);
  244. _triangleStrip->draw();
  245. m.setIdentity();
  246. m.translate(-offset, -offset, 0);
  247. Matrix::multiply(m, wvp, &m);
  248. _lineStrip->getMaterial()->getParameter("u_worldViewProjectionMatrix")->setValue(m);
  249. _lineStrip->draw();
  250. m.setIdentity();
  251. m.translate(0, -offset, 0);
  252. Matrix::multiply(m, wvp, &m);
  253. _lines->getMaterial()->getParameter("u_worldViewProjectionMatrix")->setValue(m);
  254. _lines->draw();
  255. drawFrameRate(_font, Vector4(0, 0.5f, 1, 1), 5, 1, getFrameRate());
  256. }
  257. void MeshPrimitiveSample::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  258. {
  259. switch (evt)
  260. {
  261. case Touch::TOUCH_PRESS:
  262. if (x < 75 && y < 50)
  263. {
  264. // Toggle Vsync if the user touches the top left corner
  265. setVsync(!isVsync());
  266. }
  267. else
  268. {
  269. _touchPoint.set(x, y);
  270. }
  271. break;
  272. case Touch::TOUCH_RELEASE:
  273. _touchPoint.set(-1.0f, -1.0f);
  274. break;
  275. case Touch::TOUCH_MOVE:
  276. if (_touchPoint.x > 0.0f && _touchPoint.y > 0.0f)
  277. {
  278. float deltaX = x - _touchPoint.x;
  279. float deltaY = y - _touchPoint.y;
  280. _tilt.x -= deltaX;
  281. _tilt.y += deltaY;
  282. _touchPoint.set(x, y);
  283. }
  284. break;
  285. };
  286. }