2023-10-25 13:02:23 +00:00
|
|
|
#include <cx.h>
|
|
|
|
|
2024-10-08 09:29:52 +00:00
|
|
|
static void
|
|
|
|
cx_glBindBuffer(GLfloat *render_buffer, GLuint buffer_address,
|
|
|
|
GLuint gl_index, GLint member_size, GLsizeiptr bufsize) {
|
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, buffer_address);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, bufsize,
|
|
|
|
render_buffer, GL_STATIC_DRAW);
|
|
|
|
|
|
|
|
// 1rst attribute buffer : vertices
|
|
|
|
glEnableVertexAttribArray(gl_index);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, buffer_address);
|
|
|
|
glVertexAttribPointer(
|
|
|
|
gl_index, // attribute 0 in the pipeline
|
|
|
|
member_size, // size
|
|
|
|
GL_FLOAT, // type
|
|
|
|
GL_FALSE, // normalized?
|
|
|
|
0, // stride
|
|
|
|
NULL // array buffer offset
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-09-29 20:11:45 +00:00
|
|
|
static int
|
2024-10-02 20:18:24 +00:00
|
|
|
cx_glrender(GLFWwindow *window, GLuint programID,
|
|
|
|
ModelRegistry *mr) {
|
|
|
|
|
|
|
|
GLuint vertexbuffer;
|
|
|
|
GLuint colorbuffer;
|
|
|
|
// Buffer for render data
|
|
|
|
GLfloat *render_buffer;
|
2024-09-29 20:11:45 +00:00
|
|
|
// Clear the screen.
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
|
|
|
// Use our shader
|
|
|
|
glUseProgram(programID);
|
|
|
|
|
2024-10-02 20:18:24 +00:00
|
|
|
// Bind the render buffer to OpenGL
|
|
|
|
glGenBuffers(1, &vertexbuffer);
|
|
|
|
glGenBuffers(1, &colorbuffer);
|
|
|
|
|
|
|
|
for (int i = 0; i < mr->model_count; i++) {
|
|
|
|
|
2024-10-08 09:29:52 +00:00
|
|
|
// Allocate the render buffer
|
|
|
|
// GL uses this to feed the GPU
|
2024-10-02 20:18:24 +00:00
|
|
|
render_buffer = model_applyTransformations(mr->models[i]);
|
|
|
|
|
2024-10-08 09:29:52 +00:00
|
|
|
cx_glBindBuffer(render_buffer, vertexbuffer, 0, 4,
|
|
|
|
mr->models[i]->bufsize*4*sizeof(GLfloat));
|
|
|
|
cx_glBindBuffer(mr->models[i]->colors, colorbuffer, 2, 3,
|
|
|
|
mr->models[i]->bufsize*3*sizeof(GLfloat));
|
2024-10-02 20:18:24 +00:00
|
|
|
|
|
|
|
// Draw!
|
2024-10-08 09:29:52 +00:00
|
|
|
glDrawArrays(GL_TRIANGLES, 0, mr->models[i]->bufsize);
|
2024-10-02 20:18:24 +00:00
|
|
|
|
|
|
|
glDisableVertexAttribArray(0);
|
|
|
|
glDisableVertexAttribArray(2);
|
|
|
|
free(render_buffer);
|
|
|
|
}
|
2024-09-29 20:11:45 +00:00
|
|
|
|
|
|
|
// Swap buffers
|
|
|
|
glfwSwapBuffers(window);
|
|
|
|
glfwPollEvents();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-10-02 20:18:24 +00:00
|
|
|
static inline int
|
|
|
|
cx_loadShaders(GLuint *VertexArrayID, GLuint *programID) {
|
|
|
|
glGenVertexArrays(1, VertexArrayID);
|
|
|
|
glBindVertexArray(*VertexArrayID);
|
2024-09-29 20:11:45 +00:00
|
|
|
|
2024-10-02 20:18:24 +00:00
|
|
|
// 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;
|
2024-09-29 20:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2024-10-19 09:32:39 +00:00
|
|
|
*window = glfwCreateWindow(1280, 720, "CONTROL-X", NULL, NULL);
|
2023-12-13 09:56:21 +00:00
|
|
|
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-10-19 09:32:39 +00:00
|
|
|
static int
|
|
|
|
cx_nnrun(Neural_Network *nn) {
|
|
|
|
|
|
|
|
// Establish a neural interface.
|
|
|
|
float *input_buffer = malloc(64*sizeof(float));
|
|
|
|
float *output_buffer;
|
|
|
|
|
|
|
|
output_buffer = neural_process(nn, input_buffer);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-09-29 20:11:45 +00:00
|
|
|
int
|
2024-10-19 09:32:39 +00:00
|
|
|
cx_run(GLFWwindow *window, Neural_Network *nn) {
|
2024-10-13 21:54:16 +00:00
|
|
|
Model *model;
|
2024-10-13 20:43:43 +00:00
|
|
|
ModelRegistry *mr;
|
|
|
|
Model *neural_network_model;
|
2024-09-29 20:11:45 +00:00
|
|
|
GLuint VertexArrayID;
|
|
|
|
GLuint programID;
|
|
|
|
if (cx_loadShaders(&VertexArrayID, &programID)) {
|
|
|
|
return -1;
|
|
|
|
}
|
2023-10-25 13:02:23 +00:00
|
|
|
|
2024-10-13 20:43:43 +00:00
|
|
|
|
2024-09-29 20:11:45 +00:00
|
|
|
// Establish a model registry
|
|
|
|
mr = modelRegistry_new();
|
2024-10-08 09:29:52 +00:00
|
|
|
// Fill the model registry with mesh models
|
2024-10-19 09:32:39 +00:00
|
|
|
for (int j = 0; j < nn->layer_count; j++) {
|
|
|
|
Neural_Layer *nl = nn->layers[j];
|
|
|
|
for (int i = 0; i < nl->layer_size; i++) {
|
2024-10-12 09:17:52 +00:00
|
|
|
// Load model to render from file
|
|
|
|
//Model *model = model_load("../3d_assets/triangle.obj");
|
2024-10-19 09:32:39 +00:00
|
|
|
for (int k = 0; k < nl->layer_size_next; k++) {
|
|
|
|
model = model_line((-.90)
|
|
|
|
+ ((GLfloat)2 * i * .90/(nl->layer_size-1)),
|
|
|
|
|
|
|
|
.90 - ((GLfloat)2 * j *.90/(nn->layer_count)),
|
|
|
|
|
|
|
|
(-.90)
|
|
|
|
+ ((GLfloat)2 * k * .90/(nl->layer_size_next-1)),
|
|
|
|
|
|
|
|
.90 - ((GLfloat)2 * (j+1) *.90/(nn->layer_count)),
|
|
|
|
|
|
|
|
.001 // girth
|
|
|
|
);
|
|
|
|
modelRegistry_register(mr, model);
|
|
|
|
}
|
|
|
|
|
2024-10-13 21:54:16 +00:00
|
|
|
model = model_circle(0, (GLfloat)1/64);
|
2024-10-12 09:17:52 +00:00
|
|
|
GLfloat *translation_matrix = matrix_new();
|
|
|
|
GLfloat *aspectRatio_matrix = matrix_new();
|
|
|
|
aspectRatio_matrix[0] = (GLfloat)9/16;
|
|
|
|
|
|
|
|
translation_matrix[3] = (((GLfloat)-1*16/9)*.90)
|
2024-10-19 09:32:39 +00:00
|
|
|
+ ((GLfloat)1/(nl->layer_size-1)*2 * i * (((GLfloat)16/9))*.90);
|
2024-10-12 09:17:52 +00:00
|
|
|
|
2024-10-19 09:32:39 +00:00
|
|
|
translation_matrix[7] = .90 - ((GLfloat)1/(nn->layer_count)*2 * j *.90);
|
2024-10-12 09:17:52 +00:00
|
|
|
|
|
|
|
model->transformations[0] = translation_matrix;
|
|
|
|
model->transformations[1] = aspectRatio_matrix;
|
|
|
|
model->transformation_count = 2;
|
|
|
|
model_colorWhite(model);
|
|
|
|
|
|
|
|
modelRegistry_register(mr, model);
|
2024-10-19 09:32:39 +00:00
|
|
|
|
2024-10-12 09:17:52 +00:00
|
|
|
}
|
2024-10-02 20:18:24 +00:00
|
|
|
}
|
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);
|
|
|
|
|
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-10-02 20:18:24 +00:00
|
|
|
cx_glrender(window, programID, 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
|
2024-10-02 20:18:24 +00:00
|
|
|
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS
|
|
|
|
&& !glfwWindowShouldClose(window));
|
2023-12-13 09:56:21 +00:00
|
|
|
|
|
|
|
// Close OpenGL window and terminate GLFW
|
|
|
|
glfwTerminate();
|
2024-09-29 20:11:45 +00:00
|
|
|
modelRegistry_free(mr);
|
2023-10-25 13:02:23 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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
|
2024-10-12 09:17:52 +00:00
|
|
|
*nn = neural_new(64, 4, 8);
|
2024-07-06 16:04:24 +00:00
|
|
|
if(!*nn) {
|
|
|
|
fprintf(stderr, "Failed to initialize Neural Network.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Populate the neural network with sensible values.
|
|
|
|
neural_randomize(*nn);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|