Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Mesh.cpp 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*!
  2. * \file src/Mesh.cpp
  3. * \brief OpenGL Mesh
  4. *
  5. * \author xythobuz
  6. */
  7. #include "global.h"
  8. #include "TextureManager.h"
  9. #include "system/Window.h"
  10. #include "Mesh.h"
  11. Mesh::Mesh(const std::vector<glm::vec3>& vert,
  12. const std::vector<IndexedRectangle>& rect,
  13. const std::vector<IndexedRectangle>& tri,
  14. const std::vector<IndexedColoredRectangle>& coloredRect,
  15. const std::vector<IndexedColoredRectangle>& coloredTri) {
  16. for (auto& t : rect) {
  17. indices.push_back(0);
  18. vertices.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
  19. vertices.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
  20. vertices.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
  21. vertices.push_back(glm::vec3(vert.at(t.v4).x, vert.at(t.v4).y, vert.at(t.v4).z));
  22. textures.push_back(t.texture);
  23. }
  24. for (auto& t : tri) {
  25. indices.push_back(1);
  26. vertices.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
  27. vertices.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
  28. vertices.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
  29. textures.push_back(t.texture);
  30. }
  31. for (auto& t : coloredRect) {
  32. indicesColor.push_back(0);
  33. verticesColor.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
  34. verticesColor.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
  35. verticesColor.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
  36. verticesColor.push_back(glm::vec3(vert.at(t.v4).x, vert.at(t.v4).y, vert.at(t.v4).z));
  37. colors.push_back(glm::vec3(t.r, t.g, t.b));
  38. }
  39. for (auto& t : coloredTri) {
  40. indicesColor.push_back(1);
  41. verticesColor.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
  42. verticesColor.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
  43. verticesColor.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
  44. colors.push_back(glm::vec3(t.r, t.g, t.b));
  45. }
  46. }
  47. void Mesh::prepare() {
  48. std::vector<unsigned short> ind;
  49. std::vector<glm::vec3> vert;
  50. std::vector<unsigned int> tex;
  51. std::map<PackedVertex, unsigned short> vertexMap;
  52. int vertIndex = 0;
  53. for (int i = 0; i < indices.size(); i++) {
  54. unsigned int texture = getTextureManager().getTile(textures.at(i)).getTexture();
  55. for (int v = 0; v < ((indices.at(i) == 0) ? 4 : 3); v++) {
  56. glm::vec2 uv = getTextureManager().getTile(textures.at(i)).getUV(v);
  57. PackedVertex p(vertices.at(vertIndex + v), uv, texture);
  58. unsigned short s;
  59. if (findSimilarVertex(p, vertexMap, s)) {
  60. ind.push_back(s); // Vertex already cached
  61. } else {
  62. vertexMap[p] = vert.size();
  63. ind.push_back(vert.size());
  64. vert.push_back(p.pos);
  65. uvs.push_back(p.uv);
  66. tex.push_back(p.tex);
  67. }
  68. }
  69. if (indices.at(i) == 0) {
  70. ind.push_back(ind.at(ind.size() - 2));
  71. ind.push_back(ind.at(ind.size() - 5));
  72. }
  73. vertIndex += (indices.at(i) == 0) ? 4 : 3;
  74. }
  75. assert((ind.size() % 3) == 0);
  76. assert(vert.size() == tex.size());
  77. assert(vert.size() == uvs.size());
  78. indices = std::move(ind);
  79. vertices = std::move(vert);
  80. textures = std::move(tex);
  81. std::vector<unsigned short> indC;
  82. std::vector<glm::vec3> vertC;
  83. std::vector<glm::vec3> col;
  84. std::map<PackedColoredVertex, unsigned short> vertexMapC;
  85. vertIndex = 0;
  86. for (int i = 0; i < indicesColor.size(); i++) {
  87. for (int v = 0; v < ((indicesColor.at(i) == 0) ? 4 : 3); v++) {
  88. PackedColoredVertex p(verticesColor.at(vertIndex + v), colors.at(i));
  89. unsigned short s;
  90. if (findSimilarVertex(p, vertexMapC, s)) {
  91. indC.push_back(s); // Vertex already cached
  92. } else {
  93. vertexMapC[p] = vertC.size();
  94. indC.push_back(vertC.size());
  95. vertC.push_back(p.pos);
  96. col.push_back(p.col);
  97. }
  98. }
  99. if (indicesColor.at(i) == 0) {
  100. indC.push_back(indC.at(indC.size() - 2));
  101. indC.push_back(indC.at(indC.size() - 5));
  102. }
  103. vertIndex += (indicesColor.at(i) == 0) ? 4 : 3;
  104. }
  105. assert((indC.size() % 3) == 0);
  106. assert(vertC.size() == col.size());
  107. indicesColor = std::move(indC);
  108. verticesColor = std::move(vertC);
  109. colors = std::move(col);
  110. }
  111. void Mesh::display(glm::mat4 MVP) {
  112. if (indices.size() > 0) {
  113. unsigned int indexStart = 0;
  114. unsigned int indexPos = 1;
  115. unsigned int texture = textures.at(indices.at(0));
  116. while ((indexStart != indexPos) && (indexPos < indices.size())) {
  117. while ((indexPos < indices.size()) && (textures.at(indices.at(indexPos)) == texture))
  118. indexPos++;
  119. std::vector<unsigned short> ind(indices.begin() + indexStart, indices.begin() + indexPos);
  120. Window::drawGL(vertices, uvs, ind, MVP, texture);
  121. if (indexPos < indices.size()) {
  122. indexStart = indexPos;
  123. indexPos += 1;
  124. texture = textures.at(indices.at(indexStart));
  125. }
  126. }
  127. }
  128. if (indicesColor.size() > 0)
  129. Window::drawGL(verticesColor, colors, indicesColor, MVP);
  130. }