#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); }