atomes 1.1.15
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
startup_testing.c
Go to the documentation of this file.
1/* This file is part of the 'atomes' software
2
3'atomes' is free software: you can redistribute it and/or modify it under the terms
4of the GNU Affero General Public License as published by the Free Software Foundation,
5either version 3 of the License, or (at your option) any later version.
6
7'atomes' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9See the GNU General Public License for more details.
10
11You should have received a copy of the GNU Affero General Public License along with 'atomes'.
12If not, see <https://www.gnu.org/licenses/>
13
14Copyright (C) 2022-2024 by CNRS and University of Strasbourg */
15
22#ifdef HAVE_CONFIG_H
23# include <config.h>
24#endif
25
26#include <gtk/gtk.h>
27#include <gdk/gdk.h>
28#ifdef GTK3
29# include <gtk/gtkx.h>
30#endif
31
32#ifdef G_OS_WIN32
33# include <windef.h>
34# include <windows.h>
35# include <epoxy/gl.h>
36# include <GL/glu.h>
37#else
38# include <epoxy/gl.h>
39# include <GL/glu.h>
40# ifdef OSX
41# include <GL/glx.h>
42# else
43# include <epoxy/glx.h>
44# endif
45#endif
46
47#ifdef G_OS_WIN32
48#define APP_EXTENSION ".exe"
49#else
50#include <pwd.h>
51#define APP_EXTENSION
52#endif
53
54int opengl_visual = 1; // OpenGL visual: 1 = GTK default, 0 = X11 default (GTK3 + GtkGLArea only), -1 = no OpenGL
55
62{
63 char * help = "\nUsage: ATOMES_OPENGL_TESTING\n\n"
64 " atomes OpenGL setup utility\n\n"
65 "options:\n"
66 " -v, --version version information\n"
67 " -h, --help display this help message\n\n";
68 char bug[20] = "\nReport a bug to <";
69 char eh[4] = ">\n";
70
71 printf("%s", help);
72 printf("%s", bug);
73 printf("%s", PACKAGE_BUGREPORT);
74 printf("%s\n", eh);
75}
76
83{
84 char scanid[80]="\natomes OpenGL setup utility\n";
85 char bug[20] = "\nReport a bug to <";
86 char eh[4] = ">\n";
87
88 printf ("%s", scanid);
89 printf ("\n%s version : %s\n", PACKAGE, VERSION);
90 printf ("\nGTK+ version : %1d.%1d.%1d\n",
91 GTK_MAJOR_VERSION,
92 GTK_MINOR_VERSION,
93 GTK_MICRO_VERSION);
94 printf ("%s", bug);
95 printf ("%s", PACKAGE_BUGREPORT);
96 printf ("%s\n", eh);
97}
98
106void show_the_widgets (GtkWidget * widg)
107{
108#ifdef GTK4
109 gtk_widget_set_visible (widg, TRUE);
110#else
111 gtk_widget_show_all (widg);
112#endif
113}
114
122void hide_the_widgets (GtkWidget * widg)
123{
124#ifdef GTK4
125 gtk_widget_set_visible (widg, FALSE);
126#else
127 gtk_widget_hide (widg);
128#endif
129}
130
138gboolean is_the_widget_visible (GtkWidget * widg)
139{
140 if (GTK_IS_WIDGET(widg))
141 {
142 return gtk_widget_is_visible (widg);
143 }
144 else
145 {
146 return FALSE;
147 }
148}
149
157GtkWidget * destroy_this_widget (GtkWidget * widg)
158{
159 if (widg != NULL)
160 {
161 if (GTK_IS_WIDGET(widg))
162 {
163 if (is_the_widget_visible(widg)) hide_the_widgets (widg);
164#ifdef GTK3
165 gtk_widget_destroy (widg);
166#endif
167 }
168 }
169 return NULL;
170}
171
172
180gboolean is_GLExtension_Supported (const char * extension)
181{
182 int i, j;
183 i = j = 0;
184 glGetIntegerv (GL_NUM_EXTENSIONS, & i);
185 for (j=0; j<i; j++)
186 {
187 if (g_strcmp0 (extension, (const char*)glGetStringi(GL_EXTENSIONS, j)) == 0) return TRUE;
188 }
189 return FALSE;
190}
191
198{
199 glEnable (GL_DEPTH_TEST);
200 glDepthMask (GL_TRUE);
201 glDepthFunc (GL_LEQUAL);
202 glDepthRange (0.0f, 1.0f);
203 glClearDepth (1.0f);
204 glEnable (GL_NORMALIZE);
205
206 glShadeModel(GL_SMOOTH);
207 glCullFace(GL_BACK);
208 glEnable (GL_CULL_FACE); // Incompatible with polyhedra viz
209
210 glEnable (GL_COLOR_SUM_EXT);
211
212 glEnable (GL_PROGRAM_POINT_SIZE);
213 glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
214 glEnable (GL_POINT_SPRITE);
215
216 glEnable (GL_POINT_SMOOTH);
217 glHint (GL_POINT_SMOOTH_HINT, GL_NICEST);
218 glEnable (GL_LINE_SMOOTH); // Lines antialiasing
219 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
220
221 glDisable (GL_POLYGON_SMOOTH); // To disable ploygon antialiasing
222 glEnable (GL_POLYGON_STIPPLE);
223 glEnable (GL_POLYGON_OFFSET_FILL);
224
225 glEnable (GL_BLEND);
226 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
227
228 glPolygonOffset (1.0, 1.0);
229 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
230
231 glHint (GL_FOG_HINT, GL_NICEST);
232 glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
233}
234
242GError * init_gtk_gl_area (GtkGLArea * area)
243{
244 if (area == NULL)
245 {
246 area = (GtkGLArea *)gtk_gl_area_new ();
247 }
248 else
249 {
250 gtk_gl_area_make_current (area);
251 }
252 gtk_gl_area_set_has_depth_buffer (area, TRUE);
253 gtk_gl_area_set_has_stencil_buffer (area, TRUE);
254 return gtk_gl_area_get_error (area);
255}
256
257#ifdef GTKGLAREA
266G_MODULE_EXPORT void on_realize (GtkGLArea * area, gpointer data)
267#else
276G_MODULE_EXPORT void on_realize (GtkWidget * widg, gpointer data)
277#endif
278{
279 GError * err;
280#ifdef GTKGLAREA
281 err = init_gtk_gl_area (area);
282 if (err == NULL)
283 {
284#else
285 GdkWindow * xwin = gtk_widget_get_window (widg);
286 GLint attr_list[] = {GLX_DOUBLEBUFFER,
287 GLX_RGBA,
288 GLX_DEPTH_SIZE, 1,
289 GLX_RED_SIZE, 1,
290 GLX_GREEN_SIZE, 1,
291 GLX_BLUE_SIZE, 1,
292 None};
293 XVisualInfo * visualinfo = glXChooseVisual (GDK_WINDOW_XDISPLAY (xwin),
294 gdk_screen_get_number (gdk_window_get_screen (xwin)), attr_list);
295 GLXcontext * glcontext = glXCreateContext (GDK_WINDOW_XDISPLAY (xwin), visualinfo, NULL, TRUE);
296 g_free (visualinfo);
297 if (glXMakeCurrent (GDK_WINDOW_XDISPLAY (xwin), GDK_WINDOW_XID (xwin), glcontext))
298 {
299#endif
300 init_opengl ();
301 }
302 else
303 {
304#ifdef GTK3
305#ifdef GTKGLAREA
306#ifndef G_OS_WIN32
307 if (opengl_visual)
308 {
309 opengl_visual = 0;
310 goto end;
311 }
312#endif
313#endif
314#endif
315 opengl_visual = -1;
316 }
317#ifdef GTK3
318#ifdef GTKGLAREA
319#ifndef G_OS_WIN32
320 end:;
321#endif
322#endif
323#endif
324}
325
326#ifdef GTK3
327#ifdef LINUX
335void gtk_window_change_gdk_visual (GtkWidget * win)
336{
337 // GTK+ > 3.15.1 uses an X11 visual optimized for GTK+'s OpenGL stuff
338 // since revid dae447728d: https://github.com/GNOME/gtk/commit/dae447728d
339 // However, in some cases it simply cannot start an OpenGL context.
340 // This changes to the default X11 visual instead the GTK's default.
341 GdkScreen * screen = gdk_screen_get_default ();
342 GList * visuals = gdk_screen_list_visuals (screen);
343 // printf("n visuals: %u\n", g_list_length(visuals));
344 GdkX11Screen* x11_screen = GDK_X11_SCREEN (screen);
345 g_assert (x11_screen != NULL);
346 Visual * default_xvisual = DefaultVisual (GDK_SCREEN_XDISPLAY(x11_screen), GDK_SCREEN_XNUMBER(x11_screen));
347 GdkVisual * default_visual = NULL;
348 // int i = 0;
349 while (visuals != NULL)
350 {
351 GdkVisual * visual = GDK_X11_VISUAL (visuals -> data);
352 if (default_xvisual -> visualid == gdk_x11_visual_get_xvisual(GDK_X11_VISUAL (visuals -> data)) -> visualid)
353 {
354 // printf("Default visual %d\n", i);
355 default_visual = visual;
356 }
357 // i++;
358 visuals = visuals -> next;
359 }
360 gtk_widget_set_visual (win, default_visual);
361}
362#endif
363#endif
364
372GtkWidget * create_opengl_window (GApplication * app)
373{
374 GtkWidget * win = gtk_application_window_new (GTK_APPLICATION(app));
375#ifdef GTK3
376#ifdef GTKGLAREA
377#ifdef LINUX
378 if (! opengl_visual) gtk_window_change_gdk_visual (win);
379#endif
380#endif
381#endif
382 GtkWidget * area;
383#ifdef GTKGLAREA
384 area = gtk_gl_area_new ();
385#else
386 area = gtk_drawing_area_new ();
387#endif
388#ifdef GTK3
389 gtk_container_add (GTK_CONTAINER(win), area);
390#else
391 gtk_window_set_child (GTK_WINDOW(win), area);
392#endif
393 g_signal_connect (G_OBJECT (area), "realize", G_CALLBACK(on_realize), NULL);
394 show_the_widgets (win);
395 return win;
396}
397
405void test_opengl_window (GApplication * app)
406{
407 GtkWidget * win = create_opengl_window (app);
408#ifdef GTK3
409#ifdef GTKGLAREA
410#ifndef G_OS_WIN32
411 if (! opengl_visual)
412 {
413 win = destroy_this_widget (win);
414 win = create_opengl_window (app);
415 }
416#endif // G_OS_WIN32
417#endif // GTKGLAREA
418#endif // GTK3
419 win = destroy_this_widget (win);
420}
421
430G_MODULE_EXPORT void run_opengl_test (GApplication * app, gpointer data)
431{
432 test_opengl_window (app);
433 g_application_quit (app);
434}
435
436int main (int argc, char * argv[])
437{
438 gboolean RUNC = TRUE;
439 switch (argc)
440 {
441 case 2:
442 if (g_strcmp0 (argv[1], "-h") == 0 || g_strcmp0 (argv[1], "--help") == 0)
443 {
444 printhelp();
445 RUNC=FALSE;
446 }
447 else if (g_strcmp0 (argv[1], "-v") == 0 || g_strcmp0 (argv[1], "--version") == 0)
448 {
449 printversion();
450 RUNC=FALSE;
451 }
452 break;
453 default:
454 break;
455 }
456#ifdef G_OS_WIN32
457#ifndef DEBUG
458 FreeConsole ();
459#endif
460#endif
461 if (RUNC)
462 {
463 GtkApplication * TestOpenGLApp;
464#if GLIB_MINOR_VERSION < 74
465 TestOpenGLApp = gtk_application_new (g_strdup_printf ("fr.ipcms.atomes.ogl-%d", (int)clock()), G_APPLICATION_FLAGS_NONE);
466#else
467 TestOpenGLApp = gtk_application_new (g_strdup_printf ("fr.ipcms.atomes.ogl-%d", (int)clock()), G_APPLICATION_DEFAULT_FLAGS);
468#endif
469 GError * error = NULL;
470 g_application_register (G_APPLICATION(TestOpenGLApp), NULL, & error);
471 g_signal_connect (G_OBJECT(TestOpenGLApp), "activate", G_CALLBACK(run_opengl_test), NULL);
472 int status = g_application_run (G_APPLICATION (TestOpenGLApp), 0, NULL);
473 g_object_unref (TestOpenGLApp);
474 switch (opengl_visual)
475 {
476 case 0:
477 // X11 default
478 return -1;
479 break;
480 case -1:
481 // Impossible
482 return -2;
483 break;
484 default:
485 // Gtk default (0) or impossible with fatal error (1)
486 return status;
487 break;
488 }
489 }
490 return 0;
491}
#define GL_COLOR_SUM_EXT
Definition glwin.h:39
GLXContext glcontext
GdkWindow * xwin
G_MODULE_EXPORT void on_realize(GtkWidget *widg, gpointer data)
realize event for the OpenGL widget
int main(int argc, char *argv[])
int opengl_visual
void printversion()
gboolean is_the_widget_visible(GtkWidget *widg)
test if a GtkWidget exist, then return if it is visible or not
GError * init_gtk_gl_area(GtkGLArea *area)
void test_opengl_window(GApplication *app)
test possibility to create an OpenGL context
G_MODULE_EXPORT void run_opengl_test(GApplication *app, gpointer data)
run the OpenGL testing
void init_opengl()
initialize OpenGL rendering parameters
GtkWidget * create_opengl_window(GApplication *app)
create the test OpenGL window
GtkWidget * destroy_this_widget(GtkWidget *widg)
destroy a GtkWidget
void hide_the_widgets(GtkWidget *widg)
hide GtkWidget
void printhelp()
gboolean is_GLExtension_Supported(const char *extension)
void show_the_widgets(GtkWidget *widg)
show GtkWidget
int status
Definition w_advance.c:160