GLX/EGL are supposed to abstract exactly this away, this is a bad hack at best and might totally break stuff at worst.
		
			
				
	
	
		
			483 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			483 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright (C) 2013 Christian Stehno
 | |
| // This file is part of the "Irrlicht Engine".
 | |
| // For conditions of distribution and use, see copyright notice in Irrlicht.h
 | |
| 
 | |
| #include "CGLXManager.h"
 | |
| 
 | |
| #ifdef _IRR_COMPILE_WITH_GLX_MANAGER_
 | |
| 
 | |
| #include "os.h"
 | |
| 
 | |
| #if defined(_IRR_OPENGL_USE_EXTPOINTER_)
 | |
| 	#define GL_GLEXT_LEGACY 1
 | |
| 	#define GLX_GLXEXT_LEGACY 1
 | |
| #else
 | |
| 	#define GL_GLEXT_PROTOTYPES 1
 | |
| 	#define GLX_GLXEXT_PROTOTYPES 1
 | |
| #endif
 | |
| #include <GL/gl.h>
 | |
| #include <GL/glx.h>
 | |
| #if defined(_IRR_OPENGL_USE_EXTPOINTER_)
 | |
| #include <GL/glext.h>
 | |
| #include <GL/glxext.h>
 | |
| #endif
 | |
| 
 | |
| namespace irr
 | |
