Added DeviceCapabilities

master
Tomasz Kapuściński 2016-03-22 14:27:00 +01:00
parent 926f7cf115
commit d3ef04428b
7 changed files with 157 additions and 300 deletions

View File

@ -99,6 +99,30 @@ struct DeviceConfig
} }
}; };
/**
* \struct DeviceCapabilities
* \brief This structs contains various capabilities of graphics device
*/
struct DeviceCapabilities
{
bool multitexturingSupported = false;
int maxTextures = 1;
int maxTextureSize = 1024;
int maxLights = 8;
bool shadowMappingSupported = false;
bool framebufferSupported = false;
int maxRenderbufferSize = 0;
bool anisotropySupported = false;
int maxAnisotropy = 1;
bool multisamplingSupported = false;
int maxSamples = 1;
};
/** /**
* \enum TextureUnit * \enum TextureUnit
* \brief Texture unit values for binding textures * \brief Texture unit values for binding textures
@ -301,6 +325,10 @@ class CDevice
protected: protected:
std::string m_errorMessage; std::string m_errorMessage;
//! Capabilities of this device
//! Should only be changed by code in concrete device implementation
DeviceCapabilities m_capabilities;
public: public:
virtual ~CDevice() {} virtual ~CDevice() {}
@ -310,6 +338,12 @@ public:
return m_errorMessage; return m_errorMessage;
} }
//! Returns device capabilities
const DeviceCapabilities& GetCapabilities()
{
return m_capabilities;
}
//! Provides a hook to debug graphics code (implementation-specific) //! Provides a hook to debug graphics code (implementation-specific)
virtual void DebugHook() = 0; virtual void DebugHook() = 0;

View File

@ -200,16 +200,16 @@ bool CGL21Device::Create()
GetLogger()->Info("%s\n", renderer); GetLogger()->Info("%s\n", renderer);
// Detect support of anisotropic filtering // Detect support of anisotropic filtering
m_anisotropyAvailable = glewIsSupported("GL_EXT_texture_filter_anisotropic"); m_capabilities.anisotropySupported = glewIsSupported("GL_EXT_texture_filter_anisotropic");
if(m_anisotropyAvailable) if (m_capabilities.anisotropySupported)
{ {
// Obtain maximum anisotropy level available // Obtain maximum anisotropy level available
float level; float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level); glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
m_maxAnisotropy = static_cast<int>(level); m_capabilities.maxAnisotropy = static_cast<int>(level);
GetLogger()->Info("Anisotropic filtering available\n"); GetLogger()->Info("Anisotropic filtering available\n");
GetLogger()->Info("Maximum anisotropy: %d\n", m_maxAnisotropy); GetLogger()->Info("Maximum anisotropy: %d\n", m_capabilities.maxAnisotropy);
} }
else else
{ {
@ -219,14 +219,18 @@ bool CGL21Device::Create()
// Read maximum sample count for MSAA // Read maximum sample count for MSAA
if(glewIsSupported("GL_EXT_framebuffer_multisample")) if(glewIsSupported("GL_EXT_framebuffer_multisample"))
{ {
glGetIntegerv(GL_MAX_SAMPLES_EXT, &m_maxSamples); m_capabilities.multisamplingSupported = true;
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_maxSamples);
glGetIntegerv(GL_MAX_SAMPLES_EXT, &m_capabilities.maxSamples);
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_capabilities.maxSamples);
} }
else else
{ {
GetLogger()->Info("Multisampling not supported\n"); GetLogger()->Info("Multisampling not supported\n");
} }
m_capabilities.shadowMappingSupported = true;
// This is mostly done in all modern hardware by default // This is mostly done in all modern hardware by default
// DirectX doesn't even allow the option to turn off perspective correction anymore // DirectX doesn't even allow the option to turn off perspective correction anymore
// So turn it on permanently // So turn it on permanently
@ -243,13 +247,40 @@ bool CGL21Device::Create()
m_lights = std::vector<Light>(numLights, Light()); m_lights = std::vector<Light>(numLights, Light());
m_lightsEnabled = std::vector<bool> (numLights, false); m_lightsEnabled = std::vector<bool> (numLights, false);
m_capabilities.maxLights = numLights;
int maxTextures = 0; int maxTextures = 0;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextures); glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextures);
GetLogger()->Info("Maximum texture image units: %d\n", maxTextures); GetLogger()->Info("Maximum texture image units: %d\n", maxTextures);
m_capabilities.multitexturingSupported = true;
m_capabilities.maxTextures = maxTextures;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_capabilities.maxTextureSize);
GetLogger()->Info("Maximum texture size: %d\n", m_capabilities.maxTextureSize);
m_framebufferSupport = DetectFramebufferSupport(); m_framebufferSupport = DetectFramebufferSupport();
if (m_framebufferSupport != FBS_NONE) if (m_framebufferSupport == FBS_ARB)
GetLogger()->Info("Framebuffer supported\n"); {
m_capabilities.framebufferSupported = true;
GetLogger()->Info("Framebuffer supported (ARB)\n");
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_capabilities.maxRenderbufferSize);
GetLogger()->Info("Maximum renderbuffer size: %d\n", m_capabilities.maxRenderbufferSize);
}
else if (m_framebufferSupport == FBS_EXT)
{
m_capabilities.framebufferSupported = true;
GetLogger()->Info("Framebuffer supported (EXT)\n");
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &m_capabilities.maxRenderbufferSize);
GetLogger()->Info("Maximum renderbuffer size: %d\n", m_capabilities.maxRenderbufferSize);
}
else
{
m_capabilities.framebufferSupported = false;
GetLogger()->Info("Framebuffer not supported\n");
}
m_currentTextures = std::vector<Texture> (maxTextures, Texture()); m_currentTextures = std::vector<Texture> (maxTextures, Texture());
m_texturesEnabled = std::vector<bool> (maxTextures, false); m_texturesEnabled = std::vector<bool> (maxTextures, false);
@ -813,9 +844,9 @@ Texture CGL21Device::CreateTexture(ImageData *data, const TextureCreateParams &p
} }
// Set anisotropy level if available // Set anisotropy level if available
if (m_anisotropyAvailable) if (m_capabilities.anisotropySupported)
{ {
float level = Math::Min(m_maxAnisotropy, CEngine::GetInstance().GetTextureAnisotropyLevel()); float level = Math::Min(m_capabilities.maxAnisotropy, CEngine::GetInstance().GetTextureAnisotropyLevel());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, level); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, level);
} }
@ -1787,34 +1818,32 @@ void CGL21Device::DeleteFramebuffer(std::string name)
bool CGL21Device::IsAnisotropySupported() bool CGL21Device::IsAnisotropySupported()
{ {
return m_anisotropyAvailable; return m_capabilities.anisotropySupported;
} }
int CGL21Device::GetMaxAnisotropyLevel() int CGL21Device::GetMaxAnisotropyLevel()
{ {
return m_maxAnisotropy; return m_capabilities.maxAnisotropy;
} }
int CGL21Device::GetMaxSamples() int CGL21Device::GetMaxSamples()
{ {
return m_maxSamples; return m_capabilities.maxSamples;
} }
bool CGL21Device::IsShadowMappingSupported() bool CGL21Device::IsShadowMappingSupported()
{ {
return true; return m_capabilities.shadowMappingSupported;
} }
int CGL21Device::GetMaxTextureSize() int CGL21Device::GetMaxTextureSize()
{ {
int value; return m_capabilities.maxTextureSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
return value;
} }
bool CGL21Device::IsFramebufferSupported() bool CGL21Device::IsFramebufferSupported()
{ {
return m_framebufferSupport != FBS_NONE; return m_capabilities.framebufferSupported;
} }
} // namespace Gfx } // namespace Gfx

View File

@ -241,12 +241,6 @@ private:
}; };
//! Detected capabilities //! Detected capabilities
//! Whether anisotropic filtering is available
bool m_anisotropyAvailable = false;
//! Maximum anisotropy level
int m_maxAnisotropy = 1;
//! Maximum samples
int m_maxSamples = 1;
//! Framebuffer support //! Framebuffer support
FramebufferSupport m_framebufferSupport = FBS_NONE; FramebufferSupport m_framebufferSupport = FBS_NONE;
//! Map of saved VBO objects //! Map of saved VBO objects

View File

@ -207,24 +207,25 @@ bool CGL33Device::Create()
} }
// Detect support of anisotropic filtering // Detect support of anisotropic filtering
m_anisotropyAvailable = AreExtensionsSupported("GL_EXT_texture_filter_anisotropic"); m_capabilities.anisotropySupported = AreExtensionsSupported("GL_EXT_texture_filter_anisotropic");
if (m_anisotropyAvailable) if (m_capabilities.anisotropySupported)
{ {
// Obtain maximum anisotropy level available // Obtain maximum anisotropy level available
float level; float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level); glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
m_maxAnisotropy = static_cast<int>(level); m_capabilities.maxAnisotropy = static_cast<int>(level);
GetLogger()->Info("Anisotropic filtering available\n"); GetLogger()->Info("Anisotropic filtering available\n");
GetLogger()->Info("Maximum anisotropy: %d\n", m_maxAnisotropy); GetLogger()->Info("Maximum anisotropy: %d\n", m_capabilities.maxAnisotropy);
} }
else else
{ {
GetLogger()->Info("Anisotropic filtering not available\n"); GetLogger()->Info("Anisotropic filtering not available\n");
} }
glGetIntegerv(GL_MAX_SAMPLES, &m_maxSamples); m_capabilities.multisamplingSupported = true;
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_maxSamples); glGetIntegerv(GL_MAX_SAMPLES, &m_capabilities.maxSamples);
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_capabilities.maxSamples);
// Set just to be sure // Set just to be sure
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@ -232,19 +233,31 @@ bool CGL33Device::Create()
glViewport(0, 0, m_config.size.x, m_config.size.y); glViewport(0, 0, m_config.size.x, m_config.size.y);
// this is set in shader // this is set in shader
int numLights = 8; m_capabilities.maxLights = 8;
m_lights = std::vector<Light>(numLights, Light()); m_lights = std::vector<Light>(m_capabilities.maxLights, Light());
m_lightsEnabled = std::vector<bool> (numLights, false); m_lightsEnabled = std::vector<bool>(m_capabilities.maxLights, false);
int maxTextures = 0; int maxTextures = 0;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextures); glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextures);
GetLogger()->Info("Maximum texture image units: %d\n", maxTextures); GetLogger()->Info("Maximum texture image units: %d\n", maxTextures);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_capabilities.maxTextureSize);
GetLogger()->Info("Maximum texture size: %d\n", m_capabilities.maxTextureSize);
m_capabilities.multitexturingSupported = true;
m_capabilities.maxTextures = maxTextures;
m_currentTextures = std::vector<Texture> (maxTextures, Texture()); m_currentTextures = std::vector<Texture> (maxTextures, Texture());
m_texturesEnabled = std::vector<bool> (maxTextures, false); m_texturesEnabled = std::vector<bool> (maxTextures, false);
m_textureStageParams = std::vector<TextureStageParams>(maxTextures, TextureStageParams()); m_textureStageParams = std::vector<TextureStageParams>(maxTextures, TextureStageParams());
m_capabilities.shadowMappingSupported = true;
m_capabilities.framebufferSupported = true;
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_capabilities.maxRenderbufferSize);
GetLogger()->Info("Maximum renderbuffer size: %d\n", m_capabilities.maxRenderbufferSize);
// Create shader program for normal rendering // Create shader program for normal rendering
GLint shaders[2]; GLint shaders[2];
char filename[64]; char filename[64];
@ -684,7 +697,7 @@ void CGL33Device::SetMaterial(const Material &material)
int CGL33Device::GetMaxLightCount() int CGL33Device::GetMaxLightCount()
{ {
return m_lights.size(); return m_capabilities.maxLights;
} }
void CGL33Device::SetLight(int index, const Light &light) void CGL33Device::SetLight(int index, const Light &light)
@ -713,50 +726,6 @@ void CGL33Device::SetLight(int index, const Light &light)
// TODO: add spotlight params // TODO: add spotlight params
} }
// probably makes no sense anymore
void CGL33Device::UpdateLightPosition(int index)
{
assert(index >= 0);
assert(index < static_cast<int>( m_lights.size() ));
/*
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
Math::Matrix mat = m_viewMat;
mat.Set(1, 4, 0.0f);
mat.Set(2, 4, 0.0f);
mat.Set(3, 4, 0.0f);
glMultMatrixf(mat.Array());
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 };
glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
}
if (m_lights[index].type == LIGHT_DIRECTIONAL)
{
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);
}
else
{
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 };
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
}
glPopMatrix();
*/
}
void CGL33Device::SetLightEnabled(int index, bool enabled) void CGL33Device::SetLightEnabled(int index, bool enabled)
{ {
assert(index >= 0); assert(index >= 0);
@ -842,9 +811,9 @@ Texture CGL33Device::CreateTexture(ImageData *data, const TextureCreateParams &p
} }
// Set anisotropy level if available // Set anisotropy level if available
if (m_anisotropyAvailable) if (m_capabilities.anisotropySupported)
{ {
float level = Math::Min(m_maxAnisotropy, CEngine::GetInstance().GetTextureAnisotropyLevel()); float level = Math::Min(m_capabilities.maxAnisotropy, CEngine::GetInstance().GetTextureAnisotropyLevel());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, level); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, level);
} }
@ -1035,46 +1004,7 @@ void CGL33Device::SetTextureStageParams(int index, const TextureStageParams &par
void CGL33Device::SetTextureCoordGeneration(int index, TextureGenerationParams &params) void CGL33Device::SetTextureCoordGeneration(int index, TextureGenerationParams &params)
{ {
// TODO: think about generalized way
/*
glActiveTexture(GL_TEXTURE0 + index);
for (int i = 0; i < 4; i++)
{
GLuint texCoordGen = textureCoordGen[i];
GLuint texCoord = textureCoordinates[i];
if (params.coords[i].mode == TEX_GEN_NONE)
{
glDisable(texCoordGen);
}
else
{
glEnable(texCoordGen);
switch (params.coords[i].mode)
{
case TEX_GEN_OBJECT_LINEAR:
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(texCoord, GL_OBJECT_PLANE, params.coords[i].plane);
break;
case TEX_GEN_EYE_LINEAR:
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(texCoord, GL_EYE_PLANE, params.coords[i].plane);
break;
case TEX_GEN_SPHERE_MAP:
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
break;
case TEX_GEN_NORMAL_MAP:
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
break;
case TEX_GEN_REFLECTION_MAP:
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
break;
}
}
}
// */
} }
void CGL33Device::UpdateTextureParams(int index) void CGL33Device::UpdateTextureParams(int index)
@ -1104,145 +1034,6 @@ void CGL33Device::UpdateTextureParams(int index)
else if (params.wrapT == TEX_WRAP_REPEAT) else if (params.wrapT == TEX_WRAP_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
else assert(false); else assert(false);
// TODO: this needs to be redone
/*
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, params.factor.Array());
// To save some trouble
if ( (params.colorOperation == TEX_MIX_OPER_DEFAULT) &&
(params.alphaOperation == TEX_MIX_OPER_DEFAULT) )
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
goto after_tex_operations;
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
// Only these modes of getting color & alpha are used
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
// Color operation
if (params.colorOperation == TEX_MIX_OPER_DEFAULT)
{
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
goto after_tex_color;
}
else if (params.colorOperation == TEX_MIX_OPER_REPLACE)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
else if (params.colorOperation == TEX_MIX_OPER_MODULATE)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
else if (params.colorOperation == TEX_MIX_OPER_ADD)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
else if (params.colorOperation == TEX_MIX_OPER_SUBTRACT)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT);
else assert(false);
// Color arg1
if (params.colorArg1 == TEX_MIX_ARG_TEXTURE)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
else if (params.colorArg1 == TEX_MIX_ARG_TEXTURE_0)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
else if (params.colorArg1 == TEX_MIX_ARG_TEXTURE_1)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1);
else if (params.colorArg1 == TEX_MIX_ARG_TEXTURE_2)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE2);
else if (params.colorArg1 == TEX_MIX_ARG_TEXTURE_3)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE3);
else if (params.colorArg1 == TEX_MIX_ARG_COMPUTED_COLOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
else if (params.colorArg1 == TEX_MIX_ARG_SRC_COLOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
else if (params.colorArg1 == TEX_MIX_ARG_FACTOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT);
else assert(false);
// Color arg2
if (params.colorArg2 == TEX_MIX_ARG_TEXTURE)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
else if (params.colorArg2 == TEX_MIX_ARG_TEXTURE_0)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE0);
else if (params.colorArg2 == TEX_MIX_ARG_TEXTURE_1)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1);
else if (params.colorArg2 == TEX_MIX_ARG_TEXTURE_2)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE2);
else if (params.colorArg2 == TEX_MIX_ARG_TEXTURE_3)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE3);
else if (params.colorArg2 == TEX_MIX_ARG_COMPUTED_COLOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
else if (params.colorArg2 == TEX_MIX_ARG_SRC_COLOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
else if (params.colorArg2 == TEX_MIX_ARG_FACTOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
else assert(false);
after_tex_color:
// Alpha operation
if (params.alphaOperation == TEX_MIX_OPER_DEFAULT)
{
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);
goto after_tex_operations;
}
else if (params.alphaOperation == TEX_MIX_OPER_REPLACE)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
else if (params.alphaOperation == TEX_MIX_OPER_MODULATE)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
else if (params.alphaOperation == TEX_MIX_OPER_ADD)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
else if (params.alphaOperation == TEX_MIX_OPER_SUBTRACT)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_SUBTRACT);
else assert(false);
// Alpha arg1
if (params.alphaArg1 == TEX_MIX_ARG_TEXTURE)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
else if (params.alphaArg1 == TEX_MIX_ARG_TEXTURE_0)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE0);
else if (params.alphaArg1 == TEX_MIX_ARG_TEXTURE_1)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE1);
else if (params.alphaArg1 == TEX_MIX_ARG_TEXTURE_2)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE2);
else if (params.alphaArg1 == TEX_MIX_ARG_TEXTURE_3)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE3);
else if (params.alphaArg1 == TEX_MIX_ARG_COMPUTED_COLOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
else if (params.alphaArg1 == TEX_MIX_ARG_SRC_COLOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
else if (params.alphaArg1 == TEX_MIX_ARG_FACTOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT);
else assert(false);
// Alpha arg2
if (params.alphaArg2 == TEX_MIX_ARG_TEXTURE)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);
else if (params.alphaArg2 == TEX_MIX_ARG_TEXTURE_0)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE0);
else if (params.alphaArg2 == TEX_MIX_ARG_TEXTURE_1)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE1);
else if (params.alphaArg2 == TEX_MIX_ARG_TEXTURE_2)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE2);
else if (params.alphaArg2 == TEX_MIX_ARG_TEXTURE_3)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE3);
else if (params.alphaArg2 == TEX_MIX_ARG_COMPUTED_COLOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
else if (params.alphaArg2 == TEX_MIX_ARG_SRC_COLOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PRIMARY_COLOR);
else if (params.alphaArg2 == TEX_MIX_ARG_FACTOR)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT);
else assert(false);
after_tex_operations: ;
*/
} }
void CGL33Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT) void CGL33Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT)
@ -2239,17 +2030,17 @@ unsigned int CGL33Device::UploadVertexData(void* data, unsigned int size)
bool CGL33Device::IsAnisotropySupported() bool CGL33Device::IsAnisotropySupported()
{ {
return m_anisotropyAvailable; return m_capabilities.anisotropySupported;
} }
int CGL33Device::GetMaxAnisotropyLevel() int CGL33Device::GetMaxAnisotropyLevel()
{ {
return m_maxAnisotropy; return m_capabilities.maxAnisotropy;
} }
int CGL33Device::GetMaxSamples() int CGL33Device::GetMaxSamples()
{ {
return m_maxSamples; return m_capabilities.maxSamples;
} }
bool CGL33Device::IsShadowMappingSupported() bool CGL33Device::IsShadowMappingSupported()
@ -2259,9 +2050,7 @@ bool CGL33Device::IsShadowMappingSupported()
int CGL33Device::GetMaxTextureSize() int CGL33Device::GetMaxTextureSize()
{ {
int value; return m_capabilities.maxTextureSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
return value;
} }
bool CGL33Device::IsFramebufferSupported() bool CGL33Device::IsFramebufferSupported()

