Encapsulates information about GL inside device.
Commented By: Stan Differential Revision: https://code.wildfiregames.com/D4375 This was SVN commit r26072.
This commit is contained in:
parent
784f734480
commit
89c181ded1
@ -772,6 +772,8 @@ function setup_all_libs ()
|
||||
"graphics",
|
||||
"graphics/scripting",
|
||||
"renderer",
|
||||
"renderer/backend",
|
||||
"renderer/backend/gl",
|
||||
"renderer/scripting",
|
||||
"third_party/mikktspace",
|
||||
"third_party/ogre3d_preprocessor"
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
#include "lib/external_libraries/libsdl.h"
|
||||
#include "lib/debug.h"
|
||||
#include "lib/sysdep/gfx.h"
|
||||
#include "lib/res/h_mgr.h"
|
||||
|
||||
#if MSC_VERSION
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
/**
|
||||
* initialization: import extension function pointers and do feature detect.
|
||||
* call before using any other function, and after each video mode change.
|
||||
* call before using any other function.
|
||||
* fails if OpenGL not ready for use.
|
||||
**/
|
||||
extern void ogl_Init();
|
||||
|
@ -1,92 +0,0 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* graphics card detection.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "lib/sysdep/gfx.h"
|
||||
|
||||
#include "lib/external_libraries/libsdl.h"
|
||||
#include "lib/ogl.h"
|
||||
|
||||
#if OS_WIN
|
||||
# include "lib/sysdep/os/win/wgfx.h"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace gfx {
|
||||
|
||||
std::wstring CardName()
|
||||
{
|
||||
// GL_VENDOR+GL_RENDERER are good enough here, so we don't use WMI to detect the cards.
|
||||
// On top of that WMI can cause crashes with Nvidia Optimus and some netbooks
|
||||
// see http://trac.wildfiregames.com/ticket/1952
|
||||
// http://trac.wildfiregames.com/ticket/1575
|
||||
wchar_t cardName[128];
|
||||
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
||||
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
||||
// (happens if called before ogl_Init or between glBegin and glEnd.)
|
||||
if(!vendor || !renderer)
|
||||
return L"";
|
||||
swprintf_s(cardName, ARRAY_SIZE(cardName), L"%hs %hs", vendor, renderer);
|
||||
|
||||
// remove crap from vendor names. (don't dare touch the model name -
|
||||
// it's too risky, there are too many different strings)
|
||||
#define SHORTEN(what, charsToKeep)\
|
||||
if(!wcsncmp(cardName, what, ARRAY_SIZE(what)-1))\
|
||||
memmove(cardName+charsToKeep, cardName+ARRAY_SIZE(what)-1, (wcslen(cardName)-(ARRAY_SIZE(what)-1)+1)*sizeof(wchar_t));
|
||||
SHORTEN(L"ATI Technologies Inc.", 3);
|
||||
SHORTEN(L"NVIDIA Corporation", 6);
|
||||
SHORTEN(L"S3 Graphics", 2); // returned by EnumDisplayDevices
|
||||
SHORTEN(L"S3 Graphics, Incorporated", 2); // returned by GL_VENDOR
|
||||
#undef SHORTEN
|
||||
|
||||
return cardName;
|
||||
}
|
||||
|
||||
|
||||
std::wstring DriverInfo()
|
||||
{
|
||||
std::wstring driverInfo;
|
||||
#if OS_WIN
|
||||
driverInfo = wgfx_DriverInfo();
|
||||
if(driverInfo.empty())
|
||||
#endif
|
||||
{
|
||||
const char* version = (const char*)glGetString(GL_VERSION);
|
||||
if(version)
|
||||
{
|
||||
// add "OpenGL" to differentiate this from the real driver version
|
||||
// (returned by platform-specific detect routines).
|
||||
driverInfo = std::wstring(L"OpenGL ") + std::wstring(version, version+strlen(version));
|
||||
}
|
||||
}
|
||||
|
||||
if(driverInfo.empty())
|
||||
return L"(unknown)";
|
||||
return driverInfo;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
@ -1,46 +0,0 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* graphics card detection.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GFX
|
||||
#define INCLUDED_GFX
|
||||
|
||||
namespace gfx {
|
||||
|
||||
/**
|
||||
* @return description of graphics card,
|
||||
* or L"" if unknown.
|
||||
**/
|
||||
LIB_API std::wstring CardName();
|
||||
|
||||
/**
|
||||
* @return string describing the graphics driver and its version,
|
||||
* or L"" if unknown.
|
||||
**/
|
||||
LIB_API std::wstring DriverInfo();
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
#endif // #ifndef INCLUDED_GFX
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -24,7 +24,6 @@
|
||||
|
||||
#include "lib/lib.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
#include "lib/sysdep/gfx.h"
|
||||
#include "lib/utf8.h"
|
||||
#include "osx_bundle.h"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -27,7 +27,6 @@
|
||||
#include "precompiled.h"
|
||||
#include "lib/sysdep/os/win/wgfx.h"
|
||||
|
||||
#include "lib/sysdep/gfx.h"
|
||||
#include "lib/sysdep/os/win/wdll_ver.h"
|
||||
#include "lib/sysdep/os/win/wutil.h"
|
||||
|
||||
|
@ -931,15 +931,9 @@ void InitGraphics(const CmdLineArgs& args, int flags, const std::vector<CStr>& i
|
||||
|
||||
g_GUI = new CGUIManager();
|
||||
|
||||
// (must come after SetVideoMode, since it calls ogl_Init)
|
||||
CStr8 renderPath = "default";
|
||||
CFG_GET_VAL("renderpath", renderPath);
|
||||
if ((ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", nullptr) // ARB
|
||||
&& ogl_HaveExtensions(0, "GL_ARB_vertex_shader", "GL_ARB_fragment_shader", nullptr)) // GLSL
|
||||
|| !ogl_HaveExtension("GL_ARB_vertex_buffer_object") // VBO
|
||||
|| ogl_HaveExtensions(0, "GL_ARB_multitexture", "GL_EXT_draw_range_elements", nullptr)
|
||||
|| (!ogl_HaveExtension("GL_EXT_framebuffer_object") && !ogl_HaveExtension("GL_ARB_framebuffer_object"))
|
||||
|| RenderPathEnum::FromString(renderPath) == FIXED)
|
||||
if (RenderPathEnum::FromString(renderPath) == FIXED)
|
||||
{
|
||||
// It doesn't make sense to continue working here, because we're not
|
||||
// able to display anything.
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "lib/res/graphics/ogl_tex.h"
|
||||
#include "lib/posix/posix_utsname.h"
|
||||
#include "lib/sysdep/cpu.h"
|
||||
#include "lib/sysdep/gfx.h"
|
||||
#include "lib/sysdep/numa.h"
|
||||
#include "lib/sysdep/os_cpu.h"
|
||||
#if ARCH_X86_X64
|
||||
@ -43,6 +42,7 @@
|
||||
#include "ps/scripting/JSInterface_Debug.h"
|
||||
#include "ps/UserReport.h"
|
||||
#include "ps/VideoMode.h"
|
||||
#include "renderer/backend/gl/Device.h"
|
||||
#include "scriptinterface/FunctionWrapper.h"
|
||||
#include "scriptinterface/JSON.h"
|
||||
#include "scriptinterface/Object.h"
|
||||
@ -160,8 +160,8 @@ void RunHardwareDetection()
|
||||
Script::SetProperty(rq, settings, "build_gcc", (int)GCC_VERSION);
|
||||
Script::SetProperty(rq, settings, "build_clang", (int)CLANG_VERSION);
|
||||
|
||||
Script::SetProperty(rq, settings, "gfx_card", gfx::CardName());
|
||||
Script::SetProperty(rq, settings, "gfx_drv_ver", gfx::DriverInfo());
|
||||
Script::SetProperty(rq, settings, "gfx_card", g_VideoMode.GetBackendDevice()->GetName());
|
||||
Script::SetProperty(rq, settings, "gfx_drv_ver", g_VideoMode.GetBackendDevice()->GetDriverInformation());
|
||||
#if CONFIG2_AUDIO
|
||||
if (g_SoundManager)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -21,7 +21,7 @@
|
||||
/**
|
||||
* Runs hardware-detection script to adjust default config settings
|
||||
* and/or emit warnings depending on the user's system configuration.
|
||||
* This must only be called after ogl_Init.
|
||||
* This must only be called after backend device creation.
|
||||
*/
|
||||
void RunHardwareDetection();
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
#if ARCH_X86_X64
|
||||
#include "lib/sysdep/arch/x86_x64/topology.h"
|
||||
#endif
|
||||
#include "lib/sysdep/gfx.h"
|
||||
#include "lib/sysdep/cpu.h"
|
||||
#include "lib/sysdep/os_cpu.h"
|
||||
#include "lib/sysdep/smbios.h"
|
||||
@ -44,6 +43,7 @@
|
||||
#include "ps/GameSetup/GameSetup.h"
|
||||
#include "ps/Pyrogenesis.h"
|
||||
#include "ps/VideoMode.h"
|
||||
#include "renderer/backend/gl/Device.h"
|
||||
#include "renderer/Renderer.h"
|
||||
|
||||
#if CONFIG2_AUDIO
|
||||
@ -53,29 +53,6 @@
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
static std::string SplitExts(const char *exts)
|
||||
{
|
||||
std::string str = exts;
|
||||
std::string ret = "";
|
||||
size_t idx = str.find_first_of(" ");
|
||||
while(idx != std::string::npos)
|
||||
{
|
||||
if(idx >= str.length() - 1)
|
||||
{
|
||||
ret += str;
|
||||
break;
|
||||
}
|
||||
|
||||
ret += str.substr(0, idx);
|
||||
ret += "\n";
|
||||
str = str.substr(idx + 1);
|
||||
idx = str.find_first_of(" ");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void WriteSystemInfo()
|
||||
{
|
||||
TIMER(L"write_sys_info");
|
||||
@ -126,10 +103,8 @@ void WriteSystemInfo()
|
||||
fprintf(f, "Memory : %u MiB; %u MiB free\n", (unsigned)os_cpu_MemorySize(), (unsigned)os_cpu_MemoryAvailable());
|
||||
|
||||
// graphics
|
||||
const std::wstring cardName = gfx::CardName();
|
||||
const std::wstring driverInfo = gfx::DriverInfo();
|
||||
fprintf(f, "Graphics Card : %ls\n", cardName.c_str());
|
||||
fprintf(f, "OpenGL Drivers : %s; %ls\n", glGetString(GL_VERSION), driverInfo.c_str());
|
||||
fprintf(f, "Video Card : %s\n", g_VideoMode.GetBackendDevice()->GetName().c_str());
|
||||
fprintf(f, "Video Driver : %s\n", g_VideoMode.GetBackendDevice()->GetDriverInformation().c_str());
|
||||
fprintf(f, "Video Mode : %dx%d:%d\n", g_VideoMode.GetXRes(), g_VideoMode.GetYRes(), g_VideoMode.GetBPP());
|
||||
|
||||
#if CONFIG2_AUDIO
|
||||
@ -147,9 +122,12 @@ void WriteSystemInfo()
|
||||
#endif
|
||||
|
||||
// OpenGL extensions (write them last, since it's a lot of text)
|
||||
const char* exts = ogl_ExtensionString();
|
||||
if (!exts) exts = "{unknown}";
|
||||
fprintf(f, "\nOpenGL Extensions: \n%s\n", SplitExts(exts).c_str());
|
||||
fprintf(f, "\nBackend Extensions:\n");
|
||||
if (g_VideoMode.GetBackendDevice()->GetExtensions().empty())
|
||||
fprintf(f, "{unknown}\n");
|
||||
else
|
||||
for (const std::string& extension : g_VideoMode.GetBackendDevice()->GetExtensions())
|
||||
fprintf(f, "%s\n", extension.c_str());
|
||||
|
||||
// System Management BIOS (even more text than OpenGL extensions)
|
||||
std::string smbios = SMBIOS::StringizeStructures(SMBIOS::GetStructures());
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "lib/config2.h"
|
||||
#include "lib/external_libraries/libsdl.h"
|
||||
#include "lib/ogl.h"
|
||||
#include "lib/sysdep/gfx.h"
|
||||
#include "lib/tex/tex.h"
|
||||
#include "ps/CConsole.h"
|
||||
#include "ps/CLogger.h"
|
||||
@ -34,6 +33,7 @@
|
||||
#include "ps/Game.h"
|
||||
#include "ps/GameSetup/Config.h"
|
||||
#include "ps/Pyrogenesis.h"
|
||||
#include "renderer/backend/gl/Device.h"
|
||||
#include "renderer/Renderer.h"
|
||||
|
||||
namespace
|
||||
@ -286,11 +286,15 @@ bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Context = SDL_GL_CreateContext(m_Window);
|
||||
if (!m_Context)
|
||||
#if OS_WIN
|
||||
// We need to set the window for an error dialog.
|
||||
wutil_SetAppWindow(m_Window);
|
||||
#endif
|
||||
|
||||
if (!CreateBackendDevice(true))
|
||||
{
|
||||
LOGERROR("SetVideoMode failed in SDL_GL_CreateContext: %dx%d:%d %d (\"%s\")",
|
||||
w, h, bpp, fullscreen ? 1 : 0, SDL_GetError());
|
||||
LOGERROR("SetVideoMode failed in backend device creation: %dx%d:%d %d",
|
||||
w, h, bpp, fullscreen ? 1 : 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -330,11 +334,6 @@ bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen)
|
||||
else
|
||||
SDL_SetWindowGrab(m_Window, SDL_FALSE);
|
||||
|
||||
#if OS_WIN
|
||||
// We need to set the window for an error dialog.
|
||||
wutil_SetAppWindow(m_Window);
|
||||
#endif
|
||||
|
||||
m_IsFullscreen = fullscreen;
|
||||
|
||||
g_xres = m_CurrentW;
|
||||
@ -468,9 +467,6 @@ bool CVideoMode::InitSDL()
|
||||
atexit(SDL_Quit);
|
||||
// End work around.
|
||||
|
||||
ogl_Init(); // required after each mode change
|
||||
// (TODO: does that mean we need to call this when toggling fullscreen later?)
|
||||
|
||||
m_IsInitialised = true;
|
||||
|
||||
if (!m_ConfigFullscreen)
|
||||
@ -505,11 +501,7 @@ void CVideoMode::Shutdown()
|
||||
|
||||
m_IsFullscreen = false;
|
||||
m_IsInitialised = false;
|
||||
if (m_Context)
|
||||
{
|
||||
SDL_GL_DeleteContext(m_Context);
|
||||
m_Context = nullptr;
|
||||
}
|
||||
m_BackendDevice.reset();
|
||||
if (m_Window)
|
||||
{
|
||||
SDL_DestroyWindow(m_Window);
|
||||
@ -517,6 +509,12 @@ void CVideoMode::Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
bool CVideoMode::CreateBackendDevice(const bool createSDLContext)
|
||||
{
|
||||
m_BackendDevice = Renderer::Backend::GL::CDevice::Create(createSDLContext ? m_Window : nullptr);
|
||||
return !!m_BackendDevice;
|
||||
}
|
||||
|
||||
bool CVideoMode::ResizeWindow(int w, int h)
|
||||
{
|
||||
ENSURE(m_IsInitialised);
|
||||
|
@ -25,6 +25,17 @@
|
||||
typedef struct SDL_Window SDL_Window;
|
||||
typedef void* SDL_GLContext;
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
namespace Backend
|
||||
{
|
||||
namespace GL
|
||||
{
|
||||
class CDevice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CVideoMode
|
||||
{
|
||||
public:
|
||||
@ -53,6 +64,12 @@ public:
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* Creates a backend device. Also we use wxWidgets in Atlas so we don't need
|
||||
* to create one for that case.
|
||||
*/
|
||||
bool CreateBackendDevice(const bool createSDLContext);
|
||||
|
||||
/**
|
||||
* Resize the SDL window and associated graphics stuff to the new size.
|
||||
*/
|
||||
@ -112,6 +129,8 @@ public:
|
||||
|
||||
Backend GetBackend() const { return m_Backend; }
|
||||
|
||||
Renderer::Backend::GL::CDevice* GetBackendDevice() { return m_BackendDevice.get(); }
|
||||
|
||||
private:
|
||||
void ReadConfig();
|
||||
int GetBestBPP();
|
||||
@ -125,7 +144,6 @@ private:
|
||||
bool m_IsInitialised = false;
|
||||
|
||||
SDL_Window* m_Window = nullptr;
|
||||
SDL_GLContext m_Context = nullptr;
|
||||
|
||||
// Initial desktop settings.
|
||||
// Frequency is in Hz, and BPP means bits per pixels (not bytes per pixels).
|
||||
@ -167,6 +185,7 @@ private:
|
||||
std::unique_ptr<CCursor> m_Cursor;
|
||||
|
||||
Backend m_Backend = Backend::GL;
|
||||
std::unique_ptr<Renderer::Backend::GL::CDevice> m_BackendDevice;
|
||||
};
|
||||
|
||||
extern CVideoMode g_VideoMode;
|
||||
|
@ -1388,8 +1388,10 @@ void CRenderer::OnSwapBuffers()
|
||||
{
|
||||
bool checkGLErrorAfterSwap = false;
|
||||
CFG_GET_VAL("gl.checkerrorafterswap", checkGLErrorAfterSwap);
|
||||
#if defined(NDEBUG)
|
||||
if (!checkGLErrorAfterSwap)
|
||||
return;
|
||||
#endif
|
||||
PROFILE3("error check");
|
||||
// We have to check GL errors after SwapBuffer to avoid possible
|
||||
// synchronizations during rendering.
|
||||
|
166
source/renderer/backend/gl/Device.cpp
Normal file
166
source/renderer/backend/gl/Device.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "Device.h"
|
||||
|
||||
#include "lib/external_libraries/libsdl.h"
|
||||
#include "lib/ogl.h"
|
||||
#include "ps/CLogger.h"
|
||||
|
||||
#if OS_WIN
|
||||
#include "lib/sysdep/os/win/wgfx.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
namespace Backend
|
||||
{
|
||||
|
||||
namespace GL
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string GetNameImpl()
|
||||
{
|
||||
// GL_VENDOR+GL_RENDERER are good enough here, so we don't use WMI to detect the cards.
|
||||
// On top of that WMI can cause crashes with Nvidia Optimus and some netbooks
|
||||
// see http://trac.wildfiregames.com/ticket/1952
|
||||
// http://trac.wildfiregames.com/ticket/1575
|
||||
char cardName[128];
|
||||
const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
|
||||
const char* renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
// Happens if called before GL initialization.
|
||||
if (!vendor || !renderer)
|
||||
return {};
|
||||
sprintf_s(cardName, std::size(cardName), "%s %s", vendor, renderer);
|
||||
|
||||
// Remove crap from vendor names. (don't dare touch the model name -
|
||||
// it's too risky, there are too many different strings).
|
||||
#define SHORTEN(what, charsToKeep) \
|
||||
if (!strncmp(cardName, what, std::size(what) - 1)) \
|
||||
memmove(cardName + charsToKeep, cardName + std::size(what) - 1, (strlen(cardName) - (std::size(what) - 1) + 1) * sizeof(char));
|
||||
SHORTEN("ATI Technologies Inc.", 3);
|
||||
SHORTEN("NVIDIA Corporation", 6);
|
||||
SHORTEN("S3 Graphics", 2); // returned by EnumDisplayDevices
|
||||
SHORTEN("S3 Graphics, Incorporated", 2); // returned by GL_VENDOR
|
||||
#undef SHORTEN
|
||||
|
||||
return cardName;
|
||||
}
|
||||
|
||||
std::string GetVersionImpl()
|
||||
{
|
||||
return reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
}
|
||||
|
||||
std::string GetDriverInformationImpl()
|
||||
{
|
||||
const std::string version = GetVersionImpl();
|
||||
|
||||
std::string driverInfo;
|
||||
#if OS_WIN
|
||||
driverInfo = CStrW(wgfx_DriverInfo()).ToUTF8();
|
||||
if (driverInfo.empty())
|
||||
#endif
|
||||
{
|
||||
if (!version.empty())
|
||||
{
|
||||
// Add "OpenGL" to differentiate this from the real driver version
|
||||
// (returned by platform-specific detect routines).
|
||||
driverInfo = std::string("OpenGL ") + version;
|
||||
}
|
||||
}
|
||||
|
||||
if (driverInfo.empty())
|
||||
return version;
|
||||
return version + " " + driverInfo;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetExtensionsImpl()
|
||||
{
|
||||
std::vector<std::string> extensions;
|
||||
const std::string exts = ogl_ExtensionString();
|
||||
boost::split(extensions, exts, boost::algorithm::is_space(), boost::token_compress_on);
|
||||
std::sort(extensions.begin(), extensions.end());
|
||||
return extensions;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
std::unique_ptr<CDevice> CDevice::Create(SDL_Window* window)
|
||||
{
|
||||
std::unique_ptr<CDevice> device(new CDevice());
|
||||
|
||||
if (window)
|
||||
{
|
||||
device->m_Context = SDL_GL_CreateContext(window);
|
||||
if (!device->m_Context)
|
||||
{
|
||||
LOGERROR("SDL_GL_CreateContext failed: '%s'", SDL_GetError());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ogl_Init();
|
||||
|
||||
if ((ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", nullptr) // ARB
|
||||
&& ogl_HaveExtensions(0, "GL_ARB_vertex_shader", "GL_ARB_fragment_shader", nullptr)) // GLSL
|
||||
|| !ogl_HaveExtension("GL_ARB_vertex_buffer_object") // VBO
|
||||
|| ogl_HaveExtensions(0, "GL_ARB_multitexture", "GL_EXT_draw_range_elements", nullptr)
|
||||
|| (!ogl_HaveExtension("GL_EXT_framebuffer_object") && !ogl_HaveExtension("GL_ARB_framebuffer_object")))
|
||||
{
|
||||
// It doesn't make sense to continue working here, because we're not
|
||||
// able to display anything.
|
||||
DEBUG_DISPLAY_FATAL_ERROR(
|
||||
L"Your graphics card doesn't appear to be fully compatible with OpenGL shaders."
|
||||
L" The game does not support pre-shader graphics cards."
|
||||
L" You are advised to try installing newer drivers and/or upgrade your graphics card."
|
||||
L" For more information, please see http://www.wildfiregames.com/forum/index.php?showtopic=16734"
|
||||
);
|
||||
}
|
||||
|
||||
device->m_Name = GetNameImpl();
|
||||
device->m_Version = GetVersionImpl();
|
||||
device->m_DriverInformation = GetDriverInformationImpl();
|
||||
device->m_Extensions = GetExtensionsImpl();
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
CDevice::CDevice() = default;
|
||||
|
||||
CDevice::~CDevice()
|
||||
{
|
||||
if (m_Context)
|
||||
SDL_GL_DeleteContext(m_Context);
|
||||
}
|
||||
|
||||
} // namespace GL
|
||||
|
||||
} // namespace Backend
|
||||
|
||||
} // namespace Renderer
|
68
source/renderer/backend/gl/Device.h
Normal file
68
source/renderer/backend/gl/Device.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_RENDERER_BACKEND_GL_DEVICE
|
||||
#define INCLUDED_RENDERER_BACKEND_GL_DEVICE
|
||||
|
||||
#include "lib/external_libraries/libsdl.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
namespace Backend
|
||||
{
|
||||
|
||||
namespace GL
|
||||
{
|
||||
|
||||
class CDevice
|
||||
{
|
||||
public:
|
||||
~CDevice();
|
||||
|
||||
/**
|
||||
* Creates the GL device and the GL context for the window if it presents.
|
||||
*/
|
||||
static std::unique_ptr<CDevice> Create(SDL_Window* window);
|
||||
|
||||
const std::string& GetName() const { return m_Name; }
|
||||
const std::string& GetVersion() const { return m_Version; }
|
||||
const std::string& GetDriverInformation() const { return m_DriverInformation; }
|
||||
const std::vector<std::string>& GetExtensions() const { return m_Extensions; }
|
||||
|
||||
private:
|
||||
CDevice();
|
||||
|
||||
SDL_GLContext m_Context = nullptr;
|
||||
|
||||
std::string m_Name;
|
||||
std::string m_Version;
|
||||
std::string m_DriverInformation;
|
||||
std::vector<std::string> m_Extensions;
|
||||
};
|
||||
|
||||
} // namespace GL
|
||||
|
||||
} // namespace Backend
|
||||
|
||||
} // namespace Renderer
|
||||
|
||||
#endif // INCLUDED_RENDERER_BACKEND_GL_DEVICE
|
@ -111,7 +111,7 @@ MESSAGEHANDLER(InitGraphics)
|
||||
{
|
||||
UNUSED2(msg);
|
||||
|
||||
ogl_Init();
|
||||
g_VideoMode.CreateBackendDevice(false);
|
||||
|
||||
InitGraphics(g_AtlasGameLoop->args, g_InitFlags, {});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user