175 lines
4.2 KiB
C
175 lines
4.2 KiB
C
/**
|
|
* Copyright (c) 2026 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "display/mesh/mesh.h"
|
|
#include "assert/assertgl.h"
|
|
#include "error/errorgl.h"
|
|
|
|
errorret_t meshInitGL(
|
|
meshgl_t *mesh,
|
|
const meshprimitivetypegl_t primitiveType,
|
|
const int32_t vertexCount,
|
|
const meshvertex_t *vertices
|
|
) {
|
|
assertNotNull(mesh, "Mesh cannot be NULL");
|
|
assertNotNull(vertices, "Vertices cannot be NULL");
|
|
assertTrue(vertexCount > 0, "Vertex count must be greater than 0");
|
|
|
|
mesh->primitiveType = primitiveType;
|
|
mesh->vertexCount = vertexCount;
|
|
mesh->vertices = vertices;
|
|
|
|
#ifdef DUSK_OPENGL_LEGACY
|
|
// Nothing needed.
|
|
#else
|
|
// Generate Vertex Buffer Object
|
|
glGenBuffers(1, &mesh->vboId);
|
|
errorChain(errorGLCheck());
|
|
glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId);
|
|
errorChain(errorGLCheck());
|
|
glBufferData(
|
|
GL_ARRAY_BUFFER,
|
|
vertexCount * sizeof(meshvertex_t),
|
|
vertices,
|
|
GL_DYNAMIC_DRAW
|
|
);
|
|
errorChain(errorGLCheck());
|
|
|
|
// Generate Vertex Array Object
|
|
glGenVertexArrays(1, &mesh->vaoId);
|
|
errorChain(errorGLCheck());
|
|
glBindVertexArray(mesh->vaoId);
|
|
errorChain(errorGLCheck());
|
|
glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId);
|
|
errorChain(errorGLCheck());
|
|
|
|
// Set up vertex attribute pointers
|
|
glVertexAttribPointer(
|
|
0,
|
|
MESH_VERTEX_POS_SIZE,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof(meshvertex_t),
|
|
(const GLvoid*)offsetof(meshvertex_t, pos)
|
|
);
|
|
errorChain(errorGLCheck());
|
|
glEnableVertexAttribArray(0);
|
|
errorChain(errorGLCheck());
|
|
|
|
glVertexAttribPointer(
|
|
1,
|
|
MESH_VERTEX_UV_SIZE,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof(meshvertex_t),
|
|
(const GLvoid*)offsetof(meshvertex_t, uv)
|
|
);
|
|
errorChain(errorGLCheck());
|
|
glEnableVertexAttribArray(1);
|
|
errorChain(errorGLCheck());
|
|
|
|
glVertexAttribPointer(
|
|
2,
|
|
sizeof(color_t) / sizeof(GLubyte),
|
|
GL_UNSIGNED_BYTE,
|
|
GL_TRUE,
|
|
sizeof(meshvertex_t),
|
|
(const GLvoid*)offsetof(meshvertex_t, color)
|
|
);
|
|
errorChain(errorGLCheck());
|
|
glEnableVertexAttribArray(2);
|
|
errorChain(errorGLCheck());
|
|
|
|
// Unbind VAO and VBO to prevent accidental modification
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
errorChain(errorGLCheck());
|
|
glBindVertexArray(0);
|
|
errorChain(errorGLCheck());
|
|
#endif
|
|
|
|
errorOk();
|
|
}
|
|
|
|
errorret_t meshFlushGL(
|
|
meshgl_t *mesh,
|
|
const int32_t vertOffset,
|
|
const int32_t vertCount
|
|
) {
|
|
#ifdef DUSK_OPENGL_LEGACY
|
|
// Nothing doing, we use the glClientState stuff.
|
|
#else
|
|
glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId);
|
|
errorChain(errorGLCheck());
|
|
glBufferData(
|
|
GL_ARRAY_BUFFER,
|
|
vertCount * sizeof(meshvertex_t),
|
|
&mesh->vertices[vertOffset],
|
|
GL_DYNAMIC_DRAW
|
|
);
|
|
errorChain(errorGLCheck());
|
|
#endif
|
|
errorOk();
|
|
}
|
|
|
|
errorret_t meshDrawGL(
|
|
const meshgl_t *mesh,
|
|
const int32_t offset,
|
|
const int32_t count
|
|
) {
|
|
#ifdef DUSK_OPENGL_LEGACY
|
|
// Legacy pointer style rendering
|
|
const GLsizei stride = sizeof(meshvertex_t);
|
|
|
|
glColorPointer(
|
|
sizeof(color4b_t),
|
|
GL_UNSIGNED_BYTE,
|
|
stride,
|
|
(const GLvoid*)&mesh->vertices[offset].color
|
|
);
|
|
glTexCoordPointer(
|
|
MESH_VERTEX_UV_SIZE,
|
|
GL_FLOAT,
|
|
stride,
|
|
(const GLvoid*)&mesh->vertices[offset].uv
|
|
);
|
|
glVertexPointer(
|
|
MESH_VERTEX_POS_SIZE,
|
|
GL_FLOAT,
|
|
stride,
|
|
(const GLvoid*)&mesh->vertices[offset].pos
|
|
);
|
|
|
|
glDrawArrays(mesh->primitiveType, offset, count);
|
|
errorChain(errorGLCheck());
|
|
#else
|
|
// Modern VAO/VBO rendering
|
|
glBindVertexArray(mesh->vaoId);
|
|
errorChain(errorGLCheck());
|
|
glDrawArrays(mesh->primitiveType, offset, count);
|
|
errorChain(errorGLCheck());
|
|
glBindVertexArray(0);
|
|
errorChain(errorGLCheck());
|
|
#endif
|
|
|
|
errorOk();
|
|
}
|
|
|
|
int32_t meshGetVertexCountGL(const meshgl_t *mesh) {
|
|
return mesh->vertexCount;
|
|
}
|
|
|
|
errorret_t meshDisposeGL(meshgl_t *mesh) {
|
|
#ifdef DUSK_OPENGL_LEGACY
|
|
// No dynamic resources to free for this mesh implementation
|
|
#else
|
|
glDeleteBuffers(1, &mesh->vboId);
|
|
errorChain(errorGLCheck());
|
|
glDeleteVertexArrays(1, &mesh->vaoId);
|
|
errorChain(errorGLCheck());
|
|
#endif
|
|
errorOk();
|
|
} |