]> Pileus Git - grits/blob - src/gtkgl.c
Abort when opengl setup fails
[grits] / src / gtkgl.c
1 #include <gtk/gtk.h>
2
3 /***************************
4  * GtkGlExt implementation *
5  ***************************/
6 #if defined(USE_GTKGLEXT)
7 #include <gtk/gtkgl.h>
8 void gtk_gl_enable(GtkWidget *widget)
9 {
10         GdkGLConfig *glconfig = gdk_gl_config_new_by_mode(
11                         GDK_GL_MODE_RGBA   | GDK_GL_MODE_DEPTH |
12                         GDK_GL_MODE_ALPHA  | GDK_GL_MODE_DOUBLE);
13         gtk_widget_set_gl_capability(widget,
14                         glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
15 }
16
17 void gtk_gl_begin(GtkWidget *widget)
18 {
19         GdkGLContext  *glcontext  = gtk_widget_get_gl_context(widget);
20         GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
21         gdk_gl_drawable_gl_begin(gldrawable, glcontext);
22 }
23
24 void gtk_gl_end(GtkWidget *widget)
25 {
26         GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
27         gdk_gl_drawable_swap_buffers(gldrawable);
28         gdk_gl_drawable_gl_end(gldrawable);
29 }
30
31 void gtk_gl_disable(GtkWidget *widget)
32 {
33 }
34
35
36 /**********************
37  * X11 implementation *
38  **********************/
39 #elif defined(USE_GLX)
40 #include <GL/glx.h>
41 #include <gdk/gdkx.h>
42 void gtk_gl_enable(GtkWidget *widget)
43 {
44         g_debug("GtkGl: enable");
45         GdkScreen *screen   = gdk_screen_get_default();
46         Display   *xdisplay = GDK_SCREEN_XDISPLAY(screen);
47         gint       nscreen  = GDK_SCREEN_XNUMBER(screen);
48
49         /* Create context */
50         int attribs[] = {GLX_RGBA,
51                          GLX_RED_SIZE,    1,
52                          GLX_GREEN_SIZE,  1,
53                          GLX_BLUE_SIZE,   1,
54                          GLX_ALPHA_SIZE,  1,
55                          GLX_DOUBLEBUFFER,
56                          GLX_DEPTH_SIZE,  1,
57                          None};
58         XVisualInfo *xvinfo  = glXChooseVisual(xdisplay, nscreen, attribs);
59         if (!xvinfo)
60                 g_error("GtkGl: enable - unable to get valid OpenGL Visual");
61         GLXContext   context = glXCreateContext(xdisplay, xvinfo, NULL, False);
62         g_object_set_data(G_OBJECT(widget), "glcontext", context);
63
64         /* Fix up colormap */
65         GdkVisual   *visual = gdk_x11_screen_lookup_visual(screen, xvinfo->visualid);
66         GdkColormap *cmap   = gdk_colormap_new(visual, FALSE);
67         gtk_widget_set_colormap(widget, cmap);
68
69         /* Disable GTK double buffering */
70         gtk_widget_set_double_buffered(widget, FALSE);
71 }
72
73 void gtk_gl_begin(GtkWidget *widget)
74 {
75         g_debug("GtkGl: begin");
76         Display   *xdisplay = GDK_SCREEN_XDISPLAY(gtk_widget_get_screen(widget));
77         Window     xwindow  = GDK_WINDOW_XID(gtk_widget_get_window(widget));
78         GLXContext context  = g_object_get_data(G_OBJECT(widget), "glcontext");
79         glXMakeCurrent(xdisplay, xwindow, context);
80 }
81
82 void gtk_gl_end(GtkWidget *widget)
83 {
84         g_debug("GtkGl: end");
85         Display   *xdisplay = GDK_SCREEN_XDISPLAY(gtk_widget_get_screen(widget));
86         Window     xwindow  = GDK_WINDOW_XID(gtk_widget_get_window(widget));
87         glXSwapBuffers(xdisplay, xwindow);
88 }
89
90 void gtk_gl_disable(GtkWidget *widget)
91 {
92         g_debug("GtkGl: disable");
93         Display   *xdisplay = GDK_SCREEN_XDISPLAY(gtk_widget_get_screen(widget));
94         GLXContext context  = g_object_get_data(G_OBJECT(widget), "glcontext");
95         glXDestroyContext(xdisplay, context);
96 }
97
98
99 /************************
100  * Win32 implementation *
101  ************************/
102 #elif defined(USE_WGL)
103 #include <windows.h>
104 #include <gdk/gdkwin32.h>
105 static void on_realize(GtkWidget *widget, gpointer _)
106 {
107         g_debug("GtkGl: on_realize");
108         gdk_window_ensure_native(gtk_widget_get_window(widget));
109         gtk_widget_set_double_buffered(widget, FALSE);
110
111         HWND  hwnd = GDK_WINDOW_HWND(gtk_widget_get_window(widget));
112         HDC   hDC  = GetDC(hwnd);
113
114         PIXELFORMATDESCRIPTOR pfd = {
115                 .nSize       = sizeof(pfd),
116                 .nVersion    = 1,
117                 .dwFlags     = PFD_DRAW_TO_WINDOW
118                              | PFD_SUPPORT_OPENGL
119                              | PFD_DOUBLEBUFFER,
120                 //.dwFlags     = PFD_SUPPORT_OPENGL
121                 //             | PFD_DRAW_TO_WINDOW,
122                 .iPixelType  = PFD_TYPE_RGBA,
123                 .cColorBits  = 24,
124                 .cAlphaBits  = 8,
125                 .cDepthBits  = 32,
126                 .iLayerType  = PFD_MAIN_PLANE,
127         };
128         int pf = ChoosePixelFormat(hDC, &pfd);
129         if (pf == 0)
130                 g_error("GtkGl: ChoosePixelFormat failed");
131         if (!SetPixelFormat(hDC, pf, &pfd))
132                 g_error("GtkGl: SetPixelFormat failed");
133         HGLRC hRC = wglCreateContext(hDC);
134         if (hRC == NULL)
135                 g_error("GtkGl: wglCreateContext failed");
136         g_object_set_data(G_OBJECT(widget), "glcontext", hRC);
137 }
138
139 void gtk_gl_enable(GtkWidget *widget)
140 {
141         g_debug("GtkGl: enable");
142         g_signal_connect(widget, "realize", G_CALLBACK(on_realize), NULL);
143 }
144
145 void gtk_gl_begin(GtkWidget *widget)
146 {
147         g_debug("GtkGl: begin");
148         HWND  hwnd = GDK_WINDOW_HWND(gtk_widget_get_window(widget));
149         HDC   hDC  = GetDC(hwnd);
150         HGLRC hRC  = g_object_get_data(G_OBJECT(widget), "glcontext");
151         if (!wglMakeCurrent(hDC, hRC))
152                 g_error("GtkGl: wglMakeCurrent failed");
153 }
154
155 void gtk_gl_end(GtkWidget *widget)
156 {
157         g_debug("GtkGl: end");
158         HWND  hwnd = GDK_WINDOW_HWND(gtk_widget_get_window(widget));
159         HDC   hDC  = GetDC(hwnd);
160         if (!SwapBuffers(hDC))
161                 g_error("GtkGl: SwapBuffers failed");
162 }
163
164 void gtk_gl_disable(GtkWidget *widget)
165 {
166         g_debug("GtkGl: disable");
167         HGLRC hRC = g_object_get_data(G_OBJECT(widget), "glcontext");
168         wglDeleteContext(hRC);
169 }
170
171
172
173 /**************************
174  * Mac OSX implementation *
175  **************************/
176 #elif defined(USE_CGL)
177 void gtk_gl_enable(GtkWidget *widget)
178 {
179         CGDisplayCapture( kCGDirectMainDisplay );
180         CGLPixelFormatAttribute attribs[] =
181         {
182                 kCGLPFANoRecovery,
183                 kCGLPFADoubleBuffer,
184                 kCGLPFAFullScreen,
185                 kCGLPFAStencilSize, ( CGLPixelFormatAttribute ) 8,
186                 kCGLPFADisplayMask, ( CGLPixelFormatAttribute ) CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay ),
187                 ( CGLPixelFormatAttribute ) NULL
188         };
189
190         CGLPixelFormatObj pixelFormatObj;
191         GLint numPixelFormats;
192         CGLChoosePixelFormat( attribs, &pixelFormatObj, &numPixelFormats );
193
194         CGLCreateContext( pixelFormatObj, NULL, &contextObj );
195
196         CGLDestroyPixelFormat( pixelFormatObj );
197
198         CGLSetCurrentContext( contextObj );
199         CGLSetFullScreen( contextObj );
200 }
201
202 void gtk_gl_begin(GtkWidget *widget)
203 {
204 }
205
206 void gtk_gl_end(GtkWidget *widget)
207 {
208 }
209
210 void gtk_gl_disable(GtkWidget *widget)
211 {
212 }
213
214
215 /****************************
216  * Undefined implementation *
217  ****************************/
218 #else
219 #warning "Unimplemented GtkGl"
220 void gtk_gl_enable(GtkWidget *widget) { }
221 void gtk_gl_begin(GtkWidget *widget) { }
222 void gtk_gl_end(GtkWidget *widget) { }
223 void gtk_gl_disable(GtkWidget *widget) { }
224 #endif