[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