Interesting commit for artists using huge textures;
authorTon Roosendaal <ton@blender.org>
Fri, 10 Feb 2006 18:57:52 +0000 (18:57 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 10 Feb 2006 18:57:52 +0000 (18:57 +0000)
The code that generated mipmaps took a real long time to do it... on a
5k x 5k image it took here (no optim, debug compile) 32.5 sec.

Recoded the very old filtering routine, which already brought it down to
2.8 seconds. Then tested if we even need this filtering... in many cases
the images are painted or photographs, which is filtered OK already.
Without the filter, the mipmap timing went down to 0.39 second. :)

http://www.blender.org/bf/filters/index1.html

Here's an example of two 'mips' generated with or without gauss filter.
Note that aliasing in an image remains there... which can be a wanted
effect anyway.

So; added the gauss filter as option in making mipmaps. Also had to
reshuffle the buttons there in a more logical manner.
There's also disabled code in the do_versions to set 'gauss' on in older
files. Will be enabled during release time.

source/blender/blenloader/intern/readfile.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/filter.c
source/blender/makesdna/DNA_texture_types.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/imagetexture.c
source/blender/src/buttons_shading.c

index cb441d746e8f27fa7512d3f26840a0013894b710..83e72d95c14a6ef7150128a1bc834233bbdfee77 100644 (file)
@@ -5286,6 +5286,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        }
        
        if(main->versionfile <= 241) {
+               Tex *tex;
                Scene *sce;
                bArmature *arm;
                bNodeTree *ntree;
@@ -5333,6 +5334,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
                        ntree_version_241(ntree);
                
+//             for(tex= main->tex.first; tex; tex= tex->id.next)
+//                     tex->imaflag |= TEX_GAUSS_MIP;
+
                //Object *ob;
                
                /* for empty drawsize and drawtype */
index e78ee5901e904e01c7ee3325e009fa4f547a849d..744c3b663459967da02ed02b3de7eb5d3fef4da3 100644 (file)
@@ -284,6 +284,7 @@ void IMB_antialias(struct ImBuf * ibuf);
  * @attention Defined in filter.c
  */
 void IMB_filter(struct ImBuf *ibuf);
+void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
 
 /**
  *
index 810e012761b47b8ea6f2b6e2c0620261699c2483..8c5bc430aea008275b4d949d3e5d39419df1bb6e 100644 (file)
@@ -203,6 +203,36 @@ void imb_filterx(struct ImBuf *ibuf)
        }
 }
 
+void IMB_filterN(ImBuf *out, ImBuf *in)
+{
+       register char *row1, *row2, *row3;
+       register char *cp;
+       int rowlen, x, y;
+       
+       rowlen= in->x;
+       
+       for(y=2; y<in->y; y++) {
+               /* setup rows */
+               row1= (char *)(in->rect + (y-2)*rowlen);
+               row2= row1 + 4*rowlen;
+               row3= row2 + 4*rowlen;
+               
+               cp= (char *)(out->rect + (y-1)*rowlen);
+               cp[0]= row2[0];
+               cp[1]= row2[1];
+               cp[2]= row2[2];
+               cp[3]= row2[3];
+               cp+= 4;
+               
+               for(x=2; x<rowlen; x++) {
+                       cp[0]= (row1[0] + 2*row1[4] + row1[8] + 2*row2[0] + 4*row2[4] + 2*row2[8] + row3[0] + 2*row3[4] + row3[8])>>4;
+                       cp[1]= (row1[1] + 2*row1[5] + row1[9] + 2*row2[1] + 4*row2[5] + 2*row2[9] + row3[1] + 2*row3[5] + row3[9])>>4;
+                       cp[2]= (row1[2] + 2*row1[6] + row1[10] + 2*row2[2] + 4*row2[6] + 2*row2[10] + row3[2] + 2*row3[6] + row3[10])>>4;
+                       cp[3]= (row1[3] + 2*row1[7] + row1[11] + 2*row2[3] + 4*row2[7] + 2*row2[11] + row3[3] + 2*row3[7] + row3[11])>>4;
+                       cp+=4; row1+=4; row2+=4; row3+=4;
+               }
+       }
+}
 
 void IMB_filter(struct ImBuf *ibuf)
 {
index 3cb37dff29ea18ef4935cfa339117895a6d45a13..7aad3ee6e37c5f88d3ad7e278dd9d735f107a290 100644 (file)
@@ -238,8 +238,8 @@ typedef struct TexMapping {
 #define TEX_ANTISCALE  512
 #define TEX_STD_FIELD  1024
 #define TEX_NORMALMAP  2048
+#define TEX_GAUSS_MIP  4096
 
-#define TEX_LASOPPATCH 8192
 #define TEX_MORKPATCH  16384
 
 /* flag */
index 45a3e6c9b807f92e628005a1a71b3725514dffd6..fe03dd5ed20fe850ebddea316dce3892c2d77d0b 100644 (file)
@@ -2581,20 +2581,6 @@ void RE_Database_Free(Render *re)
        
        re->totvlak=re->totvert=re->totlamp=re->tothalo= 0;
        re->i.convertdone= 0;
-       
-       {
-               int curmap;
-               Image *ima;
-               for(ima= G.main->image.first; ima; ima= ima->id.next) {
-                       if(ima->ibuf)
-                               printf("%s %d %d ref %d\n", ima->id.name+2, ima->ibuf->x, ima->ibuf->y, ima->ibuf->encodedsize);
-                       for(curmap=0; curmap<BLI_ARRAY_NELEMS(ima->mipmap); curmap++) {
-                               if(ima->mipmap[curmap]) {
-                                       printf("%s %d %d ref %d\n", ima->id.name+2, ima->mipmap[curmap]->x, ima->mipmap[curmap]->y, ima->mipmap[curmap]->encodedsize);
-                               }
-                       }
-               }
-       }
 }
 
 /* per face check if all samples should be taken.
index 6e93acde5bd443a4fe6027fc9032ec9ed6a1405d..e1868eda917b36ddc35f915ce9a440c18ba080c7 100644 (file)
@@ -566,20 +566,24 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max
        }
 }      
 
-static void makemipmap(Image *ima)
+static void makemipmap(Tex *tex, Image *ima)
 {
-       struct ImBuf *ibuf;
+       struct ImBuf *ibuf, *nbuf;
        int minsize, curmap=0;
        
        ibuf= ima->ibuf;
        minsize= MIN2(ibuf->x, ibuf->y);
        
-       while(minsize>3 && curmap<BLI_ARRAY_NELEMS(ima->mipmap)) {
-               
-               ibuf= IMB_dupImBuf(ibuf);
-               IMB_filter(ibuf);
-               ima->mipmap[curmap]= (struct ImBuf *)IMB_onehalf(ibuf);
-               IMB_freeImBuf(ibuf);
+       while(minsize>10 && curmap<BLI_ARRAY_NELEMS(ima->mipmap)) {
+               if(tex->imaflag & TEX_GAUSS_MIP) {
+                       nbuf= IMB_allocImBuf(ibuf->x, ibuf->y, 32, IB_rect, 0);
+                       IMB_filterN(nbuf, ibuf);
+                       ima->mipmap[curmap]= (struct ImBuf *)IMB_onehalf(nbuf);
+                       IMB_freeImBuf(nbuf);
+               }
+               else {
+                       ima->mipmap[curmap]= (struct ImBuf *)IMB_onehalf(ibuf);
+               }
                ibuf= ima->mipmap[curmap];
                
                curmap++;
@@ -617,7 +621,7 @@ int imagewraposa(Tex *tex, Image *ima, float *texvec, float *dxt, float *dyt, Te
                if(tex->imaflag & TEX_MIPMAP) {
                        if(ima->mipmap[0]==NULL) {
                                if(load_ibuf_lock) SDL_mutexP(load_ibuf_lock);
-                               if(ima->mipmap[0]==NULL) makemipmap(ima);
+                               if(ima->mipmap[0]==NULL) makemipmap(tex, ima);
                                if(load_ibuf_lock) SDL_mutexV(load_ibuf_lock);
                        }
                }
@@ -800,9 +804,8 @@ int imagewraposa(Tex *tex, Image *ima, float *texvec, float *dxt, float *dyt, Te
                                pixsize= 1.0f / (float)MIN2(ibuf->x, ibuf->y); /* this used to be 1.0 */                
                                curmap++;
                        }
