Revision: 57735
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=57735
Author: psy-fi
Date: 2013-06-25 13:27:43 +0000 (Tue, 25 Jun 2013)
Log Message:
-----------
Fix #34909 Texture paint mode does not correctly update when using
textures larger than 2048x2048.
Check if texture is over user preference or GPU limit in texture paint
mode and if it is, scale the partial redraw rectangle before uploading
to GPU. This should be faster than rescaling the whole texture.
Modified Paths:
--------------
trunk/blender/source/blender/gpu/intern/gpu_draw.c
Modified: trunk/blender/source/blender/gpu/intern/gpu_draw.c
===================================================================
--- trunk/blender/source/blender/gpu/intern/gpu_draw.c 2013-06-25 12:26:49 UTC
(rev 57734)
+++ trunk/blender/source/blender/gpu/intern/gpu_draw.c 2013-06-25 13:27:43 UTC
(rev 57735)
@@ -932,6 +932,77 @@
}
}
+
+/* check if image has been downscaled and do scaled partial update */
+static bool GPU_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int
x, int y, int w, int h)
+{
+ if ((!GPU_non_power_of_two_support() &&
!is_power_of_2_resolution(ibuf->x, ibuf->y)) ||
+ is_over_resolution_limit(ibuf->x, ibuf->y))
+ {
+ int x_limit = smaller_power_of_2_limit(ibuf->x);
+ int y_limit = smaller_power_of_2_limit(ibuf->y);
+
+ float xratio = x_limit/(float)ibuf->x;
+ float yratio = y_limit/(float)ibuf->y;
+
+ /* find new width, height and x,y gpu texture coordinates */
+
+ /* take ceiling because we will be losing 1 pixel due to
rounding errors in x,y... */
+ int rectw = (int)ceil(xratio * w);
+ int recth = (int)ceil(yratio * h);
+
+ x *= xratio;
+ y *= yratio;
+
+ /* ...but take back if we are over the limit! */
+ if (rectw + x > x_limit) rectw--;
+ if (recth + y > y_limit) recth--;
+
+ /* float rectangles are already continuous in memory so we can
use gluScaleImage */
+ if (frect) {
+ float *fscalerect =
MEM_mallocN(rectw*recth*sizeof(*fscalerect)*4, "fscalerect");
+ gluScaleImage(GL_RGBA, w, h, GL_FLOAT, frect, rectw,
recth, GL_FLOAT, fscalerect);
+
+ glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth,
GL_RGBA,
+ GL_FLOAT, fscalerect);
+
+ MEM_freeN(fscalerect);
+ }
+ /* byte images are not continuous in memory so do manual
interpolation */
+ else {
+ unsigned char *scalerect=
MEM_mallocN(rectw*recth*sizeof(*scalerect)*4, "scalerect");
+ unsigned int *p = (unsigned int *)scalerect;
+ int i, j;
+ float inv_xratio = 1.0/xratio;
+ float inv_yratio = 1.0/yratio;
+ for (i = 0; i < rectw; i++) {
+ float u = (x + i)*inv_xratio;
+ for (j = 0; j < recth; j++) {
+ float v = (y + j)*inv_yratio;
+ bilinear_interpolation_color_wrap(ibuf,
(unsigned char *)(p + i + j * (rectw)), NULL, u, v);
+ }
+ }
+ glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth,
GL_RGBA,
+ GL_UNSIGNED_BYTE, scalerect);
+
+ MEM_freeN(scalerect);
+ }
+
+ if (GPU_get_mipmap()) {
+ gpu_generate_mipmap(GL_TEXTURE_2D);
+ }
+ else {
+ ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
{
ImBuf *ibuf;
@@ -959,6 +1030,15 @@
int is_data = (ima->tpageflag & IMA_GLBIND_IS_DATA);
IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h,
is_data);
+ if (GPU_check_scaled_image(ibuf, ima, buffer, x, y, w,
h)) {
+ MEM_freeN(buffer);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS,
skip_pixels);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return;
+ }
+
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
GL_FLOAT, buffer);
@@ -977,7 +1057,15 @@
BKE_image_release_ibuf(ima, ibuf, NULL);
return;
}
-
+
+ if (GPU_check_scaled_image(ibuf, ima, NULL, x, y, w, h)) {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return;
+ }
+
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
glPixelStorei(GL_UNPACK_ROW_LENGTH, ibuf->x);
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs