#include "app.h" #include "platform.h" bool compile_shaders(const char *vert, const char *frag, u32 *handle, PlatformAPI platform) { int success = 0; char memory[MB(1)] = {0}; // Memory for reading shader files // Initialize shader handles. u32 vert_handle = glCreateShader(GL_VERTEX_SHADER); u32 frag_handle = glCreateShader(GL_FRAGMENT_SHADER); // Vertex shader. { platform.read_file(vert, memory); const char * source = memory; glShaderSource(vert_handle, 1, &source, NULL); glCompileShader(vert_handle); glGetShaderiv(vert_handle, GL_COMPILE_STATUS, &success); if (!success) { glDeleteShader(vert_handle); glDeleteShader(frag_handle); return false; } } // Fragment shader. { platform.read_file(frag, memory); const char * source = memory; glShaderSource(frag_handle, 1, &source, NULL); glCompileShader(frag_handle); glGetShaderiv(frag_handle, GL_COMPILE_STATUS, &success); if (!success) { glDeleteShader(vert_handle); glDeleteShader(frag_handle); return false; } } // Program linkage. *handle = glCreateProgram(); glAttachShader(*handle, vert_handle); glAttachShader(*handle, frag_handle); glLinkProgram(*handle); glGetProgramiv(*handle, GL_LINK_STATUS, &success); if(!success) { glDeleteProgram(*handle); glDeleteShader(vert_handle); glDeleteShader(frag_handle); return false; } glDeleteShader(vert_handle); glDeleteShader(frag_handle); return true; } static inline bool app_init(AppState *state, PlatformAPI platform) { platform.log("INIT"); // Initialize GLFW. if (!glfwInit()) { platform.log("ERROR: failed to initialize GLFW"); return false; } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Initialize window. GLFWwindow* window = glfwCreateWindow(400, 300, "Hello MIC", NULL, NULL); if (window == NULL) { platform.log("ERROR: failed to create GLFW window"); glfwTerminate(); return false; } glfwMakeContextCurrent(window); // Initialize GLEW. if(glewInit() != GLEW_OK) { platform.log("ERROR: glew initialization"); glfwTerminate(); return false; } // Initialize viewport. glViewport(0, 0, 400, 300); // Initialize vertex data. state->vertices[0] = -0.5f; state->vertices[1] = -0.5f; state->vertices[2] = 0.0f; state->vertices[3] = 0.5f; state->vertices[4] = -0.5f; state->vertices[5] = 0.0f; state->vertices[6] = 0.0f; state->vertices[7] = 0.5f; state->vertices[8] = 0.0f; // Initialize Vertex Buffer Object (VBO) and Vertex Array Object (VAO). u32 VBO; glGenBuffers(1, &VBO); u32 VAO; glGenVertexArrays(1, &VAO); // Bind the VAO before any other binding. glBindVertexArray(VAO); // Send vertex data to VBO. glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(state->vertices), state->vertices, GL_STATIC_DRAW); // Set vertex attribute pointers. glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); // Compile shader program. const char *vert = "shaders/triangle.vert"; const char *frag = "shaders/triangle.frag"; if (!compile_shaders(vert, frag, &state->shader_program, platform)) { platform.log("WARNING: failed to compile shader program"); } // Initialize application state. state->window = window; state->VBO = VBO; state->VAO = VAO; return true; } static inline void app_destroy(AppState *state, PlatformAPI platform) { (void)state; // Unused parameter. platform.log("DESTROY"); } static inline void app_reload(AppState *state, PlatformAPI platform) { platform.log("RELOAD"); glDeleteProgram(state->shader_program); const char *vert = "shaders/triangle.vert"; const char *frag = "shaders/triangle.frag"; if (!compile_shaders(vert, frag, &state->shader_program, platform)) { platform.log("WARNING: failed to compile shader program"); } } static inline void app_unload(AppState *state, PlatformAPI platform) { (void)state; // Unused parameter. platform.log("UNLOAD"); } static inline bool app_step(AppState *state, PlatformAPI platform) { (void)platform; // Unused parameter glClearColor(0.8f, 0.0f, 0.4f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(state->shader_program); glBindVertexArray(state->VAO); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(state->window); glfwPollEvents(); return true; } const AppAPI APP_API = { .init = app_init, .destroy = app_destroy, .reload = app_reload, .step = app_step, .unload = app_unload, };