-       ibuf->encodedsize++;
+
                        if(previbuf!=ibuf || (tex->imaflag & TEX_INTERPOL)) {
-       previbuf->encodedsize++;
                                /* sample at least 1 pixel */
                                if (minx < 0.5f / ima->ibuf->x) minx = 0.5f / ima->ibuf->x;
                                if (miny < 0.5f / ima->ibuf->y) miny = 0.5f / ima->ibuf->y;
index 52cc8843594fce9b96a1ed9bf6ae2a76abb6f40b..87a4481fa1856b57143c7f437ce2e1a85800b922 100644 (file)
@@ -986,17 +986,18 @@ static void texture_panel_image(Tex *tex)
 
        /* types */
        uiBlockBeginAlign(block);
-       uiDefButBitS(block, TOG, TEX_INTERPOL, 0, "InterPol",                   10, 180, 75, 18, &tex->imaflag, 0, 0, 0, 0, "Interpolates pixels of the Image to fit texture mapping");
-       uiDefButBitS(block, TOG, TEX_USEALPHA, B_TEXPRV, "UseAlpha",    85, 180, 75, 18, &tex->imaflag, 0, 0, 0, 0, "Click to use Image's alpha channel");
-       uiDefButBitS(block, TOG, TEX_CALCALPHA, B_TEXPRV, "CalcAlpha",  160, 180, 75, 18, &tex->imaflag, 0, 0, 0, 0, "Click to calculate an alpha channel based on Image RGB values");
-       uiDefButBitS(block, TOG, TEX_NEGALPHA, B_TEXPRV, "NegAlpha",    235, 180, 75, 18, &tex->flag, 0, 0, 0, 0, "Click to invert the alpha values");
-       
-       uiDefButBitS(block, TOG, TEX_MIPMAP, B_IMAPTEST, "MipMap",      10, 160, 60, 18, &tex->imaflag, 0, 0, 0, 0, "Generates a series of pictures to use for mipmapping");
-       uiDefButBitS(block, TOG, TEX_FIELDS, B_IMAPTEST, "Fields",      70, 160, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Click to enable use of fields in Image");
-       uiDefButBitS(block, TOG, TEX_IMAROT, B_TEXPRV, "Rot90",         120, 160, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Actually flips X and Y for rendering, rotates and mirrors");
-       uiDefButBitS(block, TOG, TEX_ANIM5, B_RELOADIMA, "Movie",       170, 160, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Click to enable movie frames as Images");
-       uiDefButBitS(block, TOG, TEX_ANTIALI, 0, "Anti",                                220, 160, 40, 18, &tex->imaflag, 0, 0, 0, 0, "Toggles Image anti-aliasing");
-       uiDefButBitS(block, TOG, TEX_STD_FIELD, 0, "StField",                   260, 160, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Standard Field Toggle");
+       uiDefButBitS(block, TOG, TEX_MIPMAP, B_IMAPTEST, "MipMap",      10, 180, 60, 18, &tex->imaflag, 0, 0, 0, 0, "Generates and uses mipmaps");
+       uiDefButBitS(block, TOG, TEX_GAUSS_MIP, 0, "Gauss",                     70, 180, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Enable Gauss filter to sample down mipmaps");
+       uiDefButBitS(block, TOG, TEX_INTERPOL, 0, "Interpol",           120, 180, 60, 18, &tex->imaflag, 0, 0, 0, 0, "Interpolates pixels using Area filter");
+       uiDefButBitS(block, TOG, TEX_IMAROT, B_TEXPRV, "Rot90",         180, 180, 40, 18, &tex->imaflag, 0, 0, 0, 0, "Actually flips X and Y for rendering, rotates and mirrors");
+       uiDefButBitS(block, TOG, TEX_ANTIALI, 0, "Anti",                        220, 180, 40, 18, &tex->imaflag, 0, 0, 0, 0, "Toggles Image anti-aliasing");
+       uiDefButBitS(block, TOG, TEX_ANIM5, B_RELOADIMA, "Movie",       260, 180, 50, 18, &tex->imaflag, 0, 0, 0, 0, "Click to enable movie frames as Images");
+       
+       uiDefButBitS(block, TOG, TEX_USEALPHA, B_TEXPRV, "UseAlpha",    10, 160, 70, 18, &tex->imaflag, 0, 0, 0, 0, "Click to use Image's alpha channel");
+       uiDefButBitS(block, TOG, TEX_CALCALPHA, B_TEXPRV, "CalcAlpha",  80, 160, 70, 18, &tex->imaflag, 0, 0, 0, 0, "Click to calculate an alpha channel based on Image RGB values");
+       uiDefButBitS(block, TOG, TEX_NEGALPHA, B_TEXPRV, "NegAlpha",    150, 160, 60, 18, &tex->flag, 0, 0, 0, 0, "Click to invert the alpha values");
+       uiDefButBitS(block, TOG, TEX_FIELDS, B_IMAPTEST, "Fields",              210, 160, 60, 18, &tex->imaflag, 0, 0, 0, 0, "Click to enable use of fields in Image");
+       uiDefButBitS(block, TOG, TEX_STD_FIELD, 0, "Odd",                               270, 160, 40, 18, &tex->imaflag, 0, 0, 0, 0, "Standard Field Toggle");
        uiBlockEndAlign(block);
        
        /* file input */