Committing patch #25676 Anisotropic filtering in viewport and BGE by me.
authorMitchell Stokes <mogurijin@gmail.com>
Wed, 15 Jun 2011 18:59:22 +0000 (18:59 +0000)
committerMitchell Stokes <mogurijin@gmail.com>
Wed, 15 Jun 2011 18:59:22 +0000 (18:59 +0000)
This patch adds anisotropic filtering of textures in the viewport and the BGE. The quality of the filtering is adjustable in the user preferences under System. For more information on anisotropic filtering:
http://en.wikipedia.org/wiki/Anisotropic_filtering

One current limitation of this setup (having the option a user preference) is it makes runtimes more troublesome. Runtimes don't have user preferences set, so for now the blender player defaults to 2x AF. Options will be added later to change this value (probably a command line option).

release/scripts/startup/bl_ui/space_userpref.py
source/blender/editors/interface/resources.c
source/blender/gpu/GPU_draw.h
source/blender/gpu/intern/gpu_draw.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c
source/blender/windowmanager/intern/wm_init_exit.c
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/BL_Texture.cpp

index 2e9448cca27652f058ad75ee27f39e13fe280059..7804a1a3c93560df2c1cc6052635cdb2c4b1a5d5 100644 (file)
@@ -438,6 +438,8 @@ class USERPREF_PT_system(bpy.types.Panel):
         col.label(text="OpenGL:")
         col.prop(system, "gl_clip_alpha", slider=True)
         col.prop(system, "use_mipmaps")
+        col.label(text="Anisotropic Filtering")
+        col.prop(system, "anisotropic_filter", text="")
         col.prop(system, "use_vertex_buffer_objects")
         #Anti-aliasing is disabled as it breaks broder/lasso select
         #col.prop(system, "use_antialiasing")
index 6527e0140b83da92bd7a9f815680ec3a7c550c28..3f825762d74b41fba94dc0e78e47b0d5ac63aa61 100644 (file)
@@ -1580,6 +1580,8 @@ void init_userdef_do_versions(void)
                U.dragthreshold= 5;
        if (U.widget_unit==0)
                U.widget_unit= (U.dpi * 20 + 36)/72;
+       if (U.anisotropic_filter <= 0)
+               U.anisotropic_filter = 1;
 
        /* funny name, but it is GE stuff, moves userdef stuff to engine */
 // XXX space_set_commmandline_options();
index 18a6f1ba73dfd82737b80e0ce0361389fce7d60f..d75b8db2c4e2f7dc65d0bfd7af6a5108844a4c39 100644 (file)
@@ -112,6 +112,11 @@ void GPU_set_mipmap(int mipmap);
 void GPU_set_linear_mipmap(int linear);
 void GPU_paint_set_mipmap(int mipmap);
 
+/* Anisotropic filtering settings
+ * - these will free textures on changes */
+void GPU_set_anisotropic(float value);
+float GPU_get_anisotropic(void);
+
 /* Image updates and free
  * - these deal with images bound as opengl textures */
 
index 7dfbc52819ef3c8749e8efcea5e914e3c711cc29..87d25ac850aebc0c78a78d90cbb2ef735957a64b 100644 (file)
@@ -246,8 +246,9 @@ static struct GPUTextureState {
        int domipmap, linearmipmap;
 
        int alphamode;
+       float anisotropic;
        MTFace *lasttface;
-} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, -1, NULL};
+} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, -1, 1.f, NULL};
 
 /* Mipmap settings */
 
@@ -292,6 +293,26 @@ static GLenum gpu_get_mipmap_filter(int mag)
        }
 }
 
+/* Anisotropic filtering settings */
+void GPU_set_anisotropic(float value)
+{
+       if (GTS.anisotropic != value)
+       {
+               GPU_free_images();
+
+               /* Clamp value to the maximum value the graphics card supports */
+               if (value > GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)
+                       value = GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT;
+
+               GTS.anisotropic = value;
+       }
+}
+
+float GPU_get_anisotropic()
+{
+       return GTS.anisotropic;
+}
+
 /* Set OpenGL state for an MTFace */
 
 static void gpu_make_repbind(Image *ima)
@@ -559,6 +580,8 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
                ima->tpageflag |= IMA_MIPMAP_COMPLETE;
        }
 
+       if (GLEW_EXT_texture_filter_anisotropic)
+               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
        /* set to modulate with vertex color */
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                
index 907710ae4cd19120004c8993322605a391de1618..ae57cf3f80b03ec5a80e4798803a76fc108b5b9e 100644 (file)
@@ -375,7 +375,7 @@ typedef struct UserDef {
        short scrcastwait;              /* milliseconds between screencast snapshots */
        
        short widget_unit;              /* defaults to 20 for 72 DPI setting */
-       short pad[3];                   
+       short anisotropic_filter;
 
        char versemaster[160];
        char verseuser[160];
@@ -385,7 +385,6 @@ typedef struct UserDef {
        short autokey_flag;             /* flags for autokeying */
        
        short text_render, pad9;                /*options for text rendering*/
-       float pad10;
 
        struct ColorBand coba_weight;   /* from texture.h */
 
index 14af5ed7a3f470a1a398256ec753206fb066905a..cf371fbf9bc0fbfe0d4fa4ac0135758fe3f9138a 100644 (file)
@@ -117,6 +117,12 @@ static void rna_userdef_mipmap_update(Main *bmain, Scene *scene, PointerRNA *ptr
        rna_userdef_update(bmain, scene, ptr);
 }
 
+static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+       GPU_set_anisotropic(U.anisotropic_filter);
+       rna_userdef_update(bmain, scene, ptr);
+}
+
 static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
        GPU_free_images();
@@ -2346,6 +2352,14 @@ static void rna_def_userdef_system(BlenderRNA *brna)
                {128, "CLAMP_128", 0, "128", ""},
                {0, NULL, 0, NULL, NULL}};
 
+       static EnumPropertyItem anisotropic_items[]  ={
+               {1, "FILTER_0", 0, "Off", ""},
+               {2, "FILTER_2", 0, "2x", ""},
+               {4, "FILTER_4", 0, "4x", ""},
+               {8, "FILTER_8", 0, "8x", ""},
+               {16, "FILTER_16", 0, "16x", ""},
+               {0, NULL, 0, NULL, NULL}};
+
        static EnumPropertyItem audio_mixing_samples_items[] = {
                {256, "SAMPLES_256", 0, "256", "Set audio mixing buffer size to 256 samples"},
                {512, "SAMPLES_512", 0, "512", "Set audio mixing buffer size to 512 samples"},
@@ -2568,6 +2582,13 @@ static void rna_def_userdef_system(BlenderRNA *brna)
        prop= RNA_def_property(srna, "use_antialiasing", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_AA);
        RNA_def_property_ui_text(prop, "Anti-aliasing", "Use anti-aliasing for the 3D view (may impact redraw performance)");
+
+       prop= RNA_def_property(srna, "anisotropic_filter", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "anisotropic_filter");
+       RNA_def_property_enum_items(prop, anisotropic_items);
+       RNA_def_property_enum_default(prop, 1);
+       RNA_def_property_ui_text(prop, "Anisotropic Filter", "The quality of the anisotropic filtering (values greater than 1.0 enable anisotropic filtering)");
+       RNA_def_property_update(prop, 0, "rna_userdef_anisotropic_update");
        
        prop= RNA_def_property(srna, "gl_texture_limit", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "glreslimit");
index 2a733bf28a929eb0f050399693f77e900da007cd..c61db1d653e9e2088a05c2b41fa9c50f72a54c15 100644 (file)
@@ -169,6 +169,7 @@ void WM_init(bContext *C, int argc, const char **argv)
        if (!G.background) {
                GPU_extensions_init();
                GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
+               GPU_set_anisotropic(U.anisotropic_filter);
        
                UI_init();
        }
index 121f38eef028900d90311b54f9d1cd12b501f1cc..31e4b223ff279c59c2e3e6f729c49d403f95bf53 100644 (file)
@@ -450,6 +450,9 @@ int main(int argc, char** argv)
        U.audioformat = 0x24;
        U.audiochannels = 2;
 
+       // XXX this one too
+       U.anisotropic_filter = 2;
+
        sound_init_once();
 
        /* if running blenderplayer the last argument can't be parsed since it has to be the filename. */
@@ -705,6 +708,8 @@ int main(int argc, char** argv)
                {
                        GPU_set_mipmap(0);
                }
+
+               GPU_set_anisotropic(U.anisotropic_filter);
                
                // Create the system
                if (GHOST_ISystem::createSystem() == GHOST_kSuccess)
index d2438a66367e96800c3bb726a2813b9f08085499..a306e059442e435bb2ca246f31051be9500b6dc1 100644 (file)
@@ -28,6 +28,7 @@
 #define spit(x) std::cout << x << std::endl;
 
 #include "MEM_guardedalloc.h"
+#include "GPU_draw.h"
 
 extern "C" {
        // envmaps
@@ -175,6 +176,8 @@ void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
                glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix );
        }
 
+       if (GLEW_EXT_texture_filter_anisotropic)
+               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 }
 
@@ -199,6 +202,9 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
        }
+
+       if (GLEW_EXT_texture_filter_anisotropic)
+               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        free(newPixels);
 }