diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index d6b6177dc..deb206c6e 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -2241,8 +2241,29 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt s_InitDefaultParams = true; } + //clamp the versions to existing versions(only for OpenGL major <= 3) + if(g_Config.m_GfxOpenGLMajor == 1) + { + g_Config.m_GfxOpenGLMinor = clamp(g_Config.m_GfxOpenGLMinor, 1, 5); + if(g_Config.m_GfxOpenGLMinor == 2) + g_Config.m_GfxOpenGLPatch = clamp(g_Config.m_GfxOpenGLPatch, 0, 1); + else + g_Config.m_GfxOpenGLPatch = 0; + } + else if(g_Config.m_GfxOpenGLMajor == 2) + { + g_Config.m_GfxOpenGLMinor = clamp(g_Config.m_GfxOpenGLMinor, 0, 1); + g_Config.m_GfxOpenGLPatch = 0; + } + else if(g_Config.m_GfxOpenGLMajor == 3) + { + g_Config.m_GfxOpenGLMinor = clamp(g_Config.m_GfxOpenGLMinor, 0, 3); + g_Config.m_GfxOpenGLPatch = 0; + } + // if OpenGL3 context was tried to be created, but failed, we have to restore the old context attributes - if(s_TriedOpenGL3Context && !g_Config.m_GfxOpenGL3) + bool IsNewOpenGL = (g_Config.m_GfxOpenGLMajor == 3 && g_Config.m_GfxOpenGLMinor == 3) || g_Config.m_GfxOpenGLMajor >= 4; + if(s_TriedOpenGL3Context && !IsNewOpenGL) { s_TriedOpenGL3Context = false; @@ -2251,8 +2272,8 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, s_SDLGLContextMinorVersion); } - m_UseOpenGL3_3 = false; - if(g_Config.m_GfxOpenGL3) + m_UseNewOpenGL = false; + if(IsNewOpenGL) { s_TriedOpenGL3Context = true; @@ -2261,23 +2282,23 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt pErr = SDL_GetError(); if(pErr[0] != '\0') { - dbg_msg("gfx", "Using old OpenGL context, because an error occurred while trying to use OpenGL context 3.3: %s.", pErr); + dbg_msg("gfx", "Using old OpenGL context, because an error occurred while trying to use OpenGL context %zu.%zu: %s.", (size_t)g_Config.m_GfxOpenGLMajor, (size_t)g_Config.m_GfxOpenGLMinor, pErr); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, s_SDLGLContextProfileMask); } else { - if(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) == 0 && SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3) == 0) + if(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, g_Config.m_GfxOpenGLMajor) == 0 && SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, g_Config.m_GfxOpenGLMinor) == 0) { pErr = SDL_GetError(); if(pErr[0] != '\0') { - dbg_msg("gfx", "Using old OpenGL context, because an error occurred while trying to use OpenGL context 3.3: %s.", pErr); + dbg_msg("gfx", "Using old OpenGL context, because an error occurred while trying to use OpenGL context %zu.%zu: %s.", (size_t)g_Config.m_GfxOpenGLMajor, (size_t)g_Config.m_GfxOpenGLMinor, pErr); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, s_SDLGLContextMajorVersion); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, s_SDLGLContextMinorVersion); } else { - m_UseOpenGL3_3 = true; + m_UseNewOpenGL = true; int vMaj, vMin; SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &vMaj); SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &vMin); @@ -2286,7 +2307,7 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt } else { - dbg_msg("gfx", "Couldn't create OpenGL 3.3 context."); + dbg_msg("gfx", "Couldn't create OpenGL %zu.%zu context.", (size_t)g_Config.m_GfxOpenGLMajor, (size_t)g_Config.m_GfxOpenGLMinor); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, s_SDLGLContextMajorVersion); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, s_SDLGLContextMinorVersion); } @@ -2300,6 +2321,12 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, s_SDLGLContextMinorVersion); } } + //if non standard opengl, set it + else if(s_SDLGLContextMajorVersion != g_Config.m_GfxOpenGLMajor || s_SDLGLContextMinorVersion != g_Config.m_GfxOpenGLMinor) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, g_Config.m_GfxOpenGLMajor); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, g_Config.m_GfxOpenGLMinor); + dbg_msg("gfx", "Created OpenGL %zu.%zu context.", (size_t)g_Config.m_GfxOpenGLMajor, (size_t)g_Config.m_GfxOpenGLMinor); + } // set screen SDL_Rect ScreenPos; @@ -2416,7 +2443,7 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt return -1; } - if(m_UseOpenGL3_3) + if(m_UseNewOpenGL) { //support graphic cards that are pretty old(and linux) glewExperimental = GL_TRUE; @@ -2430,12 +2457,12 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt // start the command processor m_pProcessor = new CCommandProcessor_SDL_OpenGL; - ((CCommandProcessor_SDL_OpenGL*)m_pProcessor)->UseOpenGL3_3(m_UseOpenGL3_3); + ((CCommandProcessor_SDL_OpenGL*)m_pProcessor)->UseOpenGL3_3(m_UseNewOpenGL); StartProcessor(m_pProcessor); // issue init commands for OpenGL and SDL CCommandBuffer CmdBuffer(1024, 512); - if(m_UseOpenGL3_3) + if(m_UseNewOpenGL) { //run sdl first to have the context in the thread CCommandProcessorFragment_SDL::SCommand_Init CmdSDL; @@ -2504,7 +2531,7 @@ int CGraphicsBackend_SDL_OpenGL::Shutdown() { // issue a shutdown command CCommandBuffer CmdBuffer(1024, 512); - if(m_UseOpenGL3_3) + if(m_UseNewOpenGL) { CCommandProcessorFragment_OpenGL3_3::SCommand_Shutdown Cmd; CmdBuffer.AddCommand(Cmd); diff --git a/src/engine/client/backend_sdl.h b/src/engine/client/backend_sdl.h index a8a9f8144..f8d621bd1 100644 --- a/src/engine/client/backend_sdl.h +++ b/src/engine/client/backend_sdl.h @@ -135,7 +135,7 @@ class CGLSLBorderTileLineProgram; class CGLSLTextProgram; class CGLSLSpriteProgram; class CGLSLSpriteMultipleProgram; -// takes care of opengl 3.3 related rendering +// takes care of opengl 3.3+ related rendering class CCommandProcessorFragment_OpenGL3_3 { bool m_UseMultipleTextureUnits; @@ -346,7 +346,7 @@ class CGraphicsBackend_SDL_OpenGL : public CGraphicsBackend_Threaded volatile int m_TextureMemoryUsage; int m_NumScreens; - bool m_UseOpenGL3_3; + bool m_UseNewOpenGL; public: virtual int Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight, int *pCurrentWidth, int *pCurrentHeight, class IStorage *pStorage); virtual int Shutdown(); @@ -366,7 +366,7 @@ public: virtual void SetWindowGrab(bool Grab); virtual void NotifyWindow(); - virtual bool IsOpenGL3_3() { return m_UseOpenGL3_3; } + virtual bool IsNewOpenGL() { return m_UseNewOpenGL; } }; #endif // ENGINE_CLIENT_BACKEND_SDL_H diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index 3b5b8295a..225011a5b 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -68,7 +68,7 @@ void CGraphics_Threaded::FlushVertices(bool KeepVertices) if(m_Drawing == DRAWING_QUADS) { - if(g_Config.m_GfxQuadAsTriangle && !m_UseOpenGL3_3) + if(g_Config.m_GfxQuadAsTriangle && !m_IsNewOpenGL) { Cmd.m_PrimType = CCommandBuffer::PRIMTYPE_TRIANGLES; Cmd.m_PrimCount = NumVerts/3; @@ -705,7 +705,7 @@ void CGraphics_Threaded::ChangeColorOfCurrentQuadVertices(float r, float g, floa void CGraphics_Threaded::ChangeColorOfQuadVertices(int QuadOffset, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - if(g_Config.m_GfxQuadAsTriangle && !m_UseOpenGL3_3) + if(g_Config.m_GfxQuadAsTriangle && !m_IsNewOpenGL) { m_aVertices[QuadOffset * 6].m_Color.r = r; m_aVertices[QuadOffset * 6].m_Color.g = g; @@ -806,7 +806,7 @@ void CGraphics_Threaded::QuadsDrawTL(const CQuadItem *pArray, int Num) dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsDrawTL without begin"); - if(g_Config.m_GfxQuadAsTriangle && !m_UseOpenGL3_3) + if(g_Config.m_GfxQuadAsTriangle && !m_IsNewOpenGL) { for(int i = 0; i < Num; ++i) { @@ -894,7 +894,7 @@ void CGraphics_Threaded::QuadsDrawFreeform(const CFreeformItem *pArray, int Num) { dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsDrawFreeform without begin"); - if(g_Config.m_GfxQuadAsTriangle && !m_UseOpenGL3_3) + if(g_Config.m_GfxQuadAsTriangle && !m_IsNewOpenGL) { for(int i = 0; i < Num; ++i) { @@ -1228,7 +1228,7 @@ int CGraphics_Threaded::CreateQuadContainer() void CGraphics_Threaded::QuadContainerUpload(int ContainerIndex) { - if(m_UseOpenGL3_3) + if(m_IsNewOpenGL) { SQuadContainer& Container = m_QuadContainers[ContainerIndex]; if(Container.m_Quads.size() > 0) @@ -1364,7 +1364,7 @@ void CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CFreeformItem void CGraphics_Threaded::QuadContainerReset(int ContainerIndex) { SQuadContainer& Container = m_QuadContainers[ContainerIndex]; - if(m_UseOpenGL3_3) + if(m_IsNewOpenGL) { if(Container.m_QuadBufferContainerIndex != -1) DeleteBufferContainer(Container.m_QuadBufferContainerIndex, true); @@ -1397,7 +1397,7 @@ void CGraphics_Threaded::RenderQuadContainer(int ContainerIndex, int QuadOffset, if((int)Container.m_Quads.size() < QuadOffset + QuadDrawNum || QuadDrawNum == 0) return; - if(m_UseOpenGL3_3) + if(m_IsNewOpenGL) { if(Container.m_QuadBufferContainerIndex == -1) return; @@ -1455,7 +1455,7 @@ void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int Qua if((int)Container.m_Quads.size() < QuadOffset + 1) return; - if(m_UseOpenGL3_3) + if(m_IsNewOpenGL) { if(Container.m_QuadBufferContainerIndex == -1) return; @@ -1581,7 +1581,7 @@ void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex, if(DrawCount == 0) return; - if(m_UseOpenGL3_3) + if(m_IsNewOpenGL) { if(Container.m_QuadBufferContainerIndex == -1) return; @@ -2057,7 +2057,8 @@ int CGraphics_Threaded::IssueInit() if(g_Config.m_GfxResizable) Flags |= IGraphicsBackend::INITFLAG_RESIZABLE; int r = m_pBackend->Init("DDNet Client", &g_Config.m_GfxScreen, &g_Config.m_GfxScreenWidth, &g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags, &m_DesktopScreenWidth, &m_DesktopScreenHeight, &m_ScreenWidth, &m_ScreenHeight, m_pStorage); - m_UseOpenGL3_3 = m_pBackend->IsOpenGL3_3(); + m_IsNewOpenGL = m_pBackend->IsNewOpenGL(); + m_OpenGLBufferingEnabled = m_IsNewOpenGL; return r; } @@ -2081,9 +2082,12 @@ int CGraphics_Threaded::InitWindow() } // try using old opengl context - if(g_Config.m_GfxOpenGL3) + bool IsNewOpenGL = (g_Config.m_GfxOpenGLMajor == 3 && g_Config.m_GfxOpenGLMinor == 3) || g_Config.m_GfxOpenGLMajor >= 4; + if(IsNewOpenGL) { - g_Config.m_GfxOpenGL3 = 0; + g_Config.m_GfxOpenGLMajor = 2; + g_Config.m_GfxOpenGLMinor = 1; + g_Config.m_GfxOpenGLPatch = 0; if(IssueInit() == 0) { return 0; diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h index 051b52ca3..229d6d256 100644 --- a/src/engine/client/graphics_threaded.h +++ b/src/engine/client/graphics_threaded.h @@ -592,7 +592,7 @@ public: virtual bool IsIdle() const = 0; virtual void WaitForIdle() = 0; - virtual bool IsOpenGL3_3() { return false; } + virtual bool IsNewOpenGL() { return false; } }; class CGraphics_Threaded : public IEngineGraphics @@ -610,7 +610,8 @@ class CGraphics_Threaded : public IEngineGraphics CCommandBuffer::SState m_State; IGraphicsBackend *m_pBackend; - bool m_UseOpenGL3_3; + bool m_OpenGLBufferingEnabled; + bool m_IsNewOpenGL; CCommandBuffer *m_apCommandBuffers[NUM_CMDBUFFERS]; CCommandBuffer *m_pCommandBuffer; @@ -827,7 +828,7 @@ public: virtual bool IsIdle(); virtual void WaitForIdle(); - virtual bool IsBufferingEnabled() { return m_UseOpenGL3_3; } + virtual bool IsBufferingEnabled() { return m_OpenGLBufferingEnabled; } }; extern IGraphicsBackend *CreateGraphicsBackend(); diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index f54172a87..cee3652b0 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -366,7 +366,9 @@ MACRO_CONFIG_INT(ClDemoShowSpeed, cl_demo_show_speed, 0, 0, 1, CFGFLAG_SAVE|CFGF MACRO_CONFIG_INT(ClDemoKeyboardShortcuts, cl_demo_keyboard_shortcuts, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Enable keyboard shortcuts in demo player") //opengl -MACRO_CONFIG_INT(GfxOpenGL3, gfx_opengl3, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Use new OpenGL3 with shaders") +MACRO_CONFIG_INT(GfxOpenGLMajor, gfx_opengl_major, 2, 1, 10, CFGFLAG_SAVE|CFGFLAG_CLIENT, "OpenGL major version") +MACRO_CONFIG_INT(GfxOpenGLMinor, gfx_opengl_minor, 1, 0, 10, CFGFLAG_SAVE|CFGFLAG_CLIENT, "OpenGL minor version") +MACRO_CONFIG_INT(GfxOpenGLPatch, gfx_opengl_patch, 0, 0, 10, CFGFLAG_SAVE|CFGFLAG_CLIENT, "OpenGL patch version") #if !defined(CONF_PLATFORM_MACOSX) MACRO_CONFIG_INT(GfxEnableTextureUnitOptimization, gfx_enable_texture_unit_optimization, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Use multiple texture units, instead of only one.") #else diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 807cd7873..51d93e49e 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -905,7 +905,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView) static int s_GfxFsaaSamples = g_Config.m_GfxFsaaSamples; static int s_GfxTextureQuality = g_Config.m_GfxTextureQuality; static int s_GfxTextureCompression = g_Config.m_GfxTextureCompression; - static int s_GfxOpenGLVersion = g_Config.m_GfxOpenGL3; + static int s_GfxOpenGLVersion = (g_Config.m_GfxOpenGLMajor == 3 && g_Config.m_GfxOpenGLMinor == 3) || g_Config.m_GfxOpenGLMajor >= 4; static int s_GfxEnableTextureUnitOptimization = g_Config.m_GfxEnableTextureUnitOptimization; static int s_GfxUsePreinitBuffer = g_Config.m_GfxUsePreinitBuffer; static int s_GfxHighdpi = g_Config.m_GfxHighdpi; @@ -1031,13 +1031,27 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView) g_Config.m_GfxHighDetail ^= 1; MainView.HSplitTop(20.0f, &Button, &MainView); - if(DoButton_CheckBox(&g_Config.m_GfxOpenGL3, Localize("Use OpenGL 3.3 (experimental)"), g_Config.m_GfxOpenGL3, &Button)) + bool IsNewOpenGL = (g_Config.m_GfxOpenGLMajor == 3 && g_Config.m_GfxOpenGLMinor == 3) || g_Config.m_GfxOpenGLMajor >= 4; + if(DoButton_CheckBox(&g_Config.m_GfxOpenGLMajor, Localize("Use OpenGL 3.3 (experimental)"), IsNewOpenGL, &Button)) { CheckSettings = true; - g_Config.m_GfxOpenGL3 ^= 1; + if(IsNewOpenGL) + { + g_Config.m_GfxOpenGLMajor = 2; + g_Config.m_GfxOpenGLMinor = 1; + g_Config.m_GfxOpenGLPatch = 0; + IsNewOpenGL = false; + } + else + { + g_Config.m_GfxOpenGLMajor = 3; + g_Config.m_GfxOpenGLMinor = 3; + g_Config.m_GfxOpenGLPatch = 0; + IsNewOpenGL = true; + } } - if(g_Config.m_GfxOpenGL3) + if(IsNewOpenGL) { MainView.HSplitTop(20.0f, &Button, &MainView); if(DoButton_CheckBox(&g_Config.m_GfxUsePreinitBuffer, Localize("Preinit VBO (iGPUs only)"), g_Config.m_GfxUsePreinitBuffer, &Button)) @@ -1072,7 +1086,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView) s_GfxFsaaSamples == g_Config.m_GfxFsaaSamples && s_GfxTextureQuality == g_Config.m_GfxTextureQuality && s_GfxTextureCompression == g_Config.m_GfxTextureCompression && - s_GfxOpenGLVersion == g_Config.m_GfxOpenGL3 && + s_GfxOpenGLVersion == (int)IsNewOpenGL && s_GfxUsePreinitBuffer == g_Config.m_GfxUsePreinitBuffer && s_GfxEnableTextureUnitOptimization == g_Config.m_GfxEnableTextureUnitOptimization && s_GfxHighdpi == g_Config.m_GfxHighdpi)