Implement model registry
This allows for mass handling of multiple objects to be rendered.
This commit is contained in:
parent
01896962be
commit
bd31c409a6
4 changed files with 165 additions and 92 deletions
|
@ -1,13 +1,23 @@
|
|||
#ifndef MODEL_LOADER_H
|
||||
#define MODEL_LOADER_H
|
||||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
typedef struct _model {
|
||||
GLfloat *object;
|
||||
GLfloat **transformations;
|
||||
size_t transformation_count;
|
||||
size_t bufsize;
|
||||
} Model;
|
||||
|
||||
typedef struct _model_registry {
|
||||
Model **models;
|
||||
size_t model_count;
|
||||
size_t size;
|
||||
} ModelRegistry;
|
||||
|
||||
Model *model_load(const char *);
|
||||
int model_free(Model *);
|
||||
ModelRegistry* modelRegistry_new(void);
|
||||
int modelRegistry_register(ModelRegistry *, Model *);
|
||||
void modelRegistry_free(ModelRegistry *);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
183
src/cx.c
183
src/cx.c
|
@ -1,6 +1,77 @@
|
|||
#include <cx.h>
|
||||
|
||||
int cx_glinit(GLFWwindow **window) {
|
||||
static int
|
||||
cx_glrender(GLFWwindow *window, GLuint programID, GLfloat *render_buffer,
|
||||
GLuint vertexbuffer, ModelRegistry *mr) {
|
||||
// Clear the screen.
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Use our shader
|
||||
glUseProgram(programID);
|
||||
|
||||
GLfloat *rotation_matrix = matrix_new();
|
||||
GLfloat *translation_matrix = matrix_new();
|
||||
|
||||
translation_matrix[3] = 0.5f;
|
||||
|
||||
rotation_matrix[0] = cos(M_PI*2/256);
|
||||
rotation_matrix[8] = -sin(M_PI*2/256);
|
||||
rotation_matrix[2] = sin(M_PI*2/256);
|
||||
rotation_matrix[10] = cos(M_PI*2/256);
|
||||
|
||||
// BANANA, ROH-TAH-TEH
|
||||
GLfloat *temp_buffer[2];
|
||||
temp_buffer[0] = matrix_transform(mr->models[0]->object, mr->models[0]->bufsize, rotation_matrix);
|
||||
temp_buffer[1] = matrix_transform(temp_buffer[0], mr->models[0]->bufsize, translation_matrix);
|
||||
|
||||
memcpy(render_buffer, temp_buffer[1],
|
||||
mr->models[0]->bufsize * 4 * sizeof(GLfloat));
|
||||
|
||||
free(temp_buffer[0]);
|
||||
free(temp_buffer[1]);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, mr->models[0]->bufsize*4*sizeof(GLfloat),
|
||||
render_buffer, GL_STATIC_DRAW);
|
||||
|
||||
// 1rst attribute buffer : vertices
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
|
||||
glVertexAttribPointer(
|
||||
0, // attribute 0 in the pipeline
|
||||
4, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // normalized?
|
||||
0, // stride
|
||||
NULL // array buffer offset
|
||||
);
|
||||
|
||||
|
||||
// Draw!
|
||||
glDrawArrays(GL_TRIANGLES, 0, mr->models[0]->bufsize); // 3 indices starting at 0 -> 1 triangle
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
|
||||
temp_buffer[0] = matrix_transform(mr->models[0]->object, mr->models[0]->bufsize, translation_matrix);
|
||||
free(rotation_matrix);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cx_glbufferBind(size_t bufsize, GLfloat *render_buffer, GLuint *vertexbuffer) {
|
||||
glGenBuffers(1, vertexbuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, *vertexbuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, bufsize,
|
||||
render_buffer, GL_STATIC_DRAW);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
cx_glinit(GLFWwindow **window) {
|
||||
// Initialise GLFW
|
||||
if(!glfwInit()) {
|
||||
fprintf(stderr, "Failed to initialize GLFW\n");
|
||||
|
@ -41,25 +112,39 @@ int cx_glinit(GLFWwindow **window) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cx_glrun(GLFWwindow *window) {
|
||||
GLuint VertexArrayID;
|
||||
GLuint programID;
|
||||
static int
|
||||
cx_loadShaders(GLuint *VertexArrayID, GLuint *programID) {
|
||||
|
||||
glGenVertexArrays(1, &VertexArrayID);
|
||||
glBindVertexArray(VertexArrayID);
|
||||
glGenVertexArrays(1, VertexArrayID);
|
||||
glBindVertexArray(*VertexArrayID);
|
||||
|
||||
// Create and compile our GLSL program from the shaders
|
||||
if (LoadShaders(&programID,
|
||||
if (LoadShaders(programID,
|
||||
"../shaders/SimpleVertexShader.vertexshader",
|
||||
"../shaders/SimpleFragmentShader.fragmentshader")) {
|
||||
fprintf(stderr, "Could not load shaders.\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cx_glrun(GLFWwindow *window) {
|
||||
GLuint VertexArrayID;
|
||||
GLuint programID;
|
||||
GLuint vertexbuffer;
|
||||
if (cx_loadShaders(&VertexArrayID, &programID)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Load model to render from file
|
||||
Model *model;
|
||||
model = model_load("../3d_assets/cube.obj");
|
||||
// Establish a model registry
|
||||
ModelRegistry *mr;
|
||||
mr = modelRegistry_new();
|
||||
modelRegistry_register(mr, model);
|
||||
|
||||
// Allocate the render buffer
|
||||
// GL uses this to feed the GPU
|
||||
|
@ -69,91 +154,20 @@ int cx_glrun(GLFWwindow *window) {
|
|||
model->bufsize * 4 * sizeof(GLfloat));
|
||||
|
||||
// Bind the render buffer to OpenGL
|
||||
GLuint vertexbuffer;
|
||||
glGenBuffers(1, &vertexbuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, model->bufsize*4*sizeof(GLfloat),
|
||||
render_buffer, GL_STATIC_DRAW);
|
||||
|
||||
// 1rst attribute buffer : vertices
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
|
||||
glVertexAttribPointer(
|
||||
0, // attribute 0 in the pipeline
|
||||
4, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // normalized?
|
||||
0, // stride
|
||||
NULL // array buffer offset
|
||||
);
|
||||
cx_glbufferBind(model->bufsize*4*sizeof(GLfloat), render_buffer, &vertexbuffer);
|
||||
|
||||
// Remainder from cursor experiments, might be useful later
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
|
||||
GLfloat *rotation_matrix = matrix_new();
|
||||
GLfloat *translation_matrix = matrix_new();
|
||||
|
||||
|
||||
// Temporary storage of transformation results
|
||||
GLfloat *temp_buffer[2];
|
||||
|
||||
translation_matrix[3] = 0.5f;
|
||||
|
||||
|
||||
int t = 0;
|
||||
|
||||
do {
|
||||
// Clear the screen. It's not mentioned before Tutorial 02,
|
||||
// but it can cause flickering, so it's there nonetheless.
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Use our shader
|
||||
glUseProgram(programID);
|
||||
|
||||
|
||||
rotation_matrix[0] = cos(M_PI*2/256*(t%256));
|
||||
rotation_matrix[8] = -sin(M_PI*2/256*(t%256));
|
||||
rotation_matrix[2] = sin(M_PI*2/256*(t%256));
|
||||
rotation_matrix[10] = cos(M_PI*2/256*(t%256));
|
||||
|
||||
|
||||
// BANANA, ROH-TAH-TEH
|
||||
temp_buffer[0] = matrix_transform(model->object, model->bufsize, rotation_matrix);
|
||||
temp_buffer[1] = matrix_transform(temp_buffer[0], model->bufsize, translation_matrix);
|
||||
|
||||
// Guess I'm just projecting.
|
||||
free(temp_buffer[0]);
|
||||
|
||||
memcpy(render_buffer, temp_buffer[1], model->bufsize * 4 * sizeof(GLfloat));
|
||||
free(temp_buffer[1]);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, model->bufsize*4*sizeof(GLfloat), render_buffer, GL_STATIC_DRAW);
|
||||
|
||||
// 1rst attribute buffer : vertices
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
|
||||
glVertexAttribPointer(
|
||||
0, // attribute 0 in the pipeline
|
||||
4, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // normalized?
|
||||
0, // stride
|
||||
NULL // array buffer offset
|
||||
);
|
||||
|
||||
|
||||
// Draw!
|
||||
glDrawArrays(GL_TRIANGLES, 0, model->bufsize); // 3 indices starting at 0 -> 1 triangle
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
|
||||
temp_buffer[0] = matrix_transform(model->object, model->bufsize, translation_matrix);
|
||||
|
||||
cx_glrender(window, programID, render_buffer, vertexbuffer, mr);
|
||||
t++;
|
||||
usleep(1000000/60);
|
||||
// Check if the ESC key was pressed or the window was closed
|
||||
|
@ -162,15 +176,15 @@ int cx_glrun(GLFWwindow *window) {
|
|||
|
||||
// Close OpenGL window and terminate GLFW
|
||||
glfwTerminate();
|
||||
free(rotation_matrix);
|
||||
model_free(model);
|
||||
modelRegistry_free(mr);
|
||||
free(render_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cx_nninit(Neural_Network **nn) {
|
||||
int
|
||||
cx_nninit(Neural_Network **nn) {
|
||||
// Allocate a Neural Network
|
||||
*nn = neural_new(64, 1);
|
||||
if(!*nn) {
|
||||
|
@ -184,7 +198,8 @@ int cx_nninit(Neural_Network **nn) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cx_nnrun(Neural_Network *nn) {
|
||||
int
|
||||
cx_nnrun(Neural_Network *nn) {
|
||||
|
||||
// Establish a neural interface.
|
||||
float *input_buffer = malloc(64*sizeof(float));
|
||||
|
|
|
@ -13,10 +13,10 @@ main(void) {
|
|||
Neural_Network *nn;
|
||||
int retval;
|
||||
|
||||
|
||||
if (cx_glinit(&window)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cx_nninit(&nn)) {
|
||||
return -1;
|
||||
}
|
||||
|
|
56
src/model.c
56
src/model.c
|
@ -4,10 +4,18 @@ Model *
|
|||
model_new(size_t size) {
|
||||
Model *self = calloc(1, sizeof(Model));
|
||||
self->object = calloc((size ? size : 1) *4 , sizeof(GLfloat));
|
||||
self->transformations = calloc(8 , sizeof(GLfloat*));
|
||||
self->bufsize = size;
|
||||
return self;
|
||||
}
|
||||
|
||||
int
|
||||
model_free(Model *self) {
|
||||
free(self->object);
|
||||
free(self->transformations);
|
||||
free(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Model *
|
||||
model_load(const char *path) {
|
||||
|
@ -50,7 +58,7 @@ model_load(const char *path) {
|
|||
}
|
||||
} while(check != EOF);
|
||||
|
||||
self = model_new(facecount*4);
|
||||
self = model_new(facecount*3);
|
||||
for (int i = 0; i < facecount; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
for (int k = 0; k < 3; k++) {
|
||||
|
@ -66,10 +74,50 @@ model_load(const char *path) {
|
|||
return self;
|
||||
}
|
||||
|
||||
ModelRegistry *
|
||||
modelRegistry_new() {
|
||||
ModelRegistry *mr;
|
||||
mr = malloc(1 * sizeof(ModelRegistry));
|
||||
if (mr == NULL) {
|
||||
goto err;
|
||||
}
|
||||
mr->models = calloc(16, sizeof(Model));
|
||||
if (mr->models == NULL) {
|
||||
goto err;
|
||||
}
|
||||
mr->model_count = 0;
|
||||
mr->size = 16;
|
||||
return mr;
|
||||
|
||||
err:
|
||||
if (mr) {
|
||||
free(mr->models);
|
||||
}
|
||||
free(mr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
model_free(Model *self) {
|
||||
free(self->object);
|
||||
free(self);
|
||||
modelRegistry_register(ModelRegistry *self, Model *model) {
|
||||
if (self->model_count >= self->size) {
|
||||
self->size *= 2;
|
||||
self->models = realloc(self->models, self->size);
|
||||
if (self->models == NULL) {
|
||||
modelRegistry_free(self);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
self->models[self->model_count] = model;
|
||||
self->model_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
modelRegistry_free(ModelRegistry *self) {
|
||||
for (int i = 0; i < self->model_count; i++) {
|
||||
model_free(self->models[i]);
|
||||
}
|
||||
free(self->models);
|
||||
free(self);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue