/* * Gem-graph OpenGL experiments * * Desc: GL functions * * Copyright (C) 2023 Arthur Menges * Copyright (C) 2023 Adrien Bourmault * * This file is part of Gem-graph. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ /* -------------------------------------------------------------------------- */ #include #include #include "../../include/base.h" #include "../../include/ui.h" #include "../../include/graphics.h" /* Initializes the buffer of a gl_area * Calls according to the user preferences * @param gl_area, ptr to the gl_area widget * @return void */ void graphics_init_buffers(const int stack_id) { struct graphic_stack_t *stack = &graphic_stack[stack_id]; //XXX graphics_model_setup(stack_id); GLuint vao, vertex_buffer, color_buffer; glGenBuffers(1, &vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); glBufferData(GL_ARRAY_BUFFER, stack->buffer_vertex_size * sizeof(stack->buffer_vertex_origin[0]), stack->buffer_vertex_origin, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // colors glGenBuffers(1, &color_buffer); glBindBuffer(GL_ARRAY_BUFFER, color_buffer); glBufferData(GL_ARRAY_BUFFER, stack->buffer_colors_size * sizeof(stack->buffer_colors_origin[0]), stack->buffer_colors_origin, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // We only use one VAO, so we always keep it bound glGenVertexArrays(1, &vao); glBindVertexArray(vao); stack->vao = vao; stack->position_buffer = vertex_buffer; stack->color_buffer = color_buffer; } /* * Initializes the shaders of a gl_area and link them to a program * * @param gl_area, ptr to the gl_area widget * * @return true if initialized */ bool graphics_init_shaders(const int stack_id) { struct graphic_stack_t *stack = &graphic_stack[stack_id]; char *vertex_shader; char *fragment_shader; int status; GLuint vertex, fragment; GLuint program = 0; GLuint m = 0; GLuint v = 0; GLuint p = 0; // Load vertex shader file vertex_shader = read_file(VERTEX_SHADER_FILE); if (vertex_shader == NULL) return false; vertex = create_shader(stack_id, GL_VERTEX_SHADER, vertex_shader); if(vertex == 0) { stack->program = 0; g_free(vertex_shader); return false; } // Load fragment shader file fragment_shader = read_file(FRAG_SHADER_FILE); if (fragment_shader == NULL) return false; fragment = create_shader(stack_id, GL_FRAGMENT_SHADER, fragment_shader); if(fragment == 0) { glDeleteShader(vertex); stack->program = 0; g_free(vertex_shader); g_free(fragment_shader); return false; } // Link shaders to program program = glCreateProgram(); glAttachShader(program, vertex); glAttachShader(program, fragment); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &status); if(status == GL_FALSE) { int log_len; char *buffer; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len); buffer = g_malloc(log_len + 1); assert(buffer); glGetProgramInfoLog(program, log_len, NULL, buffer); g_warning("Linking failure:\n%s", buffer); g_free(buffer); glDeleteProgram(program); program = 0; glDeleteShader(vertex); glDeleteShader(fragment); g_free(vertex_shader); g_free(fragment_shader); return false; } /* Get the location of the "mvp" uniform */ m = glGetUniformLocation(program, "model_matrix"); v = glGetUniformLocation(program, "view_matrix"); p = glGetUniformLocation(program, "projection_matrix"); glDetachShader(program, vertex); glDetachShader(program, fragment); glDeleteShader(vertex); glDeleteShader(fragment); stack->program = program; stack->m = m; stack->v = v; stack->p = p; g_free(vertex_shader); g_free(fragment_shader); return true; }