Changes in detection of graphics hardware capabilities

dev-time-step
Tomasz Kapuściński 2016-02-12 16:14:29 +01:00
parent c784bd10de
commit bf8916b9eb
8 changed files with 371 additions and 288 deletions

View File

@ -166,65 +166,55 @@ bool CGL21Device::Create()
{
GetLogger()->Info("Creating CDevice - OpenGL 2.1\n");
static bool glewInited = false;
if (!glewInited)
if (!InitializeGLEW())
{
glewInited = true;
m_errorMessage = "An error occured while initializing GLEW.";
return false;
}
glewExperimental = GL_TRUE;
// Extract OpenGL version
int glMajor, glMinor;
int glVersion = GetOpenGLVersion(glMajor, glMinor);
if (glewInit() != GLEW_OK)
{
GetLogger()->Error("GLEW initialization failed\n");
m_errorMessage = "An error occured while initializing GLEW.";
return false;
}
if (glVersion < 20)
{
GetLogger()->Error("Unsupported OpenGL version: %d.%d\n", glMajor, glMinor);
GetLogger()->Error("OpenGL 2.0 or newer is required to use this engine.\n");
m_errorMessage = "It seems your graphics card does not support OpenGL 2.0.\n";
m_errorMessage += "Please make sure you have appropriate hardware and newest drivers installed.\n";
m_errorMessage += "(OpenGL 2.0 is roughly equivalent to Direct3D 9)\n\n";
m_errorMessage += GetHardwareInfo();
return false;
}
// Extract OpenGL version
const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
sscanf(version, "%d.%d", &m_glMajor, &m_glMinor);
GetLogger()->Info("OpenGL %d.%d\n", glMajor, glMinor);
if (m_glMajor < 2)
{
GetLogger()->Error("Unsupported OpenGL version: %d.%d\n", m_glMajor, m_glMinor);
GetLogger()->Error("OpenGL 2.0 or newer is required to use this engine.\n");
m_errorMessage = "It seems your graphics card does not support OpenGL 2.0.\n";
m_errorMessage += "Please make sure you have appropriate hardware and newest drivers installed.\n";
m_errorMessage += "(OpenGL 2.0 is roughly equivalent to Direct3D 9)\n\n";
m_errorMessage += GetHardwareInfo(false);
return false;
}
// Detect support of anisotropic filtering
m_anisotropyAvailable = glewIsSupported("GL_EXT_texture_filter_anisotropic");
if(m_anisotropyAvailable)
{
// Obtain maximum anisotropy level available
float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
m_maxAnisotropy = static_cast<int>(level);
GetLogger()->Info("OpenGL %d.%d\n", m_glMajor, m_glMinor);
GetLogger()->Info("Anisotropic filtering available\n");
GetLogger()->Info("Maximum anisotropy: %d\n", m_maxAnisotropy);
}
else
{
GetLogger()->Info("Anisotropic filtering not available\n");
}
// Detect support of anisotropic filtering
m_anisotropyAvailable = glewIsSupported("GL_EXT_texture_filter_anisotropic");
if(m_anisotropyAvailable)
{
// Obtain maximum anisotropy level available
float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
m_maxAnisotropy = static_cast<int>(level);
GetLogger()->Info("Anisotropic filtering available\n");
GetLogger()->Info("Maximum anisotropy: %d\n", m_maxAnisotropy);
}
else
{
GetLogger()->Info("Anisotropic filtering not available\n");
}
// Read maximum sample count for MSAA
if(glewIsSupported("GL_ARB_multisample"))
{
glGetIntegerv(GL_MAX_SAMPLES_EXT, &m_maxSamples);
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_maxSamples);
}
else
{
GetLogger()->Info("Multisampling not supported\n");
}
// Read maximum sample count for MSAA
if(glewIsSupported("GL_EXT_framebuffer_multisample"))
{
glGetIntegerv(GL_MAX_SAMPLES_EXT, &m_maxSamples);
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_maxSamples);
}
else
{
GetLogger()->Info("Multisampling not supported\n");
}
// This is mostly done in all modern hardware by default
@ -237,8 +227,8 @@ bool CGL21Device::Create()
glViewport(0, 0, m_config.size.x, m_config.size.y);
int numLights = 0;
glGetIntegerv(GL_MAX_LIGHTS, &numLights);
// this is set in shader
int numLights = 8;
m_lights = std::vector<Light>(numLights, Light());
m_lightsEnabled = std::vector<bool> (numLights, false);
@ -247,20 +237,24 @@ bool CGL21Device::Create()
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextures);
GetLogger()->Info("Maximum texture image units: %d\n", maxTextures);
m_framebufferSupport = DetectFramebufferSupport();
if (m_framebufferSupport != FBS_NONE)
GetLogger()->Info("Framebuffer supported\n");
m_currentTextures = std::vector<Texture> (maxTextures, Texture());
m_texturesEnabled = std::vector<bool> (maxTextures, false);
m_textureStageParams = std::vector<TextureStageParams>(maxTextures, TextureStageParams());
int value;
if (CConfigFile::GetInstance().GetIntProperty("Setup", "PerPixelLighting", value))
if (GetConfigFile().GetIntProperty("Setup", "PerPixelLighting", value))
{
m_perPixelLighting = value > 0;
}
if (m_perPixelLighting)
CLogger::GetInstance().Info("Using per-pixel lighting\n");
GetLogger()->Info("Using per-pixel lighting\n");
else
CLogger::GetInstance().Info("Using per-vertex lighting\n");
GetLogger()->Info("Using per-vertex lighting\n");
// Create normal shader program
@ -301,7 +295,6 @@ bool CGL21Device::Create()
glDeleteShader(shaders[0]);
glDeleteShader(shaders[1]);
// Obtain uniform locations
uni_ProjectionMatrix = glGetUniformLocation(m_program, "uni_ProjectionMatrix");
uni_ViewMatrix = glGetUniformLocation(m_program, "uni_ViewMatrix");
@ -399,10 +392,6 @@ bool CGL21Device::Create()
m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams);
m_framebufferSupport = DetectFramebufferSupport();
if (m_framebufferSupport != FBS_NONE)
GetLogger()->Debug("Framebuffer supported\n");
GetLogger()->Info("CDevice created successfully\n");
return true;

