5Mesh::Mesh(
const std::vector<Vertex> &verts,
const std::vector<unsigned int> &idx, QOpenGLFunctions_4_5_Core* glFuncs)
6 : indexCount(idx.size()), vertices(verts), indices(idx), funcs(glFuncs), localAABB(){
7 assert(QOpenGLContext::currentContext() !=
nullptr &&
"GL context is NOT current during Mesh construction!");
8 assert(funcs !=
nullptr);
10 funcs->glGenVertexArrays(1, &VAO);
11 assert(VAO != 0 &&
"VAO generation failed — is GL context current?");
12 funcs->glGenBuffers(1, &VBO);
13 funcs->glGenBuffers(1, &EBO);
15 funcs->glBindVertexArray(VAO);
16 funcs->glBindBuffer(GL_ARRAY_BUFFER, VBO);
17 funcs->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
19 funcs->glBufferData(GL_ARRAY_BUFFER, vertices.size() *
sizeof(
Vertex), vertices.data(), GL_STATIC_DRAW);
20 funcs->glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() *
sizeof(
unsigned int), indices.data(), GL_STATIC_DRAW);
21 funcs->glEnableVertexAttribArray(0);
22 funcs->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
sizeof(
Vertex),
nullptr);
23 funcs->glEnableVertexAttribArray(1);
24 funcs->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
sizeof(
Vertex), (
void*)offsetof(
Vertex, normal));
25 setupInstanceAttributes();
30 funcs->glDeleteVertexArrays(1, &VAO);
31 funcs->glDeleteBuffers(1, &VBO);
32 funcs->glDeleteBuffers(1, &EBO);
35void Mesh::setupInstanceAttributes() {
36 funcs->glGenBuffers(1, &instanceVBO);
37 funcs->glBindVertexArray(VAO);
38 funcs->glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
41 for (
int i = 0; i < 4; ++i) {
42 funcs->glEnableVertexAttribArray(2 + i);
43 funcs->glVertexAttribPointer(2 + i, 4, GL_FLOAT, GL_FALSE,
sizeof(
Rendering::InstanceData), (
void*)(
sizeof(glm::vec4) * i));
44 funcs->glVertexAttribDivisor(2 + i, 1);
48 funcs->glEnableVertexAttribArray(6);
50 funcs->glVertexAttribDivisor(6, 1);
53 funcs->glEnableVertexAttribArray(7);
55 funcs->glVertexAttribDivisor(7, 1);
57 funcs->glBindVertexArray(0);
60void Mesh::createLocalAABB() {
61 glm::vec3 minV(std::numeric_limits<float>::max()), maxV(-std::numeric_limits<float>::max());
62 for (
const Vertex& vertex : vertices) {
63 minV = glm::min(minV, vertex.pos);
64 maxV = glm::max(maxV, vertex.pos);
66 glm::vec3 center = (minV + maxV) * 0.5f;
67 glm::vec3 halfExtents = (maxV - minV) * 0.5f;
73 funcs->glBindVertexArray(VAO);
74 glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT,
nullptr);
75 funcs->glBindVertexArray(0);
79 assert(VAO != 0 &&
"asdVAO generation failed — is GL context current?");
80 funcs->glBindVertexArray(VAO);
82 funcs->glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
83 funcs->glBufferData(GL_ARRAY_BUFFER, instances.size() *
sizeof(
Rendering::InstanceData), instances.data(), GL_DYNAMIC_DRAW);
85 funcs->glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT,
nullptr,
86 static_cast<GLsizei
>(instances.size()));
88 funcs->glBindVertexArray(0);
~Mesh()
Destroys the mesh and releases GPU resources.
void draw() const
Draws a single instance of this mesh.
Mesh(const std::vector< Vertex > &verts, const std::vector< unsigned int > &idx, QOpenGLFunctions_4_5_Core *funcs)
Constructs a mesh from vertex and index data.
std::span< const Vertex > getVertices() const
Provides read-only view of vertex data without copying.
std::span< const unsigned int > getIndices() const
Provides read-only view of index data without copying.
void drawInstanced(const std::vector< Rendering::InstanceData > &instances)
Draws multiple instances of this mesh in a single draw call.
Per-instance data for instanced rendering.
Vertex data for a single vertex in a mesh.