/* * Gem-graph OpenGL experiments * * Desc: OpenGL utils header * * Copyright (C) 2023 Arthur Menges * Copyright (C) 2023 Adrien Bourmault * Copyright (C) 2023 Jean Sirmai * * 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 . */ #pragma once #include "base.h" #include #include #include #include #include /* * Structure describing a gl_area and its parameters, used to create a table * of Gem-graph client current gl_areas */ struct gl_area_entry { char name[16]; GLuint vao; // init_buffers GLuint position_buffer; // shutdown, draw GLuint color_buffer; // shutdown, draw GLuint program; // shutdown, init_shaders, draw GLuint m; // init_shaders, draw GLuint v; // init_shaders, draw GLuint p; // init_shaders, draw }; /* * Find gl_area_entry from a gl_area ptr * * @param gl_area, ptr to the gl_area widget * * * @return entry ptr */ struct gl_area_entry *graphics_find_glarea_from_ptr(const char *name); /* * Initializes a gl_area * * @param gl_area, ptr to the gl_area widget * * @return true if initialized */ bool graphics_init(const char *gl_area); /* * Draws the current buffer to a gl_area * * @param gl_area, ptr to the gl_area widget * * @return void */ void graphics_draw(const void *gl_area); /* * Shutdowns a gl_area * * @param gl_area, ptr to the gl_area widget * * @return true if success */ bool graphics_shutdown(const void *gl_area); /* * 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 void *gl_area); /* 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 void *gl_area); /* * Draws a vertex (x, y, z) * if (console) prints (x, y, z) values to console * * @param GLfloat x, GLfloat y, GLfloat z * * @return void */ void graphics_draw_vertex (GLfloat x, GLfloat y, GLfloat z, int console); /* * Draws the color (r, g, b) associated to a vertex * if (console) prints (r, g, b) values to console * * @param GLfloat r, GLfloat g, GLfloat b * * @return void */ void graphics_draw_color (GLfloat r, GLfloat g, GLfloat b, int console); /* * Writes values to describe a line from a to b into the line buffer * * @param coords GLuint (a,b) * * @return void */ void graphics_draw_line (GLuint a, GLuint b, int console); /* * Writes values to describe an (a,b,c) plan (triangle) into the plan buffer * * @param coords GLuint (a,b,c) * * @return void */ void graphics_draw_plan (GLuint a, GLuint b, GLuint c, int console); /* * Initializes an identity matrix * * @param res, target ptr * * @return void */ static inline void compute_i(float *res) { /* initialize to the identity matrix */ res[0] = 1.f; res[4] = 0.f; res[8] = 0.f; res[12] = 0.f; res[1] = 0.f; res[5] = 1.f; res[9] = 0.f; res[13] = 0.f; res[2] = 0.f; res[6] = 0.f; res[10] = 1.f; res[14] = 0.f; res[3] = 0.f; res[7] = 0.f; res[11] = 0.f; res[15] = 1.f; } /* * Computes the projection matrix * * @param res, target ptr * phi, XXX * theta, XXX * psi, XXX * * @return void */ static inline void compute_mvp(float *res, float phi, float theta, float psi) { float x = phi *(G_PI / 180.f); float y = theta *(G_PI / 180.f); float z = psi *(G_PI / 180.f); float c1 = cosf(x), s1 = sinf(x); float c2 = cosf(y), s2 = sinf(y); float c3 = cosf(z), s3 = sinf(z); float c3c2 = c3 * c2; float s3c1 = s3 * c1; float c3s2s1 = c3 * s2 * s1; float s3s1 = s3 * s1; float c3s2c1 = c3 * s2 * c1; float s3c2 = s3 * c2; float c3c1 = c3 * c1; float s3s2s1 = s3 * s2 * s1; float c3s1 = c3 * s1; float s3s2c1 = s3 * s2 * c1; float c2s1 = c2 * s1; float c2c1 = c2 * c1; compute_i(res); /* apply all three rotations using the three matrices: * * ⎡ c3 s3 0 ⎤ ⎡ c2 0 -s2 ⎤ ⎡ 1 0 0 ⎤ * ⎢ -s3 c3 0 ⎥ ⎢ 0 1 0 ⎥ ⎢ 0 c1 s1 ⎥ * ⎣ 0 0 1 ⎦ ⎣ s2 0 c2 ⎦ ⎣ 0 -s1 c1 ⎦ */ res[0] = c3c2; res[4] = s3c1 + c3s2s1; res[8] = s3s1 - c3s2c1; res[12] = 0.f; res[1] = -s3c2; res[5] = c3c1 - s3s2s1; res[9] = c3s1 + s3s2c1; res[13] = 0.f; res[2] = s2; res[6] = -c2s1; res[10] = c2c1; res[14] = 0.f; res[3] = 0.f; res[7] = 0.f; res[11] = 0.f; res[15] = 1.f; } /* * Created and compile a shader * * @param type, shader type * src, source code of shader * * @return shader id */ static inline GLuint create_shader(int type, const char *src) { GLuint shader; int status; shader = glCreateShader(type); glShaderSource(shader, 1, &src, NULL); glCompileShader(shader); glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if(status == GL_FALSE) { int log_len; char *buffer; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len); buffer = g_malloc(log_len + 1); assert (buffer); glGetShaderInfoLog(shader, log_len, NULL, buffer); g_warning("Compile failure in %s shader:\n%s", type == GL_VERTEX_SHADER ? "vertex" : "fragment", buffer); g_free(buffer); glDeleteShader(shader); return 0; } return shader; } /* * Find the gl_area_entry size * * @param void * * @return size of array */ extern struct gl_area_entry **gl_area_array; static inline short gl_area_size(void) { struct gl_area_entry **cur; short size; // Check uninitialized and quit if (gl_area_array == NULL) return 0; cur = gl_area_array; while(*cur) { cur++; size++; } return size; } /*** TEST ***/ void main_test_graphics (void);