| {
 | |
| namespace video
 | |
| {
 | |
| 
 | |
| CGLXManager::CGLXManager(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata, int screennr)
 | |
| 	: Params(params), PrimaryContext(videodata), VisualInfo(0), glxFBConfig(0), GlxWin(0)
 | |
| {
 | |
| 	#ifdef _DEBUG
 | |
| 	setDebugName("CGLXManager");
 | |
| 	#endif
 | |
| 
 | |
| 	CurrentContext.OpenGLLinux.X11Display=PrimaryContext.OpenGLLinux.X11Display;
 | |
| 
 | |
| 	int major, minor;
 | |
| 	Display* display = (Display*)PrimaryContext.OpenGLLinux.X11Display;
 | |
| 	const bool isAvailableGLX=glXQueryExtension(display,&major,&minor);
 | |
| 
 | |
| 	if (isAvailableGLX && glXQueryVersion(display, &major, &minor))
 | |
| 	{
 | |
| #if defined(GLX_VERSION_1_3)
 | |
| 		typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
 | |
| 
 | |
| #ifdef _IRR_OPENGL_USE_EXTPOINTER_
 | |
| 		PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXChooseFBConfig"));
 | |
| #else
 | |
| 		PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig=glXChooseFBConfig;
 | |
| #endif
 | |
| 		if (major==1 && minor>2 && glxChooseFBConfig)
 | |
| 		{
 | |
| os::Printer::log("GLX >= 1.3", ELL_DEBUG);
 | |
| 			// attribute array for the draw buffer
 | |
| 			int visualAttrBuffer[] =
 | |
| 			{
 | |
| 				GLX_RENDER_TYPE, GLX_RGBA_BIT,
 | |
| 				GLX_RED_SIZE, 4,
 | |
| 				GLX_GREEN_SIZE, 4,
 | |
| 				GLX_BLUE_SIZE, 4,
 | |
| 				GLX_ALPHA_SIZE, Params.WithAlphaChannel?1:0,
 | |
| 				GLX_DEPTH_SIZE, Params.ZBufferBits, //10,11
 | |
| 				GLX_DOUBLEBUFFER, Params.Doublebuffer?True:False,
 | |
| 				GLX_STENCIL_SIZE, Params.Stencilbuffer?1:0,
 | |
| #if defined(GLX_VERSION_1_4) && defined(GLX_SAMPLE_BUFFERS) // we need to check the extension string!
 | |
| 				GLX_SAMPLE_BUFFERS, 1,
 | |
| 				GLX_SAMPLES, Params.AntiAlias, // 18,19
 | |
| #elif defined(GLX_ARB_multisample)
 | |
| 				GLX_SAMPLE_BUFFERS_ARB, 1,
 | |
| 				GLX_SAMPLES_ARB, Params.AntiAlias, // 18,19
 | |
| #elif defined(GLX_SGIS_multisample)
 | |
| 				GLX_SAMPLE_BUFFERS_SGIS, 1,
 | |
| 				GLX_SAMPLES_SGIS, Params.AntiAlias, // 18,19
 | |
| #endif
 | |
| //#ifdef GL_ARB_framebuffer_sRGB
 | |
| //					GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, Params.HandleSRGB,
 | |
| //#elif defined(GL_EXT_framebuffer_sRGB)
 | |
| //					GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, Params.HandleSRGB,
 | |
| //#endif
 | |
| 				GLX_STEREO, Params.Stereobuffer?True:False,
 | |
| 				None
 | |
| 			};
 | |
| 
 | |
| 			GLXFBConfig *configList=0;
 | |
| 			int nitems=0;
 | |
| 			if (Params.AntiAlias<2)
 | |
| 			{
 | |
| 				visualAttrBuffer[17] = 0;
 | |
| 				visualAttrBuffer[19] = 0;
 | |
| 			}
 | |
| 			// first round with unchanged values
 | |
| 			{
 | |
| 				configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
 | |
| 				if (!configList && Params.AntiAlias)
 | |
| 				{
 | |
| 					while (!configList && (visualAttrBuffer[19]>1))
 | |
| 					{
 | |
| 						visualAttrBuffer[19] -= 1;
 | |
| 						configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
 | |
| 					}
 | |
| 					if (!configList)
 | |
| 					{
 | |
| 						visualAttrBuffer[17] = 0;
 | |
| 						visualAttrBuffer[19] = 0;
 | |
| 						configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
 | |
| 						if (configList)
 | |
| 						{
 | |
| 							os::Printer::log("No FSAA available.", ELL_WARNING);
 | |
| 							Params.AntiAlias=0;
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							//reenable multisampling
 | |
| 							visualAttrBuffer[17] = 1;
 | |
| 							visualAttrBuffer[19] = Params.AntiAlias;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			// Next try with flipped stencil buffer value
 | |
| 			// If the first round was with stencil flag it's now without
 | |
| 			// Other way round also makes sense because some configs
 | |
| 			// only have depth buffer combined with stencil buffer
 | |
| 			if (!configList)
 | |
| 			{
 | |
| 				if (Params.Stencilbuffer)
 | |
| 					os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING);
 | |
| 				Params.Stencilbuffer = !Params.Stencilbuffer;
 | |
| 				visualAttrBuffer[15]=Params.Stencilbuffer?1:0;
 | |
| 
 | |
| 				configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
 | |
| 				if (!configList && Params.AntiAlias)
 | |
| 				{
 | |
| 					while (!configList && (visualAttrBuffer[19]>1))
 | |
| 					{
 | |
| 						visualAttrBuffer[19] -= 1;
 | |
| 						configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
 | |
| 					}
 | |
| 					if (!configList)
 | |
| 					{
 | |
| 						visualAttrBuffer[17] = 0;
 | |
| 						visualAttrBuffer[19] = 0;
 | |
| 						configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
 | |
| 						if (configList)
 | |
| 						{
 | |
| 							os::Printer::log("No FSAA available.", ELL_WARNING);
 | |
| 							Params.AntiAlias=0;
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							//reenable multisampling
 | |
| 							visualAttrBuffer[17] = 1;
 | |
| 							visualAttrBuffer[19] = Params.AntiAlias;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			// Next try without double buffer
 | |
| 			if (!configList && Params.Doublebuffer)
 | |
| 			{
 | |
| 				os::Printer::log("No doublebuffering available.", ELL_WARNING);
 | |
| 				Params.Doublebuffer=false;
 | |
| 				visualAttrBuffer[13] = GLX_DONT_CARE;
 | |
| 				Params.Stencilbuffer = false;
 | |
| 				visualAttrBuffer[15]=0;
 | |
| 				configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
 | |
| 				if (!configList && Params.AntiAlias)
 | |
| 				{
 | |
| 					while (!configList && (visualAttrBuffer[19]>1))
 | |
| 					{
 | |
| 						visualAttrBuffer[19] -= 1;
 | |
| 						configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
 | |
| 					}
 | |
| 					if (!configList)
 | |
| 					{
 | |
| 						visualAttrBuffer[17] = 0;
 | |
| 						visualAttrBuffer[19] = 0;
 | |
| 						configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
 | |
| 						if (configList)
 | |
| 						{
 | |
| 							os::Printer::log("No FSAA available.", ELL_WARNING);
 | |
| 							Params.AntiAlias=0;
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							//reenable multisampling
 | |
| 							visualAttrBuffer[17] = 1;
 | |
| 							visualAttrBuffer[19] = Params.AntiAlias;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			if (configList)
 | |
| 			{
 | |
| 				glxFBConfig=configList[0];
 | |
| 				XFree(configList);
 | |
| #ifdef _IRR_OPENGL_USE_EXTPOINTER_
 | |
| 				typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
 | |
| 				PFNGLXGETVISUALFROMFBCONFIGPROC glxGetVisualFromFBConfig= (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXGetVisualFromFBConfig"));
 | |
| 				if (glxGetVisualFromFBConfig)
 | |
| 					VisualInfo = glxGetVisualFromFBConfig(display,(GLXFBConfig)glxFBConfig);
 | |
| #else
 | |
| 					VisualInfo = glXGetVisualFromFBConfig(display,(GLXFBConfig)glxFBConfig);
 | |
| #endif
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| #endif
 | |
| 		{
 | |
| 			// attribute array for the draw buffer
 | |
| 			int visualAttrBuffer[] =
 | |
| 			{
 | |
| 				GLX_RGBA, GLX_USE_GL,
 | |
| 				GLX_RED_SIZE, 4,
 | |
| 				GLX_GREEN_SIZE, 4,
 | |
| 				GLX_BLUE_SIZE, 4,
 | |
| 				GLX_ALPHA_SIZE, Params.WithAlphaChannel?1:0,
 | |
| 				GLX_DEPTH_SIZE, Params.ZBufferBits,
 | |
| 				GLX_STENCIL_SIZE, Params.Stencilbuffer?1:0, // 12,13
 | |
| 				// The following attributes have no flags, but are
 | |
| 				// either present or not. As a no-op we use
 | |
| 				// GLX_USE_GL, which is silently ignored by glXChooseVisual
 | |
| 				Params.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14
 | |
| 				Params.Stereobuffer?GLX_STEREO:GLX_USE_GL, // 15
 | |
| //#ifdef GL_ARB_framebuffer_sRGB
 | |
| //					Params.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB:GLX_USE_GL,
 | |
| //#elif defined(GL_EXT_framebuffer_sRGB)
 | |
| //					Params.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:GLX_USE_GL,
 | |
| //#endif
 | |
| 				None
 | |
| 			};
 | |
| 
 | |
| 			VisualInfo=glXChooseVisual(display, screennr, visualAttrBuffer);
 | |
| 			if (!VisualInfo)
 | |
| 			{
 | |
| 				if (Params.Stencilbuffer)
 | |
| 					os::Printer::log("No stencilbuffer available, disabling.", ELL_WARNING);
 | |
| 				Params.Stencilbuffer = !Params.Stencilbuffer;
 | |
| 				visualAttrBuffer[13]=Params.Stencilbuffer?1:0;
 | |
| 
 | |
| 				VisualInfo=glXChooseVisual(display, screennr, visualAttrBuffer);
 | |
| 				if (!VisualInfo && Params.Doublebuffer)
 | |
| 				{
 | |
| 					os::Printer::log("No doublebuffering available.", ELL_WARNING);
 | |
| 					Params.Doublebuffer=false;
 | |
| 					visualAttrBuffer[14] = GLX_USE_GL;
 | |
| 					VisualInfo=glXChooseVisual(display, screennr, visualAttrBuffer);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 		os::Printer::log("No GLX support available. OpenGL driver will not work.", ELL_WARNING);
 | |
| }
 | |
| 
 | |
| CGLXManager::~CGLXManager()
 | |
| {
 | |
| }
 | |
| 
 | |
| bool CGLXManager::initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata)
 | |
| {
 | |
| 	// store params
 | |
| 	Params=params;
 | |
| 
 | |
| 	// set display
 | |
| 	CurrentContext.OpenGLLinux.X11Display=videodata.OpenGLLinux.X11Display;
 | |
| 
 | |
| 	// now get new window
 | |
| 	CurrentContext.OpenGLLinux.X11Window=videodata.OpenGLLinux.X11Window;
 | |
| 	if (!PrimaryContext.OpenGLLinux.X11Window)
 | |
| 	{
 | |
| 		PrimaryContext.OpenGLLinux.X11Window=CurrentContext.OpenGLLinux.X11Window;
 | |
| 	}
 | |
| 
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| void CGLXManager::terminate()
 | |
| {
 | |
| 	memset((void*)&CurrentContext, 0, sizeof(CurrentContext));
 | |
| }
 | |
| 
 | |
| bool CGLXManager::generateSurface()
 | |
| {
 | |
| 	if (glxFBConfig)
 | |
| 	{
 | |
| 		GlxWin=glXCreateWindow((Display*)CurrentContext.OpenGLLinux.X11Display,(GLXFBConfig)glxFBConfig,CurrentContext.OpenGLLinux.X11Window,NULL);
 | |
| 		if (!GlxWin)
 | |
| 		{
 | |
| 			os::Printer::log("Could not create GLX window.", ELL_WARNING);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		CurrentContext.OpenGLLinux.GLXWindow=GlxWin;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		CurrentContext.OpenGLLinux.GLXWindow=CurrentContext.OpenGLLinux.X11Window;
 | |
| 	}
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| void CGLXManager::destroySurface()
 | |
| {
 | |
| 	if (GlxWin)
 | |
| 		glXDestroyWindow((Display*)CurrentContext.OpenGLLinux.X11Display, GlxWin);
 | |
| }
 | |
| 
 | |
| #if defined(GLX_ARB_create_context)
 | |
| static int IrrIgnoreError(Display *display, XErrorEvent *event)
 | |
| {
 | |
| 	char msg[256];
 | |
| 	XGetErrorText(display, event->error_code, msg, 256);
 | |
| 	os::Printer::log("Ignoring an X error", msg, ELL_DEBUG);
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| bool CGLXManager::generateContext()
 | |
| {
 | |
| 	GLXContext context = 0;
 | |
| 
 | |
| 	if (glxFBConfig)
 | |
| 	{
 | |
| 		if (GlxWin)
 | |
| 		{
 | |
| #if defined(GLX_ARB_create_context)
 | |
| 
 | |
| #ifdef _IRR_OPENGL_USE_EXTPOINTER_
 | |
| 		PFNGLXCREATECONTEXTATTRIBSARBPROC glxCreateContextAttribsARB=(PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB"));
 | |
| #else
 | |
| 		PFNGLXCREATECONTEXTATTRIBSARBPROC glxCreateContextAttribsARB=glXCreateContextAttribsARB;
 | |
| #endif
 | |
| 
 | |
| 			if (glxCreateContextAttribsARB)
 | |
| 			{
 | |
| 				os::Printer::log("GLX with GLX_ARB_create_context", ELL_DEBUG);
 | |
| 				int contextAttrBuffer[] = {
 | |
| 					GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
 | |
| 					GLX_CONTEXT_MINOR_VERSION_ARB, 0,
 | |
| 					// GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
 | |
| 					None
 | |
| 				};
 | |
| 				XErrorHandler old = XSetErrorHandler(IrrIgnoreError);
 | |
| 				context = glxCreateContextAttribsARB((Display*)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, NULL, True, contextAttrBuffer);
 | |
| 				XSetErrorHandler(old);
 | |
| 				// transparently fall back to legacy call
 | |
| 			}
 | |
| 			if (!context)
 | |
| #endif
 | |
| 			{
 | |
| 				// create glx context
 | |
| 				context = glXCreateNewContext((Display*)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, GLX_RGBA_TYPE, NULL, True);
 | |
| 				if (!context)
 | |
| 				{
 | |
| 					os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
 | |
| 					return false;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			os::Printer::log("GLX window was not properly created.", ELL_WARNING);
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		context = glXCreateContext((Display*)CurrentContext.OpenGLLinux.X11Display, VisualInfo, NULL, True);
 | |
| 		if (!context)
 | |
| 		{
 | |
| 			os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 	CurrentContext.OpenGLLinux.X11Context=context;
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| const SExposedVideoData& CGLXManager::getContext() const
 | |
| {
 | |
| 	return CurrentContext;
 | |
| }
 | |
| 
 | |
| bool CGLXManager::activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero)
 | |
| {
 | |
| 	//TODO: handle restorePrimaryOnZero
 | |
| 
 | |
| 	if (videoData.OpenGLLinux.X11Window)
 | |
| 	{
 | |
| 		if (videoData.OpenGLLinux.X11Display && videoData.OpenGLLinux.X11Context)
 | |
| 		{
 | |
| 			if (!glXMakeCurrent((Display*)videoData.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)videoData.OpenGLLinux.X11Context))
 | |
| 			{
 | |
| 				os::Printer::log("Context activation failed.");
 | |
| 				return false;
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
 | |
| 				CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
 | |
| 				CurrentContext.OpenGLLinux.X11Display = videoData.OpenGLLinux.X11Display;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			// in case we only got a window ID, try with the existing values for display and context
 | |
| 			if (!glXMakeCurrent((Display*)PrimaryContext.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)PrimaryContext.OpenGLLinux.X11Context))
 | |
| 			{
 | |
| 				os::Printer::log("Context activation failed.");
 | |
| 				return false;
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
 | |
| 				CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
 | |
| 				CurrentContext.OpenGLLinux.X11Display = PrimaryContext.OpenGLLinux.X11Display;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	else if (!restorePrimaryOnZero && !videoData.OpenGLLinux.X11Window && !videoData.OpenGLLinux.X11Display)
 | |
| 	{
 | |
| 		if (!glXMakeCurrent((Display*)PrimaryContext.OpenGLLinux.X11Display, None, NULL))
 | |
| 		{
 | |
| 			os::Printer::log("Render Context reset failed.");
 | |
| 			return false;
 | |
| 		}
 | |
| 		CurrentContext.OpenGLLinux.X11Window = 0;
 | |
| 		CurrentContext.OpenGLLinux.X11Display = 0;
 | |
| 	}
 | |
| 	// set back to main context
 | |
| 	else if (CurrentContext.OpenGLLinux.X11Display != PrimaryContext.OpenGLLinux.X11Display)
 | |
| 	{
 | |
| 		if (!glXMakeCurrent((Display*)PrimaryContext.OpenGLLinux.X11Display, PrimaryContext.OpenGLLinux.X11Window, (GLXContext)PrimaryContext.OpenGLLinux.X11Context))
 | |
| 		{
 | |
| 			os::Printer::log("Context activation failed.");
 | |
| 			return false;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			CurrentContext = PrimaryContext;
 | |
| 		}
 | |
| 	}
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| void CGLXManager::destroyContext()
 | |
| {
 | |
| 	if (CurrentContext.OpenGLLinux.X11Context)
 | |
| 	{
 | |
| 		if (GlxWin)
 | |
| 		{
 | |
| 			if (!glXMakeContextCurrent((Display*)CurrentContext.OpenGLLinux.X11Display, None, None, NULL))
 | |
| 				os::Printer::log("Could not release glx context.", ELL_WARNING);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			if (!glXMakeCurrent((Display*)CurrentContext.OpenGLLinux.X11Display, None, NULL))
 | |
| 				os::Printer::log("Could not release glx context.", ELL_WARNING);
 | |
| 		}
 | |
| 		glXDestroyContext((Display*)CurrentContext.OpenGLLinux.X11Display, (GLXContext)CurrentContext.OpenGLLinux.X11Context);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void* CGLXManager::getProcAddress(const std::string &procName)
 | |
| {
 | |
| 	return (void*)glXGetProcAddressARB(reinterpret_cast<const GLubyte*>(procName.c_str()));
 | |
| }
 | |
| 
 | |
| bool CGLXManager::swapBuffers()
 | |
| {
 | |
| 	glXSwapBuffers((Display*)CurrentContext.OpenGLLinux.X11Display, CurrentContext.OpenGLLinux.GLXWindow);
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| }
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 |