[Bf-blender-cvs] [31d1895] master: Fix T46951: invalid OpenGL mipmaps when using high bit depth textures.

Brecht Van Lommel noreply at git.blender.org
Tue Dec 15 01:48:20 CET 2015


Commit: 31d1895abfbcc3857109bd81343894e94d4cabc9
Author: Brecht Van Lommel
Date:   Tue Dec 15 01:38:59 2015 +0100
Branches: master
https://developer.blender.org/rB31d1895abfbcc3857109bd81343894e94d4cabc9

Fix T46951: invalid OpenGL mipmaps when using high bit depth textures.

===================================================================

M	source/blender/imbuf/IMB_imbuf.h
M	source/blender/imbuf/intern/filter.c

===================================================================

diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 77e8601..043f160 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -332,7 +332,6 @@ void IMB_free_anim(struct anim *anim);
 #define FILTER_MASK_USED		2
 
 void IMB_filter(struct ImBuf *ibuf);
-void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
 void IMB_mask_filter_extend(char *mask, int width, int height);
 void IMB_mask_clear(struct ImBuf *ibuf, char *mask, int val);
 void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter);
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index ef44523..90b3fe0 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -203,54 +203,97 @@ void imb_filterx(struct ImBuf *ibuf)
 	}
 }
 
-void IMB_filterN(ImBuf *out, ImBuf *in)
+static void imb_filterN(ImBuf *out, ImBuf *in)
 {
-	register char *row1, *row2, *row3;
-	register char *cp, *r11, *r13, *r21, *r23, *r31, *r33;
-	int rowlen, x, y;
-	
-	rowlen = in->x;
-	
-	/* generate 32-bit version for float images if it is not already generated by other space */
-	if (in->rect == NULL)
-		IMB_rect_from_float(in);
+	BLI_assert(out->channels == in->channels);
+	BLI_assert(out->x == in->x && out->y == out->y);
+
+	const int channels = in->channels;
+	const int rowlen = in->x;
 	
-	for (y = 0; y < in->y; y++) {
-		/* setup rows */
-		row2 = (char *)(in->rect + y * rowlen);
-		row1 = (y == 0) ? row2 : row2 - 4 * rowlen;
-		row3 = (y == in->y - 1) ? row2 : row2 + 4 * rowlen;
-		
-		cp = (char *)(out->rect + y * rowlen);
-		
-		for (x = 0; x < rowlen; x++) {
-			if (x == 0) {
-				r11 = row1;
-				r21 = row2;
-				r31 = row3;
-			}
-			else {
-				r11 = row1 - 4;
-				r21 = row2 - 4;
-				r31 = row3 - 4;
-			}
+	if (in->rect && out->rect) {
+		for (int y = 0; y < in->y; y++) {
+			/* setup rows */
+			const char *row2 = (const char *)in->rect + y * channels * rowlen;
+			const char *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
+			const char *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
+
+			char *cp = (char *)out->rect + y * channels * rowlen;
+
+			for (int x = 0; x < rowlen; x++) {
+				const char *r11, *r13, *r21, *r23, *r31, *r33;
+
+				if (x == 0) {
+					r11 = row1;
+					r21 = row2;
+					r31 = row3;
+				}
+				else {
+					r11 = row1 - channels;
+					r21 = row2 - channels;
+					r31 = row3 - channels;
+				}
 
-			if (x == rowlen - 1) {
-				r13 = row1;
-				r23 = row2;
-				r33 = row3;
-			}
-			else {
-				r13 = row1 + 4;
-				r23 = row2 + 4;
-				r33 = row3 + 4;
+				if (x == rowlen - 1) {
+					r13 = row1;
+					r23 = row2;
+					r33 = row3;
+				}
+				else {
+					r13 = row1 + channels;
+					r23 = row2 + channels;
+					r33 = row3 + channels;
+				}
+
+				cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] + 2 * row3[0] + r33[0]) >> 4;
+				cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] + 2 * row3[1] + r33[1]) >> 4;
+				cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] + 2 * row3[2] + r33[2]) >> 4;
+				cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] + 2 * row3[3] + r33[3]) >> 4;
+				cp += channels; row1 += channels; row2 += channels; row3 += channels;
 			}
+		}
+	}
+
+	if (in->rect_float && out->rect_float) {
+		for (int y = 0; y < in->y; y++) {
+			/* setup rows */
+			const float *row2 = (const float *)in->rect_float + y * channels * rowlen;
+			const float *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
+			const float *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
+
+			float *cp = (float *)out->rect_float + y * channels * rowlen;
+
+			for (int x = 0; x < rowlen; x++) {
+				const float *r11, *r13, *r21, *r23, *r31, *r33;
 
-			cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] + 2 * row3[0] + r33[0]) >> 4;
-			cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] + 2 * row3[1] + r33[1]) >> 4;
-			cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] + 2 * row3[2] + r33[2]) >> 4;
-			cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] + 2 * row3[3] + r33[3]) >> 4;
-			cp += 4; row1 += 4; row2 += 4; row3 += 4;
+				if (x == 0) {
+					r11 = row1;
+					r21 = row2;
+					r31 = row3;
+				}
+				else {
+					r11 = row1 - channels;
+					r21 = row2 - channels;
+					r31 = row3 - channels;
+				}
+
+				if (x == rowlen - 1) {
+					r13 = row1;
+					r23 = row2;
+					r33 = row3;
+				}
+				else {
+					r13 = row1 + channels;
+					r23 = row2 + channels;
+					r33 = row3 + channels;
+				}
+
+				cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] + 2 * row3[0] + r33[0]) * (1.0f/16.0f);
+				cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] + 2 * row3[1] + r33[1]) * (1.0f/16.0f);
+				cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] + 2 * row3[2] + r33[2]) * (1.0f/16.0f);
+				cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] + 2 * row3[3] + r33[3]) * (1.0f/16.0f);
+				cp += channels; row1 += channels; row2 += channels; row3 += channels;
+			}
 		}
 	}
 }
@@ -477,8 +520,8 @@ void IMB_remakemipmap(ImBuf *ibuf, int use_filter)
 		if (ibuf->mipmap[curmap]) {
 			
 			if (use_filter) {
-				ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, 32, IB_rect);
-				IMB_filterN(nbuf, hbuf);
+				ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, hbuf->planes, hbuf->flags);
+				imb_filterN(nbuf, hbuf);
 				imb_onehalf_no_alloc(ibuf->mipmap[curmap], nbuf);
 				IMB_freeImBuf(nbuf);
 			}
@@ -514,8 +557,8 @@ void IMB_makemipmap(ImBuf *ibuf, int use_filter)
 
 	while (curmap < IMB_MIPMAP_LEVELS) {
 		if (use_filter) {
-			ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, 32, IB_rect);
-			IMB_filterN(nbuf, hbuf);
+			ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, hbuf->planes, hbuf->flags);
+			imb_filterN(nbuf, hbuf);
 			ibuf->mipmap[curmap] = IMB_onehalf(nbuf);
 			IMB_freeImBuf(nbuf);
 		}




More information about the Bf-blender-cvs mailing list