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 2e9448c..7804a1a 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 6527e01..3f82576 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 18a6f1b..d75b8db 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 7dfbc52..87d25ac 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 907710a..ae57cf3 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 14af5ed..cf371fb 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 2a733bf..c61db1d 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 121f38e..31e4b22 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 d2438a6..a306e05 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);
 }