diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 88484e071c5..7a7c68a724d 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -134,6 +134,7 @@ data_to_c_simple(shaders/gpu_shader_2D_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_flat_color_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_smooth_color_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_smooth_color_frag.glsl SRC) +data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_depth_linear_frag.glsl SRC) diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 4084e3d4180..cf7e00d682c 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -107,6 +107,7 @@ typedef enum GPUBuiltinShader { GPU_SHADER_3D_SMOOTH_COLOR, GPU_SHADER_3D_DEPTH_ONLY, /* basic image drawing */ + GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR, GPU_SHADER_3D_IMAGE_MODULATE_ALPHA, GPU_SHADER_3D_IMAGE_RECT_MODULATE_ALPHA, GPU_SHADER_3D_IMAGE_DEPTH, diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 382faacb4f6..4f6206bf11f 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -55,6 +55,7 @@ extern char datatoc_gpu_shader_2D_flat_color_vert_glsl[]; extern char datatoc_gpu_shader_2D_smooth_color_vert_glsl[]; extern char datatoc_gpu_shader_2D_smooth_color_frag_glsl[]; extern char datatoc_gpu_shader_3D_image_vert_glsl[]; +extern char datatoc_gpu_shader_image_mask_uniform_color_frag_glsl[]; extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[]; extern char datatoc_gpu_shader_image_rect_modulate_alpha_frag_glsl[]; extern char datatoc_gpu_shader_image_depth_linear_frag_glsl[]; @@ -122,6 +123,7 @@ static struct GPUShadersGlobal { GPUShader *edges_overlay_simple; GPUShader *edges_overlay; /* for drawing images */ + GPUShader *image_mask_uniform_color_2D; GPUShader *image_modulate_alpha_3D; GPUShader *image_rect_modulate_alpha_3D; GPUShader *image_depth_3D; @@ -721,6 +723,14 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) NULL, NULL, 0, 0, 0); retval = GG.shaders.edges_overlay; break; + case GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR: + if (!GG.shaders.image_mask_uniform_color_2D) + GG.shaders.image_mask_uniform_color_2D = GPU_shader_create( + datatoc_gpu_shader_3D_image_vert_glsl, + datatoc_gpu_shader_image_mask_uniform_color_frag_glsl, + NULL, NULL, NULL, 0, 0, 0); + retval = GG.shaders.image_mask_uniform_color_2D; + break; case GPU_SHADER_3D_IMAGE_MODULATE_ALPHA: if (!GG.shaders.image_modulate_alpha_3D) GG.shaders.image_modulate_alpha_3D = GPU_shader_create( @@ -1028,6 +1038,11 @@ void GPU_shader_free_builtin_shaders(void) GG.shaders.edges_overlay = NULL; } + if (GG.shaders.image_mask_uniform_color_2D) { + GPU_shader_free(GG.shaders.image_mask_uniform_color_2D); + GG.shaders.image_mask_uniform_color_2D = NULL; + } + if (GG.shaders.image_modulate_alpha_3D) { GPU_shader_free(GG.shaders.image_modulate_alpha_3D); GG.shaders.image_modulate_alpha_3D = NULL; diff --git a/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl new file mode 100644 index 00000000000..e78779559a1 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl @@ -0,0 +1,18 @@ + +#if __VERSION__ == 120 + varying vec2 texCoord_interp; + #define fragColor gl_FragColor +#else + in vec2 texCoord_interp; + out vec4 fragColor; + #define texture2D texture +#endif + +uniform sampler2D image; +uniform vec4 color; + +void main() +{ + fragColor.a = texture2D(image, texCoord_interp).a * color.a; + fragColor.rgb = color.rgb; +} diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index a132d323a8c..7c68a0ce438 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -98,6 +98,7 @@ #include "ED_view3d.h" #include "GPU_basic_shader.h" +#include "GPU_immediate.h" #include "RNA_access.h" #include "RNA_define.h" @@ -2988,8 +2989,8 @@ static void radial_control_set_tex(RadialControl *rc) if ((ibuf = BKE_brush_gen_radial_control_imbuf(rc->image_id_ptr.data, rc->use_secondary_tex))) { glGenTextures(1, &rc->gltex); glBindTexture(GL_TEXTURE_2D, rc->gltex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, ibuf->x, ibuf->y, 0, - GL_ALPHA, GL_FLOAT, ibuf->rect_float); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, ibuf->x, ibuf->y, 0, + GL_RED, GL_FLOAT, ibuf->rect_float); MEM_freeN(ibuf->rect_float); MEM_freeN(ibuf); } @@ -3022,13 +3023,26 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph RNA_property_float_get_array(fill_ptr, fill_prop, col); } - glColor4f(col[0], col[1], col[2], alpha); + + VertexFormat *format = immVertexFormat(); + unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); if (rc->gltex) { + + unsigned texCoord = add_attrib(format, "texCoord", GL_FLOAT, 2, KEEP_FLOAT); + glBindTexture(GL_TEXTURE_2D, rc->gltex); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + GLint swizzleMask[] = {GL_ZERO, GL_ZERO, GL_ZERO, GL_RED}; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); + + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR); + + immUniform4f("color", col[0], col[1], col[2], alpha); + immUniform1i("image", GL_TEXTURE0); /* set up rotation if available */ if (rc->rot_prop) { @@ -3038,18 +3052,21 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph } /* draw textured quad */ - GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(-radius, -radius); - glTexCoord2f(1, 0); - glVertex2f(radius, -radius); - glTexCoord2f(1, 1); - glVertex2f(radius, radius); - glTexCoord2f(0, 1); - glVertex2f(-radius, radius); - glEnd(); - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); + immBegin(GL_QUADS, 4); + + immAttrib2f(texCoord, 0, 0); + immVertex2f(pos, -radius, -radius); + + immAttrib2f(texCoord, 1, 0); + immVertex2f(pos, radius, -radius); + + immAttrib2f(texCoord, 1, 1); + immVertex2f(pos, radius, radius); + + immAttrib2f(texCoord, 0, 1); + immVertex2f(pos, -radius, radius); + + immEnd(); /* undo rotation */ if (rc->rot_prop) @@ -3057,8 +3074,12 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph } else { /* flat color if no texture available */ - glutil_draw_filled_arc(0, M_PI * 2, radius, 40); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor3fvAlpha(col, alpha); + imm_draw_filled_circle(pos, 0.0f, 0.0f, radius, 40); } + + immUnbindProgram(); } static void radial_control_paint_cursor(bContext *C, int x, int y, void *customdata) @@ -3134,24 +3155,38 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd /* set line color */ if (rc->col_prop) RNA_property_float_get_array(&rc->col_ptr, rc->col_prop, col); - glColor4f(col[0], col[1], col[2], 0.5); + + VertexFormat *format = immVertexFormat(); + unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor3fvAlpha(col, 0.5); if (rc->subtype == PROP_ANGLE) { glPushMatrix(); + /* draw original angle line */ glRotatef(RAD2DEGF(rc->initial_value), 0, 0, 1); - fdrawline((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f); + immBegin(GL_LINES, 2); + immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f); + immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f); + immEnd(); + /* draw new angle line */ glRotatef(RAD2DEGF(rc->current_value - rc->initial_value), 0, 0, 1); - fdrawline((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f); + immBegin(GL_LINES, 2); + immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f); + immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f); + immEnd(); + glPopMatrix(); } /* draw circles on top */ - glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r1, 40); - glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r2, 40); + imm_draw_lined_circle(pos, 0.0f, 0.0f, r1, 40); + imm_draw_lined_circle(pos, 0.0f, 0.0f, r2, 40); if (rmin > 0.0f) - glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), rmin, 40); + imm_draw_lined_circle(pos, 0.0, 0.0f, rmin, 40); BLF_size(fontid, 1.5 * fstyle_points * U.pixelsize, U.dpi); BLF_enable(fontid, BLF_SHADOW); @@ -3167,6 +3202,8 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); + + immUnbindProgram(); } typedef enum {