From bd309603c5359443ace5af4e11d0e4bcd17e4ac6 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 6 May 2016 16:54:07 +0200 Subject: Clip invisible parts of image when drawing in 2D textures and GLSL Modes This commit avoids draw of invisible parts of image in image editor, making it faster to re-draw the image. Especially handy when painting on a high-res image when zoomed-in. --- source/blender/editors/screen/glutil.c | 104 +++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 17 deletions(-) (limited to 'source/blender/editors/screen') diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index a1c330d9dff..cbf87062955 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -368,7 +368,11 @@ static int get_cached_work_texture(int *r_w, int *r_h) return texid; } -void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, float scaleX, float scaleY) +void glaDrawPixelsTexScaled_clipping(float x, float y, int img_w, int img_h, + int format, int type, int zoomfilter, void *rect, + float scaleX, float scaleY, + float clip_min_x, float clip_min_y, + float clip_max_x, float clip_max_y) { unsigned char *uc_rect = (unsigned char *) rect; const float *f_rect = (float *)rect; @@ -377,6 +381,7 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y; int texid = get_cached_work_texture(&tex_w, &tex_h); int components; + const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y)); /* Specify the color outside this function, and tex will modulate it. * This is useful for changing alpha without using glPixelTransferf() @@ -443,11 +448,23 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int offset_top = (seamless && remainder_y > tex_h) ? 1 : 0; float rast_x = x + subpart_x * offset_x * xzoom; float rast_y = y + subpart_y * offset_y * yzoom; - /* check if we already got these because we always get 2 more when doing seamless */ if (subpart_w <= seamless || subpart_h <= seamless) continue; - + + if (use_clipping) { + if (rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX < clip_min_x || + rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY < clip_min_y) + { + continue; + } + if (rast_x + (float)offset_left * xzoom > clip_max_x || + rast_y + (float)offset_bot * yzoom > clip_max_y) + { + continue; + } + } + if (type == GL_FLOAT) { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_FLOAT, &f_rect[((size_t)subpart_y) * offset_y * img_w * components + subpart_x * offset_x * components]); @@ -497,9 +514,26 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, #endif } +void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, + int format, int type, int zoomfilter, void *rect, + float scaleX, float scaleY) +{ + glaDrawPixelsTexScaled_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect, + scaleX, scaleY, 0.0f, 0.0f, 0.0f, 0.0f); +} + void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect) { - glaDrawPixelsTexScaled(x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f); + glaDrawPixelsTexScaled_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f, + 0.0f, 0.0f, 0.0f, 0.0f); +} + +void glaDrawPixelsTex_clipping(float x, float y, int img_w, int img_h, + int format, int type, int zoomfilter, void *rect, + float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y) +{ + glaDrawPixelsTexScaled_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f, + clip_min_x, clip_min_y, clip_max_x, clip_max_y); } void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect) @@ -580,17 +614,27 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo } /* uses either DrawPixelsSafe or DrawPixelsTex, based on user defined maximum */ -void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect) +void glaDrawPixelsAuto_clipping(float x, float y, int img_w, int img_h, + int format, int type, int zoomfilter, void *rect, + float clip_min_x, float clip_min_y, + float clip_max_x, float clip_max_y) { if (U.image_draw_method != IMAGE_DRAW_METHOD_DRAWPIXELS) { glColor4f(1.0, 1.0, 1.0, 1.0); - glaDrawPixelsTex(x, y, img_w, img_h, format, type, zoomfilter, rect); + glaDrawPixelsTex_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect, + clip_min_x, clip_min_y, clip_max_x, clip_max_y); } else { glaDrawPixelsSafe(x, y, img_w, img_h, img_w, format, type, rect); } } +void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect) +{ + glaDrawPixelsAuto_clipping(x, y, img_w, img_h, format, type, zoomfilter, rect, + 0.0f, 0.0f, 0.0f, 0.0f); +} + /* 2D Drawing Assistance */ void glaDefine2DArea(rcti *screen_rect) @@ -822,9 +866,11 @@ void bglPolygonOffset(float viewdist, float dist) /* **** Color management helper functions for GLSL display/transform ***** */ /* Draw given image buffer on a screen using GLSL for display transform */ -void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, - ColorManagedViewSettings *view_settings, - ColorManagedDisplaySettings *display_settings) +void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter, + ColorManagedViewSettings *view_settings, + ColorManagedDisplaySettings *display_settings, + float clip_min_x, float clip_min_y, + float clip_max_x, float clip_max_y) { bool force_fallback = false; bool need_fallback = true; @@ -874,14 +920,16 @@ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, BLI_assert(!"Incompatible number of channels for GLSL display"); if (format != 0) { - glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, format, GL_FLOAT, - zoomfilter, ibuf->rect_float); + glaDrawPixelsTex_clipping(x, y, ibuf->x, ibuf->y, format, GL_FLOAT, + zoomfilter, ibuf->rect_float, + clip_min_x, clip_min_y, clip_max_x, clip_max_y); } } else if (ibuf->rect) { /* ibuf->rect is always RGBA */ - glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, - zoomfilter, ibuf->rect); + glaDrawPixelsTex_clipping(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, + zoomfilter, ibuf->rect, + clip_min_x, clip_min_y, clip_max_x, clip_max_y); } IMB_colormanagement_finish_glsl_draw(); @@ -897,21 +945,43 @@ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle); - if (display_buffer) - glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, display_buffer); + if (display_buffer) { + glaDrawPixelsAuto_clipping(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, + zoomfilter, display_buffer, + clip_min_x, clip_min_y, clip_max_x, clip_max_y); + } IMB_display_buffer_release(cache_handle); } } -void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter) +void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, + ColorManagedViewSettings *view_settings, + ColorManagedDisplaySettings *display_settings) +{ + glaDrawImBuf_glsl_clipping(ibuf, x, y, zoomfilter, view_settings, display_settings, + 0.0f, 0.0f, 0.0f, 0.0f); +} + +void glaDrawImBuf_glsl_ctx_clipping(const bContext *C, + ImBuf *ibuf, + float x, float y, + int zoomfilter, + float clip_min_x, float clip_min_y, + float clip_max_x, float clip_max_y) { ColorManagedViewSettings *view_settings; ColorManagedDisplaySettings *display_settings; IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings); - glaDrawImBuf_glsl(ibuf, x, y, zoomfilter, view_settings, display_settings); + glaDrawImBuf_glsl_clipping(ibuf, x, y, zoomfilter, view_settings, display_settings, + clip_min_x, clip_min_y, clip_max_x, clip_max_y); +} + +void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter) +{ + glaDrawImBuf_glsl_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f); } void cpack(unsigned int x) -- cgit v1.2.3