View File

@ -179,8 +179,6 @@ public:
bool IsFramebufferSupported() override; bool IsFramebufferSupported() override;
private: private:
//! Updates position for given light based on transformation matrices
void UpdateLightPosition(int index);
//! Updates the texture params for given texture stage //! Updates the texture params for given texture stage
void UpdateTextureParams(int index); void UpdateTextureParams(int index);
//! Updates rendering mode //! Updates rendering mode
@ -251,12 +249,6 @@ private:
}; };
//! Detected capabilities //! Detected capabilities
//! Whether anisotropic filtering is available
bool m_anisotropyAvailable = false;
//! Maximum anisotropy level
int m_maxAnisotropy = 1;
//! Maximum samples
int m_maxSamples = 1;
//! Map of saved VBO objects //! Map of saved VBO objects
std::map<unsigned int, VertexBufferInfo> m_vboObjects; std::map<unsigned int, VertexBufferInfo> m_vboObjects;
//! Last ID of VBO object //! Last ID of VBO object

View File

@ -197,30 +197,33 @@ bool CGLDevice::Create()
if (glVersion >= 14) // Core depth texture+shadow, OpenGL 1.4+ if (glVersion >= 14) // Core depth texture+shadow, OpenGL 1.4+
{ {
m_shadowMappingSupport = SMS_CORE; m_shadowMappingSupport = SMS_CORE;
m_capabilities.shadowMappingSupported = true;
GetLogger()->Info("Shadow mapping available (core)\n"); GetLogger()->Info("Shadow mapping available (core)\n");
} }
else if (glewIsSupported("GL_ARB_depth_texture GL_ARB_shadow")) // ARB depth texture + shadow else if (glewIsSupported("GL_ARB_depth_texture GL_ARB_shadow")) // ARB depth texture + shadow
{ {
m_shadowMappingSupport = SMS_ARB; m_shadowMappingSupport = SMS_ARB;
m_capabilities.shadowMappingSupported = true;
GetLogger()->Info("Shadow mapping available (ARB)\n"); GetLogger()->Info("Shadow mapping available (ARB)\n");
} }
else // No Shadow mapping else // No Shadow mapping
{ {
m_shadowMappingSupport = SMS_NONE; m_shadowMappingSupport = SMS_NONE;
m_capabilities.shadowMappingSupported = false;
GetLogger()->Info("Shadow mapping not available\n"); GetLogger()->Info("Shadow mapping not available\n");
} }
// Detect support of anisotropic filtering // Detect support of anisotropic filtering
m_anisotropyAvailable = glewIsSupported("GL_EXT_texture_filter_anisotropic"); m_capabilities.anisotropySupported = glewIsSupported("GL_EXT_texture_filter_anisotropic");
if(m_anisotropyAvailable) if (m_capabilities.anisotropySupported)
{ {
// Obtain maximum anisotropy level available // Obtain maximum anisotropy level available
float level; float level;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level); glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
m_maxAnisotropy = static_cast<int>(level); m_capabilities.maxAnisotropy = static_cast<int>(level);
GetLogger()->Info("Anisotropic filtering available\n"); GetLogger()->Info("Anisotropic filtering available\n");
GetLogger()->Info("Maximum anisotropy: %d\n", m_maxAnisotropy); GetLogger()->Info("Maximum anisotropy: %d\n", m_capabilities.maxAnisotropy);
} }
else else
{ {
@ -230,11 +233,13 @@ bool CGLDevice::Create()
// Read maximum sample count for MSAA // Read maximum sample count for MSAA
if(glewIsSupported("GL_EXT_framebuffer_multisample")) if(glewIsSupported("GL_EXT_framebuffer_multisample"))
{ {
glGetIntegerv(GL_MAX_SAMPLES_EXT, &m_maxSamples); m_capabilities.multisamplingSupported = true;
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_maxSamples); glGetIntegerv(GL_MAX_SAMPLES_EXT, &m_capabilities.maxSamples);
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_capabilities.maxSamples);
} }
else else
{ {
m_capabilities.multisamplingSupported = false;
GetLogger()->Info("Multisampling not supported\n"); GetLogger()->Info("Multisampling not supported\n");
} }
@ -290,6 +295,8 @@ bool CGLDevice::Create()
int numLights = 0; int numLights = 0;
glGetIntegerv(GL_MAX_LIGHTS, &numLights); glGetIntegerv(GL_MAX_LIGHTS, &numLights);
m_capabilities.maxLights = numLights;
m_lights = std::vector<Light>(numLights, Light()); m_lights = std::vector<Light>(numLights, Light());
m_lightsEnabled = std::vector<bool> (numLights, false); m_lightsEnabled = std::vector<bool> (numLights, false);
@ -297,6 +304,12 @@ bool CGLDevice::Create()
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTextures); glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTextures);
GetLogger()->Info("Maximum texture units: %d\n", maxTextures); GetLogger()->Info("Maximum texture units: %d\n", maxTextures);
m_capabilities.multitexturingSupported = true;
m_capabilities.maxTextures = maxTextures;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_capabilities.maxTextureSize);
GetLogger()->Info("Maximum texture size: %d\n", m_capabilities.maxTextureSize);
m_currentTextures = std::vector<Texture> (maxTextures, Texture()); m_currentTextures = std::vector<Texture> (maxTextures, Texture());
m_texturesEnabled = std::vector<bool> (maxTextures, false); m_texturesEnabled = std::vector<bool> (maxTextures, false);
m_textureStageParams = std::vector<TextureStageParams>(maxTextures, TextureStageParams()); m_textureStageParams = std::vector<TextureStageParams>(maxTextures, TextureStageParams());
@ -317,6 +330,11 @@ bool CGLDevice::Create()
m_shadowQuality = true; m_shadowQuality = true;
GetLogger()->Debug("Using quality shadows\n"); GetLogger()->Debug("Using quality shadows\n");
} }
else
{
m_shadowQuality = false;
GetLogger()->Debug("Using simple shadows\n");
}
// create white texture // create white texture
glGenTextures(1, &m_whiteTexture); glGenTextures(1, &m_whiteTexture);
@ -337,14 +355,25 @@ bool CGLDevice::Create()
m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams); m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams);
m_framebufferSupport = DetectFramebufferSupport(); m_framebufferSupport = DetectFramebufferSupport();
if (m_framebufferSupport != FBS_NONE) if (m_framebufferSupport == FBS_ARB)
{ {
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &m_maxRenderbufferSize); m_capabilities.framebufferSupported = true;
GetLogger()->Info("Framebuffer supported\n"); GetLogger()->Info("Framebuffer supported (ARB)\n");
GetLogger()->Info("Maximum renderbuffer size: %d\n", m_maxRenderbufferSize);
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_capabilities.maxRenderbufferSize);
GetLogger()->Info("Maximum renderbuffer size: %d\n", m_capabilities.maxRenderbufferSize);
}
else if (m_framebufferSupport == FBS_EXT)
{
m_capabilities.framebufferSupported = true;
GetLogger()->Info("Framebuffer supported (EXT)\n");
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &m_capabilities.maxRenderbufferSize);
GetLogger()->Info("Maximum renderbuffer size: %d\n", m_capabilities.maxRenderbufferSize);
} }
else else
{ {
m_capabilities.framebufferSupported = false;
GetLogger()->Info("Framebuffer not supported\n"); GetLogger()->Info("Framebuffer not supported\n");
} }
@ -715,9 +744,9 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par
} }
// Set anisotropy level if available // Set anisotropy level if available
if (m_anisotropyAvailable) if (m_capabilities.anisotropySupported)
{ {
float level = Math::Min(m_maxAnisotropy, CEngine::GetInstance().GetTextureAnisotropyLevel()); float level = Math::Min(m_capabilities.maxAnisotropy, CEngine::GetInstance().GetTextureAnisotropyLevel());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, level); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, level);
} }
@ -2119,34 +2148,32 @@ void CGLDevice::DeleteFramebuffer(std::string name)
bool CGLDevice::IsAnisotropySupported() bool CGLDevice::IsAnisotropySupported()
{ {
return m_anisotropyAvailable; return m_capabilities.anisotropySupported;
} }
int CGLDevice::GetMaxAnisotropyLevel() int CGLDevice::GetMaxAnisotropyLevel()
{ {
return m_maxAnisotropy; return m_capabilities.maxAnisotropy;
} }
int CGLDevice::GetMaxSamples() int CGLDevice::GetMaxSamples()
{ {
return m_maxSamples; return m_capabilities.maxSamples;
} }
bool CGLDevice::IsShadowMappingSupported() bool CGLDevice::IsShadowMappingSupported()
{ {
return m_shadowMappingSupport != SMS_NONE; return m_capabilities.shadowMappingSupported;
} }
int CGLDevice::GetMaxTextureSize() int CGLDevice::GetMaxTextureSize()
{ {
int value; return m_capabilities.maxTextureSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
return value;
} }
bool CGLDevice::IsFramebufferSupported() bool CGLDevice::IsFramebufferSupported()
{ {
return m_framebufferSupport != FBS_NONE; return m_capabilities.framebufferSupported;
} }
} // namespace Gfx } // namespace Gfx

View File

@ -278,14 +278,6 @@ private:
ShadowMappingSupport m_shadowMappingSupport = SMS_NONE; ShadowMappingSupport m_shadowMappingSupport = SMS_NONE;
//! Whether to use VBOs or display lists //! Whether to use VBOs or display lists
bool m_vboAvailable = false; bool m_vboAvailable = false;
//! Whether anisotropic filtering is available
bool m_anisotropyAvailable = false;
//! Maximum anisotropy level
int m_maxAnisotropy = 1;
//! Maximum samples
int m_maxSamples = 1;
//! Maximum renderbuffer size
int m_maxRenderbufferSize = 0;
//! glMultiDrawArrays() available //! glMultiDrawArrays() available
bool m_multiDrawArrays = false; bool m_multiDrawArrays = false;
//! Framebuffer support //! Framebuffer support