From 9cf5b3305c4cd3d68cb1bf1ca609c659bb0568b6 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 1 Apr 2014 21:05:05 +0200 Subject: [PATCH] GL3: Create 3.3 core profile context --HG-- branch : opengl3 --- .../nel/src/3d/driver/opengl3/driver_opengl.h | 13 --- .../opengl3/driver_opengl_extension.cpp | 88 +++++++++++++++---- .../driver/opengl3/driver_opengl_extension.h | 14 ++- .../driver/opengl3/driver_opengl_program.cpp | 26 ------ .../driver_opengl_vertex_buffer_hard.cpp | 12 +-- .../driver/opengl3/driver_opengl_window.cpp | 32 ++++++- 6 files changed, 114 insertions(+), 71 deletions(-) diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl.h b/code/nel/src/3d/driver/opengl3/driver_opengl.h index 5157097f5..8586363cf 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl.h @@ -75,19 +75,6 @@ // For optimisation consideration, allow 256 lightmaps at max. #define NL3D_DRV_MAX_LIGHTMAP 256 - - -/* -#define CHECK_GL_ERROR { \ - GLenum error = glGetError(); \ - if (error != GL_NO_ERROR)\ - {\ - displayGLError(error);\ - nlassert(0);\ - }\ -} -*/ - #define UNSUPPORTED_INDEX_OFFSET_MSG "Unsupported by driver, check IDriver::supportIndexOffset." using NLMISC::CMatrix; diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_extension.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_extension.cpp index e1a3c6714..be5b36a00 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_extension.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_extension.cpp @@ -64,6 +64,8 @@ void (*nglGetProcAddress(const char *procName))() // The exported function names // Core 3.30 +PFNGLGETSTRINGIPROC nglGetStringi; + PFNGLATTACHSHADERPROC nglAttachShader; PFNGLCOMPILESHADERPROC nglCompileShader; PFNGLCREATEPROGRAMPROC nglCreateProgram; @@ -245,6 +247,9 @@ PFNWGLGETSWAPINTERVALEXTPROC nwglGetSwapIntervalEXT; // WGL_ARB_extensions_string PFNWGLGETEXTENSIONSSTRINGARBPROC nwglGetExtensionsStringARB; +// WGL_ARB_create_context_profile +PFNWGLCREATECONTEXTATTRIBSARBPROC nwglCreateContextAttribsARB; + #elif defined(NL_OS_MAC) #elif defined(NL_OS_UNIX) @@ -276,6 +281,19 @@ namespace NLDRIVERGL3 { #define CHECK_EXT(ext_str) \ if (strstr(glext, ext_str)==NULL) { nlwarning("3D: OpengGL extension '%s' was not found", ext_str); return false; } else { nldebug("3D: OpengGL Extension '%s' found", ext_str); } +bool checkExt2(std::vector &glext, const char *ext_str) +{ + for (int i = 0; i < glext.size(); ++i) + { + if (strcmp(glext[i], ext_str) == 0) + return true; + } + return false; +} + +#define CHECK_EXT_2(ext_str) \ + if (!checkExt2(glext, ext_str)) { nlwarning("3D: OpengGL extension '%s' was not found", ext_str); return false; } else { nldebug("3D: OpengGL Extension '%s' found", ext_str); } + // Debug: don't return false if the procaddr returns 0 // It means that it can crash if nel calls this extension but at least we have a warning to know why the extension is available but not the procaddr #define CHECK_ADDRESS(type, ext) \ @@ -286,11 +304,11 @@ namespace NLDRIVERGL3 { // Extensions registrations, and Windows function Registration. // ********************************* -static bool setupEXTTextureCompressionS3TC(const char *glext) +static bool setupEXTTextureCompressionS3TC(std::vector &glext) { H_AUTO_OGL(setupEXTTextureCompressionS3TC); - CHECK_EXT("GL_EXT_texture_compression_s3tc"); + CHECK_EXT_2("GL_EXT_texture_compression_s3tc"); // TODO: check also for GL_S3_s3tc, GL_EXT_texture_compression_dxt1 return true; @@ -329,14 +347,14 @@ static bool setupWGLARBPixelFormat (const char *glext) #endif // *************************************************************************** -static bool setupEXTTextureFilterAnisotropic(const char *glext) +static bool setupEXTTextureFilterAnisotropic(std::vector &glext) { H_AUTO_OGL(setupEXTTextureFilterAnisotropic); - CHECK_EXT("GL_EXT_texture_filter_anisotropic"); + CHECK_EXT_2("GL_EXT_texture_filter_anisotropic"); return true; } -static bool setupGLCore(const char *glext) +static bool setupGLCore(std::vector &glext) { CHECK_ADDRESS(PFNGLATTACHSHADERPROC, glAttachShader); CHECK_ADDRESS(PFNGLCOMPILESHADERPROC, glCompileShader); @@ -437,9 +455,9 @@ static bool setupGLCore(const char *glext) return true; } -static bool setupARBSeparateShaderObjects(const char *glext) +static bool setupARBSeparateShaderObjects(std::vector &glext) { - CHECK_EXT("GL_ARB_separate_shader_objects"); + CHECK_EXT_2("GL_ARB_separate_shader_objects"); CHECK_ADDRESS(PFNGLUSEPROGRAMSTAGESPROC, glUseProgramStages); CHECK_ADDRESS(PFNGLACTIVESHADERPROGRAMPROC, glActiveShaderProgram); @@ -507,10 +525,12 @@ static bool setupARBSeparateShaderObjects(const char *glext) // *************************************************************************** // Extension Check. -void registerGlExtensions(CGlExtensions &ext) +bool registerGlExtensions(CGlExtensions &ext) { H_AUTO_OGL(registerGlExtensions); + nldebug("Register OpenGL extensions"); + const char *nglVersion= (const char *)glGetString (GL_VERSION); sint a=0, b=0; @@ -521,21 +541,37 @@ void registerGlExtensions(CGlExtensions &ext) nlinfo("Version string: %s",nglVersion); nlassert(false); } + + nldebug("OpenGL version is OK"); // Extensions. - const char *glext= (const char*)glGetString(GL_EXTENSIONS); - GLint ntext; + /*const char *glext= (const char*)glGetString(GL_EXTENSIONS); + GLint ntext;*/ + + // Get proc address + CHECK_ADDRESS(PFNGLGETSTRINGIPROC, glGetStringi); + nldebug("GL3: glGetStringi found!"); + + std::vector glext; + GLint numExt; + glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); + nldebug("GL3: GL_NUM_EXTENSIONS = %i", numExt); + glext.resize(numExt); + for (GLint i = 0; i < numExt; ++i) + { + glext[i] = static_cast(static_cast(nglGetStringi(GL_EXTENSIONS, i))); + } nldebug("3D: Available OpenGL Extensions:"); if (DebugLog) { - vector exts; - explode(string(glext), string(" "), exts); - for (uint i = 0; i < exts.size(); i++) + //vector exts; + //explode(string(glext), string(" "), exts); + for (uint i = 0; i < glext.size(); i++) { if (i%5==0) DebugLog->displayRaw("3D: "); - DebugLog->displayRaw(string(exts[i]+" ").c_str()); + DebugLog->displayRaw(string(string(glext[i]) + " ").c_str()); if (i%5==4) DebugLog->displayRaw("\n"); } DebugLog->displayRaw("\n"); @@ -562,6 +598,8 @@ void registerGlExtensions(CGlExtensions &ext) GLint nbFragmentTextureUnits; glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &nbFragmentTextureUnits); ext.NbFragmentTextureUnits = (nbFragmentTextureUnits > IDRV_MAT_MAXTEXTURES) ? IDRV_MAT_MAXTEXTURES : nbFragmentTextureUnits; // FIXME GL3 + + return true; } @@ -579,6 +617,19 @@ static bool setupWGLEXTSwapControl(const char *glext) return true; } +// ********************************* +static bool setupWGLARBCreateContextProfile(const char *glext) +{ + H_AUTO_OGL(setupWGLARBCreateContextProfile); + CHECK_EXT("WGL_ARB_create_context_profile"); + +#ifdef NL_OS_WINDOWS + CHECK_ADDRESS(PFNWGLCREATECONTEXTATTRIBSARBPROC, wglCreateContextAttribsARB); +#endif + + return true; +} + // ********************************* static bool setupGLXEXTSwapControl(const char *glext) { @@ -652,13 +703,16 @@ bool registerWGlExtensions(CGlExtensions &ext, HDC hDC) } // Check for pbuffer - ext.WGLARBPBuffer= setupWGLARBPBuffer(glext); + ext.WGLARBPBuffer = setupWGLARBPBuffer(glext); // Check for pixel format - ext.WGLARBPixelFormat= setupWGLARBPixelFormat(glext); + ext.WGLARBPixelFormat = setupWGLARBPixelFormat(glext); // Check for swap control - ext.WGLEXTSwapControl= setupWGLEXTSwapControl(glext); + ext.WGLEXTSwapControl = setupWGLEXTSwapControl(glext); + + // Check for create context profile + ext.WGLARBCreateContextProfile = setupWGLARBCreateContextProfile(glext); return true; } diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_extension.h b/code/nel/src/3d/driver/opengl3/driver_opengl_extension.h index 7a30d0720..615398b17 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_extension.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_extension.h @@ -52,6 +52,7 @@ struct CGlExtensions bool WGLARBPBuffer; bool WGLARBPixelFormat; bool WGLEXTSwapControl; + bool WGLARBCreateContextProfile; // GLX extensions, true if supported bool GLXEXTSwapControl; @@ -75,6 +76,7 @@ public: WGLARBPBuffer = false; WGLARBPixelFormat = false; WGLEXTSwapControl = false; + WGLARBCreateContextProfile = false; GLXEXTSwapControl = false; GLXSGISwapControl = false; @@ -105,6 +107,7 @@ public: result += WGLARBPBuffer ? "WGLARBPBuffer " : ""; result += WGLARBPixelFormat ? "WGLARBPixelFormat " : ""; result += WGLEXTSwapControl ? "WGLEXTSwapControl " : ""; + result += WGLARBCreateContextProfile ? "WGLARBCreateContextProfile" : ""; #elif defined(NL_OS_MAC) #elif defined(NL_OS_UNIX) result += "\n GLX: "; @@ -130,7 +133,7 @@ bool registerGlXExtensions(CGlExtensions &ext, Display *dpy, sint screen); #endif // NL_OS_WINDOWS /// This function test and register the extensions for the current GL context. -void registerGlExtensions(CGlExtensions &ext); +bool registerGlExtensions(CGlExtensions &ext); #ifdef NL_STATIC } // NLDRIVERGL3 @@ -148,6 +151,8 @@ void registerGlExtensions(CGlExtensions &ext); */ // Core 3.30 +extern PFNGLGETSTRINGIPROC nglGetStringi; + extern PFNGLATTACHSHADERPROC nglAttachShader; extern PFNGLCOMPILESHADERPROC nglCompileShader; extern PFNGLCREATEPROGRAMPROC nglCreateProgram; @@ -329,9 +334,12 @@ extern PFNWGLCHOOSEPIXELFORMATARBPROC nwglChoosePixelFormatARB; extern PFNWGLSWAPINTERVALEXTPROC nwglSwapIntervalEXT; extern PFNWGLGETSWAPINTERVALEXTPROC nwglGetSwapIntervalEXT; - // WGL_ARB_extensions_string -extern PFNWGLGETEXTENSIONSSTRINGARBPROC nwglGetExtensionsStringARB; +extern PFNWGLGETEXTENSIONSSTRINGARBPROC nwglGetExtensionsStringARB; + +// WGL_ARB_create_context_profile +extern PFNWGLCREATECONTEXTATTRIBSARBPROC nwglCreateContextAttribsARB; + #elif defined(NL_OS_MAC) #elif defined(NL_OS_UNIX) diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp index 3461f111f..268d0c1aa 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp @@ -107,7 +107,6 @@ bool CDriverGL3::compileVertexProgram(CVertexProgram *program) return false; const char *s = src->SourcePtr; - glGetError(); unsigned int id = nglCreateShaderProgramv(GL_VERTEX_SHADER, 1, &s); if (id == 0) @@ -138,10 +137,6 @@ bool CDriverGL3::compileVertexProgram(CVertexProgram *program) } } - GLenum error = glGetError(); - if (error != GL_NO_ERROR) - return false; - ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(),(NL3D::IProgramDrvInfos*)NULL); CProgramDrvInfosGL3 *drvInfo = new CProgramDrvInfosGL3(this, it); *it = drvInfo; @@ -183,16 +178,8 @@ bool CDriverGL3::activeVertexProgram(CVertexProgram *program, bool driver) m_DriverVertexProgram = NULL; return false; } - glGetError(); nglUseProgramStages(ppoId, GL_VERTEX_SHADER_BIT, drvInfo->getProgramId()); - GLenum error = glGetError(); - if (error != GL_NO_ERROR) - { - m_UserVertexProgram = NULL; - m_DriverVertexProgram = NULL; - return false; - } if (!driver) m_UserVertexProgram = program; m_DriverVertexProgram = program; @@ -227,7 +214,6 @@ bool CDriverGL3::compilePixelProgram(CPixelProgram *program) return false; const char *s = src->SourcePtr; - glGetError(); unsigned int id = nglCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &s); if (id == 0) return false; @@ -257,10 +243,6 @@ bool CDriverGL3::compilePixelProgram(CPixelProgram *program) } } - GLenum error = glGetError(); - if (error != GL_NO_ERROR) - return false; - ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IProgramDrvInfos*)NULL); CProgramDrvInfosGL3 *drvInfo = new CProgramDrvInfosGL3(this, it); *it = drvInfo; @@ -309,16 +291,8 @@ bool CDriverGL3::activePixelProgram(CPixelProgram *program, bool driver) m_DriverPixelProgram = NULL; return false; } - glGetError(); nglUseProgramStages(ppoId, GL_FRAGMENT_SHADER_BIT, drvInfo->getProgramId()); - GLenum error = glGetError(); - if (error != GL_NO_ERROR) - { - m_UserPixelProgram = NULL; - m_DriverPixelProgram = NULL; - return false; - } if (!driver) m_UserPixelProgram = program; m_DriverPixelProgram = program; diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_buffer_hard.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_buffer_hard.cpp index 72a64f8da..420ecfd16 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_buffer_hard.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_buffer_hard.cpp @@ -75,11 +75,7 @@ IVertexBufferHardGL *CVertexArrayRange::createVBHardGL(uint size, CVertexBuffer // create a ARB VBHard GLuint vertexBufferID; - glGetError(); - nglGenBuffers(1, &vertexBufferID); - - if (glGetError() != GL_NO_ERROR) return NULL; _Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID); switch(_VBType) { @@ -96,11 +92,6 @@ IVertexBufferHardGL *CVertexArrayRange::createVBHardGL(uint size, CVertexBuffer nlassert(0); break; } - if (glGetError() != GL_NO_ERROR) - { - nglDeleteBuffers(1, &vertexBufferID); - return NULL; - } CVertexBufferHard *newVbHard= new CVertexBufferHard(_Driver, vb); newVbHard->initGL(vertexBufferID, this, _VBType); _Driver->_DriverGLStates.forceBindARBVertexBuffer(0); @@ -222,7 +213,8 @@ void *CVertexBufferHard::lock() } // recreate a vb GLuint vertexBufferID; - + + glGetError(); nglGenBuffers(1, &vertexBufferID); if (glGetError() != GL_NO_ERROR) diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_window.cpp index d4c323d9c..fc5c24887 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_window.cpp @@ -2373,9 +2373,37 @@ bool CDriverGL3::createContext() { return false; } - _hRC=wglCreateContext(_hDC); - wglMakeCurrent(_hDC,_hRC); + bool hasRegularHRC = !_Extensions.WGLARBCreateContextProfile; + if (hasRegularHRC) + { + nldebug("Create regular OpenGL context"); + _hRC = wglCreateContext(_hDC); + wglMakeCurrent(_hDC,_hRC); + } + + nldebug("Register WGL extensions"); + registerWGlExtensions(_Extensions, _hDC); + if (_Extensions.WGLARBCreateContextProfile) + { + if (hasRegularHRC) + { + nldebug("Delete regular OpenGL context"); + wglMakeCurrent(_hDC, NULL); + wglDeleteContext(_hRC); + _hRC = NULL; + } + nldebug("Create OpenGL context for Core 3.30 profile"); + int attribList[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0, 0 + }; + _hRC = nwglCreateContextAttribsARB(_hDC, 0, attribList); + nldebug("Make current"); + wglMakeCurrent(_hDC,_hRC); + } #endif return true;