View File

@ -236,8 +236,6 @@ private:
};
//! Detected capabilities
//! OpenGL version
int m_glMajor = 1, m_glMinor = 1;
//! Whether anisotropic filtering is available
bool m_anisotropyAvailable = false;
//! Maximum anisotropy level

View File

@ -168,79 +168,63 @@ bool CGL33Device::Create()
static bool glewInited = false;
if (!glewInited)
if (!InitializeGLEW())
{
glewInited = true;
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
GetLogger()->Error("GLEW initialization failed\n");
m_errorMessage = "An error occured while initializing GLEW.";
return false;
}
// Extract OpenGL version
const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
sscanf(version, "%d.%d", &m_glMajor, &m_glMinor);
int glVersion = 10 * m_glMajor + m_glMinor;
if (glVersion < 32)
{
GetLogger()->Error("Unsupported OpenGL version: %d.%d\n", m_glMajor, m_glMinor);
GetLogger()->Error("OpenGL 3.2 or newer is required to use this engine.\n");
m_errorMessage = "It seems your graphics card does not support OpenGL 3.2.\n";
m_errorMessage += "Please make sure you have appropriate hardware and newest drivers installed.\n";
m_errorMessage += "(OpenGL 3.2 is roughly equivalent to Direct3D 10)\n\n";
m_errorMessage += GetHardwareInfo(false);
return false;
}
else if (glVersion < 33)
{
GetLogger()->Warn("Partially supported OpenGL version: %d.%d\n", m_glMajor, m_glMinor);
GetLogger()->Warn("You may experience problems while running the game on this engine.\n");
GetLogger()->Warn("OpenGL 3.3 or newer is recommended.\n");
}
else
{
GetLogger()->Info("OpenGL %d.%d\n", m_glMajor, m_glMinor);
}
// Detect support of anisotropic filtering
m_anisotropyAvailable = glewIsSupported("GL_EXT_texture_filter_anisotropic");
if(m_anisotropyAvailable)
{
// Obtain maximum anisotropy level available
float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
m_maxAnisotropy = static_cast<int>(level);
GetLogger()->Info("Anisotropic filtering available\n");
GetLogger()->Info("Maximum anisotropy: %d\n", m_maxAnisotropy);
}
else
{
GetLogger()->Info("Anisotropic filtering not available\n");
}
// Read maximum sample count for MSAA
if(glewIsSupported("GL_ARB_multisample"))
{
glGetIntegerv(GL_MAX_SAMPLES_EXT, &m_maxSamples);
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_maxSamples);
}
else
{
GetLogger()->Info("Multisampling not supported\n");
}
m_errorMessage = "An error occured while initializing GLEW.";
return false;
}
// Extract OpenGL version
int glMajor, glMinor;
int glVersion = GetOpenGLVersion(glMajor, glMinor);
if (glVersion < 32)
{
GetLogger()->Error("Unsupported OpenGL version: %d.%d\n", glMajor, glMinor);
GetLogger()->Error("OpenGL 3.2 or newer is required to use this engine.\n");
m_errorMessage = "It seems your graphics card does not support OpenGL 3.2.\n";
m_errorMessage += "Please make sure you have appropriate hardware and newest drivers installed.\n";
m_errorMessage += "(OpenGL 3.2 is roughly equivalent to Direct3D 10)\n\n";
m_errorMessage += GetHardwareInfo();
return false;
}
else if (glVersion < 33)
{
GetLogger()->Warn("Partially supported OpenGL version: %d.%d\n", glMajor, glMinor);
GetLogger()->Warn("You may experience problems while running the game on this engine.\n");
GetLogger()->Warn("OpenGL 3.3 or newer is recommended.\n");
}
else
{
GetLogger()->Info("OpenGL %d.%d\n", glMajor, glMinor);
}
// Detect support of anisotropic filtering
m_anisotropyAvailable = glewIsSupported("GL_EXT_texture_filter_anisotropic");
if(m_anisotropyAvailable)
{
// Obtain maximum anisotropy level available
float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
m_maxAnisotropy = static_cast<int>(level);
GetLogger()->Info("Anisotropic filtering available\n");
GetLogger()->Info("Maximum anisotropy: %d\n", m_maxAnisotropy);
}
else
{
GetLogger()->Info("Anisotropic filtering not available\n");
}
glGetIntegerv(GL_MAX_FRAMEBUFFER_SAMPLES, &m_maxSamples);
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_maxSamples);
// Set just to be sure
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0, 0, m_config.size.x, m_config.size.y);
// this is set in shader
int numLights = 8;
m_lights = std::vector<Light>(numLights, Light());

