fix [#27662] Storing png/tga images ignore Alpha settings
authorCampbell Barton <ideasman42@gmail.com>
Wed, 15 Jun 2011 01:56:49 +0000 (01:56 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 15 Jun 2011 01:56:49 +0000 (01:56 +0000)
- don't clear alpha when baking RGB images
- when baking results in partial alpha. set the depth to 32.

source/blender/blenpluginapi/iff.h
source/blender/editors/object/object_bake.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/rectop.c
source/blender/render/intern/source/rendercore.c

index bccc7bdb769f70b1e6bd52afc4b06733c8c50b4b..77cdf889ea55159443bc0de57ada7863b258083b 100644 (file)
@@ -113,9 +113,10 @@ LIBIMPORT void interlace(struct ImBuf *ib);
 LIBIMPORT void IMB_rectcpy(struct ImBuf *dbuf, struct ImBuf *sbuf, 
        int destx, int desty, int srcx, int srcy, int width, int height);
 
-LIBIMPORT void IMB_rectfill(struct ImBuf *drect, float col[4]);
+LIBIMPORT void IMB_rectfill(struct ImBuf *drect, const float col[4]);
 LIBIMPORT void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, int y2);
 LIBIMPORT void buf_rectfill_area(unsigned char *rect, float *rectf, int width, int height, float *col, int x1, int y1, int x2, int y2);
+LIBIMPORT void IMB_rectfill_alpha(struct ImBuf *drect, const float value);
 
 #endif /* IFF_H */
 
index 565c5810cff82c284d7d1cc3e084f90b31914d97..c669a69b157091cc76f9247c601bd6d17f31b7a7 100644 (file)
@@ -854,10 +854,14 @@ static void finish_images(MultiresBakeRender *bkr)
                Image *ima= (Image*)link->data;
                int i;
                ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+               short is_new_alpha;
 
                if(ibuf->x<=0 || ibuf->y<=0)
                        continue;
 
+               /* must check before filtering */
+               is_new_alpha= (ibuf->depth != 32) && BKE_alphatest_ibuf(ibuf);
+
                /* Margin */
                if(bkr->bake_filter) {
                        char *temprect;
@@ -882,6 +886,18 @@ static void finish_images(MultiresBakeRender *bkr)
                                IMB_filter_extend(ibuf, (char *)ibuf->userdata);
                }
 
+               /* if the bake results in new alpha then change the image setting */
+               if(is_new_alpha) {
+                       ibuf->depth= 32;
+               }
+               else {
+                       if(bkr->bake_filter) {
+                               /* clear alpha added by filtering */
+                               IMB_rectfill_alpha(ibuf, 1.0f);
+                       }
+               }
+
+
                ibuf->userflags|= IB_BITMAPDIRTY;
                if(ibuf->mipmap[0]) {
                        ibuf->userflags|= IB_MIPMAP_INVALID;
@@ -1028,7 +1044,8 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
 static void clear_images(MTFace *mtface, int totface)
 {
        int a;
-       float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+       const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+       const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
 
        for(a= 0; a<totface; a++)
                mtface[a].tpage->id.flag&= ~LIB_DOIT;
@@ -1039,7 +1056,7 @@ static void clear_images(MTFace *mtface, int totface)
                if((ima->id.flag&LIB_DOIT)==0) {
                        ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
 
-                       IMB_rectfill(ibuf, vec);
+                       IMB_rectfill(ibuf, (ibuf->depth == 32) ? vec_alpha : vec_solid);
                        ima->id.flag|= LIB_DOIT;
                }
        }
index 5d61452e149e3bb875df726fb9768ced20038c3f..e9592fdc164258484f423215a182bdf8be5ebbbb 100644 (file)
@@ -442,8 +442,9 @@ void IMB_freezbuffloatImBuf(struct ImBuf *ibuf);
  *
  * @attention Defined in rectop.c
  */
-void IMB_rectfill(struct ImBuf *drect, float col[4]);
+void IMB_rectfill(struct ImBuf *drect, const float col[4]);
 void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, int y2);
+void IMB_rectfill_alpha(struct ImBuf *ibuf, const float value);
 
 /* this should not be here, really, we needed it for operating on render data, IMB_rectfill_area calls it */
 void buf_rectfill_area(unsigned char *rect, float *rectf, int width, int height, float *col, int x1, int y1, int x2, int y2);
index 44af7ffdb3fa9c356d57fcd4a96b09ed7068907d..844478e03cb659c29761cc40cf56cc3562319b6e 100644 (file)
@@ -450,7 +450,7 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
 
 /* fill */
 
-void IMB_rectfill(struct ImBuf *drect, float col[4])
+void IMB_rectfill(struct ImBuf *drect, const float col[4])
 {
        int num;
 
@@ -561,3 +561,18 @@ void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, i
        if (!ibuf) return;
        buf_rectfill_area((unsigned char *) ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y, col, x1, y1, x2, y2);
 }
+
+
+void IMB_rectfill_alpha(ImBuf *ibuf, const float value)
+{
+       int i;
+       if (ibuf->rect_float) {
+               float *fbuf= ibuf->rect_float + 3;
+               for (i = ibuf->x * ibuf->y; i > 0; i--, fbuf+= 4) { *fbuf = value; }
+       }
+       else {
+               const unsigned char cvalue= value * 255;
+               unsigned char *cbuf= ((unsigned char *)ibuf->rect) + 3;
+               for (i = ibuf->x * ibuf->y; i > 0; i--, cbuf+= 4) { *cbuf = cvalue; }
+       }
+}
index 0087be8cca94ce7a92b9b463bcf4729e42078178..e6206007b7ae0dfb0d4e39ec064f2dc059f9d1fc 100644 (file)
@@ -2464,7 +2464,8 @@ static int get_next_bake_face(BakeShade *bs)
                                if(tface && tface->tpage) {
                                        Image *ima= tface->tpage;
                                        ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
-                                       float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+                                       const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+                                       const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
                                        
                                        if(ibuf==NULL)
                                                continue;
@@ -2484,7 +2485,7 @@ static int get_next_bake_face(BakeShade *bs)
                                                        imb_freerectImBuf(ibuf);
                                                /* clear image */
                                                if(R.r.bake_flag & R_BAKE_CLEAR)
-                                                       IMB_rectfill(ibuf, vec);
+                                                       IMB_rectfill(ibuf, (ibuf->depth == 32) ? vec_alpha : vec_solid);
                                        
                                                /* might be read by UI to set active image for display */
                                                R.bakebuf= ima;
@@ -2671,10 +2672,14 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
        for(ima= G.main->image.first; ima; ima= ima->id.next) {
                if((ima->id.flag & LIB_DOIT)==0) {
                        ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+                       short is_new_alpha;
 
                        if(!ibuf)
                                continue;
 
+                       /* must check before filtering */
+                       is_new_alpha= (ibuf->depth != 32) && BKE_alphatest_ibuf(ibuf);
+
                        if(re->r.bake_filter) {
                                if (usemask) {
                                        /* extend the mask +2 pixels from the image,
@@ -2706,6 +2711,17 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
                                }
                        }
 
+                       /* if the bake results in new alpha then change the image setting */
+                       if(is_new_alpha) {
+                               ibuf->depth= 32;
+                       }
+                       else {
+                               if(re->r.bake_filter) {
+                                       /* clear alpha added by filtering */
+                                       IMB_rectfill_alpha(ibuf, 1.0f);
+                               }
+                       }
+
                        ibuf->userflags |= IB_BITMAPDIRTY;
                        if (ibuf->rect_float) IMB_rect_from_float(ibuf);
                }