src/util/draw/gl.c: add utils to generate drawing areas
This commit is contained in:
parent
14d0229ecc
commit
ad398cfaad
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue