From f4cae1e5c1bb67c4e480e448a99f1bada97417d6 Mon Sep 17 00:00:00 2001 From: Marcel Plch Date: Wed, 2 Oct 2024 22:18:24 +0200 Subject: [PATCH] Implement dynamic colors. --- include/model.h | 6 +- shaders/SimpleVertexShader.vertexshader | 7 +- src/cx.c | 162 ++++++++++++------------ src/model.c | 97 +++++++++++++- 4 files changed, 186 insertions(+), 86 deletions(-) diff --git a/include/model.h b/include/model.h index 5e1a819..43e7707 100644 --- a/include/model.h +++ b/include/model.h @@ -3,9 +3,11 @@ typedef struct _model { GLfloat *object; + GLfloat *colors; GLfloat **transformations; - size_t transformation_count; size_t bufsize; + size_t transformation_count; + size_t transformation_size; } Model; typedef struct _model_registry { @@ -18,6 +20,8 @@ Model *model_load(const char *); ModelRegistry* modelRegistry_new(void); int modelRegistry_register(ModelRegistry *, Model *); void modelRegistry_free(ModelRegistry *); +GLfloat * model_applyTransformations(Model *); +void model_colorFromPosition(Model *); #endif diff --git a/shaders/SimpleVertexShader.vertexshader b/shaders/SimpleVertexShader.vertexshader index a0fee1f..a835e38 100644 --- a/shaders/SimpleVertexShader.vertexshader +++ b/shaders/SimpleVertexShader.vertexshader @@ -3,12 +3,13 @@ // Input vertex data, different for all executions of this shader. layout(location = 0) in vec4 position; layout(location = 1) in vec4 normal; +layout(location = 2) in vec3 color; out vec3 colorF; void main() { - colorF.x = position.x; - colorF.y = position.y; - colorF.z = position.z; + colorF.x = color.x; + colorF.y = color.y; + colorF.z = color.z; gl_Position = position; } diff --git a/src/cx.c b/src/cx.c index 0341b44..935e84c 100644 --- a/src/cx.c +++ b/src/cx.c @@ -1,73 +1,87 @@ #include static int -cx_glrender(GLFWwindow *window, GLuint programID, GLfloat *render_buffer, - GLuint vertexbuffer, ModelRegistry *mr) { +cx_glrender(GLFWwindow *window, GLuint programID, + ModelRegistry *mr) { + + GLuint vertexbuffer; + GLuint colorbuffer; + // Buffer for render data + GLfloat *render_buffer; // Clear the screen. glClear(GL_COLOR_BUFFER_BIT); // Use our shader glUseProgram(programID); - GLfloat *rotation_matrix = matrix_new(); - GLfloat *translation_matrix = matrix_new(); + // Bind the render buffer to OpenGL + glGenBuffers(1, &vertexbuffer); + glGenBuffers(1, &colorbuffer); - translation_matrix[3] = 0.5f; + for (int i = 0; i < mr->model_count; i++) { - 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); + render_buffer = model_applyTransformations(mr->models[i]); - // 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); + glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); + glBufferData(GL_ARRAY_BUFFER, mr->models[i]->bufsize*4*sizeof(GLfloat), + render_buffer, GL_STATIC_DRAW); - memcpy(render_buffer, temp_buffer[1], - mr->models[0]->bufsize * 4 * sizeof(GLfloat)); + // 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 + ); - free(temp_buffer[0]); - free(temp_buffer[1]); + glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); + glBufferData(GL_ARRAY_BUFFER, mr->models[i]->bufsize*3*sizeof(GLfloat), + mr->models[i]->colors, GL_STATIC_DRAW); - glBufferData(GL_ARRAY_BUFFER, mr->models[0]->bufsize*4*sizeof(GLfloat), - render_buffer, GL_STATIC_DRAW); + // 1rst attribute buffer : vertices + glEnableVertexAttribArray(2); + glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); + glVertexAttribPointer( + 2, // attribute 0 in the pipeline + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + 0, // stride + NULL // array buffer offset + ); - // 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[i]->bufsize); // 3 indices starting at 0 -> 1 triangle - - // Draw! - glDrawArrays(GL_TRIANGLES, 0, mr->models[0]->bufsize); // 3 indices starting at 0 -> 1 triangle - - glDisableVertexAttribArray(0); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(2); + free(render_buffer); + } // 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; +static inline int +cx_loadShaders(GLuint *VertexArrayID, GLuint *programID) { + glGenVertexArrays(1, VertexArrayID); + glBindVertexArray(*VertexArrayID); + // Create and compile our GLSL program from the shaders + if (LoadShaders(programID, + "../shaders/SimpleVertexShader.vertexshader", + "../shaders/SimpleFragmentShader.fragmentshader")) { + fprintf(stderr, "Could not load shaders.\n"); + return -1; + } + return 0; } int @@ -112,77 +126,63 @@ cx_glinit(GLFWwindow **window) { return 0; } -static int -cx_loadShaders(GLuint *VertexArrayID, GLuint *programID) { - - glGenVertexArrays(1, VertexArrayID); - glBindVertexArray(*VertexArrayID); - - // Create and compile our GLSL program from the shaders - 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); + for (int i = 0; i < 3; i++) { + // Load model to render from file + Model *model = model_load("../3d_assets/triangle.obj"); + GLfloat *rotation_matrix = matrix_new(); + GLfloat *translation_matrix = matrix_new(); + + 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); + + translation_matrix[3] = -0.5 + (0.5 * i); + + model->transformations[0] = rotation_matrix; + model->transformations[1] = translation_matrix; + model->transformation_count = 2; + model_colorFromPosition(model); + + modelRegistry_register(mr, model); + } // Allocate the render buffer // GL uses this to feed the GPU - GLfloat *render_buffer; - render_buffer = malloc(model->bufsize * 4 * sizeof(GLfloat)); - memcpy(render_buffer, model->object, - model->bufsize * 4 * sizeof(GLfloat)); - // Bind the render buffer to OpenGL - 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); - // Temporary storage of transformation results - - - int t = 0; do { - cx_glrender(window, programID, render_buffer, vertexbuffer, mr); + cx_glrender(window, programID, mr); t++; usleep(1000000/60); // Check if the ESC key was pressed or the window was closed - } while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && - !glfwWindowShouldClose(window)); + } while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS + && !glfwWindowShouldClose(window)); // Close OpenGL window and terminate GLFW glfwTerminate(); modelRegistry_free(mr); - free(render_buffer); return 0; } - int cx_nninit(Neural_Network **nn) { // Allocate a Neural Network diff --git a/src/model.c b/src/model.c index 0d4527f..2bed4e6 100644 --- a/src/model.c +++ b/src/model.c @@ -4,14 +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->colors = calloc((size ? size : 1) *3 , sizeof(GLfloat)); self->bufsize = size; + self->transformations = calloc(8 , sizeof(GLfloat*)); + self->transformation_size = 8; + self->transformation_count = 0; return self; } int model_free(Model *self) { free(self->object); + free(self->colors); free(self->transformations); free(self); return 0; @@ -74,6 +78,97 @@ model_load(const char *path) { return self; } +GLfloat * +model_applyTransformations(Model *self) { + // Temporary storage of transformation results + GLfloat *temp_buffer[2] = {NULL}; + + // BANANA, ROH-TAH-TEH + temp_buffer[1] = malloc(self->bufsize * 4 * sizeof(GLfloat)); + memcpy(temp_buffer[1], self->object, self->bufsize * 4 * sizeof(GLfloat)); + + int i = 0; + do { + temp_buffer[i%2] = matrix_transform(temp_buffer[(i+1)%2], + self->bufsize, + self->transformations[i]); + free(temp_buffer[(i+1)%2]); + } while (++i < self->transformation_count); + + return temp_buffer[(i+1)%2]; + +} + +GLfloat * +model_getColorBuffer() { + return NULL; +} + +void +model_colorFromPosition(Model *self) { + for (int i = 0; i < self->bufsize; i++) { + for (int j = 0; j < 3; j++) { + self->colors[(i*3)+j] = self->object[(i*4)+j]; + } + } +} + +Model * +model_triangle(Model *self, int detail) { + if (self == NULL) { + self = model_new(3); + } + return 0; +} + +Model * +model_circle(Model *self, int detail) { + if (self == NULL) { + self = model_new(36); + } + return 0; +} + +Model * +model_line(Model *self, int detail) { + if (self == NULL) { + self = model_new(6); + } + return 0; +} + +Model * +model_sin(Model *self, int detail) { + if (self == NULL) { + self = model_new(6*256); + } + return 0; +} + +Model * +model_curve(Model *self) { + if (self == NULL) { + self = model_new(0); + } + return 0; +} + +Model * +model_chart(Model *self, int detail) { + if (self == NULL) { + self = model_new(0); + } + return 0; +} + +Model * +model_graph(Model *self, int detail) { + if (self == NULL) { + self = model_new(0); + } + return 0; +} + ModelRegistry * modelRegistry_new() { ModelRegistry *mr;