mesh.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "mesh.h"
  2. #include <QOpenGLFunctions_3_3_Core>
  3. namespace Render::GL {
  4. Mesh::Mesh(const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices)
  5. : m_vertices(vertices), m_indices(indices) {
  6. // Defer GL buffer setup until a context is current; will be created on first draw
  7. }
  8. Mesh::~Mesh() = default;
  9. void Mesh::setupBuffers() {
  10. initializeOpenGLFunctions();
  11. m_vao = std::make_unique<VertexArray>();
  12. m_vbo = std::make_unique<Buffer>(Buffer::Type::Vertex);
  13. m_ebo = std::make_unique<Buffer>(Buffer::Type::Index);
  14. m_vao->bind();
  15. // Set vertex data
  16. m_vbo->setData(m_vertices);
  17. // Set index data
  18. m_ebo->setData(m_indices);
  19. // Define vertex layout: position (3), normal (3), texCoord (2)
  20. std::vector<int> layout = {3, 3, 2};
  21. m_vao->addVertexBuffer(*m_vbo, layout);
  22. m_vao->setIndexBuffer(*m_ebo);
  23. m_vao->unbind();
  24. }
  25. void Mesh::draw() {
  26. if (!m_vao) {
  27. setupBuffers();
  28. }
  29. m_vao->bind();
  30. // Draw elements
  31. initializeOpenGLFunctions();
  32. glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_indices.size()), GL_UNSIGNED_INT, nullptr);
  33. m_vao->unbind();
  34. }
  35. Mesh* createQuadMesh() {
  36. std::vector<Vertex> vertices = {
  37. // Position Normal TexCoord
  38. {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}},
  39. {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
  40. {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
  41. {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}}
  42. };
  43. std::vector<unsigned int> indices = {
  44. 0, 1, 2,
  45. 2, 3, 0
  46. };
  47. return new Mesh(vertices, indices);
  48. }
  49. Mesh* createCubeMesh() {
  50. std::vector<Vertex> vertices = {
  51. // Front face
  52. {{-1.0f, -1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}},
  53. {{ 1.0f, -1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
  54. {{ 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
  55. {{-1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
  56. // Back face
  57. {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, -1.0f}, {1.0f, 0.0f}},
  58. {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, -1.0f}, {1.0f, 1.0f}},
  59. {{ 1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 1.0f}},
  60. {{ 1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f}},
  61. };
  62. std::vector<unsigned int> indices = {
  63. // Front face
  64. 0, 1, 2, 2, 3, 0,
  65. // Back face
  66. 4, 5, 6, 6, 7, 4,
  67. // Left face
  68. 4, 0, 3, 3, 5, 4,
  69. // Right face
  70. 1, 7, 6, 6, 2, 1,
  71. // Top face
  72. 3, 2, 6, 6, 5, 3,
  73. // Bottom face
  74. 4, 7, 1, 1, 0, 4
  75. };
  76. return new Mesh(vertices, indices);
  77. }
  78. Mesh* createPlaneMesh(float width, float height, int subdivisions) {
  79. std::vector<Vertex> vertices;
  80. std::vector<unsigned int> indices;
  81. float halfWidth = width * 0.5f;
  82. float halfHeight = height * 0.5f;
  83. // Generate vertices
  84. for (int z = 0; z <= subdivisions; ++z) {
  85. for (int x = 0; x <= subdivisions; ++x) {
  86. float xPos = (x / static_cast<float>(subdivisions)) * width - halfWidth;
  87. float zPos = (z / static_cast<float>(subdivisions)) * height - halfHeight;
  88. vertices.push_back({
  89. {xPos, 0.0f, zPos},
  90. {0.0f, 1.0f, 0.0f},
  91. {x / static_cast<float>(subdivisions), z / static_cast<float>(subdivisions)}
  92. });
  93. }
  94. }
  95. // Generate indices
  96. for (int z = 0; z < subdivisions; ++z) {
  97. for (int x = 0; x < subdivisions; ++x) {
  98. int topLeft = z * (subdivisions + 1) + x;
  99. int topRight = topLeft + 1;
  100. int bottomLeft = (z + 1) * (subdivisions + 1) + x;
  101. int bottomRight = bottomLeft + 1;
  102. // First triangle
  103. indices.push_back(topLeft);
  104. indices.push_back(bottomLeft);
  105. indices.push_back(topRight);
  106. // Second triangle
  107. indices.push_back(topRight);
  108. indices.push_back(bottomLeft);
  109. indices.push_back(bottomRight);
  110. }
  111. }
  112. return new Mesh(vertices, indices);
  113. }
  114. } // namespace Render::GL