2023-10-25 13:02:23 +00:00
|
|
|
#include <cx.h>
|
|
|
|
|
2024-09-29 20:11:45 +00:00
|
|
|
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) {
|
2023-12-13 09:56:21 +00:00
|
|
|
// Initialise GLFW
|
|
|
|
if(!glfwInit()) {
|
|
|
|
fprintf(stderr, "Failed to initialize GLFW\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
glfwWindowHint(GLFW_SAMPLES, 4);
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
|
|
|
2024-07-06 16:04:24 +00:00
|
|
|
// To make MacOS happy; should not be needed
|
|
|
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
|
|
|
|
2023-12-13 09:56:21 +00:00
|
|
|
// Open a window and create its OpenGL context
|
|
|
|
*window = glfwCreateWindow(1280, 720, "CONTROL-X", NULL, NULL);
|
|
|
|
if (*window == NULL) {
|
|
|
|
fprintf(stderr, "Failed to open GLFW window.\n");
|
|
|
|
glfwTerminate();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
glfwMakeContextCurrent(*window);
|
|
|
|
|
|
|
|
// Initialize GLEW
|
|
|
|
if (glewInit() != GLEW_OK) {
|
|
|
|
fprintf(stderr, "Failed to initialize GLEW\n");
|
|
|
|
glfwTerminate();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure we can capture the escape key being pressed below
|
|
|
|
glfwSetInputMode(*window, GLFW_STICKY_KEYS, GL_TRUE);
|
|
|
|
|
|
|
|
// Dark grey background
|
|
|
|
glClearColor(0.15f, 0.15f, 0.15f, 0.0f);
|
2023-10-25 13:02:23 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-09-29 20:11:45 +00:00
|
|
|
static int
|
|
|
|
cx_loadShaders(GLuint *VertexArrayID, GLuint *programID) {
|
2023-10-25 13:02:23 +00:00
|
|
|
|
2024-09-29 20:11:45 +00:00
|
|
|
glGenVertexArrays(1, VertexArrayID);
|
|
|
|
glBindVertexArray(*VertexArrayID);
|
2023-10-25 13:02:23 +00:00
|
|
|
|
2023-12-13 09:56:21 +00:00
|
|
|
// Create and compile our GLSL program from the shaders
|
2024-09-29 20:11:45 +00:00
|
|
|
if (LoadShaders(programID,
|
2023-10-25 13:02:23 +00:00
|
|
|
"../shaders/SimpleVertexShader.vertexshader",
|
|
|
|
"../shaders/SimpleFragmentShader.fragmentshader")) {
|
|
|
|
fprintf(stderr, "Could not load shaders.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2024-09-29 20:11:45 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
cx_glrun(GLFWwindow *window) {
|
|
|
|
GLuint VertexArrayID;
|
|
|
|
GLuint programID;
|
|
|
|
GLuint vertexbuffer;
|
|
|
|
if (cx_loadShaders(&VertexArrayID, &programID)) {
|
|
|
|
return -1;
|
|
|
|
}
|
2023-10-25 13:02:23 +00:00
|
|
|
|
2023-12-13 09:56:21 +00:00
|
|
|
|
|
|
|
// Load model to render from file
|
2023-10-25 13:02:23 +00:00
|
|
|
Model *model;
|
2024-07-06 16:04:24 +00:00
|
|
|
model = model_load("../3d_assets/cube.obj");
|
2024-09-29 20:11:45 +00:00
|
|
|
// Establish a model registry
|
|
|
|
ModelRegistry *mr;
|
|
|
|
mr = modelRegistry_new();
|
|
|
|
modelRegistry_register(mr, model);
|
2023-10-25 13:02:23 +00:00
|
|
|
|
2023-12-13 09:56:21 +00:00
|
|
|
// Allocate the render buffer
|
|
|
|
// GL uses this to feed the GPU
|
|
|
|
GLfloat *render_buffer;
|
|
|
|
render_buffer = malloc(model->bufsize * 4 * sizeof(GLfloat));
|
2024-07-06 16:04:24 +00:00
|
|
|
memcpy(render_buffer, model->object,
|
|
|
|
model->bufsize * 4 * sizeof(GLfloat));
|
2023-12-13 09:56:21 +00:00
|
|
|
|
|
|
|
// Bind the render buffer to OpenGL
|
2024-09-29 20:11:45 +00:00
|
|
|
cx_glbufferBind(model->bufsize*4*sizeof(GLfloat), render_buffer, &vertexbuffer);
|
2023-12-13 09:56:21 +00:00
|
|
|
|
|
|
|
// Remainder from cursor experiments, might be useful later
|
2023-10-25 13:02:23 +00:00
|
|
|
double xpos, ypos;
|
|
|
|
glfwGetCursorPos(window, &xpos, &ypos);
|
|
|
|
|
2023-12-13 09:56:21 +00:00
|
|
|
// Temporary storage of transformation results
|
2024-07-06 16:04:24 +00:00
|
|
|
|
2023-10-25 13:02:23 +00:00
|
|
|
|
|
|
|
|
2024-07-06 16:04:24 +00:00
|
|
|
int t = 0;
|
2023-10-25 13:02:23 +00:00
|
|
|
|
2023-12-13 09:56:21 +00:00
|
|
|
do {
|
2024-09-29 20:11:45 +00:00
|
|
|
cx_glrender(window, programID, render_buffer, vertexbuffer, mr);
|
2024-07-06 16:04:24 +00:00
|
|
|
t++;
|
2023-10-25 13:02:23 +00:00
|
|
|
usleep(1000000/60);
|
2024-07-06 16:04:24 +00:00
|
|
|
// Check if the ESC key was pressed or the window was closed
|
2023-12-13 09:56:21 +00:00
|
|
|
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
|
|
|
|
!glfwWindowShouldClose(window));
|
|
|
|
|
|
|
|
// Close OpenGL window and terminate GLFW
|
|
|
|
glfwTerminate();
|
2024-09-29 20:11:45 +00:00
|
|
|
modelRegistry_free(mr);
|
2023-12-13 09:56:21 +00:00
|
|
|
free(render_buffer);
|
2023-10-25 13:02:23 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-07-06 16:04:24 +00:00
|
|
|
|
2024-09-29 20:11:45 +00:00
|
|
|
int
|
|
|
|
cx_nninit(Neural_Network **nn) {
|
2024-07-06 16:04:24 +00:00
|
|
|
// Allocate a Neural Network
|
|
|
|
*nn = neural_new(64, 1);
|
|
|
|
if(!*nn) {
|
|
|
|
fprintf(stderr, "Failed to initialize Neural Network.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Populate the neural network with sensible values.
|
|
|
|
neural_randomize(*nn);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-09-29 20:11:45 +00:00
|
|
|
int
|
|
|
|
cx_nnrun(Neural_Network *nn) {
|
2024-07-06 16:04:24 +00:00
|
|
|
|
|
|
|
// Establish a neural interface.
|
|
|
|
float *input_buffer = malloc(64*sizeof(float));
|
|
|
|
float *output_buffer;
|
|
|
|
|
|
|
|
output_buffer = neural_process(nn, input_buffer);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|