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:
-rw-r--r--source/blender/editors/include/BIF_glutil.h30
-rw-r--r--source/blender/editors/interface/interface_icons.c21
-rw-r--r--source/blender/editors/screen/glutil.c69
3 files changed, 106 insertions, 14 deletions
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 8f2a189e35e..8546c3eae89 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -55,6 +55,36 @@ typedef struct IMMDrawPixelsTexState {
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin);
/**
+ * Unlike the other `immDrawPixelsTex` functions, this doesn't do tiled drawing, but draws into a
+ * full texture.
+ *
+ * Use the currently bound shader.
+ *
+ * Use #immDrawPixelsTexSetup to bind the shader you want before calling #immDrawPixelsTex.
+ *
+ * If using a special shader double check it uses the same attributes "pos" "texCoord" and uniform
+ * "image".
+ *
+ * If color is NULL then use white by default
+ *
+ * Unless <em>state->do_shader_unbind<em> is explicitly set to `false`, the shader is unbound when
+ * finished.
+ */
+void immDrawPixelsTexScaledFullSize(const IMMDrawPixelsTexState *state,
+ const float x,
+ const float y,
+ const int img_w,
+ const int img_h,
+ const eGPUTextureFormat gpu_format,
+ const bool use_filter,
+ const void *rect,
+ const float scaleX,
+ const float scaleY,
+ const float xzoom,
+ const float yzoom,
+ const float color[4]);
+
+/**
* #immDrawPixelsTex - Functions like a limited #glDrawPixels, but actually draws the
* image using textures, which can be tremendously faster on low-end
* cards, and also avoids problems with the raster position being
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index ca5d08ba40e..085b7d04be9 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1546,7 +1546,7 @@ static void icon_draw_rect_fast(float x,
immUniform1f("factor", desaturate);
}
- immDrawPixelsTexScaled(
+ immDrawPixelsTexScaledFullSize(
&state, draw_x, draw_y, rw, rh, GPU_RGBA8, true, rect, scale_x, scale_y, 1.0f, 1.0f, col);
}
@@ -1561,7 +1561,6 @@ static void icon_draw_rect(float x,
float alpha,
const float desaturate)
{
- ImBuf *ima = NULL;
int draw_w = w;
int draw_h = h;
int draw_x = x;
@@ -1577,6 +1576,8 @@ static void icon_draw_rect(float x,
/* modulate color */
const float col[4] = {alpha, alpha, alpha, alpha};
+ float scale_x = 1.0f;
+ float scale_y = 1.0f;
/* rect contains image in 'rendersize', we only scale if needed */
if (rw != w || rh != h) {
/* preserve aspect ratio and center */
@@ -1590,13 +1591,9 @@ static void icon_draw_rect(float x,
draw_h = h;
draw_x += (w - draw_w) / 2;
}
+ scale_x = draw_w / (float)rw;
+ scale_y = draw_h / (float)rh;
/* If the image is squared, the `draw_*` initialization values are good. */
-
- /* first allocate imbuf for scaling and copy preview into it */
- ima = IMB_allocImBuf(rw, rh, 32, IB_rect);
- memcpy(ima->rect, rect, rw * rh * sizeof(uint));
- IMB_scaleImBuf(ima, draw_w, draw_h); /* scale it */
- rect = ima->rect;
}
/* draw */
@@ -1613,12 +1610,8 @@ static void icon_draw_rect(float x,
immUniform1f("factor", desaturate);
}
- immDrawPixelsTex(
- &state, draw_x, draw_y, draw_w, draw_h, GPU_RGBA8, false, rect, 1.0f, 1.0f, col);
-
- if (ima) {
- IMB_freeImBuf(ima);
- }
+ immDrawPixelsTexScaledFullSize(
+ &state, draw_x, draw_y, rw, rh, GPU_RGBA8, true, rect, scale_x, scale_y, 1.0f, 1.0f, col);
}
/* High enough to make a difference, low enough so that
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 5f523df18d1..cb5c5df20ec 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -72,6 +72,75 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
return state;
}
+void immDrawPixelsTexScaledFullSize(const IMMDrawPixelsTexState *state,
+ const float x,
+ const float y,
+ const int img_w,
+ const int img_h,
+ const eGPUTextureFormat gpu_format,
+ const bool use_filter,
+ const void *rect,
+ const float scaleX,
+ const float scaleY,
+ const float xzoom,
+ const float yzoom,
+ const float color[4])
+{
+ const static float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float draw_width = img_w * scaleX * xzoom;
+ const float draw_height = img_h * scaleY * yzoom;
+ /* Downscaling with regular bilinear interpolation (i.e. #GL_LINEAR) doesn't give good filtering
+ * results. Mipmaps can be used to get better results (i.e. #GL_LINEAR_MIPMAP_LINEAR), so always
+ * use mipmaps when filtering. */
+ const bool use_mipmap = use_filter && ((draw_width < img_w) || (draw_height < img_h));
+
+ GPUTexture *tex = GPU_texture_create_2d("immDrawPixels", img_w, img_h, 1, gpu_format, NULL);
+
+ const bool use_float_data = ELEM(gpu_format, GPU_RGBA16F, GPU_RGB16F, GPU_R16F);
+ eGPUDataFormat gpu_data_format = (use_float_data) ? GPU_DATA_FLOAT : GPU_DATA_UBYTE;
+ GPU_texture_update(tex, gpu_data_format, rect);
+
+ GPU_texture_filter_mode(tex, use_filter);
+ if (use_mipmap) {
+ GPU_texture_generate_mipmap(tex);
+ GPU_texture_mipmap_mode(tex, true, true);
+ }
+ GPU_texture_wrap_mode(tex, false, true);
+
+ GPU_texture_bind(tex, 0);
+
+ /* optional */
+ /* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since
+ * it does not need color.
+ */
+ if (state->shader != NULL && GPU_shader_get_uniform(state->shader, "color") != -1) {
+ immUniformColor4fv((color) ? color : white);
+ }
+
+ uint pos = state->pos, texco = state->texco;
+
+ immBegin(GPU_PRIM_TRI_FAN, 4);
+ immAttr2f(texco, 0.0f, 0.0f);
+ immVertex2f(pos, x, y);
+
+ immAttr2f(texco, 1.0f, 0.0f);
+ immVertex2f(pos, x + draw_width, y);
+
+ immAttr2f(texco, 1.0f, 1.0f);
+ immVertex2f(pos, x + draw_width, y + draw_height);
+
+ immAttr2f(texco, 0.0f, 1.0f);
+ immVertex2f(pos, x, y + draw_height);
+ immEnd();
+
+ if (state->do_shader_unbind) {
+ immUnbindProgram();
+ }
+
+ GPU_texture_unbind(tex);
+ GPU_texture_free(tex);
+}
+
void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float x,
float y,