Dawn/src/display/primitive.c
2021-04-19 21:30:34 +10:00

126 lines
4.4 KiB
C

#include "primitive.h"
primitive_t * primitiveCreate(int32_t verticeCount, int32_t indiceCount) {
primitive_t *primitive = malloc(sizeof(primitive_t));
primitive->verticeCount = verticeCount;
primitive->indiceCount = indiceCount;
// size_t sizeIndices = sizeof(uint32_t) * verticeCount;
size_t sizePositions = sizeof(float) * verticeCount * PRIMITIVE_POSITIONS_PER_VERTICE;
size_t sizeCoordinates = sizeof(float) * verticeCount * PRIMITIVE_COORDINATES_PER_VERTICE;
size_t sizeIndices = sizeof(indice_t) * indiceCount;
// Create some buffers, one for the vertex data, one for the indices
GLuint *buffer = malloc(sizeof(GLuint) * 2);
glGenBuffers(2, buffer);
primitive->vertexBuffer = buffer[0];
primitive->indexBuffer = buffer[1];
free(buffer);
//Buffer an empty set of data then buffer each component
glBindBuffer(GL_ARRAY_BUFFER, primitive->vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive->indexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizePositions+sizeCoordinates, 0, GL_DYNAMIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeIndices, 0, GL_DYNAMIC_DRAW);
size_t offset = 0;
// Setup the attrib pointers
glVertexAttribPointer(0, PRIMITIVE_POSITIONS_PER_VERTICE, GL_FLOAT,
GL_FALSE, 0, (void *)offset
);
glEnableVertexAttribArray(0);
offset += sizePositions;
glVertexAttribPointer(1, PRIMITIVE_COORDINATES_PER_VERTICE, GL_FLOAT,
GL_FALSE, 0, (void *)offset
);
glEnableVertexAttribArray(1);
return primitive;
}
void primitiveBufferVertices(primitive_t *primitive,
int32_t position, int32_t count, vertice_t *vertices
) {
// Memory
size_t lengthPositions, lengthCoordinates, offsetPositions, offsetCoordinates;
float *positions, *coordinates;
int32_t i;
// Setup the size of the memory that the positions and coordinates will use
lengthPositions = sizeof(float) * PRIMITIVE_POSITIONS_PER_VERTICE * count;
offsetPositions = sizeof(float) * PRIMITIVE_POSITIONS_PER_VERTICE * position;
lengthCoordinates = sizeof(float) * PRIMITIVE_COORDINATES_PER_VERTICE * count;
offsetCoordinates = (
(sizeof(float) * PRIMITIVE_POSITIONS_PER_VERTICE * primitive->verticeCount)+
(sizeof(float) * PRIMITIVE_COORDINATES_PER_VERTICE * position)
);
// Create some memory
positions = malloc(lengthPositions);
coordinates = malloc(lengthCoordinates);
// Now copy the positions and coordinates from the vertices into the buffer
for(i = 0; i < count; i++) {
positions[i * PRIMITIVE_POSITIONS_PER_VERTICE] = vertices[i].x;
positions[i * PRIMITIVE_POSITIONS_PER_VERTICE + 1] = vertices[i].y;
positions[i * PRIMITIVE_POSITIONS_PER_VERTICE + 2] = vertices[i].z;
coordinates[i * PRIMITIVE_COORDINATES_PER_VERTICE] = vertices[i].u;
coordinates[i * PRIMITIVE_COORDINATES_PER_VERTICE + 1] = vertices[i].v;
}
// Buffer the data into the GPU
glBindBuffer(GL_ARRAY_BUFFER, primitive->vertexBuffer);
glBufferSubData(GL_ARRAY_BUFFER, offsetPositions, lengthPositions, positions);
glBufferSubData(GL_ARRAY_BUFFER, offsetCoordinates, lengthCoordinates, coordinates);
// Free the vertices.
free(positions);
free(coordinates);
}
void primitiveBufferIndices(primitive_t *primitive,
int32_t position, int32_t count, indice_t *indices
) {
size_t length, offset;
offset = position * sizeof(indice_t);
length = count * sizeof(indice_t);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive->indexBuffer);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, indices);
}
void primitiveDraw(primitive_t *primitive, int32_t start, int32_t count) {
// Re-Bind the buffers
glBindBuffer(GL_ARRAY_BUFFER, primitive->vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive->indexBuffer);
// Re-Calculate the attrib pointers.
size_t offset = 0;
glVertexAttribPointer(0, PRIMITIVE_POSITIONS_PER_VERTICE, GL_FLOAT,
GL_FALSE, 0, (void *)offset
);
glEnableVertexAttribArray(0);
offset += sizeof(float) * primitive->verticeCount * PRIMITIVE_POSITIONS_PER_VERTICE;
glVertexAttribPointer(1, PRIMITIVE_COORDINATES_PER_VERTICE, GL_FLOAT,
GL_FALSE, 0, (void *)offset
);
glEnableVertexAttribArray(1);
// Render the elements.
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, (void *)(
sizeof(indice_t)*start
));
}
void primitiveDispose(primitive_t *primitive) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &primitive->vertexBuffer);
glDeleteBuffers(1, &primitive->indexBuffer);
free(primitive);
}