Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2013-06-25 17:27:43 +0400
committerAntony Riakiotakis <kalast@gmail.com>2013-06-25 17:27:43 +0400
commitbd59bae6510c65c14956fefdcf3bedda4edf10d4 (patch)
treecde1a61cf84200041b86d8516b7f625ca3d2c468 /source/blender/gpu/intern
parent9ae8e4ca1ab491c0896e2deb40d6fd4a83b1fb32 (diff)
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.
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r--source/blender/gpu/intern/gpu_draw.c90
1 files changed, 89 insertions, 1 deletions
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index e98f8988aa6..fc28ec2d6f7 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -932,6 +932,77 @@ void GPU_paint_set_mipmap(int mipmap)
}
}
+
+/* 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 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
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 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
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);