[colobot] 342/390: Implemented trilinear filtering, mipmap level setting and anisotropic filtering
Didier Raboud
odyx at moszumanska.debian.org
Fri Jun 12 14:22:02 UTC 2015
This is an automated email from the git hooks/post-receive script.
odyx pushed a commit to branch upstream/latest
in repository colobot.
commit d3b052f19b94d333bbeb6709efb73f180c06c440
Author: Tomasz Kapuściński <tomaszkax86 at gmail.com>
Date: Wed May 6 17:55:10 2015 +0200
Implemented trilinear filtering, mipmap level setting and anisotropic filtering
---
src/graphics/core/device.h | 3 +-
src/graphics/core/texture.h | 22 ++++++++---
src/graphics/engine/engine.cpp | 73 ++++++++++++++++++++++++++++++----
src/graphics/engine/engine.h | 22 +++++++++++
src/graphics/engine/text.cpp | 3 +-
src/graphics/opengl/gldevice.cpp | 85 +++++++++++++++++++++++++++++++---------
src/graphics/opengl/gldevice.h | 6 +++
7 files changed, 178 insertions(+), 36 deletions(-)
diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h
index f52e07f..f790c24 100644
--- a/src/graphics/core/device.h
+++ b/src/graphics/core/device.h
@@ -91,7 +91,8 @@ enum TransformType
{
TRANSFORM_WORLD,
TRANSFORM_VIEW,
- TRANSFORM_PROJECTION
+ TRANSFORM_PROJECTION,
+ TRANSFORM_TEXTURE
};
/**
diff --git a/src/graphics/core/texture.h b/src/graphics/core/texture.h
index 3ce06ee..038bbbb 100644
--- a/src/graphics/core/texture.h
+++ b/src/graphics/core/texture.h
@@ -53,6 +53,19 @@ enum TexImgFormat
};
/**
+ * \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;
}
};
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index 2777396..d26304d 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -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;
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index a6d1921..903c22d 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -1117,6 +1117,24 @@ public:
//@}
//@{
+ //! 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);
bool GetTotoMode();
@@ -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;
diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp
index 9ee190a..d8a3acc 100644
--- a/src/graphics/engine/text.cpp
+++ b/src/graphics/engine/text.cpp
@@ -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);
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index a197b18..582ed26 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -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);
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index e932ab9..e543f13 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -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
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git
More information about the Pkg-games-commits
mailing list