#include 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 ); } static int 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); // Bind the render buffer to OpenGL glGenBuffers(1, &vertexbuffer); glGenBuffers(1, &colorbuffer); for (int i = 0; i < mr->model_count; i++) { // Allocate the render buffer // GL uses this to feed the GPU render_buffer = model_applyTransformations(mr->models[i]); 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)); // Draw! glDrawArrays(GL_TRIANGLES, 0, mr->models[i]->bufsize); glDisableVertexAttribArray(0); glDisableVertexAttribArray(2); free(render_buffer); } // Swap buffers glfwSwapBuffers(window); glfwPollEvents(); 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 cx_glinit(GLFWwindow **window) { // 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); // To make MacOS happy; should not be needed glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 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); return 0; } 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; } int cx_run(GLFWwindow *window, Neural_Network *nn) { Model *model; ModelRegistry *mr; Model *neural_network_model; GLuint VertexArrayID; GLuint programID; if (cx_loadShaders(&VertexArrayID, &programID)) { return -1; } // Establish a model registry mr = modelRegistry_new(); // Fill the model registry with mesh models for (int j = 0; j < nn->layer_count; j++) { Neural_Layer *nl = nn->layers[j]; for (int i = 0; i < nl->layer_size; i++) { // Load model to render from file //Model *model = model_load("../3d_assets/triangle.obj"); 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); } model = model_circle(0, (GLfloat)1/64); GLfloat *translation_matrix = matrix_new(); GLfloat *aspectRatio_matrix = matrix_new(); aspectRatio_matrix[0] = (GLfloat)9/16; translation_matrix[3] = (((GLfloat)-1*16/9)*.90) + ((GLfloat)1/(nl->layer_size-1)*2 * i * (((GLfloat)16/9))*.90); translation_matrix[7] = .90 - ((GLfloat)1/(nn->layer_count)*2 * j *.90); model->transformations[0] = translation_matrix; model->transformations[1] = aspectRatio_matrix; model->transformation_count = 2; model_colorWhite(model); modelRegistry_register(mr, model); } } // Remainder from cursor experiments, might be useful later double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); int t = 0; do { 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)); // Close OpenGL window and terminate GLFW glfwTerminate(); modelRegistry_free(mr); return 0; } int cx_nninit(Neural_Network **nn) { // Allocate a Neural Network *nn = neural_new(64, 4, 8); if(!*nn) { fprintf(stderr, "Failed to initialize Neural Network.\n"); return -1; } // Populate the neural network with sensible values. neural_randomize(*nn); return 0; }