2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
25
#include <gtk/gtkgl.h>
27
#include <X11/extensions/Xrender.h>
29
#include <GL/glxext.h>
32
#include "cairo-dock-log.h"
33
#include "cairo-dock-dock-factory.h"
34
#include "cairo-dock-load.h"
35
#include "cairo-dock-internal-icons.h"
36
#include "cairo-dock-internal-system.h"
37
#include "cairo-dock-draw-opengl.h"
38
#include "cairo-dock-X-manager.h"
39
#include "cairo-dock-opengl.h"
41
CairoDockGLConfig g_openglConfig;
42
gboolean g_bUseOpenGL = FALSE;
44
extern CairoContainer *g_pPrimaryContainer;
45
extern CairoDockDesktopGeometry g_desktopGeometry;
46
extern CairoDockDesktopBackground *g_pFakeTransparencyDesktopBg;
47
extern gboolean g_bEasterEggs;
49
static inline gboolean _check_extension (const char *extName, const gchar *cExtensions)
51
g_return_val_if_fail (cExtensions != NULL, FALSE);
53
** Search for extName in the extensions string. Use of strstr()
54
** is not sufficient because extension names can be prefixes of
55
** other extension names. Could use strtok() but the constant
56
** string returned by glGetString can be in read-only memory.
58
char *p = (char *) cExtensions;
63
extNameLen = strlen(extName);
68
int n = strcspn(p, " ");
69
if ((extNameLen == n) && (strncmp(extName, p, n) == 0))
77
static gboolean _check_gl_extension (const char *extName)
79
const gchar *glExtensions = glGetString (GL_EXTENSIONS);
80
return _check_extension (extName, glExtensions);
82
static gboolean _check_client_glx_extension (const char *extName)
84
Display *display = gdk_x11_get_default_xdisplay ();
86
//const gchar *glxExtensions = glXQueryExtensionsString (display, screen);
87
const gchar *glxExtensions = glXGetClientString (display,GLX_EXTENSIONS);
88
return _check_extension (extName, glxExtensions);
92
static inline XVisualInfo *_get_visual_from_fbconfigs (GLXFBConfig *pFBConfigs, int iNumOfFBConfigs, Display *XDisplay)
94
XRenderPictFormat *pPictFormat;
95
XVisualInfo *pVisInfo = NULL;
97
for (i = 0; i < iNumOfFBConfigs; i++)
99
pVisInfo = glXGetVisualFromFBConfig (XDisplay, pFBConfigs[i]);
102
cd_warning ("this FBConfig has no visual.");
106
pPictFormat = XRenderFindVisualFormat (XDisplay, pVisInfo->visual);
109
cd_warning ("this visual has an unknown format.");
115
if (pPictFormat->direct.alphaMask > 0)
117
cd_message ("Strike, found a GLX visual with alpha-support !");
127
gboolean cairo_dock_initialize_opengl_backend (gboolean bToggleIndirectRendering, gboolean bForceOpenGL) // taken from a MacSlow's exemple.
129
memset (&g_openglConfig, 0, sizeof (CairoDockGLConfig));
130
g_bUseOpenGL = FALSE;
131
g_openglConfig.bHasBeenForced = bForceOpenGL;
132
gboolean bStencilBufferAvailable, bAlphaAvailable;
133
Display *XDisplay = gdk_x11_get_default_xdisplay ();
135
//\_________________ On cherche un visual qui reponde a tous les criteres.
136
GLXFBConfig *pFBConfigs;
137
XRenderPictFormat *pPictFormat = NULL;
138
int doubleBufferAttributes[] = {
139
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
140
GLX_RENDER_TYPE, GLX_RGBA_BIT,
141
GLX_DOUBLEBUFFER, True,
149
GLX_SAMPLE_BUFFERS_ARB, 1,
151
/*GL_MULTISAMPLEBUFFERS, 1,
152
GL_MULTISAMPLESAMPLES, 2,*/
155
XVisualInfo *pVisInfo = NULL;
156
int iNumOfFBConfigs = 0;
157
pFBConfigs = glXChooseFBConfig (XDisplay,
158
DefaultScreen (XDisplay),
159
doubleBufferAttributes,
161
cd_debug ("got %d FBConfig(s)", iNumOfFBConfigs);
162
bStencilBufferAvailable = TRUE;
163
bAlphaAvailable = TRUE;
165
pVisInfo = _get_visual_from_fbconfigs (pFBConfigs, iNumOfFBConfigs, XDisplay);
169
//\_________________ Si pas trouve, on en cherche un moins contraignant.
170
if (pVisInfo == NULL)
172
cd_warning ("couldn't find an appropriate visual, trying to get one without Stencil buffer\n(it may cause some little deterioration in the rendering) ...");
173
doubleBufferAttributes[16] = None;
174
pFBConfigs = glXChooseFBConfig (XDisplay,
175
DefaultScreen (XDisplay),
176
doubleBufferAttributes,
178
cd_debug ("this time got %d FBConfig(s)", iNumOfFBConfigs);
179
bStencilBufferAvailable = FALSE;
180
bAlphaAvailable = TRUE;
182
pVisInfo = _get_visual_from_fbconfigs (pFBConfigs, iNumOfFBConfigs, XDisplay);
187
//\_________________ Si toujours rien, on essaye avec la methode de gdkgl.
188
if (pVisInfo == NULL)
190
cd_warning ("still couldn't find an appropriate visual ourself, trying something else, this may not work with some drivers ...");
191
g_openglConfig.pGlConfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
195
GDK_GL_MODE_STENCIL);
196
bStencilBufferAvailable = TRUE;
197
bAlphaAvailable = TRUE;
199
if (g_openglConfig.pGlConfig == NULL)
201
cd_warning ("no luck, trying without double-buffer and stencil ...");
202
g_openglConfig.pGlConfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
205
bStencilBufferAvailable = FALSE;
206
bAlphaAvailable = TRUE;
210
//\_________________ Si toujours rien et si l'utilisateur n'en demord pas, on en cherche un sans canal alpha.
211
if (pVisInfo == NULL && g_openglConfig.pGlConfig == NULL && bForceOpenGL)
213
cd_warning ("we could not get an ARGB-visual, trying to get an RGB one (fake transparency will be used in return) ...");
214
g_openglConfig.bAlphaAvailable = FALSE;
215
doubleBufferAttributes[14] = None;
216
int i, iNumOfFBConfigs;
217
pFBConfigs = glXChooseFBConfig (XDisplay,
218
DefaultScreen (XDisplay),
219
doubleBufferAttributes,
221
bStencilBufferAvailable = FALSE;
222
bAlphaAvailable = FALSE;
223
cd_debug ("got %d FBConfig(s) without alpha channel", iNumOfFBConfigs);
224
for (i = 0; i < iNumOfFBConfigs; i++)
226
pVisInfo = glXGetVisualFromFBConfig (XDisplay, pFBConfigs[i]);
229
cd_warning ("this FBConfig has no visual.");
239
if (pVisInfo == NULL)
241
cd_warning ("still no visual, this is the last chance");
242
pVisInfo = glXChooseVisual (XDisplay,
243
DefaultScreen (XDisplay),
244
doubleBufferAttributes);
247
g_openglConfig.bStencilBufferAvailable = bStencilBufferAvailable;
248
g_openglConfig.bAlphaAvailable = bAlphaAvailable;
250
//\_________________ Si rien de chez rien, on quitte.
251
if (pVisInfo == NULL && g_openglConfig.pGlConfig == NULL)
253
cd_warning ("couldn't find a suitable GLX Visual, OpenGL can't be used.\n (sorry to say that, but your graphic card and/or its driver is crappy)");
257
//\_________________ On en deduit une config opengl valide pour les widgets gtk.
258
if (pVisInfo != NULL)
260
cd_message ("ok, got a visual");
261
g_openglConfig.pGlConfig = gdk_x11_gl_config_new_from_visualid (pVisInfo->visualid);
264
g_return_val_if_fail (g_openglConfig.pGlConfig != NULL, FALSE);
267
//\_________________ On regarde si le rendu doit etre indirect ou pas.
268
g_openglConfig.bIndirectRendering = bToggleIndirectRendering;
269
/**if (glXQueryVersion(XDisplay, &g_openglConfig.iGlxMajor, &g_openglConfig.iGlxMinor) == False)
271
cd_warning ("GLX not available !\nFear the worst !");
275
if (g_openglConfig.iGlxMajor <= 1 && g_openglConfig.iGlxMinor < 3) // on a besoin de GLX >= 1.3 pour les pbuffers; mais si on a l'extension GLX_SGIX_pbuffer et un version inferieure, ca marche quand meme.
277
if (! _check_client_glx_extension ("GLX_SGIX_pbuffer"))
279
cd_warning ("No pbuffer extension in GLX.\n this might affect the drawing of some applets which are inside a dock");
283
cd_warning ("GLX version too old (%d.%d).\nCairo-Dock needs at least GLX 1.3. Indirect rendering will be toggled on/off as a workaround.", g_openglConfig.iGlxMajor, g_openglConfig.iGlxMinor);
284
g_openglConfig.bPBufferAvailable = TRUE;
285
g_openglConfig.bIndirectRendering = ! bToggleIndirectRendering;
290
g_openglConfig.bPBufferAvailable = TRUE;
294
//\_________________ on verifier les capacites des textures.
295
g_openglConfig.bTextureFromPixmapAvailable = _check_client_glx_extension ("GLX_EXT_texture_from_pixmap");
296
if (g_openglConfig.bTextureFromPixmapAvailable)
298
g_openglConfig.bindTexImage = (gpointer)glXGetProcAddress ("glXBindTexImageEXT");
299
g_openglConfig.releaseTexImage = (gpointer)glXGetProcAddress ("glXReleaseTexImageEXT");
300
g_openglConfig.bTextureFromPixmapAvailable = (g_openglConfig.bindTexImage && g_openglConfig.releaseTexImage);
308
void cairo_dock_create_icon_fbo (void) // it has been found that you get a speed boost if your textures is the same size and you use 1 FBO for them. => c'est le cas general dans le dock. Du coup on est gagnant a ne faire qu'un seul FBO pour toutes les icones.
310
if (! g_openglConfig.bFboAvailable)
312
g_return_if_fail (g_openglConfig.iFboId == 0);
314
glGenFramebuffersEXT(1, &g_openglConfig.iFboId);
316
int iWidth = 0, iHeight = 0;
318
for (i = 0; i < CAIRO_DOCK_NB_TYPES; i += 2)
320
iWidth = MAX (iWidth, myIcons.tIconAuthorizedWidth[i]);
321
iHeight = MAX (iHeight, myIcons.tIconAuthorizedHeight[i]);
327
iWidth *= (1 + myIcons.fAmplitude);
328
iHeight *= (1 + myIcons.fAmplitude);
329
g_openglConfig.iRedirectedTexture = cairo_dock_load_texture_from_raw_data (NULL, iWidth, iHeight);
332
void cairo_dock_destroy_icon_fbo (void)
334
if (g_openglConfig.iFboId == 0)
336
glDeleteFramebuffersEXT (1, &g_openglConfig.iFboId);
337
g_openglConfig.iFboId = 0;
339
_cairo_dock_delete_texture (g_openglConfig.iRedirectedTexture);
340
g_openglConfig.iRedirectedTexture = 0;
343
/**static GLXPbuffer _cairo_dock_create_pbuffer (int iWidth, int iHeight, GLXContext *pContext)
345
Display *XDisplay = gdk_x11_get_default_xdisplay ();
347
GLXFBConfig *pFBConfigs;
348
XRenderPictFormat *pPictFormat = NULL;
350
GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
351
GLX_RENDER_TYPE, GLX_RGBA_BIT,
359
XVisualInfo *pVisInfo = NULL;
360
int i, iNumOfFBConfigs = 0;
361
pFBConfigs = glXChooseFBConfig (XDisplay,
362
DefaultScreen (XDisplay),
365
if (iNumOfFBConfigs == 0)
367
cd_warning ("No suitable visual could be found for pbuffer\n this might affect the drawing of some applets which are inside a dock");
371
cd_debug (" -> %d FBConfig(s) pour le pbuffer", iNumOfFBConfigs);
373
int pbufAttribs [] = {
374
GLX_PBUFFER_WIDTH, iWidth,
375
GLX_PBUFFER_HEIGHT, iHeight,
376
GLX_LARGEST_PBUFFER, True,
378
GLXPbuffer pbuffer = glXCreatePbuffer (XDisplay, pFBConfigs[0], pbufAttribs);
380
pVisInfo = glXGetVisualFromFBConfig (XDisplay, pFBConfigs[0]);
382
GdkGLContext *pGlContext = gtk_widget_get_gl_context (g_pMainDock->container.pWidget);
383
GLXContext mainContext = GDK_GL_CONTEXT_GLXCONTEXT (pGlContext);
384
*pContext = glXCreateContext (XDisplay, pVisInfo, mainContext, ! g_openglConfig.bIndirectRendering);
392
void cairo_dock_create_icon_pbuffer (void)
394
if (! g_openglConfig.pGlConfig || ! g_openglConfig.bPBufferAvailable)
396
int iWidth = 0, iHeight = 0;
398
for (i = 0; i < CAIRO_DOCK_NB_TYPES; i += 2)
400
iWidth = MAX (iWidth, myIcons.tIconAuthorizedWidth[i]);
401
iHeight = MAX (iHeight, myIcons.tIconAuthorizedHeight[i]);
407
iWidth *= (1 + myIcons.fAmplitude);
408
iHeight *= (1 + myIcons.fAmplitude);
410
cd_debug ("%s (%dx%d)", __func__, iWidth, iHeight);
411
if (g_openglConfig.iIconPbufferWidth != iWidth || g_openglConfig.iIconPbufferHeight != iHeight)
413
Display *XDisplay = gdk_x11_get_default_xdisplay ();
414
if (g_openglConfig.iconPbuffer != 0)
416
glXDestroyPbuffer (XDisplay, g_openglConfig.iconPbuffer);
417
glXDestroyContext (XDisplay, g_openglConfig.iconContext);
418
g_openglConfig.iconContext = 0;
420
g_openglConfig.iconPbuffer = _cairo_dock_create_pbuffer (iWidth, iHeight, &g_openglConfig.iconContext);
421
g_openglConfig.iIconPbufferWidth = iWidth;
422
g_openglConfig.iIconPbufferHeight = iHeight;
424
cd_debug ("activating pbuffer, usually buggy drivers will crash here ...");
425
if (g_openglConfig.iconPbuffer != 0 && g_openglConfig.iconContext != 0 && glXMakeCurrent (XDisplay, g_openglConfig.iconPbuffer, g_openglConfig.iconContext))
427
glMatrixMode(GL_PROJECTION);
429
glOrtho(0, iWidth, 0, iHeight, 0.0, 500.0);
430
glMatrixMode (GL_MODELVIEW);
433
gluLookAt (0., 0., 3.,
437
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
440
cd_debug (" ok, they are fine enough.\n");
444
void cairo_dock_destroy_icon_pbuffer (void)
446
Display *XDisplay = gdk_x11_get_default_xdisplay ();
447
if (g_openglConfig.iconPbuffer != 0)
449
glXDestroyPbuffer (XDisplay, g_openglConfig.iconPbuffer);
450
g_openglConfig.iconPbuffer = 0;
452
if (g_openglConfig.iconContext != 0)
454
glXDestroyContext (XDisplay, g_openglConfig.iconContext);
455
g_openglConfig.iconContext = 0;
457
g_openglConfig.iIconPbufferWidth = 0;
458
g_openglConfig.iIconPbufferHeight = 0;
461
gboolean cairo_dock_begin_draw_icon (Icon *pIcon, CairoContainer *pContainer, gint iRenderingMode)
464
if (CAIRO_DOCK_IS_DESKLET (pContainer))
466
GdkGLContext *pGlContext = gtk_widget_get_gl_context (pContainer->pWidget);
467
GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pContainer->pWidget);
468
if (! gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
471
///cairo_dock_set_ortho_view (pContainer);
472
iWidth = pContainer->iWidth;
473
iHeight = pContainer->iHeight;
474
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
476
else if (g_openglConfig.iFboId != 0)
478
// on attache la texture au FBO.
479
cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
480
if (pContainer == NULL)
481
pContainer = g_pPrimaryContainer;
482
GdkGLContext *pGlContext = gtk_widget_get_gl_context (pContainer->pWidget);
483
GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pContainer->pWidget);
484
if (! gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
486
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, g_openglConfig.iFboId); // on redirige sur notre FBO.
487
g_openglConfig.bRedirected = (iRenderingMode == 2);
488
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
489
GL_COLOR_ATTACHMENT0_EXT,
491
g_openglConfig.bRedirected ? g_openglConfig.iRedirectedTexture : pIcon->iIconTexture,
492
0); // attach the texture to FBO color attachment point.
494
GLenum status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
495
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
497
cd_warning ("FBO not ready for %s (tex:%d)", pIcon->cName, pIcon->iIconTexture);
498
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch back to window-system-provided framebuffer
499
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
500
GL_COLOR_ATTACHMENT0_EXT,
507
// on se positionne au milieu.
508
/**cairo_dock_set_ortho_view (pContainer);
510
glTranslatef (iWidth/2, iHeight/2, - iHeight/2);*/
512
if (iRenderingMode != 1)
513
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
515
/**else if (g_openglConfig.iconContext != 0)
517
Display *XDisplay = gdk_x11_get_default_xdisplay ();
518
if (! glXMakeCurrent (XDisplay, g_openglConfig.iconPbuffer, g_openglConfig.iconContext))
521
glTranslatef (g_openglConfig.iIconPbufferWidth/2, g_openglConfig.iIconPbufferHeight/2, - g_openglConfig.iIconPbufferHeight/2);
526
if (pContainer->bPerspectiveView)
528
cairo_dock_set_ortho_view (pContainer);
529
g_openglConfig.bSetPerspective = TRUE;
533
cairo_dock_set_ortho_view (pContainer); // au demarrage, le contexte n'a pas encore de vue.
535
glTranslatef (iWidth/2, iHeight/2, - iHeight/2);
538
glColor4f(1., 1., 1., 1.);
540
glScalef (1., -1., 1.);
545
void cairo_dock_end_draw_icon (Icon *pIcon, CairoContainer *pContainer)
547
g_return_if_fail (pIcon->iIconTexture != 0);
549
if (CAIRO_DOCK_IS_DESKLET (pContainer))
551
// copie dans notre texture
552
glEnable (GL_TEXTURE_2D);
553
glBindTexture (GL_TEXTURE_2D, pIcon->iIconTexture);
554
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
556
glBlendFunc (GL_ZERO, GL_ONE);
557
glColor4f(1., 1., 1., 1.);
559
int iWidth, iHeight; // taille de la texture
560
cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
561
int x = (pContainer->iWidth - iWidth)/2;
562
int y = (pContainer->iHeight - iHeight)/2;
563
glCopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, x, y, iWidth, iHeight, 0); // target, num mipmap, format, x,y, w,h, border.
565
glDisable (GL_TEXTURE_2D);
566
glDisable (GL_BLEND);
568
else if (g_openglConfig.iFboId != 0)
570
if (g_openglConfig.bRedirected) // copie dans notre texture
572
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
573
GL_COLOR_ATTACHMENT0_EXT,
576
0); // maintenant on dessine dans la texture de l'icone.
577
_cairo_dock_enable_texture ();
578
_cairo_dock_set_blend_source ();
580
int iWidth, iHeight; // taille de la texture
581
cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
584
glTranslatef (iWidth/2, iHeight/2, - iHeight/2);
585
_cairo_dock_apply_texture_at_size_with_alpha (g_openglConfig.iRedirectedTexture, iWidth, iHeight, 1.);
587
_cairo_dock_disable_texture ();
588
g_openglConfig.bRedirected = FALSE;
590
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch back to window-system-provided framebuffer
591
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
592
GL_COLOR_ATTACHMENT0_EXT,
595
0); // on detache la texture (precaution).
596
//glGenerateMipmapEXT(GL_TEXTURE_2D); // si on utilise les mipmaps, il faut les generer explicitement avec les FBO.
600
x = (g_openglConfig.iIconPbufferWidth - iWidth)/2;
601
y = (g_openglConfig.iIconPbufferHeight - iHeight)/2;
604
///if (CAIRO_DOCK_IS_DESKLET (pContainer))
605
if (pContainer && g_openglConfig.bSetPerspective)
607
cairo_dock_set_perspective_view (pContainer);
608
g_openglConfig.bSetPerspective = FALSE;
613
GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pContainer->pWidget);
614
gdk_gl_drawable_gl_end (pGlDrawable);
620
static inline void _cairo_dock_set_perspective_view (int iWidth, int iHeight)
622
glMatrixMode(GL_PROJECTION);
624
gluPerspective(60.0, 1.0*(GLfloat)iWidth/(GLfloat)iHeight, 1., 4*iHeight);
625
glViewport(0, 0, iWidth, iHeight);
626
glMatrixMode (GL_MODELVIEW);
629
gluLookAt (0, 0, 3., 0, 0, 0., 0.0f, 1.0f, 0.0f);
630
//gluLookAt (0/2, 0/2, 3., 0/2, 0/2, 0., 0.0f, 1.0f, 0.0f);
631
glTranslatef (0., 0., -iHeight*(sqrt(3)/2) - 1);
632
//glTranslatef (iWidth/2, iHeight/2, -iHeight*(sqrt(3)/2) - 1);
634
void cairo_dock_set_perspective_view (CairoContainer *pContainer)
637
if (pContainer->bIsHorizontal)
639
w = pContainer->iWidth;
640
h = pContainer->iHeight;
644
w = pContainer->iHeight;
645
h = pContainer->iWidth;
647
_cairo_dock_set_perspective_view (w, h);
648
pContainer->bPerspectiveView = TRUE;
651
void cairo_dock_set_perspective_view_for_icon (Icon *pIcon, CairoContainer *pContainer)
654
cairo_dock_get_icon_extent (pIcon, pContainer, &w, &h);
655
_cairo_dock_set_perspective_view (w, h);
658
static inline void _cairo_dock_set_ortho_view (int iWidth, int iHeight)
660
glMatrixMode(GL_PROJECTION);
662
glOrtho(0, iWidth, 0, iHeight, 0.0, 500.0);
663
glViewport(0, 0, iWidth, iHeight);
664
glMatrixMode (GL_MODELVIEW);
667
gluLookAt (0/2, 0/2, 3.,
670
glTranslatef (iWidth/2, iHeight/2, - iHeight/2);
672
void cairo_dock_set_ortho_view (CairoContainer *pContainer)
675
if (pContainer->bIsHorizontal)
677
w = pContainer->iWidth;
678
h = pContainer->iHeight;
682
w = pContainer->iHeight;
683
h = pContainer->iWidth;
685
_cairo_dock_set_ortho_view (w, h);
686
pContainer->bPerspectiveView = FALSE;
689
void cairo_dock_set_ortho_view_for_icon (Icon *pIcon, CairoContainer *pContainer)
692
cairo_dock_get_icon_extent (pIcon, pContainer, &w, &h);
693
_cairo_dock_set_ortho_view (w, h);
697
void cairo_dock_apply_desktop_background_opengl (CairoContainer *pContainer)
699
if (! mySystem.bUseFakeTransparency || ! g_pFakeTransparencyDesktopBg || g_pFakeTransparencyDesktopBg->iTexture == 0)
703
gboolean bSetPerspective = pContainer->bPerspectiveView;
705
cairo_dock_set_ortho_view (pContainer);
707
_cairo_dock_enable_texture ();
708
_cairo_dock_set_blend_source ();
709
_cairo_dock_set_alpha (1.);
710
glBindTexture (GL_TEXTURE_2D, g_pFakeTransparencyDesktopBg->iTexture);
712
double x, y, w, h, W, H;
713
W = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
714
H = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
715
if (pContainer->bIsHorizontal)
717
w = pContainer->iWidth;
718
h = pContainer->iHeight;
719
x = pContainer->iWindowPositionX;
720
y = pContainer->iWindowPositionY;
724
h = pContainer->iWidth;
725
w = pContainer->iHeight;
726
y = pContainer->iWindowPositionX;
727
x = pContainer->iWindowPositionY;
731
glTexCoord2f ((x + 0) / W, (y + 0) / H);
732
glVertex3f (0., h, 0.); // Top Left.
734
glTexCoord2f ((x + w) / W, (y + 0) / H);
735
glVertex3f (w, h, 0.); // Top Right
737
glTexCoord2f ((x + w) / W, (y + h) / H);
738
glVertex3f (w, 0., 0.); // Bottom Right
740
glTexCoord2f ((x + 0.) / W, (y + h) / H);
741
glVertex3f (0., 0., 0.); // Bottom Left
744
_cairo_dock_disable_texture ();
746
cairo_dock_set_perspective_view (pContainer);
753
static void _cairo_dock_post_initialize_opengl_backend (GtkWidget* pWidget, gpointer data) // initialisation necessitant un contexte opengl.
755
static gboolean bChecked=FALSE;
758
GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
759
GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
760
if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
764
g_openglConfig.bNonPowerOfTwoAvailable = _check_gl_extension ("GL_ARB_texture_non_power_of_two");
765
g_openglConfig.bFboAvailable = _check_gl_extension ("GL_EXT_framebuffer_object");
766
if (!g_openglConfig.bFboAvailable)
767
cd_warning ("No FBO support, some applets will be invisible if placed inside the dock.");
769
g_openglConfig.bNonPowerOfTwoAvailable = _check_gl_extension ("GL_ARB_texture_non_power_of_two");
770
g_openglConfig.bAccumBufferAvailable = _check_gl_extension ("GL_SUN_slice_accum");
772
GLfloat fMaximumAnistropy = 0.;
773
if (_check_gl_extension ("GL_EXT_texture_filter_anisotropic"))
775
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fMaximumAnistropy);
776
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaximumAnistropy);
779
cd_debug ("OpenGL config summary :\n - bNonPowerOfTwoAvailable : %d\n - bFboAvailable : %d\n - direct rendering : %d\n - bTextureFromPixmapAvailable : %d\n - bAccumBufferAvailable : %d\n - Anisotroy filtering level max : %.1f\n - OpenGL version: %s\n - OpenGL vendor: %s\n - OpenGL renderer: %s\n\n",
780
g_openglConfig.bNonPowerOfTwoAvailable,
781
g_openglConfig.bFboAvailable,
782
!g_openglConfig.bIndirectRendering,
783
g_openglConfig.bTextureFromPixmapAvailable,
784
g_openglConfig.bAccumBufferAvailable,
786
glGetString (GL_VERSION),
787
glGetString (GL_VENDOR),
788
glGetString (GL_RENDERER));
790
gdk_gl_drawable_gl_end (pGlDrawable);
794
static void _reset_opengl_context (GtkWidget* pWidget, gpointer data)
799
GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
800
GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
801
if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
804
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
807
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
811
glEnable (GL_MULTISAMPLE_ARB);
813
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // GL_MODULATE / GL_DECAL / GL_BLEND
814
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
815
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
816
glTexParameteri (GL_TEXTURE_2D,
817
GL_TEXTURE_MIN_FILTER,
818
GL_LINEAR_MIPMAP_LINEAR);
819
glTexParameteri (GL_TEXTURE_2D,
820
GL_TEXTURE_MAG_FILTER,
823
gdk_gl_drawable_gl_end (pGlDrawable);
825
void cairo_dock_set_gl_capabilities (GtkWidget *pWindow)
827
gboolean bFirstContainer = (! g_pPrimaryContainer || ! g_pPrimaryContainer->pWidget);
828
GdkGLContext *pMainGlContext = (bFirstContainer ? NULL : gtk_widget_get_gl_context (g_pPrimaryContainer->pWidget)); // NULL si on est en train de creer la fenetre du main dock, ce qui nous convient.
829
gtk_widget_set_gl_capability (pWindow,
830
g_openglConfig.pGlConfig,
831
pMainGlContext, // on partage les ressources entre les contextes.
832
! g_openglConfig.bIndirectRendering, // TRUE <=> direct connection to the graphics system.
834
if (bFirstContainer) // c'est donc le 1er container cree, on finit l'initialisation du backend opengl.
835
g_signal_connect (G_OBJECT (pWindow),
837
G_CALLBACK (_cairo_dock_post_initialize_opengl_backend),
839
g_signal_connect_after (G_OBJECT (pWindow),
841
G_CALLBACK (_reset_opengl_context),