Changed: #1145 Implement VSync under Linux

This commit is contained in:
kervala 2010-10-30 14:01:31 +02:00
parent 8abae36b23
commit f38cf23644
3 changed files with 165 additions and 10 deletions

View file

@ -180,8 +180,6 @@ CDriverGL::CDriverGL()
_PBuffer = NULL;
_hRC = NULL;
_hDC = NULL;
_NeedToRestaureGammaRamp = false;
_Interval = 1;
#elif defined(NL_OS_MAC)
@ -216,6 +214,9 @@ CDriverGL::CDriverGL()
#endif // NL_OS_UNIX
_NeedToRestaureGammaRamp = false;
_Interval = 1;
_win = EmptyWindow;
_DestroyWindow = false;
@ -313,7 +314,6 @@ CDriverGL::CDriverGL()
_VBHardProfiling= false;
_CurVBHardLockCount= 0;
_NumVBHardProfileFrame= 0;
_Interval = 1;
_TexEnvReplace.setDefault();
_TexEnvReplace.Env.OpAlpha = CMaterial::Previous;
@ -355,14 +355,17 @@ bool CDriverGL::setupDisplay()
// Driver caps.
//=============
// Retrieve the extensions for the current context.
NL3D::registerGlExtensions (_Extensions);
registerGlExtensions (_Extensions);
vector<string> lines;
explode(_Extensions.toString(), string("\n"), lines);
for(uint i = 0; i < lines.size(); i++)
nlinfo("3D: %s", lines[i].c_str());
#ifdef NL_OS_WINDOWS
NL3D::registerWGlExtensions(_Extensions, _hDC);
registerWGlExtensions(_Extensions, _hDC);
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
registerGLXExtensions(_Extensions, _dpy, DefaultScreen(_dpy));
#endif // NL_OS_WINDOWS
// Check required extensions!!
@ -616,10 +619,8 @@ bool CDriverGL::setupDisplay()
}
}
#ifdef NL_OS_WINDOWS
// Reset the vbl interval
setSwapVBLInterval(_Interval);
#endif
return true;
}
@ -2036,13 +2037,40 @@ void CDriverGL::flush()
void CDriverGL::setSwapVBLInterval(uint interval)
{
H_AUTO_OGL(CDriverGL_setSwapVBLInterval)
#ifdef NL_OS_WINDOWS
if (!_Initialized)
return;
_Interval = interval;
if(_Extensions.WGLEXTSwapControl && _Initialized)
#ifdef NL_OS_WINDOWS
if(_Extensions.WGLEXTSwapControl)
{
nwglSwapIntervalEXT(_Interval);
}
#endif
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
if (_win && _Extensions.GLXEXTSwapControl)
{
if (nglXSwapIntervalEXT(_dpy, _win, interval))
{
nlwarning("Could not set swap interval");
}
}
else if (_Extensions.GLXSGISwapControl)
{
if (nglXSwapIntervalSGI(interval))
{
nlwarning("Could not set swap interval");
}
}
else if (_Extensions.GLXMESASwapControl)
{
if (nglXSwapIntervalMESA(interval))
{
nlwarning("Could not set swap interval");
}
}
}
// ***************************************************************************
@ -2059,6 +2087,8 @@ uint CDriverGL::getSwapVBLInterval()
#else
return 1;
#endif
return _Interval;
}
// ***************************************************************************

View file

