void cd_rendering_render_3D_plane_opengl (CairoDock *pDock)
{
	//\____________________ On genere le cadre.
	_define_parameters (hi, h0, H, l, r, gamma, h, w, dw);
	h = pDock->iDecorationsHeight;
	if (h < 2 * r)
		r = h / 2;
	
	double dx, dy;
	if (cairo_dock_is_extended_dock (pDock))  // mode panel etendu.
	{
		double Ws = pDock->iCurrentWidth;
		double W = Ws - 2 * r;
		double a = H + hi;
		double b = H + hi + h0 - W / 2;
		double c = - W / 2;
		gamma = (-b + sqrt (b * b - 4 * a * c)) / 2  / a;
		h = hi + h0 / (1 + gamma);
		//g_print ("h : %.2f (=) %d\n", h, pDock->iDecorationsHeight);
		w = 2 * H * gamma;
		dw = (Ws - w) / 2;
		//g_print ("dw : %.2f (=) %.2f\n", dw, h * gamma + r + (l+(r==0)*2)*sqrt(1+gamma*gamma));
		dx =dw;
	}
	else
	{
		w = cairo_dock_get_current_dock_width_linear (pDock);
		gamma = w / 2 / H;
		dw = h * gamma + r + (l+(r==0)*2)*sqrt(1+gamma*gamma);
		h = pDock->iDecorationsHeight;
		Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
		dx = (pFirstIcon != NULL ? pFirstIcon->fX - myBackground.iFrameMargin : r);
	}
	
	//\____________________ On trace le cadre.
	int sens;
	if ((pDock->bDirectionUp && pDock->bHorizontalDock) || (!pDock->bDirectionUp && !pDock->bHorizontalDock))
	{
		sens = 1;
		//dy = pDock->iCurrentHeight - pDock->iDecorationsHeight - 1.5 * l;
		dy = pDock->iDecorationsHeight + 1.5*l;
	}
	else
	{
		sens = -1;
		//dy = pDock->iDecorationsHeight + 1.5 * l;
		dy = pDock->iCurrentHeight - .5 * l;
	}
	
	int iNbVertex;
	double fDeltaXTrapeze;
	GLfloat *pVertexTab = cairo_dock_generate_trapeze_path (w - (myBackground.bRoundedBottomCorner ? 0 : 2*l/gamma), h+l, r, myBackground.bRoundedBottomCorner, gamma, &fDeltaXTrapeze, &iNbVertex);
	
	if (! pDock->bHorizontalDock)
		dx = pDock->iCurrentWidth - dx + fDeltaXTrapeze;
	else
		dx = dx - fDeltaXTrapeze;
	
	//\____________________ On dessine les decorations dedans.
	//fDockOffsetY = (!pDock->bDirectionUp ? pDock->iCurrentHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth);
	glPushMatrix ();
	cairo_dock_draw_frame_background_opengl (g_iBackgroundTexture, w+2*fDeltaXTrapeze, h+l, dx, dy, pVertexTab, iNbVertex, pDock->bHorizontalDock, pDock->bDirectionUp, pDock->fDecorationsOffsetX);
	
	//\____________________ On dessine le cadre.
	if (l != 0)
		cairo_dock_draw_current_path_opengl (l, myBackground.fLineColor, iNbVertex);
	glPopMatrix ();
	
	/// donner un effet d'epaisseur => chaud du slip avec les separateurs physiques !
	
	
	//\____________________ On dessine la ficelle qui les joint.
	if (myIcons.iStringLineWidth > 0)
		cairo_dock_draw_string_opengl (pDock, myIcons.iStringLineWidth, FALSE, (my_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR));
	
	//\____________________ On dessine les icones et les etiquettes, en tenant compte de l'ordre pour dessiner celles en arriere-plan avant celles en avant-plan.
	GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
	if (pFirstDrawnElement == NULL)
		return;
		
	double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
	Icon *icon;
	GList *ic = pFirstDrawnElement;
	
	glLoadIdentity ();
 	if (my_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
	{
		do
		{
			icon = ic->data;
			
			if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
			{
				glPushMatrix ();
				if (my_iDrawSeparator3D == CD_FLAT_SEPARATOR)
					cd_rendering_draw_flat_separator_opengl (icon, pDock);
				else
					cd_rendering_draw_physical_separator_opengl (icon, pDock, TRUE, NULL, NULL);
				glPopMatrix ();
			}
			
			ic = cairo_dock_get_next_element (ic, pDock->icons);
		} while (ic != pFirstDrawnElement);
		
		do
		{
			icon = ic->data;
			
			if (icon->acFileName != NULL || ! CAIRO_DOCK_IS_SEPARATOR (icon))
			{
				glPushMatrix ();
				cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE);
				glPopMatrix ();
			}
			
			ic = cairo_dock_get_next_element (ic, pDock->icons);
		} while (ic != pFirstDrawnElement);
		
		if (my_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
		{
			do
			{
				icon = ic->data;
				
				if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
				{
					glPushMatrix ();
					cd_rendering_draw_physical_separator_opengl (icon, pDock, FALSE, NULL, NULL);
					glPopMatrix ();
				}
				
				ic = cairo_dock_get_next_element (ic, pDock->icons);
			} while (ic != pFirstDrawnElement);
		}
	}
	else
	{
		do
		{
			icon = ic->data;
			
			glPushMatrix ();
			
			cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE);
			
			glPopMatrix ();
			
			ic = cairo_dock_get_next_element (ic, pDock->icons);
		} while (ic != pFirstDrawnElement);
	}
}
static void cd_render_opengl (CairoDock *pDock)
{
	//\_____________ On definit notre rectangle.
	double fLineWidth = myDocksParam.iDockLineWidth;
	double fMargin = myDocksParam.iFrameMargin;
	double fRadius = (pDock->iDecorationsHeight + fLineWidth - 2 * myDocksParam.iDockRadius > 0 ? myDocksParam.iDockRadius : (pDock->iDecorationsHeight + fLineWidth) / 2 - 1);
	double fExtraWidth = 2 * fRadius + fLineWidth;
	double fDockWidth;
	double fFrameHeight = pDock->iDecorationsHeight + fLineWidth;
	
	double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du cadre.
	GList *pFirstDrawnElement = pDock->icons;
	if (pFirstDrawnElement == NULL)
		return ;
	if (cairo_dock_is_extended_dock (pDock))  // mode panel etendu.
	{
		fDockWidth = pDock->container.iWidth - fExtraWidth;
		fDockOffsetX = fLineWidth / 2;
	}
	else
	{
		fDockWidth = cairo_dock_get_current_dock_width_linear (pDock);
		Icon *pFirstIcon = pFirstDrawnElement->data;
		fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX + 0 - fMargin - fRadius : fLineWidth / 2);
		if (fDockOffsetX - fLineWidth/2 < 0)
			fDockOffsetX = fLineWidth / 2;
		if (fDockOffsetX + fDockWidth + (2*fRadius + fLineWidth) > pDock->container.iWidth)
			fDockWidth = pDock->container.iWidth - fDockOffsetX - (2*fRadius + fLineWidth);
	}
	
	fDockOffsetY = pDock->iDecorationsHeight + 1.5 * fLineWidth;
	
	double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
	
	//\_____________ On genere les coordonnees du contour.
	const CairoDockGLPath *pFramePath = cairo_dock_generate_rectangle_path (fDockWidth, fFrameHeight, fRadius, FALSE);  // same remark as in cairo rendering
	
	//\_____________ On remplit avec le fond.
	glPushMatrix ();
	cairo_dock_set_container_orientation_opengl (CAIRO_CONTAINER (pDock));
	glTranslatef (fDockOffsetX + (fDockWidth+2*fRadius)/2,
		fDockOffsetY - fFrameHeight/2,
		0.);
	
	_cairo_dock_set_blend_source ();
	cairo_dock_fill_gl_path (pFramePath, pDock->backgroundBuffer.iTexture);
	
	//\_____________ On trace le contour.
	if (fLineWidth != 0)
	{
		glLineWidth (fLineWidth);
		if (myDocksParam.bUseDefaultColors)
			gldi_style_colors_set_line_color (NULL);
		else
			gldi_color_set_opengl (&myDocksParam.fLineColor);
		cairo_dock_stroke_gl_path (pFramePath, TRUE);
	}
	glPopMatrix ();
	
	
	//\_____________ On trace les separateurs physiques.
	GList *ic;
	Icon *pIcon;
	if (my_bPanelPhysicalSeparator)
	{
		glPushMatrix ();
		cairo_dock_set_container_orientation_opengl (CAIRO_CONTAINER (pDock));
		
		double x1, x2, dx, delta, h = pDock->iDecorationsHeight + 2*fLineWidth, h_ = h - fLineWidth;
		for (ic = pDock->icons; ic != NULL; ic = ic->next)
		{
			pIcon = ic->data;
			if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon))
			{
				x1 = pIcon->fDrawX = pIcon->fX;
				
				pIcon = NULL;
				for (ic = ic->next; ic != NULL; ic = ic->next)
				{
					pIcon = ic->data;
					if (!CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon))
						break;
				}
				if (ic != NULL)
				{
					pIcon = ic->data;
					x2 = pIcon->fDrawX;
				}
				else
					break;
				
				CairoDockGLPath *pPath = cairo_dock_new_gl_path (2*(iNbCurveSteps+1) + 1, (x1+x2)/2, h, 0., 0.);  // on part du milieu en haut pour que les triangles soient contenus dans l'enveloppe.
				
				dx = MIN (my_fPanelRadius, (x2 - x1) / 2);
				delta = dx + h*tan(my_fPanelInclination)/2;
				if (delta > (x2 - x1) / 2)
					delta = (x2 - x1) / 2;
				
				cairo_dock_gl_path_rel_line_to (pPath,
					-(x2-x1)/2, 0.);
				cairo_dock_gl_path_rel_curve_to (pPath, iNbCurveSteps,
					dx, 0.,
					delta - dx, -h,
					delta, -h);
				cairo_dock_gl_path_rel_line_to (pPath,
					x2 - x1 - 2*delta, 0.);
				cairo_dock_gl_path_rel_curve_to (pPath, iNbCurveSteps,
					dx, 0.,
					delta - dx, h,
					delta, h);
				
				glBlendFunc (GL_ONE, GL_ZERO);
				glColor4f (0., 0., 0., 0.);
				cairo_dock_fill_gl_path (pPath, 0);
				glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
				
				if (fLineWidth > 0)
				{
					cairo_dock_gl_path_move_to (pPath, x1, h - fLineWidth/2);  // on part du haut/gauche, le nombre de points est ok.
					cairo_dock_gl_path_rel_curve_to (pPath, iNbCurveSteps,
						dx, 0.,
						delta - dx, -h_,
						delta, -h_);
					cairo_dock_gl_path_rel_line_to (pPath,
						x2 - x1 - 2*delta, 0.);
					cairo_dock_gl_path_rel_curve_to (pPath, iNbCurveSteps,
						dx, 0.,
						delta - dx, h_,
						delta, h_);
					glLineWidth (fLineWidth);
					if (myDocksParam.bUseDefaultColors)
						gldi_style_colors_set_line_color (NULL);
					else
						gldi_color_set_opengl (&myDocksParam.fLineColor);
					cairo_dock_stroke_gl_path (pPath, FALSE);
				}
				
				cairo_dock_free_gl_path (pPath);
			}
		}
		glPopMatrix ();
	}
	
	//\_____________ On dessine la ficelle.
	if (myIconsParam.iStringLineWidth > 0)
		cairo_dock_draw_string_opengl (pDock, myIconsParam.iStringLineWidth, FALSE, FALSE);
	
	
	//\_____________ On dessine les icones.
	pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
	if (pFirstDrawnElement == NULL)
		return;
	
	ic = pFirstDrawnElement;
	do
	{
		pIcon = ic->data;
		
		if (! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon))
		{
			glPushMatrix ();
			cairo_dock_render_one_icon_opengl (pIcon, pDock, fDockMagnitude, pIcon->bPointed);
			glPopMatrix ();
		}
		
		ic = cairo_dock_get_next_element (ic, pDock->icons);
	} while (ic != pFirstDrawnElement);
}