View File

@ -254,8 +254,6 @@ private:
};
//! Detected capabilities
//! OpenGL version
int m_glMajor = 1, m_glMinor = 1;
//! Whether anisotropic filtering is available
bool m_anisotropyAvailable = false;
//! Maximum anisotropy level

View File

@ -162,118 +162,107 @@ bool CGLDevice::Create()
{
GetLogger()->Info("Creating CDevice - OpenGL 1.4\n");
static bool glewInited = false;
if (!glewInited)
if (!InitializeGLEW())
{
glewInited = true;
m_errorMessage = "An error occured while initializing GLEW.";
return false;
}
glewExperimental = GL_TRUE;
// Extract OpenGL version
int glMajor, glMinor;
int glVersion = GetOpenGLVersion(glMajor, glMinor);
if (glewInit() != GLEW_OK)
{
GetLogger()->Error("GLEW initialization failed\n");
m_errorMessage = "An error occured while initializing GLEW.";
return false;
}
if (glVersion < 13)
{
GetLogger()->Error("Unsupported OpenGL version: %d.%d\n", glMajor, glMinor);
GetLogger()->Error("OpenGL 1.3 or newer is required to use this engine.\n");
m_errorMessage = "It seems your graphics card does not support OpenGL 1.3.\n";
m_errorMessage += "Please make sure you have appropriate hardware and newest drivers installed.\n\n";
m_errorMessage += GetHardwareInfo();
return false;
}
// Extract OpenGL version
const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
sscanf(version, "%d.%d", &m_glMajor, &m_glMinor);
GetLogger()->Info("OpenGL %d.%d\n", glMajor, glMinor);
int glVersion = 10 * m_glMajor + m_glMinor;
if (glVersion < 13)
{
GetLogger()->Error("Unsupported OpenGL version: %d.%d\n", m_glMajor, m_glMinor);
GetLogger()->Error("OpenGL 1.3 or newer is required to use this engine.\n");
m_errorMessage = "It seems your graphics card does not support OpenGL 1.3.\n";
m_errorMessage += "Please make sure you have appropriate hardware and newest drivers installed.\n\n";
m_errorMessage += GetHardwareInfo(false);
return false;
}
// Detect multitexture support
m_multitextureAvailable = glewIsSupported("GL_ARB_multitexture GL_ARB_texture_env_combine");
if (!m_multitextureAvailable)
GetLogger()->Warn("GLEW reports multitexturing not supported - graphics quality will be degraded!\n");
GetLogger()->Info("OpenGL %d.%d\n", m_glMajor, m_glMinor);
// Detect Shadow mapping support
if (glVersion >= 14) // Core depth texture+shadow, OpenGL 1.4+
{
m_shadowMappingSupport = SMS_CORE;
GetLogger()->Info("Shadow mapping available (core)\n");
}
else if (glewIsSupported("GL_ARB_depth_texture GL_ARB_shadow")) // ARB depth texture + shadow
{
m_shadowMappingSupport = SMS_ARB;
GetLogger()->Info("Shadow mapping available (ARB)\n");
}
else // No Shadow mapping
{
m_shadowMappingSupport = SMS_NONE;
GetLogger()->Info("Shadow mapping not available\n");
}
// Detect multitexture support
m_multitextureAvailable = glewIsSupported("GL_ARB_multitexture GL_ARB_texture_env_combine");
if (!m_multitextureAvailable)
GetLogger()->Warn("GLEW reports multitexturing not supported - graphics quality will be degraded!\n");
m_shadowAmbientSupported = glewIsSupported("GL_ARB_shadow_ambient");
if (m_shadowAmbientSupported)
GetLogger()->Info("Shadow ambient supported\n");
// Detect Shadow mapping support
if (m_glMajor > 1 || m_glMinor >= 4) // Core depth texture+shadow, OpenGL 1.4+
{
m_shadowMappingSupport = SMS_CORE;
GetLogger()->Info("Shadow mapping available (core)\n");
}
else if (glewIsSupported("GL_ARB_depth_texture GL_ARB_shadow")) // ARB depth texture + shadow
{
m_shadowMappingSupport = SMS_ARB;
GetLogger()->Info("Shadow mapping available (ARB)\n");
}
else // No Shadow mapping
{
m_shadowMappingSupport = SMS_NONE;
GetLogger()->Info("Shadow mapping not available\n");
}
// Detect support of anisotropic filtering
m_anisotropyAvailable = glewIsSupported("GL_EXT_texture_filter_anisotropic");
if(m_anisotropyAvailable)
{
// Obtain maximum anisotropy level available
float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
m_maxAnisotropy = static_cast<int>(level);
m_shadowAmbientSupported = glewIsSupported("GL_ARB_shadow_ambient");
if (m_shadowAmbientSupported)
GetLogger()->Info("Shadow ambient supported\n");
GetLogger()->Info("Anisotropic filtering available\n");
GetLogger()->Info("Maximum anisotropy: %d\n", m_maxAnisotropy);
}
else
{
GetLogger()->Info("Anisotropic filtering not available\n");
}
// Detect support of anisotropic filtering
m_anisotropyAvailable = glewIsSupported("GL_EXT_texture_filter_anisotropic");
if(m_anisotropyAvailable)
{
// Obtain maximum anisotropy level available
float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
m_maxAnisotropy = static_cast<int>(level);
// Read maximum sample count for MSAA
if(glewIsSupported("GL_EXT_framebuffer_multisample"))
{
glGetIntegerv(GL_MAX_SAMPLES_EXT, &m_maxSamples);
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_maxSamples);
}
else
{
GetLogger()->Info("Multisampling not supported\n");
}
GetLogger()->Info("Anisotropic filtering available\n");
GetLogger()->Info("Maximum anisotropy: %d\n", m_maxAnisotropy);
}
else
{
GetLogger()->Info("Anisotropic filtering not available\n");
}
// check for glMultiDrawArrays()
if (glVersion >= 14)
m_multiDrawArrays = true;
// Read maximum sample count for MSAA
if(glewIsSupported("GL_ARB_multisample GL_EXT_framebuffer_multisample"))
{
glGetIntegerv(GL_MAX_SAMPLES_EXT, &m_maxSamples);
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_maxSamples);
}
else
{
GetLogger()->Info("Multisampling not supported\n");
}
GetLogger()->Info("Auto-detecting VBO support\n");
// check for glMultiDrawArrays()
if (glVersion >= 14)
m_multiDrawArrays = true;
// detecting VBO ARB extension
bool vboARB = glewIsSupported("GL_ARB_vertex_buffer_object");
GetLogger()->Info("Auto-detecting VBO support\n");
// detecting VBO ARB extension
bool vboARB = glewIsSupported("GL_ARB_vertex_buffer_object");
// VBO is core OpenGL feature since 1.5
// everything below 1.5 means no VBO support
if (m_glMajor > 1 || m_glMinor > 4)
{
GetLogger()->Info("Core VBO supported\n", m_glMajor, m_glMinor);
m_vertexBufferType = VBT_VBO_CORE;
}
else if(vboARB) // VBO ARB extension available
{
GetLogger()->Info("ARB VBO supported\n");
m_vertexBufferType = VBT_VBO_ARB;
}
else // no VBO support
{
GetLogger()->Info("VBO not supported\n");
m_vertexBufferType = VBT_DISPLAY_LIST;
}
// VBO is core OpenGL feature since 1.5
// everything below 1.5 means no VBO support
if (glVersion >= 15)
{
GetLogger()->Info("Core VBO supported\n", glMajor, glMinor);
m_vertexBufferType = VBT_VBO_CORE;
}
else if (vboARB) // VBO ARB extension available
{
GetLogger()->Info("ARB VBO supported\n");
m_vertexBufferType = VBT_VBO_ARB;
}
else // no VBO support
{
GetLogger()->Info("VBO not supported\n");
m_vertexBufferType = VBT_DISPLAY_LIST;
}
// This is mostly done in all modern hardware by default
@ -332,6 +321,7 @@ bool CGLDevice::Create()
{
GetLogger()->Info("Framebuffer not supported\n");
}
GetLogger()->Info("CDevice created successfully\n");
return true;
@ -502,17 +492,15 @@ void CGLDevice::UpdateLightPosition(int index)
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
if (m_lights[index].type == LIGHT_POINT)
Light &light = m_lights[index];
if (light.type == LIGHT_POINT)
{
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixf(m_viewMat.Array());
GLfloat position[4] = { m_lights[index].position.x,
m_lights[index].position.y,
m_lights[index].position.z,
1.0f };
GLfloat position[4] = { light.position.x, light.position.y, light.position.z, 1.0f };
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
}
else
@ -525,22 +513,14 @@ void CGLDevice::UpdateLightPosition(int index)
mat.Set(3, 4, 0.0f);
glMultMatrixf(mat.Array());
if (m_lights[index].type == LIGHT_SPOT)
if (light.type == LIGHT_SPOT)
{
GLfloat direction[4] = { -m_lights[index].direction.x,
-m_lights[index].direction.y,
-m_lights[index].direction.z,
1.0f };
GLfloat direction[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 1.0f };
glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
}
else if (m_lights[index].type == LIGHT_DIRECTIONAL)
else if (light.type == LIGHT_DIRECTIONAL)
{
GLfloat position[4] = { -m_lights[index].direction.x,
-m_lights[index].direction.y,
-m_lights[index].direction.z,
0.0f };
GLfloat position[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 0.0f };
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
}
}
@ -553,8 +533,6 @@ void CGLDevice::UpdateLightPositions()
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
int lightCount = m_lights.size();
// update spotlights and directional lights
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
@ -564,25 +542,25 @@ void CGLDevice::UpdateLightPositions()
mat.Set(3, 4, 0.0f);
glMultMatrixf(mat.Array());
for (int index = 0; index < lightCount; index++)
{
if (m_lights[index].type == LIGHT_SPOT)
{
GLfloat direction[4] = { -m_lights[index].direction.x,
-m_lights[index].direction.y,
-m_lights[index].direction.z,
1.0f };
int lightIndex = 0;
glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
}
else if (m_lights[index].type == LIGHT_DIRECTIONAL)
for (const Light &light : m_lights)
{
if (m_lightsEnabled[lightIndex])
{
GLfloat position[4] = { -m_lights[index].direction.x,
-m_lights[index].direction.y,
-m_lights[index].direction.z,
0.0f };
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
if (light.type == LIGHT_SPOT)
{
GLfloat direction[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 1.0f };
glLightfv(GL_LIGHT0 + lightIndex, GL_SPOT_DIRECTION, direction);
}
else if (light.type == LIGHT_DIRECTIONAL)
{
GLfloat position[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 0.0f };
glLightfv(GL_LIGHT0 + lightIndex, GL_POSITION, position);
}
}
lightIndex++;
}
// update point lights
@ -590,17 +568,20 @@ void CGLDevice::UpdateLightPositions()
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixf(m_viewMat.Array());
for (int index = 0; index < lightCount; index++)
{
if (m_lights[index].type == LIGHT_POINT)
{
GLfloat position[4] = { m_lights[index].position.x,
m_lights[index].position.y,
m_lights[index].position.z,
1.0f };
lightIndex = 0;
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
for (const Light &light : m_lights)
{
if (m_lightsEnabled[lightIndex])
{
if (light.type == LIGHT_POINT)
{
GLfloat position[4] = { light.position.x, light.position.y, light.position.z, 1.0f };
glLightfv(GL_LIGHT0 + lightIndex, GL_POSITION, position);
}
}
lightIndex++;
}
glPopMatrix();

View File

@ -256,8 +256,6 @@ private:
};
//! Detected capabilities
//! OpenGL version
int m_glMajor = 1, m_glMinor = 1;
//! Depth texture support
ShadowMappingSupport m_shadowMappingSupport = SMS_NONE;
//! Shadow ambient support

View File

@ -28,6 +28,7 @@
#include <physfs.h>
#include <cstring>
#include <sstream>
// Graphics module namespace
namespace Gfx
@ -36,6 +37,26 @@ namespace Gfx
GLuint textureCoordinates[] = { GL_S, GL_T, GL_R, GL_Q };
GLuint textureCoordGen[] = { GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_T, GL_TEXTURE_GEN_R, GL_TEXTURE_GEN_Q };
bool InitializeGLEW()
{
static bool glewInited = false;
if (!glewInited)
{
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
GetLogger()->Error("GLEW initialization failed\n");
return false;
}
glewInited = true;
}
return true;
}
FramebufferSupport DetectFramebufferSupport()
{
if (GetOpenGLVersion() >= 30) return FBS_ARB;
@ -64,9 +85,15 @@ std::unique_ptr<CDevice> CreateDevice(const DeviceConfig &config, const std::str
}
int GetOpenGLVersion()
{
int major, minor;
return GetOpenGLVersion(major, minor);
}
int GetOpenGLVersion(int &major, int &minor)
{
const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
int major = 0, minor = 0;
sscanf(version, "%d.%d", &major, &minor);
@ -77,24 +104,126 @@ std::string GetHardwareInfo(bool full)
{
int glversion = GetOpenGLVersion();
std::stringstream result;
// basic hardware information
const char* version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
const char* renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
std::string result;
result += std::string("Hardware information:\n\n");
result += "Version:\t" + std::string(version) + '\n';
result += "Vendor:\t" + std::string(vendor) + '\n';
result += "Renderer:\t" + std::string(renderer) + '\n';
result << "Hardware information:\n\n";
result << "OpenGL Version:\t\t" << version << '\n';
result << "Hardware Vendor:\t\t" << vendor << '\n';
result << "Renderer:\t\t\t" << renderer << '\n';
// GLSL version if available
if (glversion >= 20)
{
const char* glslVersion = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
result += "Shading Language:\t" + std::string(glslVersion) + '\n';
result << "Shading Language Version:\t" << glslVersion << '\n';
}
return result;
if (!full) return result.str();
// extended hardware information
int value = 0;
result << "\nCapabilities:\n\n";
// texture size
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
result << "Max Texture Size:\t\t" << value << '\n';
if (glewIsSupported("GL_EXT_texture_filter_anisotropic"))
{
result << "Anisotropic filtering:\t\tsupported\n";
float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
result << " Max Level:\t\t" << static_cast<int>(level) << '\n';
}
else
{
result << "Anisotropic filtering:\t\tunsupported\n";
}
// multitexturing
if (glversion >= 13)
{
result << "Multitexturing:\t\tsupported\n";
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &value);
result << " Max Texture Units:\t\t" << value << '\n';
if (glversion >= 20)
{
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &value);
result << " Max Texture Image Units:\t" << value << '\n';
}
}
else
{
result << "Multitexturing:\t\tunsupported\n";
}
// FBO support
FramebufferSupport framebuffer = DetectFramebufferSupport();
if (framebuffer == FBS_ARB)
{
result << "Framebuffer Object:\t\tsupported\n";
result << " Type:\t\t\tCore/ARB\n";
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &value);
result << " Max Renderbuffer Size:\t" << value << '\n';
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &value);
result << " Max Color Attachments:\t" << value << '\n';
result << "Multisampling:\t\tsupported\n";
glGetIntegerv(GL_MAX_FRAMEBUFFER_SAMPLES, &value);
result << " Max Framebuffer Samples:\t" << value << '\n';
}
else if (framebuffer == FBS_EXT)
{
result << "Framebuffer Object:\tsupported\n";
result << " Type:\tEXT\n";
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &value);
result << " Max Renderbuffer Size:\t" << value << '\n';
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &value);
result << " Max Color Attachments:\t" << value << '\n';
if (glewIsSupported("GL_EXT_framebuffer_multisample"))
{
result << "Multisampling:\tsupported\n";
glGetIntegerv(GL_MAX_SAMPLES_EXT, &value);
result << " Max Framebuffer Samples:\t" << value << '\n';
}
}
else
{
result << "Framebuffer Object:\tunsupported\n";
}
// VBO support
if (glversion >= 15)
{
result << "VBO:\t\t\tsupported (core)\n";
}
else if (glewIsSupported("GL_ARB_vertex_buffer_object"))
{
result << "VBO:\t\t\tsupported (ARB)\n";
}
else
{
result << "VBO:\t\t\tunsupported\n";
}
return result.str();
}
GLenum TranslateGfxPrimitive(PrimitiveType type)

View File

@ -45,17 +45,23 @@ enum FramebufferSupport
FBS_ARB,
};
bool InitializeGLEW();
FramebufferSupport DetectFramebufferSupport();
//! Creates OpenGL device
std::unique_ptr<CDevice> CreateDevice(const DeviceConfig &config, const std::string& name);
//! Returns OpenGL version as one number.
// First digit is major part, second digit is minor part.
//! Returns OpenGL version
// \return First digit is major part, second digit is minor part.
int GetOpenGLVersion();
//! Returns OpenGL version
// \return First digit is major part, second digit is minor part.
int GetOpenGLVersion(int &major, int &minor);
//! Returns information about graphics card
std::string GetHardwareInfo(bool full);
std::string GetHardwareInfo(bool full = false);
//! Translate Gfx primitive type to OpenGL primitive type
GLenum TranslateGfxPrimitive(PrimitiveType type);