src/util/draw/gl.c: add utils to generate drawing areas

This commit is contained in:
Adrien Bourmault 2024-09-10 13:25:47 +02:00
parent 14d0229ecc
commit ad398cfaad
1 changed files with 332 additions and 0 deletions

332
src/util/draw/gl.c Normal file
View File

@ -0,0 +1,332 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Gem-graph client *
* Widgets - graphic stack management *
* *
* Copyright © 2024 Libre en Communs <contact@a-lec.org> *
* Copyright © 2023-2024 Adrien Bourmault <neox@a-lec.org> *
* *
* 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 <http://www.gnu.org/licenses/>. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#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;
}