diff --git a/src/util/draw/gl.c b/src/util/draw/gl.c new file mode 100644 index 0000000..5a96c44 --- /dev/null +++ b/src/util/draw/gl.c @@ -0,0 +1,332 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* Gem-graph client * +* Widgets - graphic stack management * +* * +* Copyright © 2024 Libre en Communs * +* Copyright © 2023-2024 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/graphics.h" +#include "../../../include/signal.h" + +#define GL_AREA_1000 1000 + +struct stack_index_t { + long stack_id; + void *container_widget; + void *gl_area; +}; + +static struct stack_index_t *stack_index = NULL; +size_t stack_index_size = 0; + + +int util_gl_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("util_gl_area.c > int util_gl_set_arrow (...) 2024-06-27 DEBUG\n"); + return 0; + +} // 2024-06-27 DEBUG ! + + + +/* + * Look for stack entry and returns stack_id + * + * @params container_widget, generally the GtkBox that contains the GLArea + * + * @returns stack_id + */ +long util_gl_get_stack(void *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) { + return stack_index[i].stack_id; + } + } + return -1; +} + +/* + * Look for stack entry and returns stack_id + * + * @params container_widget, generally the GtkBox that contains the GLArea + * + * @returns stack_id + */ +long util_gl_is_util_ready(void *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) { + return stack_index[i].stack_id; + } + } + return -1; +} + +/* + * Look for stack entry and initializes OpenGL for it + * + * @params container_widget, generally the GtkBox that contains the GLArea + * + * @returns bool, true if success + */ +bool util_gl_init_stack(void *container_widget, GError *error_buffer) +{ + g_printerr("[debug] util_gl_init_util_gl_stack()\n"); + + g_printerr("[debug] util_gl_init_util_gl_stack() : target is %p\n", container_widget); + + // look for stack_index entry + for (int i = 0; i < stack_index_size; i++) { + g_printerr("[debug] util_gl_init_util_gl_stack() : i is %d\n", i); + g_printerr("[debug] util_gl_init_util_gl_stack() : target would be %p\n", + stack_index[i].container_widget); + if (stack_index[i].container_widget == (void *)container_widget) { + stack_index[i].stack_id = graphics_init(&error_buffer); + g_printerr("[debug] util_gl_init_util_gl_stack() : stack_id is %ld\n", + stack_index[i].stack_id); + if (stack_index[i].stack_id >= 0) + return true; + else + return false; + } + } + return false; +} + +/* + * Look for stack entry and shutdowns OpenGL for it + * + * @params container_widget, generally the GtkBox that contains the GLArea + * + * @returns bool, true if success + */ +bool util_gl_shutdown_stack(void *container_widget, GError *error_buffer) +{ + // look for stack_index entry + for (int i = 0; i < stack_index_size; i++) { + if (stack_index[i].container_widget == (void *)container_widget) { + if (graphics_shutdown(stack_index[i].stack_id, + &error_buffer) == false) { + return false; + } + stack_index[i].stack_id = 0; + return true; + } + } + return false; +} + + +void util_gl_clean_stack_index(void) +{ + // look for stack_index entry + for (int i = 0; i < stack_index_size; i++) { + stack_index[i].stack_id = 0; + } + return; +} + +/* + * Look for stack entry and triggers OpenGL for drawing + * + * @params container_widget, generally the GtkBox that contains the GLArea + * + * @returns bool, true if success + */ +bool util_gl_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); + return true; + } + } + return false; +} + +//void graphics_draw(const int stack_id) {printf("util_gl_area.c > void graphics_draw(const int stack_id) (161)\n");} + +/* + * Look for stack entry and triggers OpenGL for drawing + * + * @params container_widget, generally the GtkBox that contains the GLArea + * + * @returns bool, true if success + */ +bool util_gl_update_axis(GtkWidget *container_widget, int axis, int value) +{ + // look for stack_index entry + for (int i = 0; i < stack_index_size; i++) { + if (stack_index[i].container_widget == (void *)container_widget) { + graphics_stack[stack_index[i].stack_id].rotation_angles[axis] = value; + gtk_widget_queue_draw((GtkWidget*)(stack_index[i].gl_area)); + return true; + } + } + return false; +} + +/* + * Look for every stack entry and shutdowns OpenGL for it + * + * @params void + * + * @returns bool, true if success + */ +void util_gl_shutdown_all_stacks(void) +{ + // look for stack_index entry + for (int i = 0; i < stack_index_size; i++) { + graphics_shutdown(stack_index[i].stack_id, NULL); + } + return; +} + +/* + * Creates a slider widget + * + * @params axis, meaning which axis we're building (for label) + * + * @returns GtkWidget*, pointer to the new widget + */ +GtkWidget *create_axis_slider(int axis) +{ + GtkWidget *box, *label, *slider; + GtkAdjustment *adj; + const char *text; + + box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + + switch (axis) { + case X_AXIS: + text = "X"; + break; + + case Y_AXIS: + text = "Y"; + break; + + case Z_AXIS: + text = "Z"; + break; + + default: + g_assert_not_reached(); + } + + label = gtk_label_new(text); + gtk_box_append(GTK_BOX(box), label); + gtk_widget_set_visible (label, TRUE); + + adj = gtk_adjustment_new(0.0, 0.0, 360.0, 1.0, 12.0, 0.0); + g_signal_connect (adj, "value-changed", G_CALLBACK(on_axis_value_change), (gpointer) label); + slider = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, adj); + gtk_box_append(GTK_BOX(box), slider); + gtk_widget_set_hexpand(slider, TRUE); + gtk_widget_set_visible (slider, TRUE); + + gtk_widget_set_visible (box, TRUE); + + return box; +} + +/* + * Creates GLArea and indexes it + * + * @params target_mode, meaning which util_gl_stack we're on + * target_widget, meaning the box that will host the GLArea + * + * @returns bool, true if success + */ +bool util_gl_setup_glarea(int target_mode, GtkWidget *target_widget) +{ + GtkWidget *gl_area; + + g_printerr("[debug] util_gl_setup_glarea()\n"); + + assert(target_widget); + + g_printerr("[debug] util_gl_setup_glarea() : target is %p\n", target_widget); + + if (stack_index == NULL) { + stack_index = g_malloc(sizeof(struct stack_index_t)); + stack_index_size = 1; + } else { + // look for stack_index entry + for (int i = 0; i < stack_index_size; i++) { + if (stack_index[i].container_widget == (void *)target_widget) { + return false; + } + } + // create entry + stack_index = + g_realloc(stack_index, + ++stack_index_size * sizeof(struct stack_index_t)); + } + + gl_area = GTK_WIDGET(gtk_gl_area_new()); + assert(gl_area); + + gtk_widget_set_size_request(gl_area, GL_AREA_1000, GL_AREA_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); + + // The main "draw" call for GtkGLArea + g_signal_connect(GTK_GL_AREA(gl_area), "render", G_CALLBACK(on_glarea_render), NULL); + g_signal_connect(gl_area, "realize", G_CALLBACK(on_glarea_realize), NULL); + g_signal_connect(gl_area, "unrealize", G_CALLBACK(on_glarea_unrealize), NULL); + + stack_index[stack_index_size-1].container_widget = + (void*)target_widget; + + stack_index[stack_index_size-1].gl_area = (void*)gl_area; + + g_printerr("[debug] util_gl_setup_glarea() : set target to %p\n", target_widget); + + g_printerr("[debug] util_gl_setup_glarea() : stack_index (@0x%p) had %ld elements\n", + stack_index, + stack_index_size); + + gtk_box_append (GTK_BOX (target_widget), gl_area); + gtk_widget_set_visible (GTK_WIDGET (gl_area), TRUE); + + // Create sliders + for(int i = 0; i < N_AXIS; i++) + gtk_box_append(GTK_BOX(target_widget), create_axis_slider(i)); + + return true; +}