diff --git a/callback.c b/callback.c index eeffc12..a7ba971 100644 --- a/callback.c +++ b/callback.c @@ -79,14 +79,14 @@ gboolean on_glarea_render(GtkGLArea *area, GdkGLContext *context) { // Check if the widget is a glarea if(gtk_gl_area_get_error(area) != NULL) { -////////////////////////// on_auto_notification("An OpenGL error occured !"); + on_auto_notification("An OpenGL error occured !"); return false; } -////////////////////////// if (ui_render_stack(gtk_widget_get_parent(GTK_WIDGET(area))) == false) { -////////////////////////// on_auto_notification("Failed to render corresponding graphic stack !"); -////////////////////////// return false; -////////////////////////// } + if (ui_render_stack(gtk_widget_get_parent(GTK_WIDGET(area))) == false) { + on_auto_notification("Failed to render corresponding graphic stack !"); + return false; + } return true; } diff --git a/draw.c.todo b/draw.c similarity index 95% rename from draw.c.todo rename to draw.c index 53f0079..fea1ca7 100644 --- a/draw.c.todo +++ b/draw.c @@ -151,9 +151,9 @@ void graphics_draw(const int stack_id) { struct graphic_stack_t *stack = &graphic_stack[stack_id]; - //g_printerr("[debug] graphics_draw() started\n"); + g_printerr("[debug] graphics_draw() started\n"); - //print_stack(stack_id); + print_stack(stack_id); GLint cur_viewport[4]; glGetIntegerv(GL_VIEWPORT, cur_viewport); @@ -166,9 +166,9 @@ void graphics_draw(const int stack_id) mat4 v = GLM_MAT4_IDENTITY_INIT; // XXX define zoom and translations here ? mat4 p = GLM_MAT4_IDENTITY_INIT; - //glm_ortho(-1.0f, +1.0f, -1.0f, +1.0f, -1.0f, +1.0f, p); + glm_ortho(-1.0f, +1.0f, -1.0f, +1.0f, -1.0f, +1.0f, p); glm_ortho_default((float)cur_viewport[2] / (float)cur_viewport[3], p); - //glm_perspective_default((float)cur_viewport[2] / (float)cur_viewport[3], p); + glm_perspective_default((float)cur_viewport[2] / (float)cur_viewport[3], p); /* Use our shaders */ glUseProgram(stack->program); @@ -191,7 +191,7 @@ void graphics_draw(const int stack_id) glBindBuffer(GL_ARRAY_BUFFER, stack->color_buffer); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0,(void*)0); - //glEnable(GL_DEPTH_TEST); + glEnable(GL_DEPTH_TEST); glDrawElements(GL_LINES, stack->buffer_lines_size, GL_UNSIGNED_INT, stack->buffer_lines_origin); glDrawElements(GL_TRIANGLES, stack->buffer_plans_size, GL_UNSIGNED_INT, stack->buffer_plans_origin); @@ -203,5 +203,5 @@ void graphics_draw(const int stack_id) glUseProgram(0); glFlush(); - //g_printerr("[debug] graphics_draw() ended\n"); + g_printerr("[debug] graphics_draw() ended\n"); } diff --git a/graph_area.c b/graph_area.c index 602d814..2732cf3 100644 --- a/graph_area.c +++ b/graph_area.c @@ -39,6 +39,23 @@ static struct stack_index_t *stack_index = NULL; size_t stack_index_size = 0; +int set_arrow (int stack_id, // 2024-06-27 DEBUG ! + int arrows_nb, + int space_X, + int space_Y, + int space_Z, + int requested_weight, + int site, + int arrow_x, + int arrow_y, + int arrow_z) { + printf("graph_area.c > int set_arrow (...) 2024-06-27 DEBUG\n"); + return 0; + +} // 2024-06-27 DEBUG ! + + + /* * Look for stack entry and returns stack_id * @@ -151,13 +168,15 @@ bool ui_render_stack(GtkWidget *container_widget) // look for stack_index entry for (int i = 0; i < stack_index_size; i++) { if (stack_index[i].container_widget == (void *)container_widget) { -////////////////////////// graphics_draw (stack_index[i].stack_id); + graphics_draw (stack_index[i].stack_id); return true; } } return false; } +//void graphics_draw(const int stack_id) {printf("graph_area.c > void graphics_draw(const int stack_id) (161)\n");} + /* * Look for stack entry and triggers OpenGL for drawing * @@ -279,12 +298,12 @@ bool ui_setup_glarea(int target_mode, GtkWidget *target_widget) gl_area = GTK_WIDGET(gtk_gl_area_new()); assert(gl_area); - //gtk_widget_set_size_request(gl_area, 1000, 1000); + gtk_widget_set_size_request(gl_area, 1000, 1000); gtk_gl_area_set_auto_render(GTK_GL_AREA(gl_area), true); gtk_widget_set_hexpand(gl_area, TRUE); gtk_widget_set_vexpand(gl_area, TRUE); - //gtk_widget_set_halign(gl_area, GTK_ALIGN_CENTER); - //gtk_widget_set_valign(gl_area, GTK_ALIGN_CENTER); + gtk_widget_set_halign(gl_area, GTK_ALIGN_CENTER); + gtk_widget_set_valign(gl_area, GTK_ALIGN_CENTER); // The main "draw" call for GtkGLArea g_signal_connect(GTK_GL_AREA(gl_area), "render", G_CALLBACK(on_glarea_render), NULL); diff --git a/graph_area.h b/graph_area.h index 528168f..e492cc6 100644 --- a/graph_area.h +++ b/graph_area.h @@ -25,6 +25,8 @@ #pragma once #include +#include +#include #include #include #include @@ -79,6 +81,8 @@ struct graphic_stack_t { long buffer_plans_0_arrow; }; +bool ui_render_stack(GtkWidget *container_widget); + bool ui_setup_glarea(int target_mode, GtkWidget *target_widget); /* diff --git a/graph_stack.c b/graph_stack.c index 1c269b8..6d77b9e 100644 --- a/graph_stack.c +++ b/graph_stack.c @@ -286,10 +286,10 @@ void graphics_model_setup (const int stack_id) /*------------------------------------------------------------------------*/ -////////////////////////// draw_space_ridges_vertex (stack_id, stack->buffer_vertex_size, space_X, space_Y, space_Z); -////////////////////////// draw_space_ridges_lines (stack_id); -////////////////////////// draw_grids_on_space_faces_vertex (stack_id, space_X, space_Y, space_Z); -////////////////////////// draw_grids_on_space_faces_lines (stack_id, stack->buffer_lines_size, space_X, space_Y, space_Z); + draw_space_ridges_vertex (stack_id, stack->buffer_vertex_size, space_X, space_Y, space_Z); + draw_space_ridges_lines (stack_id); + draw_grids_on_space_faces_vertex (stack_id, space_X, space_Y, space_Z); + draw_grids_on_space_faces_lines (stack_id, stack->buffer_lines_size, space_X, space_Y, space_Z); stack->buffer_vertex_0_arrow = stack->buffer_vertex_size; stack->buffer_colors_0_arrow = stack->buffer_colors_size; @@ -314,10 +314,10 @@ void graphics_model_setup (const int stack_id) while (model_get_next_arrow(&arrow, (char *)&state_id, dimension)) { g_print("[GRAPH DEBUG] cur arrow has x = %d\n", arrow.x); -////////////////////////// stack->arrows_nb = set_arrow (stack_id, stack->arrows_nb, space_X, space_Y, space_Z, arrow.load, arrow.site, arrow.x, arrow.y, arrow.z); + stack->arrows_nb = set_arrow (stack_id, stack->arrows_nb, space_X, space_Y, space_Z, arrow.load, arrow.site, arrow.x, arrow.y, arrow.z); } if (stack->arrows_nb != announced_arrows_nb) - g_printerr("ARGH : all the arrows have not been parsed !\n"); + g_printerr("ARGH : not all arrows have been parsed !\n"); } diff --git a/graphics.h b/graphics.h new file mode 100644 index 0000000..c83b60c --- /dev/null +++ b/graphics.h @@ -0,0 +1,314 @@ +/* + * 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 +#include + +#define VERTEX_SHADER_FILE "src/graphics/shaders/shader.vert" +#define FRAG_SHADER_FILE "src/graphics/shaders/shader.frag" +#define GL_TARGET_MAJOR_VERSION 0 +#define GL_TARGET_MINOR_VERSION 4 + +/* + * Structure describing a gl_area and its parameters, used to create a table + * of Gem-graph client current gl_areas + */ +struct graphic_stack_t { + + int id; + int mode; + + float rotation_angles[N_AXIS]; // Rotation angles on each axis + + 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 + + struct arrow_t *arrows_ptr; + long arrows_nb; + + GLfloat *buffer_vertex_origin; + GLfloat *buffer_colors_origin; + GLuint *buffer_lines_origin; + GLuint *buffer_plans_origin; + + long buffer_vertex_size; + long buffer_colors_size; + long buffer_lines_size; + long buffer_plans_size; + + long buffer_vertex_0_arrow; + long buffer_colors_0_arrow; + long buffer_lines_0_arrow; + long buffer_plans_0_arrow; +}; + +/* + * Dynamic array of ptrs to dynamically allocated gl_area_entry + */ +extern struct graphic_stack_t *graphic_stack; + +/* + * Initializes a gl_area + * + * @param gl_area, ptr to the gl_area widget + * + * @return true if initialized + */ +int graphics_init(void *error_buffer); + +/* + * Draws the current buffer to a gl_area + * + * @param gl_area, ptr to the gl_area widget + * + * @return void + */ +//void graphics_draw(const int stack_id); + +/* + * Shutdowns a gl_area + * + * @param gl_area, ptr to the gl_area widget + * + * @return true if success + */ +bool graphics_shutdown(const int stack_id, void *error_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); + +/* 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); + +/* + * 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 (const int stack_id, + GLfloat x, + GLfloat y, + GLfloat z); + +/* + * 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 (const int stack_id, GLfloat r, GLfloat g, GLfloat b); + +/* + * 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 (const int stack_id, GLuint a, GLuint b); + +/* + * 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 (const int stack_id, GLuint a, GLuint b, GLuint c); + +/* + * Created and compile a shader + * + * @param type, shader type + * src, source code of shader + * + * @return shader id + */ +static inline GLuint create_shader(const int stack_id, 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; +} + +static inline void print_stack(int stack_id) +{ + static int n = 0; + + printf("\n[n=%d]***************", n); + + printf("id = %d\tmode = %d\n", + graphic_stack[stack_id].id, + graphic_stack[stack_id].mode); + + printf("rotation_angles = "); + for (int i = 0; i < N_AXIS; i++) { + printf("%f\t", graphic_stack[stack_id].rotation_angles[i]); // Rotation angles on each axis + } + printf("\n"); + + printf("vao = %d\n", graphic_stack[stack_id].vao); + printf("position_buffer = %d\n", graphic_stack[stack_id].position_buffer); + printf("color_buffer = %d\n", graphic_stack[stack_id].color_buffer); + printf("program = %d\n", graphic_stack[stack_id].program); + printf("m = %d\n", graphic_stack[stack_id].m); + printf("v = %d\n", graphic_stack[stack_id].v); + printf("p = %d\n", graphic_stack[stack_id].p); + + printf("arrows_ptr = %p\n", graphic_stack[stack_id].arrows_ptr); + printf("arrows_nb = %ld\n", graphic_stack[stack_id].arrows_nb); + + printf("buffer_vertex_origin = %p\n", graphic_stack[stack_id].buffer_vertex_origin); + printf("buffer_colors_origin = %p\n", graphic_stack[stack_id].buffer_colors_origin); + printf("buffer_lines_origin = %p\n", graphic_stack[stack_id].buffer_lines_origin); + printf("buffer_plans_origin = %p\n", graphic_stack[stack_id].buffer_plans_origin); + + printf("buffer_vertex_size = %ld\n", graphic_stack[stack_id].buffer_vertex_size); + printf("buffer_colors_size = %ld\n", graphic_stack[stack_id].buffer_colors_size); + printf("buffer_lines_size = %ld\n", graphic_stack[stack_id].buffer_lines_size); + printf("buffer_plans_size = %ld\n", graphic_stack[stack_id].buffer_plans_size); + + printf("buffer_vertex_0_arrow = %ld\n", graphic_stack[stack_id].buffer_vertex_0_arrow); + printf("buffer_colors_0_arrow = %ld\n", graphic_stack[stack_id].buffer_colors_0_arrow); + printf("buffer_lines_0_arrow = %ld\n", graphic_stack[stack_id].buffer_lines_0_arrow); + printf("buffer_plans_0_arrow = %ld\n", graphic_stack[stack_id].buffer_plans_0_arrow); + + printf("********************\n"); + n++; +} + + +void graphics_model_setup (const int stack_id); + +int draw_one_arrow_vertex (const int stack_id, + int space_X, + int space_Y, + int space_Z, + int weight, + int site, + int x, + int y, + int z); + +int draw_one_arrow_line(const int stack_id, + int offset_vertex); + +/* + * Writes grid ridges to vertex and color buffers + * + * @param coords long (x,y,z), step_x, step_y, step_z + * + * @return void + */ +int draw_space_ridges_vertex (const int stack_id, + long offset_vertex, + long x, + long y, + long z); + +int draw_space_ridges_lines (const int stack_id); + +/* + * Writes grid lines on space faces + * + * @param coords long (x,y,z) + * + * @return void + */ +long draw_grids_on_space_faces_vertex (const int stack_id, + long x, + long y, + long z); + +long draw_grids_on_space_faces_lines (const int stack_id, + long offset_vertex, + long x, + long y, + long z); + +int set_arrow (int stack_id, + int arrows_nb, + int space_X, + int space_Y, + int space_Z, + int requested_weight, + int site, + int arrow_x, + int arrow_y, + int arrow_z); + diff --git a/grid.c b/grid.c new file mode 100644 index 0000000..0947d80 --- /dev/null +++ b/grid.c @@ -0,0 +1,162 @@ +/* + * Gem-graph + * + * Desc: OpenGL grid functions + * + * Copyright (C) 2023 Jean Sirmai + * 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 "base.h" +//#include "ui.h" +#include "graphics.h" + +int draw_space_ridges_vertex (const int stack_id, + long offset_vertex, + long x, + long y, + long z) +{ + GLfloat max = fmax(x, y); max = fmax(max, z); + + graphics_draw_vertex (stack_id, offset_vertex - x / max, offset_vertex - y / max, - z / max); + + graphics_draw_vertex (stack_id, offset_vertex + x / max, offset_vertex - y / max, - z / max); + graphics_draw_vertex (stack_id, offset_vertex - x / max, offset_vertex + y / max, - z / max); + graphics_draw_vertex (stack_id, offset_vertex - x / max, offset_vertex - y / max, + z / max); + + graphics_draw_vertex (stack_id, offset_vertex + x / max, offset_vertex + y / max, - z / max); + graphics_draw_vertex (stack_id, offset_vertex + x / max, offset_vertex - y / max, + z / max); + graphics_draw_vertex (stack_id, offset_vertex - x / max, offset_vertex + y / max, + z / max); + + graphics_draw_vertex (stack_id, offset_vertex + x / max, + y / max, + z / max); + + graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f); + graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f); + graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f); + graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f); + graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f); + graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f); + graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f); + graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f); + + return 8; +} + +int draw_space_ridges_lines (const int stack_id) +{ + graphics_draw_line (stack_id, 0, 1); graphics_draw_line (stack_id, 7, 4); + graphics_draw_line (stack_id, 0, 2); graphics_draw_line (stack_id, 7, 5); + graphics_draw_line (stack_id, 0, 3); graphics_draw_line (stack_id, 7, 6); + + graphics_draw_line (stack_id, 1, 4); graphics_draw_line (stack_id, 2, 4); + graphics_draw_line (stack_id, 1, 5); graphics_draw_line (stack_id, 3, 5); + graphics_draw_line (stack_id, 2, 6); graphics_draw_line (stack_id, 3, 6); + + return 12; +} + +long draw_grids_on_space_faces_vertex (const int stack_id, + long x, + long y, + long z) +{ + float i, max = fmax(x, y); max = fmax(max, z); + + for (i = 1; i < x; i++) { + + graphics_draw_vertex (stack_id, (2 * i / x - 1) * x / max, - y / max, - z / max); + graphics_draw_vertex (stack_id, (2 * i / x - 1) * x / max, - y / max, z / max); + graphics_draw_vertex (stack_id, (2 * i / x - 1) * x / max, y / max, z / max); + graphics_draw_vertex (stack_id, (2 * i / x - 1) * x / max, y / max, - z / max); + + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + } + + /* offset_vertex += (x - 1) * 4; */ /* offset_colors += (x - 1) * 4; */ + + for (i = 1; i < y; i++) { + + graphics_draw_vertex (stack_id, - x / max, (2 * i / y - 1) * y / max, - z / max); + graphics_draw_vertex (stack_id, - x / max, (2 * i / y - 1) * y / max, z / max); + graphics_draw_vertex (stack_id, x / max, (2 * i / y - 1) * y / max, z / max); + graphics_draw_vertex (stack_id, x / max, (2 * i / y - 1) * y / max, - z / max); + + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + } + + /* offset_vertex += (y - 1) * 4; */ /* offset_colors += (y - 1) * 4; */ + + for (i = 1; i < z; i++) { + + graphics_draw_vertex (stack_id, - x / max, - y / max, (2 * i / z - 1) * z / max); + graphics_draw_vertex (stack_id, - x / max, y / max, (2 * i / z - 1) * z / max); + graphics_draw_vertex (stack_id, x / max, y / max, (2 * i / z - 1) * z / max); + graphics_draw_vertex (stack_id, x / max, - y / max, (2 * i / z - 1) * z / max); + + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f); + } + + return (x + y + z - 3) * 3; +} + + +long draw_grids_on_space_faces_lines (const int stack_id, + long offset_vertex, + long x, + long y, + long z) +{ + offset_vertex = offset_vertex / 3; + + for (int i = 0; i < x - 1; i ++) { + + graphics_draw_line (stack_id, offset_vertex + i * 4 + 1, offset_vertex + i * 4 + 2); + graphics_draw_line (stack_id, offset_vertex + i * 4 + 2, offset_vertex + i * 4 + 3); + } + + offset_vertex += (x - 1) * 4; + + for (int i = 0; i < y - 1; i ++) { + + graphics_draw_line (stack_id, offset_vertex + i * 4 + 2, offset_vertex + i * 4 + 3); + graphics_draw_line (stack_id, offset_vertex + i * 4 + 3, offset_vertex + i * 4 + 0); + } + + offset_vertex += (y - 1) * 4; + + for (int i = 0; i < z - 1; i ++) { + + graphics_draw_line (stack_id, offset_vertex + i * 4 + 0, offset_vertex + i * 4 + 1); + graphics_draw_line (stack_id, offset_vertex + i * 4 + 3, offset_vertex + i * 4 + 0); + } + + return (x + y + z - 3) * 4; +} +