@ -440,6 +440,18 @@ PFNWGLGETSWAPINTERVALEXTPROC nwglGetSwapIntervalEXT;
// WGL_ARB_extensions_string
PFNWGLGETEXTENSIONSSTRINGARBPROC nwglGetExtensionsStringARB;
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
// Swap control extensions
PFNGLXSWAPINTERVALEXTPROC nglXSwapIntervalEXT;
PFNGLXSWAPINTERVALSGIPROC nglXSwapIntervalSGI;
PFNGLXSWAPINTERVALMESAPROC nglXSwapIntervalMESA;
PFNGLXGETSWAPINTERVALMESAPROC nglXGetSwapIntervalMESA;
#endif
// ***************************************************************************
@ -1410,6 +1422,46 @@ static bool setupWGLEXTSwapControl(const char *glext)
return true;
}
// *********************************
static bool setupGLXEXTSwapControl(const char *glext)
{
H_AUTO_OGL(setupGLXEXTSwapControl);
CHECK_EXT("GLX_EXT_swap_control");
#ifdef NL_OS_UNIX
CHECK_ADDRESS(PFNGLXSWAPINTERVALEXTPROC, glXSwapIntervalEXT);
#endif
return true;
}
// *********************************
static bool setupGLXSGISwapControl(const char *glext)
{
H_AUTO_OGL(setupGLXSGISwapControl);
CHECK_EXT("GLX_SGI_swap_control");
#ifdef NL_OS_UNIX
CHECK_ADDRESS(PFNGLXSWAPINTERVALSGIPROC, glXSwapIntervalSGI);
#endif
return true;
}
// *********************************
static bool setupGLXMESASwapControl(const char *glext)
{
H_AUTO_OGL(setupGLXMESASwapControl);
CHECK_EXT("GLX_MESA_swap_control");
#ifdef NL_OS_UNIX
CHECK_ADDRESS(PFNGLXSWAPINTERVALMESAPROC, glXSwapIntervalMESA);
CHECK_ADDRESS(PFNGLXGETSWAPINTERVALMESAPROC, glXGetSwapIntervalMESA);
#endif
return true;
}
#ifdef NL_OS_WINDOWS
// ***************************************************************************
bool registerWGlExtensions(CGlExtensions &ext, HDC hDC)
@ -1452,6 +1504,49 @@ bool registerWGlExtensions(CGlExtensions &ext, HDC hDC)
return true;
}
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
// ***************************************************************************
bool registerGlXExtensions(CGlExtensions &ext, Display *dpy, sint screen)
{
H_AUTO_OGL(registerGlXExtensions);
// Get extension string
const char *glext = glXQueryExtensionsString(dpy, screen);
if (glext == NULL)
{
nlwarning ("glXQueryExtensionsString failed");
return false;
}
nldebug("3D: Available GLX Extensions:");
if (DebugLog)
{
vector<string> exts;
explode(string(glext), string(" "), exts);
for(uint i = 0; i < exts.size(); i++)
{
if(i%5==0) DebugLog->displayRaw("3D: ");
DebugLog->displayRaw(string(exts[i]+" ").c_str());
if(i%5==4) DebugLog->displayRaw("\n");
}
DebugLog->displayRaw("\n");
}
// Check for pbuffer
// ext.WGLARBPBuffer= setupWGLARBPBuffer(glext);
// Check for pixel format
// ext.WGLARBPixelFormat= setupWGLARBPixelFormat(glext);
// Check for swap control
ext.GLXEXTSwapControl= setupGLXEXTSwapControl(glext);
ext.GLXSGISwapControl= setupGLXSGISwapControl(glext);
ext.GLXMESASwapControl= setupGLXMESASwapControl(glext);
return true;
}
#endif // NL_OS_WINDOWS
}

View file

@ -34,6 +34,7 @@
# include <GL/gl.h>
# include <GL/glext.h> // Please download it from http://www.opengl.org/registry/
# include <GL/glx.h>
# include <GL/glxext.h>
#endif // NL_OS_UNIX
#ifndef GL_GLEXT_VERSION
@ -93,6 +94,11 @@ struct CGlExtensions
bool WGLARBPixelFormat;
bool WGLEXTSwapControl;
// GLX extensions, true if supported
bool GLXEXTSwapControl;
bool GLXSGISwapControl;
bool GLXMESASwapControl;
// ATI Extensions.
bool ATIVertexArrayObject;
bool ATIMapObjectBuffer;
@ -147,6 +153,9 @@ public:
WGLARBPBuffer= false;
WGLARBPixelFormat= false;
WGLEXTSwapControl= false;
GLXEXTSwapControl= false;
GLXSGISwapControl= false;
GLXMESASwapControl= false;
EXTBlendColor= false;
ATIVertexArrayObject= false;
ATIEnvMapBumpMap = false;
@ -225,6 +234,11 @@ public:
result += WGLARBPBuffer ? "WGLARBPBuffer " : "";
result += WGLARBPixelFormat ? "WGLARBPixelFormat " : "";
result += WGLEXTSwapControl ? "WGLEXTSwapControl " : "";
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
result += GLXEXTSwapControl ? "GLXEXTSwapControl " : "";
result += GLXSGISwapControl ? "GLXSGISwapControl " : "";
result += GLXMESASwapControl ? "GLXMESASwapControl " : "";
#endif
result += "\n Array/VBO: ";
@ -249,6 +263,10 @@ public:
#ifdef NL_OS_WINDOWS
/// This function will test and register WGL functions before than the gl context is created
bool registerWGlExtensions(CGlExtensions &ext, HDC hDC);
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
/// This function will test and register GLX functions before than the gl context is created
bool registerGlXExtensions(CGlExtensions &ext, Display *dpy, sint screen);
#endif // NL_OS_WINDOWS
/// This function test and register the extensions for the current GL context.
@ -674,6 +692,18 @@ extern PFNWGLGETSWAPINTERVALEXTPROC nwglGetSwapIntervalEXT;
// WGL_ARB_extensions_string
extern PFNWGLGETEXTENSIONSSTRINGARBPROC nwglGetExtensionsStringARB;
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
// Swap control extensions
//===========================
extern PFNGLXSWAPINTERVALEXTPROC nglXSwapIntervalEXT;
extern PFNGLXSWAPINTERVALSGIPROC nglXSwapIntervalSGI;
extern PFNGLXSWAPINTERVALMESAPROC nglXSwapIntervalMESA;
extern PFNGLXGETSWAPINTERVALMESAPROC nglXGetSwapIntervalMESA;
#endif
// GL_EXT_framebuffer_object