static void _render_desklet_opengl (CairoDesklet *pDesklet)
{
	gboolean bUseDefaultColors = pDesklet->bUseDefaultColors;
	glPushMatrix ();
	///glTranslatef (0*pDesklet->container.iWidth/2, 0*pDesklet->container.iHeight/2, 0.);  // avec une perspective ortho.
	///glTranslatef (0*pDesklet->container.iWidth/2, 0*pDesklet->container.iHeight/2, -pDesklet->container.iWidth*(1.87 +.35*fabs (sin(pDesklet->fDepthRotationY))));  // avec 30 deg de perspective
	_set_desklet_matrix (pDesklet);
	
	if (bUseDefaultColors)
	{
		_cairo_dock_set_blend_alpha ();
		gldi_style_colors_set_bg_color (NULL);
		cairo_dock_draw_rounded_rectangle_opengl (pDesklet->container.iWidth - 2 * (myStyleParam.iCornerRadius + myStyleParam.iLineWidth), pDesklet->container.iHeight - 2*myStyleParam.iLineWidth, myStyleParam.iCornerRadius, 0, NULL);
		
		gldi_style_colors_set_line_color (NULL);
		cairo_dock_draw_rounded_rectangle_opengl (pDesklet->container.iWidth - 2 * (myStyleParam.iCornerRadius + myStyleParam.iLineWidth), pDesklet->container.iHeight - 2*myStyleParam.iLineWidth, myStyleParam.iCornerRadius, myStyleParam.iLineWidth, NULL);
	}
	
	_cairo_dock_enable_texture ();
	_cairo_dock_set_blend_pbuffer ();
	_cairo_dock_set_alpha (1.);
	if (pDesklet->backGroundImageBuffer.iTexture != 0)
	{
		cairo_dock_apply_image_buffer_texture (&pDesklet->backGroundImageBuffer);
	}
	
	glPushMatrix ();
	if (pDesklet->iLeftSurfaceOffset != 0 || pDesklet->iTopSurfaceOffset != 0 || pDesklet->iRightSurfaceOffset != 0 || pDesklet->iBottomSurfaceOffset != 0)
	{
		glTranslatef ((pDesklet->iLeftSurfaceOffset - pDesklet->iRightSurfaceOffset)/2, (pDesklet->iBottomSurfaceOffset - pDesklet->iTopSurfaceOffset)/2, 0.);
		glScalef (1. - (double)(pDesklet->iLeftSurfaceOffset + pDesklet->iRightSurfaceOffset) / pDesklet->container.iWidth,
			1. - (double)(pDesklet->iTopSurfaceOffset + pDesklet->iBottomSurfaceOffset) / pDesklet->container.iHeight,
			1.);
	}
	
	if (pDesklet->pRenderer != NULL && pDesklet->pRenderer->render_opengl != NULL)  // un moteur de rendu specifique a ete fourni.
	{
		pDesklet->pRenderer->render_opengl (pDesklet);
	}
	glPopMatrix ();
	
	_cairo_dock_enable_texture ();
	_cairo_dock_set_blend_pbuffer ();
	if (pDesklet->foreGroundImageBuffer.iTexture != 0)
	{
		cairo_dock_apply_image_buffer_texture (&pDesklet->foreGroundImageBuffer);
	}
	
	//if (pDesklet->container.bInside && cairo_dock_desklet_is_free (pDesklet))
	{
		if (! pDesklet->rotating && ! pDesklet->rotatingY && ! pDesklet->rotatingX)
		{
			glPopMatrix ();
			glPushMatrix ();
			glTranslatef (0., 0., -pDesklet->container.iHeight*(sqrt(3)/2));
		}
	}
	
	if ((pDesklet->container.bInside || pDesklet->fButtonsAlpha != 0 || pDesklet->rotating || pDesklet->rotatingY || pDesklet->rotatingX) && cairo_dock_desklet_is_free (pDesklet))
	{
		_cairo_dock_set_blend_alpha ();
		_cairo_dock_set_alpha (sqrt(pDesklet->fButtonsAlpha));
		if (s_pRotateButtonBuffer.iTexture != 0)
		{
			cairo_dock_apply_image_buffer_texture_with_offset (&s_pRotateButtonBuffer,
				-pDesklet->container.iWidth/2 + s_pRotateButtonBuffer.iWidth/2,
				pDesklet->container.iHeight/2 - s_pRotateButtonBuffer.iHeight/2);
		}
		if (s_pRetachButtonBuffer.iTexture != 0 && g_pMainDock)
		{
			cairo_dock_apply_image_buffer_texture_with_offset (&s_pRetachButtonBuffer,
				pDesklet->container.iWidth/2 - s_pRetachButtonBuffer.iWidth/2,
				pDesklet->container.iHeight/2 - s_pRetachButtonBuffer.iHeight/2);
		}
		if (s_pDepthRotateButtonBuffer.iTexture != 0)
		{
			cairo_dock_apply_image_buffer_texture_with_offset (&s_pDepthRotateButtonBuffer,
				0.,
				pDesklet->container.iHeight/2 - s_pDepthRotateButtonBuffer.iHeight/2);
			
			glPushMatrix ();
			glRotatef (90., 0., 0., 1.);
			cairo_dock_apply_image_buffer_texture_with_offset (&s_pDepthRotateButtonBuffer,
				0.,
				pDesklet->container.iWidth/2 - s_pDepthRotateButtonBuffer.iHeight/2);
			glPopMatrix ();
		}
	}
	if ((pDesklet->container.bInside || pDesklet->fButtonsAlpha != 0 || pDesklet->bNoInput) && s_pNoInputButtonBuffer.iTexture != 0 && pDesklet->bAllowNoClickable)
	{
		_cairo_dock_set_blend_alpha ();
		_cairo_dock_set_alpha (_no_input_button_alpha(pDesklet));
		cairo_dock_apply_image_buffer_texture_with_offset (&s_pNoInputButtonBuffer,
			pDesklet->container.iWidth/2 - s_pNoInputButtonBuffer.iWidth/2,
			- pDesklet->container.iHeight/2 + s_pNoInputButtonBuffer.iHeight/2);
	}
	
	_cairo_dock_disable_texture ();
	glPopMatrix ();
}
void cd_opengl_scene (CairoDockModuleInstance *myApplet, int iWidth, int iHeight)
{
	//g_print ("%s (%d)\n", __func__, myData.iCoverTransition);
	_cairo_dock_enable_texture ();
	_cairo_dock_set_blend_source ();
	
	// on dessine le cadre.
	_cairo_dock_apply_texture_at_size_with_alpha (myData.TextureFrame, iWidth, iHeight, 1.);
	
	// on dessine la couverture.
	glPushMatrix ();
	glScalef (iWidth, iHeight, 1.);
	if (myData.iPrevTextureCover != 0 && myData.iCoverTransition != 0)
	{
		_cairo_dock_set_blend_over ();
		_cairo_dock_set_alpha ((double)myData.iCoverTransition/NB_TRANSITION_STEP);
		glBindTexture(GL_TEXTURE_2D, myData.iPrevTextureCover);
		glCallList(myData.draw_cover);
	}
	if (myData.TextureCover != 0)
	{
		_cairo_dock_set_blend_over ();
		_cairo_dock_set_alpha (1.-(double)myData.iCoverTransition/NB_TRANSITION_STEP);
		glBindTexture(GL_TEXTURE_2D, myData.TextureCover);
		glCallList(myData.draw_cover);
	}
	glPopMatrix ();
	_cairo_dock_set_blend_over ();
	
	
	// on dessine les boutons qui sont allumes.
	if (myData.iButton1Count)
	{
		glPushMatrix ();
		glTranslatef (-iWidth/2 + myData.button1coordX, +iHeight/2 - myData.button1coordY, 0.);
		_cairo_dock_apply_texture_at_size_with_alpha (myData.TextureButton1, myData.button1sizeX, myData.button1sizeY, (double)myData.iButton1Count/NB_TRANSITION_STEP);
		glPopMatrix ();
	}
	if (myData.iButton2Count)
	{
		glPushMatrix ();
		glTranslatef (-iWidth/2 + myData.button2coordX, +iHeight/2 - myData.button2coordY, 0.);
		_cairo_dock_apply_texture_at_size_with_alpha (myData.TextureButton2, myData.button2sizeX, myData.button2sizeY, (double)myData.iButton2Count/NB_TRANSITION_STEP);
		glPopMatrix ();
	}
	if (myData.iButton3Count)
	{
		glPushMatrix ();
		glTranslatef (-iWidth/2 + myData.button3coordX, +iHeight/2 - myData.button3coordY, 0.);
		_cairo_dock_apply_texture_at_size_with_alpha (myData.TextureButton3, myData.button3sizeX, myData.button3sizeY, (double)myData.iButton3Count/NB_TRANSITION_STEP);
		glPopMatrix ();
	}
	if (myData.iButton4Count)
	{
		glPushMatrix ();
		glTranslatef (-iWidth/2 + myData.button4coordX, +iHeight/2 - myData.button4coordY, 0.);
		_cairo_dock_apply_texture_at_size_with_alpha (myData.TextureButton4, myData.button4sizeX, myData.button4sizeY, (double)myData.iButton4Count/NB_TRANSITION_STEP);
		glPopMatrix ();
	}
	
	// on determine la transformation pour les OSD.
	// en majuscule : coordonees initiales.
	double W = iWidth, H = iHeight;
	double X1 = 0, Y1 = 0;
	double X2 = W, Y2 = 0;
	double X3 = W, Y3 = H;
	double X4 = 0, Y4 = H;
	// translation du point P1(0;0)
	double x1 = myData.ibottomleftX, y1 = myData.ibottomleftY;
	double t1x = x1 - X1;
	double t1y = y1 - X1;
	// translation du point P2(500;0)
	double x2 = myData.ibottomrightX, y2 = myData.ibottomrightY;
	double t2x = x2 - X2;
	double t2y = y2 - Y2;
	// translation du point P2(500;500)
	double x3 = myData.itoprightX, y3 = myData.itoprightY;
	double t3x = x3 - X3;
	double t3y = y3 - Y3;
	// translation du point P2(0;500)
	double x4 = myData.itopleftX, y4 = myData.itopleftY;
	double t4x = x4 - X4;
	double t4y = y4 - Y4;
	
	double dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4;  // ponderations.
	double X, Y;  // coordonnees initiales d'un coin de l'OSD.
	double u1, v1, u2, v2, u3, v3, u4, v4;  // coordonnees finales des coins de l'OSD.
	
	// on dessine les OSD.
	//if(myData.bIsRunning && myData.iState != 0)
	{
		_cairo_dock_set_alpha (1.);
		if (myData.mouseOnButton1)
		{
			if (myData.iPlayingStatus == PLAYER_PLAYING)
			{
				_draw_osd (myData.TextureOsdPause, myData.osdPausecoordX, myData.osdPausecoordY, myData.osdPausesizeX, myData.osdPausesizeY);
				//g_print ("%.1f;%.1f ; %.1f;%.1f ;%.1f;%.1f ;%.1f;%.1f\n", u1, v1, u2, v2,u3,v3,u4,v4);
			}
			else
			{
				_draw_osd (myData.TextureOsdPlay, myData.osdPlaycoordX, myData.osdPlaycoordY, myData.osdPlaysizeX, myData.osdPlaysizeY);
				//g_print ("%.1f;%.1f ; %.1f;%.1f ;%.1f;%.1f ;%.1f;%.1f\n", u1, v1, u2, v2,u3,v3,u4,v4);
			}
		}
		else if (myData.mouseOnButton2)
		{
			_draw_osd (myData.TextureOsdPrev, myData.osdPrevcoordX, myData.osdPrevcoordY, myData.osdPrevsizeX, myData.osdPrevsizeY);
		}
		else if (myData.mouseOnButton3)
		{
			_draw_osd (myData.TextureOsdNext, myData.osdNextcoordX, myData.osdNextcoordY, myData.osdNextsizeX, myData.osdNextsizeY);
		}
		else if (myData.mouseOnButton4)
		{
			_draw_osd (myData.TextureOsdHome, myData.osdHomecoordX, myData.osdHomecoordY, myData.osdHomesizeX, myData.osdHomesizeY);
		}
		else if (myData.iPlayingStatus != PLAYER_PLAYING)
		{
			if (myData.bIsRunning)  // on verifie que le lecteur est bien ouvert (il se peut qu'il ne nous previenne pas lorsqu'il quitte).
			{
				cd_musicplayer_dbus_detect_player ();
			}
			if (myData.bIsRunning)  // si rhythmbox n'est pas lancé, on n'affiche pas l'osd de pause ;-)
			{
				_draw_osd (myData.TextureOsdPause, myData.osdPausecoordX, myData.osdPausecoordY, myData.osdPausesizeX, myData.osdPausesizeY);
			}
		}
		else if (myData.iPlayingStatus == PLAYER_PLAYING && ! myData.cover_exist)
		{
			_draw_osd (myData.TextureOsdPlay, myData.osdPlaycoordX, myData.osdPlaycoordY, myData.osdPlaysizeX, myData.osdPlaysizeY);
		}
	}
	
	// on dessine les reflets.
	_cairo_dock_set_blend_pbuffer ();
	if (myData.TextureReflect != 0)
		_cairo_dock_apply_texture_at_size_with_alpha (myData.TextureReflect, iWidth, iHeight, 1.);
	
	_cairo_dock_disable_texture ();
}
void cairo_dock_render_overlays_to_texture (CairoDataRenderer *pRenderer, int iNumValue)
{
	gint iWidth = pRenderer->iWidth, iHeight = pRenderer->iHeight;
	cairo_data_renderer_get_size (pRenderer, &iWidth, &iHeight);
	glPushMatrix ();
	if (pRenderer->bisRotate)
		glRotatef (90., 0., 0., 1.);
	
	if (pRenderer->pEmblems != NULL)
	{
		_cairo_dock_enable_texture ();
		_cairo_dock_set_blend_over ();
		
		CairoDataRendererEmblem *pEmblem;
		pEmblem = &pRenderer->pEmblems[iNumValue];
		if (pEmblem->iTexture != 0)
		{
			glBindTexture (GL_TEXTURE_2D, pEmblem->iTexture);
			_cairo_dock_set_alpha (pEmblem->param.fAlpha);
			_cairo_dock_apply_current_texture_at_size_with_offset (
				pEmblem->param.fWidth * iWidth,
				pEmblem->param.fHeight * iHeight,
				pEmblem->param.fX * iWidth,
				pEmblem->param.fY * iHeight);
		}
		_cairo_dock_disable_texture ();
	}
	
	if (pRenderer->pLabels != NULL)
	{
		_cairo_dock_enable_texture ();
		_cairo_dock_set_blend_pbuffer ();  // rend mieux pour les textes
		
		CairoDataRendererText *pLabel;
		int w, h, dw, dh;
		pLabel = &pRenderer->pLabels[iNumValue];
		if (pLabel->iTexture != 0)
		{
			double f = MIN (pLabel->param.fWidth * iWidth / pLabel->iTextWidth, pLabel->param.fHeight * iHeight / pLabel->iTextHeight);  // on garde le ratio du texte.
			w = pLabel->iTextWidth * f;
			h = pLabel->iTextHeight * f;
			dw = w & 1;
			dh = h & 1;
			
			glBindTexture (GL_TEXTURE_2D, pLabel->iTexture);
			_cairo_dock_set_alpha (pLabel->param.pColor[3]);
			_cairo_dock_apply_current_texture_at_size_with_offset (
				w + dw,
				h + dh,
				pLabel->param.fX * iWidth,
				pLabel->param.fY * iHeight);
		}
		_cairo_dock_disable_texture ();
	}
	
	if (pRenderer->bWriteValues && pRenderer->bCanRenderValueAsText)
	{
		CairoDataRendererTextParam *pText;
		pText = &pRenderer->pValuesText[iNumValue];
		if (pText->fWidth != 0 && pText->fHeight != 0)
		{
			cairo_data_renderer_format_value (pRenderer, iNumValue);
			
			CairoDockGLFont *pFont = cairo_dock_get_default_data_renderer_font ();
			glColor3f (pText->pColor[0], pText->pColor[1], pText->pColor[2]);
			glPushMatrix ();
			
			int w = pText->fWidth * pRenderer->iWidth;
			int h = pText->fHeight * pRenderer->iHeight;
			int dw = w & 1;
			int dh = h & 1;
			cairo_dock_draw_gl_text_at_position_in_area ((guchar *) pRenderer->cFormatBuffer,
				pFont,
				floor (pText->fX * iWidth) + .5*dw,
				floor (pText->fY * iHeight) + .5*dh,
				w,
				h,
				TRUE);
			
			glPopMatrix ();
			glColor3f (1.0, 1.0, 1.0);
		}
	}
	glPopMatrix ();
}