Implement dynamic colors.

This commit is contained in:
Marcel Plch 2024-10-02 22:18:24 +02:00
parent bd31c409a6
commit f4cae1e5c1
Signed by: dormouse
GPG key ID: 2CA77596BC4BDFFE
4 changed files with 186 additions and 86 deletions

View file

@ -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

View file

@ -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;
}

134
src/cx.c
View file

@ -1,36 +1,29 @@
#include <cx.h>
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);
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),
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, mr->models[i]->bufsize*4*sizeof(GLfloat),
render_buffer, GL_STATIC_DRAW);
// 1rst attribute buffer : vertices
@ -45,29 +38,50 @@ cx_glrender(GLFWwindow *window, GLuint programID, GLfloat *render_buffer,
NULL // array buffer offset
);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, mr->models[i]->bufsize*3*sizeof(GLfloat),
mr->models[i]->colors, 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
);
// Draw!
glDrawArrays(GL_TRIANGLES, 0, mr->models[0]->bufsize); // 3 indices starting at 0 -> 1 triangle
glDrawArrays(GL_TRIANGLES, 0, mr->models[i]->bufsize); // 3 indices starting at 0 -> 1 triangle
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();
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

View file

@ -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;