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.
This commit is contained in:
@@ -143,6 +143,8 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect);
|
void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect);
|
||||||
|
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* glaDrawPixelsAuto - Switches between texture or pixel drawing using UserDef.
|
* glaDrawPixelsAuto - Switches between texture or pixel drawing using UserDef.
|
||||||
@@ -150,9 +152,13 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int ty
|
|||||||
* needs glaDefine2DArea to be set.
|
* needs glaDefine2DArea to be set.
|
||||||
*/
|
*/
|
||||||
void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect);
|
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);
|
||||||
|
|
||||||
|
|
||||||
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(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);
|
||||||
|
|
||||||
/* 2D Drawing Assistance */
|
/* 2D Drawing Assistance */
|
||||||
|
|
||||||
@@ -205,9 +211,21 @@ void bgl_get_mats(bglMats *mats);
|
|||||||
void glaDrawImBuf_glsl(struct ImBuf *ibuf, float x, float y, int zoomfilter,
|
void glaDrawImBuf_glsl(struct ImBuf *ibuf, float x, float y, int zoomfilter,
|
||||||
struct ColorManagedViewSettings *view_settings,
|
struct ColorManagedViewSettings *view_settings,
|
||||||
struct ColorManagedDisplaySettings *display_settings);
|
struct ColorManagedDisplaySettings *display_settings);
|
||||||
|
void glaDrawImBuf_glsl_clipping(struct ImBuf *ibuf, float x, float y, int zoomfilter,
|
||||||
|
struct ColorManagedViewSettings *view_settings,
|
||||||
|
struct ColorManagedDisplaySettings *display_settings,
|
||||||
|
float clip_min_x, float clip_min_y,
|
||||||
|
float clip_max_x, float clip_max_y);
|
||||||
|
|
||||||
|
|
||||||
/* Draw imbuf on a screen, preferably using GLSL display transform */
|
/* Draw imbuf on a screen, preferably using GLSL display transform */
|
||||||
void glaDrawImBuf_glsl_ctx(const struct bContext *C, struct ImBuf *ibuf, float x, float y, int zoomfilter);
|
void glaDrawImBuf_glsl_ctx(const struct bContext *C, struct ImBuf *ibuf, float x, float y, int zoomfilter);
|
||||||
|
void glaDrawImBuf_glsl_ctx_clipping(const struct bContext *C,
|
||||||
|
struct ImBuf *ibuf,
|
||||||
|
float x, float y,
|
||||||
|
int zoomfilter,
|
||||||
|
float clip_min_x, float clip_min_y,
|
||||||
|
float clip_max_x, float clip_max_y);
|
||||||
|
|
||||||
void glaDrawBorderCorners(const struct rcti *border, float zoomx, float zoomy);
|
void glaDrawBorderCorners(const struct rcti *border, float zoomx, float zoomy);
|
||||||
|
|
||||||
|
@@ -368,7 +368,11 @@ static int get_cached_work_texture(int *r_w, int *r_h)
|
|||||||
return texid;
|
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;
|
unsigned char *uc_rect = (unsigned char *) rect;
|
||||||
const float *f_rect = (float *)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 seamless, offset_x, offset_y, nsubparts_x, nsubparts_y;
|
||||||
int texid = get_cached_work_texture(&tex_w, &tex_h);
|
int texid = get_cached_work_texture(&tex_w, &tex_h);
|
||||||
int components;
|
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.
|
/* Specify the color outside this function, and tex will modulate it.
|
||||||
* This is useful for changing alpha without using glPixelTransferf()
|
* 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;
|
int offset_top = (seamless && remainder_y > tex_h) ? 1 : 0;
|
||||||
float rast_x = x + subpart_x * offset_x * xzoom;
|
float rast_x = x + subpart_x * offset_x * xzoom;
|
||||||
float rast_y = y + subpart_y * offset_y * yzoom;
|
float rast_y = y + subpart_y * offset_y * yzoom;
|
||||||
|
|
||||||
/* check if we already got these because we always get 2 more when doing seamless */
|
/* check if we already got these because we always get 2 more when doing seamless */
|
||||||
if (subpart_w <= seamless || subpart_h <= seamless)
|
if (subpart_w <= seamless || subpart_h <= seamless)
|
||||||
continue;
|
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) {
|
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]);
|
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
|
#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)
|
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)
|
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 */
|
/* 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) {
|
if (U.image_draw_method != IMAGE_DRAW_METHOD_DRAWPIXELS) {
|
||||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
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 {
|
else {
|
||||||
glaDrawPixelsSafe(x, y, img_w, img_h, img_w, format, type, rect);
|
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 */
|
/* 2D Drawing Assistance */
|
||||||
|
|
||||||
void glaDefine2DArea(rcti *screen_rect)
|
void glaDefine2DArea(rcti *screen_rect)
|
||||||
@@ -822,9 +866,11 @@ void bglPolygonOffset(float viewdist, float dist)
|
|||||||
/* **** Color management helper functions for GLSL display/transform ***** */
|
/* **** Color management helper functions for GLSL display/transform ***** */
|
||||||
|
|
||||||
/* Draw given image buffer on a screen using GLSL for 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,
|
void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter,
|
||||||
ColorManagedViewSettings *view_settings,
|
ColorManagedViewSettings *view_settings,
|
||||||
ColorManagedDisplaySettings *display_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 force_fallback = false;
|
||||||
bool need_fallback = true;
|
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");
|
BLI_assert(!"Incompatible number of channels for GLSL display");
|
||||||
|
|
||||||
if (format != 0) {
|
if (format != 0) {
|
||||||
glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, format, GL_FLOAT,
|
glaDrawPixelsTex_clipping(x, y, ibuf->x, ibuf->y, format, GL_FLOAT,
|
||||||
zoomfilter, ibuf->rect_float);
|
zoomfilter, ibuf->rect_float,
|
||||||
|
clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ibuf->rect) {
|
else if (ibuf->rect) {
|
||||||
/* ibuf->rect is always RGBA */
|
/* ibuf->rect is always RGBA */
|
||||||
glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
|
glaDrawPixelsTex_clipping(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
zoomfilter, ibuf->rect);
|
zoomfilter, ibuf->rect,
|
||||||
|
clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMB_colormanagement_finish_glsl_draw();
|
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);
|
display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle);
|
||||||
|
|
||||||
if (display_buffer)
|
if (display_buffer) {
|
||||||
glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, 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);
|
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;
|
ColorManagedViewSettings *view_settings;
|
||||||
ColorManagedDisplaySettings *display_settings;
|
ColorManagedDisplaySettings *display_settings;
|
||||||
|
|
||||||
IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &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)
|
void cpack(unsigned int x)
|
||||||
|
@@ -526,7 +526,12 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B)) == 0) {
|
if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B)) == 0) {
|
||||||
glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
|
int clip_max_x, clip_max_y;
|
||||||
|
UI_view2d_view_to_region(&ar->v2d,
|
||||||
|
ar->v2d.cur.xmax, ar->v2d.cur.ymax,
|
||||||
|
&clip_max_x, &clip_max_y);
|
||||||
|
glaDrawImBuf_glsl_ctx_clipping(C, ibuf, x, y, GL_NEAREST,
|
||||||
|
0, 0, clip_max_x, clip_max_y);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned char *display_buffer;
|
unsigned char *display_buffer;
|
||||||
|
Reference in New Issue
Block a user