Implemented trilinear filtering, mipmap level setting and anisotropic filtering
parent
05bf5be6f4
commit
d3b052f19b
|
@ -91,7 +91,8 @@ enum TransformType
|
|||
{
|
||||
TRANSFORM_WORLD,
|
||||
TRANSFORM_VIEW,
|
||||
TRANSFORM_PROJECTION
|
||||
TRANSFORM_PROJECTION,
|
||||
TRANSFORM_TEXTURE
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,6 +52,19 @@ enum TexImgFormat
|
|||
TEX_IMG_BGRA
|
||||
};
|
||||
|
||||
/**
|
||||
* \enum TexFilter
|
||||
* \brief General texture filtering mode
|
||||
*
|
||||
* Corresponds to typical options in game graphics settings.
|
||||
*/
|
||||
enum TexFilter
|
||||
{
|
||||
TEX_FILTER_NEAREST,
|
||||
TEX_FILTER_BILINEAR,
|
||||
TEX_FILTER_TRILINEAR
|
||||
};
|
||||
|
||||
/**
|
||||
* \enum TexMinFilter
|
||||
* \brief Texture minification filter
|
||||
|
@ -135,10 +148,8 @@ struct TextureCreateParams
|
|||
bool mipmap;
|
||||
//! Format of source image data
|
||||
TexImgFormat format;
|
||||
//! Minification filter
|
||||
TexMinFilter minFilter;
|
||||
//! Magnification filter
|
||||
TexMagFilter magFilter;
|
||||
//! General texture filtering mode
|
||||
TexFilter filter;
|
||||
//! Pad the image to nearest power of 2 dimensions
|
||||
bool padToNearestPowerOfTwo;
|
||||
|
||||
|
@ -153,8 +164,7 @@ struct TextureCreateParams
|
|||
mipmap = false;
|
||||
padToNearestPowerOfTwo = false;
|
||||
|
||||
minFilter = TEX_MIN_FILTER_NEAREST;
|
||||
magFilter = TEX_MAG_FILTER_NEAREST;
|
||||
filter = TEX_FILTER_NEAREST;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -114,6 +114,8 @@ CEngine::CEngine(CApplication *app)
|
|||
m_terrainVision = 1000.0f;
|
||||
m_gadgetQuantity = 1.0f;
|
||||
m_textureQuality = 1;
|
||||
m_textureMipmapLevel = 1;
|
||||
m_textureAnisotropy = 1;
|
||||
m_totoMode = true;
|
||||
m_lensMode = true;
|
||||
m_waterMode = true;
|
||||
|
@ -158,15 +160,34 @@ CEngine::CEngine(CApplication *app)
|
|||
m_lastFrameTime = GetSystemUtils()->CreateTimeStamp();
|
||||
m_currentFrameTime = GetSystemUtils()->CreateTimeStamp();
|
||||
|
||||
TexFilter filter = TEX_FILTER_BILINEAR;
|
||||
bool mipmaps = false;
|
||||
|
||||
int value;
|
||||
if (CProfile::GetInstance().GetIntProperty("Setup", "FilterMode", value))
|
||||
{
|
||||
if (value == 1) filter = TEX_FILTER_NEAREST;
|
||||
else if (value == 2) filter = TEX_FILTER_BILINEAR;
|
||||
else if (value == 3) filter = TEX_FILTER_TRILINEAR, mipmaps = true;
|
||||
}
|
||||
|
||||
if (CProfile::GetInstance().GetIntProperty("Setup", "MipmapLevel", value))
|
||||
{
|
||||
m_textureMipmapLevel = value;
|
||||
}
|
||||
|
||||
if (CProfile::GetInstance().GetIntProperty("Setup", "Anisotropy", value))
|
||||
{
|
||||
m_textureAnisotropy = value;
|
||||
}
|
||||
|
||||
m_defaultTexParams.format = TEX_IMG_AUTO;
|
||||
m_defaultTexParams.mipmap = true;
|
||||
m_defaultTexParams.minFilter = TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR;
|
||||
m_defaultTexParams.magFilter = TEX_MAG_FILTER_LINEAR;
|
||||
m_defaultTexParams.mipmap = mipmaps;
|
||||
m_defaultTexParams.filter = filter;
|
||||
|
||||
m_terrainTexParams.format = TEX_IMG_AUTO;
|
||||
m_terrainTexParams.mipmap = false;
|
||||
m_terrainTexParams.minFilter = TEX_MIN_FILTER_LINEAR;
|
||||
m_terrainTexParams.magFilter = TEX_MAG_FILTER_LINEAR;
|
||||
m_terrainTexParams.mipmap = mipmaps;
|
||||
m_terrainTexParams.filter = filter;
|
||||
}
|
||||
|
||||
CEngine::~CEngine()
|
||||
|
@ -282,8 +303,7 @@ bool CEngine::Create()
|
|||
|
||||
TextureCreateParams params;
|
||||
params.format = TEX_IMG_AUTO;
|
||||
params.minFilter = TEX_MIN_FILTER_NEAREST;
|
||||
params.magFilter = TEX_MAG_FILTER_NEAREST;
|
||||
params.filter = TEX_FILTER_NEAREST;
|
||||
params.mipmap = false;
|
||||
m_miceTexture = LoadTexture("textures/interface/mouse.png", params);
|
||||
|
||||
|
@ -2908,6 +2928,43 @@ int CEngine::GetTextureQuality()
|
|||
return m_textureQuality;
|
||||
}
|
||||
|
||||
void CEngine::SetTextureFilterMode(TexFilter value)
|
||||
{
|
||||
m_defaultTexParams.filter = value;
|
||||
m_terrainTexParams.filter = value;
|
||||
}
|
||||
|
||||
TexFilter CEngine::GetTextureFilterMode()
|
||||
{
|
||||
return m_terrainTexParams.filter;
|
||||
}
|
||||
|
||||
void CEngine::SetTextureMipmapLevel(int value)
|
||||
{
|
||||
if (value < 1) value = 1;
|
||||
if (value > 16) value = 16;
|
||||
|
||||
m_textureMipmapLevel = value;
|
||||
}
|
||||
|
||||
int CEngine::GetTextureMipmapLevel()
|
||||
{
|
||||
return m_textureMipmapLevel;
|
||||
}
|
||||
|
||||
void CEngine::SetTextureAnisotropyLevel(int value)
|
||||
{
|
||||
if (value < 1) value = 1;
|
||||
if (value > 16) value = 16;
|
||||
|
||||
m_textureAnisotropy = value;
|
||||
}
|
||||
|
||||
int CEngine::GetTextureAnisotropyLevel()
|
||||
{
|
||||
return m_textureAnisotropy;
|
||||
}
|
||||
|
||||
void CEngine::SetTotoMode(bool present)
|
||||
{
|
||||
m_totoMode = present;
|
||||
|
|
|
@ -1116,6 +1116,24 @@ public:
|
|||
int GetTextureQuality();
|
||||
//@}
|
||||
|
||||
//@{
|
||||
//! Management the texture filter mode
|
||||
void SetTextureFilterMode(TexFilter value);
|
||||
TexFilter GetTextureFilterMode();
|
||||
//@}
|
||||
|
||||
//@{
|
||||
//! Management the mipmap level for textures
|
||||
void SetTextureMipmapLevel(int value);
|
||||
int GetTextureMipmapLevel();
|
||||
//@}
|
||||
|
||||
//@{
|
||||
//! Management the anisotropy level for textures
|
||||
void SetTextureAnisotropyLevel(int value);
|
||||
int GetTextureAnisotropyLevel();
|
||||
//@}
|
||||
|
||||
//@{
|
||||
//! Management mode of toto
|
||||
void SetTotoMode(bool present);
|
||||
|
@ -1414,6 +1432,10 @@ protected:
|
|||
TextureCreateParams m_defaultTexParams;
|
||||
//! Create params for terrain textures
|
||||
TextureCreateParams m_terrainTexParams;
|
||||
//! Requested texture mipmap level
|
||||
int m_textureMipmapLevel;
|
||||
//! Requested texture anisotropy level
|
||||
int m_textureAnisotropy;
|
||||
|
||||
//! Map of loaded textures (by name)
|
||||
std::map<std::string, Texture> m_texNameMap;
|
||||
|
|
|
@ -1014,8 +1014,7 @@ CharTexture CText::CreateCharTexture(UTF8Char ch, CachedFont* font)
|
|||
|
||||
TextureCreateParams createParams;
|
||||
createParams.format = TEX_IMG_RGBA;
|
||||
createParams.minFilter = TEX_MIN_FILTER_NEAREST;
|
||||
createParams.magFilter = TEX_MAG_FILTER_NEAREST;
|
||||
createParams.filter = TEX_FILTER_NEAREST;
|
||||
createParams.mipmap = false;
|
||||
|
||||
Texture tex = m_device->CreateTexture(&data, createParams);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
|
||||
#include "graphics/opengl/gldevice.h"
|
||||
#include "graphics/engine/engine.h"
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/image.h"
|
||||
|
@ -69,6 +70,8 @@ CGLDevice::CGLDevice(const GLDeviceConfig &config)
|
|||
m_multitextureAvailable = false;
|
||||
m_vboAvailable = false;
|
||||
m_vertexBufferType = VBT_DISPLAY_LIST;
|
||||
m_anisotropyAvailable = false;
|
||||
m_maxAnisotropy = 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -205,6 +208,23 @@ bool CGLDevice::Create()
|
|||
if (!m_multitextureAvailable)
|
||||
GetLogger()->Warn("GLEW reports multitexturing not supported - graphics quality will be degraded!\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");
|
||||
}
|
||||
|
||||
if (m_config.vboMode == VBO_MODE_ENABLE)
|
||||
{
|
||||
GetLogger()->Info("VBO enabled by override - using VBOs\n");
|
||||
|
@ -360,6 +380,12 @@ void CGLDevice::SetTransform(TransformType type, const Math::Matrix &matrix)
|
|||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(m_projectionMat.Array());
|
||||
}
|
||||
else if (type == TRANSFORM_TEXTURE)
|
||||
{
|
||||
m_textureMat = matrix;
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(m_textureMat.Array());
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
|
@ -511,7 +537,7 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par
|
|||
|
||||
if (!Math::IsPowerOfTwo(result.size.x) || !Math::IsPowerOfTwo(result.size.y))
|
||||
GetLogger()->Warn("Creating non-power-of-2 texture (%dx%d)!\n", result.size.x, result.size.y);
|
||||
|
||||
|
||||
result.originalSize = result.size;
|
||||
|
||||
// Use & enable 1st texture stage
|
||||
|
@ -523,31 +549,52 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par
|
|||
glGenTextures(1, &result.id);
|
||||
glBindTexture(GL_TEXTURE_2D, result.id);
|
||||
|
||||
// Set params
|
||||
// Set texture parameters
|
||||
GLint minF = 0, magF = 0;
|
||||
int mipmapLevel = 1;
|
||||
|
||||
GLint minF = 0;
|
||||
if (params.minFilter == TEX_MIN_FILTER_NEAREST) minF = GL_NEAREST;
|
||||
else if (params.minFilter == TEX_MIN_FILTER_LINEAR) minF = GL_LINEAR;
|
||||
else if (params.minFilter == TEX_MIN_FILTER_NEAREST_MIPMAP_NEAREST) minF = GL_NEAREST_MIPMAP_NEAREST;
|
||||
else if (params.minFilter == TEX_MIN_FILTER_LINEAR_MIPMAP_NEAREST) minF = GL_LINEAR_MIPMAP_NEAREST;
|
||||
else if (params.minFilter == TEX_MIN_FILTER_NEAREST_MIPMAP_LINEAR) minF = GL_NEAREST_MIPMAP_LINEAR;
|
||||
else if (params.minFilter == TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR) minF = GL_LINEAR_MIPMAP_LINEAR;
|
||||
else assert(false);
|
||||
switch (params.filter)
|
||||
{
|
||||
case TEX_FILTER_NEAREST:
|
||||
minF = GL_NEAREST;
|
||||
magF = GL_NEAREST;
|
||||
break;
|
||||
case TEX_FILTER_BILINEAR:
|
||||
minF = GL_LINEAR;
|
||||
magF = GL_LINEAR;
|
||||
break;
|
||||
case TEX_FILTER_TRILINEAR:
|
||||
minF = GL_LINEAR_MIPMAP_LINEAR;
|
||||
magF = GL_LINEAR;
|
||||
mipmapLevel = CEngine::GetInstance().GetTextureMipmapLevel();
|
||||
break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minF);
|
||||
|
||||
GLint magF = 0;
|
||||
if (params.magFilter == TEX_MAG_FILTER_NEAREST) magF = GL_NEAREST;
|
||||
else if (params.magFilter == TEX_MAG_FILTER_LINEAR) magF = GL_LINEAR;
|
||||
else assert(false);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magF);
|
||||
|
||||
// Set mipmap level and automatic mipmap generation if neccesary
|
||||
if (params.mipmap)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapLevel - 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
}
|
||||
else
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
|
||||
{
|
||||
// Has to be set to 0 because no mipmaps are generated
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
|
||||
}
|
||||
|
||||
// Set anisotropy level if available
|
||||
if (m_anisotropyAvailable)
|
||||
{
|
||||
float level = Math::Min(m_maxAnisotropy, CEngine::GetInstance().GetTextureAnisotropyLevel());
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, level);
|
||||
}
|
||||
|
||||
bool convert = false;
|
||||
GLenum sourceFormat = 0;
|
||||
|
@ -653,7 +700,7 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par
|
|||
actualSurface = convertedSurface;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, actualSurface->w, actualSurface->h,
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, actualSurface->w, actualSurface->h,
|
||||
0, sourceFormat, GL_UNSIGNED_BYTE, actualSurface->pixels);
|
||||
|
||||
SDL_FreeSurface(convertedSurface);
|
||||
|
|
|
@ -205,6 +205,8 @@ private:
|
|||
Math::Matrix m_modelviewMat;
|
||||
//! Current projection matrix
|
||||
Math::Matrix m_projectionMat;
|
||||
//! Current texture matrix
|
||||
Math::Matrix m_textureMat;
|
||||
|
||||
//! The current material
|
||||
Material m_material;
|
||||
|
@ -247,6 +249,10 @@ private:
|
|||
bool m_multitextureAvailable;
|
||||
//! Whether to use VBOs or display lists
|
||||
bool m_vboAvailable;
|
||||
//! Whether anisotropic filtering is available
|
||||
bool m_anisotropyAvailable;
|
||||
//! Maximum anisotropy level
|
||||
int m_maxAnisotropy;
|
||||
//! Which vertex buffer type to use
|
||||
VertexBufferType m_vertexBufferType;
|
||||
//! Map of saved VBO objects
|
||||
|
|
Loading…
Reference in New Issue