diff options
Diffstat (limited to 'source/blender/editors/interface/interface_draw.c')
-rw-r--r-- | source/blender/editors/interface/interface_draw.c | 1713 |
1 files changed, 1063 insertions, 650 deletions
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 17dc9710756..f093f47519c 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -50,19 +50,21 @@ #include "IMB_imbuf_types.h" #include "IMB_colormanagement.h" -#include "BIF_gl.h" #include "BIF_glutil.h" #include "BLF_api.h" -#include "GPU_draw.h" -#include "GPU_basic_shader.h" +#include "GPU_batch.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" +#include "GPU_matrix.h" #include "UI_interface.h" /* own include */ #include "interface_intern.h" + static int roundboxtype = UI_CNR_ALL; void UI_draw_roundbox_corner_set(int type) @@ -71,336 +73,558 @@ void UI_draw_roundbox_corner_set(int type) * if this is undone, it's not that big a deal, only makes curves edges * square for the */ roundboxtype = type; - } +#if 0 /* unused */ int UI_draw_roundbox_corner_get(void) { return roundboxtype; } +#endif + +void UI_draw_roundbox_3ubAlpha(bool filled, float minx, float miny, float maxx, float maxy, float rad, const unsigned char col[3], unsigned char alpha) +{ + float colv[4]; + colv[0] = ((float)col[0]) / 255; + colv[1] = ((float)col[1]) / 255; + colv[2] = ((float)col[2]) / 255; + colv[3] = ((float)alpha) / 255; + UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv); +} + +void UI_draw_roundbox_3fvAlpha(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[3], float alpha) +{ + float colv[4]; + colv[0] = col[0]; + colv[1] = col[1]; + colv[2] = col[2]; + colv[3] = alpha; + UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv); +} -void UI_draw_roundbox_gl_mode(int mode, float minx, float miny, float maxx, float maxy, float rad) +void UI_draw_roundbox_aa(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4]) { + uiWidgetBaseParameters widget_params = { + .recti.xmin = minx, .recti.ymin = miny, + .recti.xmax = maxx, .recti.ymax = maxy, + .radi = rad, + .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f, + .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f, + .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f, + .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f, + .color_inner1[0] = color[0], .color_inner2[0] = color[0], + .color_inner1[1] = color[1], .color_inner2[1] = color[1], + .color_inner1[2] = color[2], .color_inner2[2] = color[2], + .color_inner1[3] = color[3], .color_inner2[3] = color[3], + .alpha_discard = 1.0f, + }; + + glEnable(GL_BLEND); + + if (filled) { + /* plain antialiased filled box */ + widget_params.color_inner1[3] *= 0.125f; + widget_params.color_inner2[3] *= 0.125f; + + /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space. + * If it has been scaled, then it's no longer valid. */ + Gwn_Batch *batch = ui_batch_roundbox_get(filled, true); + GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GWN_batch_draw(batch); + } + else { + /* plain antialiased unfilled box */ + glEnable(GL_LINE_SMOOTH); + + Gwn_Batch *batch = ui_batch_roundbox_get(filled, false); + GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GWN_batch_draw(batch); + + glDisable(GL_LINE_SMOOTH); + } + + glDisable(GL_BLEND); +} + +void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[4]) +{ +#if 0 float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; int a; + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + /* mult */ for (a = 0; a < 7; a++) { mul_v2_fl(vec[a], rad); } - glBegin(mode); + unsigned int vert_ct = 0; + vert_ct += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1; + vert_ct += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1; + vert_ct += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1; + vert_ct += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1; + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4fv(col); + immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_ct); /* start with corner right-bottom */ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) { - glVertex2f(maxx - rad, miny); + immVertex2f(pos, maxx - rad, miny); for (a = 0; a < 7; a++) { - glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]); + immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]); } - glVertex2f(maxx, miny + rad); + immVertex2f(pos, maxx, miny + rad); } else { - glVertex2f(maxx, miny); + immVertex2f(pos, maxx, miny); } /* corner right-top */ if (roundboxtype & UI_CNR_TOP_RIGHT) { - glVertex2f(maxx, maxy - rad); + immVertex2f(pos, maxx, maxy - rad); for (a = 0; a < 7; a++) { - glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]); + immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]); } - glVertex2f(maxx - rad, maxy); + immVertex2f(pos, maxx - rad, maxy); } else { - glVertex2f(maxx, maxy); + immVertex2f(pos, maxx, maxy); } /* corner left-top */ if (roundboxtype & UI_CNR_TOP_LEFT) { - glVertex2f(minx + rad, maxy); + immVertex2f(pos, minx + rad, maxy); for (a = 0; a < 7; a++) { - glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]); + immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]); } - glVertex2f(minx, maxy - rad); + immVertex2f(pos, minx, maxy - rad); } else { - glVertex2f(minx, maxy); + immVertex2f(pos, minx, maxy); } /* corner left-bottom */ if (roundboxtype & UI_CNR_BOTTOM_LEFT) { - glVertex2f(minx, miny + rad); + immVertex2f(pos, minx, miny + rad); for (a = 0; a < 7; a++) { - glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]); + immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]); } - glVertex2f(minx + rad, miny); + immVertex2f(pos, minx + rad, miny); } else { - glVertex2f(minx, miny); + immVertex2f(pos, minx, miny); } - glEnd(); + immEnd(); + immUnbindProgram(); +#endif + + uiWidgetBaseParameters widget_params = { + .recti.xmin = minx, .recti.ymin = miny, + .recti.xmax = maxx, .recti.ymax = maxy, + .radi = rad, + .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f, + .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f, + .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f, + .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f, + .color_inner1[0] = col[0], .color_inner2[0] = col[0], + .color_inner1[1] = col[1], .color_inner2[1] = col[1], + .color_inner1[2] = col[2], .color_inner2[2] = col[2], + .color_inner1[3] = col[3], .color_inner2[3] = col[3], + .alpha_discard = 1.0f, + }; + + Gwn_Batch *batch = ui_batch_roundbox_get(filled, false); + GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GWN_batch_draw(batch); } -static void round_box_shade_col(const float col1[3], float const col2[3], const float fac) +#if 0 +static void round_box_shade_col(unsigned attrib, const float col1[3], float const col2[3], const float fac) { - float col[3] = { + float col[4] = { fac * col1[0] + (1.0f - fac) * col2[0], fac * col1[1] + (1.0f - fac) * col2[1], - fac * col1[2] + (1.0f - fac) * col2[2] + fac * col1[2] + (1.0f - fac) * col2[2], + 1.0f }; - glColor3fv(col); + immAttrib4fv(attrib, col); } +#endif /* linear horizontal shade within button or in outline */ /* view2d scrollers use it */ void UI_draw_roundbox_shade_x( - int mode, float minx, float miny, float maxx, float maxy, - float rad, float shadetop, float shadedown) + bool filled, float minx, float miny, float maxx, float maxy, + float rad, float shadetop, float shadedown, const float col[4]) { +#if 0 float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; const float div = maxy - miny; const float idiv = 1.0f / div; - float coltop[3], coldown[3], color[4]; + float coltop[3], coldown[3]; + int vert_count = 0; int a; + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); + /* mult */ for (a = 0; a < 7; a++) { mul_v2_fl(vec[a], rad); } - /* get current color, needs to be outside of glBegin/End */ - glGetFloatv(GL_CURRENT_COLOR, color); /* 'shade' defines strength of shading */ - coltop[0] = min_ff(1.0f, color[0] + shadetop); - coltop[1] = min_ff(1.0f, color[1] + shadetop); - coltop[2] = min_ff(1.0f, color[2] + shadetop); - coldown[0] = max_ff(0.0f, color[0] + shadedown); - coldown[1] = max_ff(0.0f, color[1] + shadedown); - coldown[2] = max_ff(0.0f, color[2] + shadedown); + coltop[0] = min_ff(1.0f, col[0] + shadetop); + coltop[1] = min_ff(1.0f, col[1] + shadetop); + coltop[2] = min_ff(1.0f, col[2] + shadetop); + coldown[0] = max_ff(0.0f, col[0] + shadedown); + coldown[1] = max_ff(0.0f, col[1] + shadedown); + coldown[2] = max_ff(0.0f, col[2] + shadedown); + + vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1; + vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1; + vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1; + vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1; - glBegin(mode); + immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_count); /* start with corner right-bottom */ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) { - round_box_shade_col(coltop, coldown, 0.0); - glVertex2f(maxx - rad, miny); + round_box_shade_col(color, coltop, coldown, 0.0); + immVertex2f(pos, maxx - rad, miny); for (a = 0; a < 7; a++) { - round_box_shade_col(coltop, coldown, vec[a][1] * idiv); - glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]); + round_box_shade_col(color, coltop, coldown, vec[a][1] * idiv); + immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]); } - round_box_shade_col(coltop, coldown, rad * idiv); - glVertex2f(maxx, miny + rad); + round_box_shade_col(color, coltop, coldown, rad * idiv); + immVertex2f(pos, maxx, miny + rad); } else { - round_box_shade_col(coltop, coldown, 0.0); - glVertex2f(maxx, miny); + round_box_shade_col(color, coltop, coldown, 0.0); + immVertex2f(pos, maxx, miny); } /* corner right-top */ if (roundboxtype & UI_CNR_TOP_RIGHT) { - round_box_shade_col(coltop, coldown, (div - rad) * idiv); - glVertex2f(maxx, maxy - rad); + round_box_shade_col(color, coltop, coldown, (div - rad) * idiv); + immVertex2f(pos, maxx, maxy - rad); for (a = 0; a < 7; a++) { - round_box_shade_col(coltop, coldown, (div - rad + vec[a][1]) * idiv); - glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]); + round_box_shade_col(color, coltop, coldown, (div - rad + vec[a][1]) * idiv); + immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]); } - round_box_shade_col(coltop, coldown, 1.0); - glVertex2f(maxx - rad, maxy); + round_box_shade_col(color, coltop, coldown, 1.0); + immVertex2f(pos, maxx - rad, maxy); } else { - round_box_shade_col(coltop, coldown, 1.0); - glVertex2f(maxx, maxy); + round_box_shade_col(color, coltop, coldown, 1.0); + immVertex2f(pos, maxx, maxy); } /* corner left-top */ if (roundboxtype & UI_CNR_TOP_LEFT) { - round_box_shade_col(coltop, coldown, 1.0); - glVertex2f(minx + rad, maxy); + round_box_shade_col(color, coltop, coldown, 1.0); + immVertex2f(pos, minx + rad, maxy); for (a = 0; a < 7; a++) { - round_box_shade_col(coltop, coldown, (div - vec[a][1]) * idiv); - glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]); + round_box_shade_col(color, coltop, coldown, (div - vec[a][1]) * idiv); + immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]); } - round_box_shade_col(coltop, coldown, (div - rad) * idiv); - glVertex2f(minx, maxy - rad); + round_box_shade_col(color, coltop, coldown, (div - rad) * idiv); + immVertex2f(pos, minx, maxy - rad); } else { - round_box_shade_col(coltop, coldown, 1.0); - glVertex2f(minx, maxy); + round_box_shade_col(color, coltop, coldown, 1.0); + immVertex2f(pos, minx, maxy); } /* corner left-bottom */ if (roundboxtype & UI_CNR_BOTTOM_LEFT) { - round_box_shade_col(coltop, coldown, rad * idiv); - glVertex2f(minx, miny + rad); + round_box_shade_col(color, coltop, coldown, rad * idiv); + immVertex2f(pos, minx, miny + rad); for (a = 0; a < 7; a++) { - round_box_shade_col(coltop, coldown, (rad - vec[a][1]) * idiv); - glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]); + round_box_shade_col(color, coltop, coldown, (rad - vec[a][1]) * idiv); + immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]); } - round_box_shade_col(coltop, coldown, 0.0); - glVertex2f(minx + rad, miny); + round_box_shade_col(color, coltop, coldown, 0.0); + immVertex2f(pos, minx + rad, miny); } else { - round_box_shade_col(coltop, coldown, 0.0); - glVertex2f(minx, miny); + round_box_shade_col(color, coltop, coldown, 0.0); + immVertex2f(pos, minx, miny); } - glEnd(); + immEnd(); + immUnbindProgram(); +#endif + + uiWidgetBaseParameters widget_params = { + .recti.xmin = minx, .recti.ymin = miny, + .recti.xmax = maxx, .recti.ymax = maxy, + .radi = rad, + .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f, + .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f, + .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f, + .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f, + .color_inner1[0] = min_ff(1.0f, col[0] + shadetop), + .color_inner2[0] = max_ff(0.0f, col[0] + shadedown), + .color_inner1[1] = min_ff(1.0f, col[1] + shadetop), + .color_inner2[1] = max_ff(0.0f, col[1] + shadedown), + .color_inner1[2] = min_ff(1.0f, col[2] + shadetop), + .color_inner2[2] = max_ff(0.0f, col[2] + shadedown), + .color_inner1[3] = 1.0f, + .color_inner2[3] = 1.0f, + .alpha_discard = 1.0f, + }; + + Gwn_Batch *batch = ui_batch_roundbox_get(filled, false); + GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GWN_batch_draw(batch); } +#if 0 /* unused */ /* linear vertical shade within button or in outline */ /* view2d scrollers use it */ void UI_draw_roundbox_shade_y( - int mode, float minx, float miny, float maxx, float maxy, - float rad, float shadeLeft, float shadeRight) + bool filled, float minx, float miny, float maxx, float maxy, + float rad, float shadeleft, float shaderight, const float col[4]) { float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; const float div = maxx - minx; const float idiv = 1.0f / div; - float colLeft[3], colRight[3], color[4]; + float colLeft[3], colRight[3]; + int vert_count = 0; int a; /* mult */ for (a = 0; a < 7; a++) { mul_v2_fl(vec[a], rad); } - /* get current color, needs to be outside of glBegin/End */ - glGetFloatv(GL_CURRENT_COLOR, color); + + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); /* 'shade' defines strength of shading */ - colLeft[0] = min_ff(1.0f, color[0] + shadeLeft); - colLeft[1] = min_ff(1.0f, color[1] + shadeLeft); - colLeft[2] = min_ff(1.0f, color[2] + shadeLeft); - colRight[0] = max_ff(0.0f, color[0] + shadeRight); - colRight[1] = max_ff(0.0f, color[1] + shadeRight); - colRight[2] = max_ff(0.0f, color[2] + shadeRight); + colLeft[0] = min_ff(1.0f, col[0] + shadeleft); + colLeft[1] = min_ff(1.0f, col[1] + shadeleft); + colLeft[2] = min_ff(1.0f, col[2] + shadeleft); + colRight[0] = max_ff(0.0f, col[0] + shaderight); + colRight[1] = max_ff(0.0f, col[1] + shaderight); + colRight[2] = max_ff(0.0f, col[2] + shaderight); + + + vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1; + vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1; + vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1; + vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1; - glBegin(mode); + immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_count); /* start with corner right-bottom */ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) { - round_box_shade_col(colLeft, colRight, 0.0); - glVertex2f(maxx - rad, miny); + round_box_shade_col(color, colLeft, colRight, 0.0); + immVertex2f(pos, maxx - rad, miny); for (a = 0; a < 7; a++) { - round_box_shade_col(colLeft, colRight, vec[a][0] * idiv); - glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]); + round_box_shade_col(color, colLeft, colRight, vec[a][0] * idiv); + immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]); } - round_box_shade_col(colLeft, colRight, rad * idiv); - glVertex2f(maxx, miny + rad); + round_box_shade_col(color, colLeft, colRight, rad * idiv); + immVertex2f(pos, maxx, miny + rad); } else { - round_box_shade_col(colLeft, colRight, 0.0); - glVertex2f(maxx, miny); + round_box_shade_col(color, colLeft, colRight, 0.0); + immVertex2f(pos, maxx, miny); } /* corner right-top */ if (roundboxtype & UI_CNR_TOP_RIGHT) { - round_box_shade_col(colLeft, colRight, 0.0); - glVertex2f(maxx, maxy - rad); + round_box_shade_col(color, colLeft, colRight, 0.0); + immVertex2f(pos, maxx, maxy - rad); for (a = 0; a < 7; a++) { - round_box_shade_col(colLeft, colRight, (div - rad - vec[a][0]) * idiv); - glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]); + round_box_shade_col(color, colLeft, colRight, (div - rad - vec[a][0]) * idiv); + immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]); } - round_box_shade_col(colLeft, colRight, (div - rad) * idiv); - glVertex2f(maxx - rad, maxy); + round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv); + immVertex2f(pos, maxx - rad, maxy); } else { - round_box_shade_col(colLeft, colRight, 0.0); - glVertex2f(maxx, maxy); + round_box_shade_col(color, colLeft, colRight, 0.0); + immVertex2f(pos, maxx, maxy); } /* corner left-top */ if (roundboxtype & UI_CNR_TOP_LEFT) { - round_box_shade_col(colLeft, colRight, (div - rad) * idiv); - glVertex2f(minx + rad, maxy); + round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv); + immVertex2f(pos, minx + rad, maxy); for (a = 0; a < 7; a++) { - round_box_shade_col(colLeft, colRight, (div - rad + vec[a][0]) * idiv); - glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]); + round_box_shade_col(color, colLeft, colRight, (div - rad + vec[a][0]) * idiv); + immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]); } - round_box_shade_col(colLeft, colRight, 1.0); - glVertex2f(minx, maxy - rad); + round_box_shade_col(color, colLeft, colRight, 1.0); + immVertex2f(pos, minx, maxy - rad); } else { - round_box_shade_col(colLeft, colRight, 1.0); - glVertex2f(minx, maxy); + round_box_shade_col(color, colLeft, colRight, 1.0); + immVertex2f(pos, minx, maxy); } /* corner left-bottom */ if (roundboxtype & UI_CNR_BOTTOM_LEFT) { - round_box_shade_col(colLeft, colRight, 1.0); - glVertex2f(minx, miny + rad); + round_box_shade_col(color, colLeft, colRight, 1.0); + immVertex2f(pos, minx, miny + rad); for (a = 0; a < 7; a++) { - round_box_shade_col(colLeft, colRight, (vec[a][0]) * idiv); - glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]); + round_box_shade_col(color, colLeft, colRight, (vec[a][0]) * idiv); + immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]); } - round_box_shade_col(colLeft, colRight, 1.0); - glVertex2f(minx + rad, miny); + round_box_shade_col(color, colLeft, colRight, 1.0); + immVertex2f(pos, minx + rad, miny); } else { - round_box_shade_col(colLeft, colRight, 1.0); - glVertex2f(minx, miny); + round_box_shade_col(color, colLeft, colRight, 1.0); + immVertex2f(pos, minx, miny); } - glEnd(); + immEnd(); + immUnbindProgram(); } +#endif /* unused */ -/* plain antialiased unfilled rectangle */ -void UI_draw_roundbox_unfilled(float minx, float miny, float maxx, float maxy, float rad) +void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4]) { - float color[4]; - - if (roundboxtype & UI_RB_ALPHA) { - glGetFloatv(GL_CURRENT_COLOR, color); - color[3] = 0.5; - glColor4fv(color); - glEnable(GL_BLEND); - } + int ofs_y = 4 * U.pixelsize; - /* set antialias line */ - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); - UI_draw_roundbox_gl_mode(GL_LINE_LOOP, minx, miny, maxx, maxy, rad); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4fv(color); - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); + immRecti(pos, pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize)); + immUnbindProgram(); } -/* (old, used in outliner) plain antialiased filled box */ -void UI_draw_roundbox(float minx, float miny, float maxx, float maxy, float rad) -{ - ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad, roundboxtype & UI_RB_ALPHA); -} +/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */ -void UI_draw_text_underline(int pos_x, int pos_y, int len, int height) +/* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */ +void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highlight[3], unsigned char highlight_fade[3]) { - int ofs_y = 4 * U.pixelsize; - glRecti(pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize)); -} + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + /* add a 1px offset, looks nicer */ + const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize; + const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize; + int a; + float vec[4][2] = { + {0.195, 0.02}, + {0.55, 0.169}, + {0.831, 0.45}, + {0.98, 0.805}, + }; -/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */ + + /* mult */ + for (a = 0; a < 4; a++) { + mul_v2_fl(vec[a], rad); + } + + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); + immBeginAtMost(GWN_PRIM_LINE_STRIP, 25); + + immAttrib3ubv(col, highlight); + + /* start with corner left-top */ + if (roundboxtype & UI_CNR_TOP_LEFT) { + immVertex2f(pos, minx, maxy - rad); + for (a = 0; a < 4; a++) { + immVertex2f(pos, minx + vec[a][1], maxy - rad + vec[a][0]); + } + immVertex2f(pos, minx + rad, maxy); + } + else { + immVertex2f(pos, minx, maxy); + } + + /* corner right-top */ + if (roundboxtype & UI_CNR_TOP_RIGHT) { + immVertex2f(pos, maxx - rad, maxy); + for (a = 0; a < 4; a++) { + immVertex2f(pos, maxx - rad + vec[a][0], maxy - vec[a][1]); + } + immVertex2f(pos, maxx, maxy - rad); + } + else { + immVertex2f(pos, maxx, maxy); + } + + immAttrib3ubv(col, highlight_fade); + + /* corner right-bottom */ + if (roundboxtype & UI_CNR_BOTTOM_RIGHT) { + immVertex2f(pos, maxx, miny + rad); + for (a = 0; a < 4; a++) { + immVertex2f(pos, maxx - vec[a][1], miny + rad - vec[a][0]); + } + immVertex2f(pos, maxx - rad, miny); + } + else { + immVertex2f(pos, maxx, miny); + } + + /* corner left-bottom */ + if (roundboxtype & UI_CNR_BOTTOM_LEFT) { + immVertex2f(pos, minx + rad, miny); + for (a = 0; a < 4; a++) { + immVertex2f(pos, minx + rad - vec[a][0], miny + vec[a][1]); + } + immVertex2f(pos, minx, miny + rad); + } + else { + immVertex2f(pos, minx, miny); + } + + immAttrib3ubv(col, highlight); + + /* back to corner left-top */ + immVertex2f(pos, minx, roundboxtype & UI_CNR_TOP_LEFT ? maxy - rad : maxy); + + immEnd(); + immUnbindProgram(); +} void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect) { @@ -412,31 +636,30 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w if (!ibuf) return; + float facx = 1.0f; + float facy = 1.0f; + int w = BLI_rcti_size_x(rect); int h = BLI_rcti_size_y(rect); /* scissor doesn't seem to be doing the right thing...? */ #if 0 - //glColor4f(1.0, 0.f, 0.f, 1.f); - //fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax) - /* prevent drawing outside widget area */ GLint scissor[4]; glGetIntegerv(GL_SCISSOR_BOX, scissor); - glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin + rect->ymin, w, h); + glScissor(rect->xmin, rect->ymin, w, h); #endif glEnable(GL_BLEND); - glColor4f(0.0, 0.0, 0.0, 0.0); if (w != ibuf->x || h != ibuf->y) { - float facx = (float)w / (float)ibuf->x; - float facy = (float)h / (float)ibuf->y; - glPixelZoom(facx, facy); + facx = (float)w / (float)ibuf->x; + facy = (float)h / (float)ibuf->y; } - glaDrawPixelsAuto((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect); - glPixelZoom(1.0f, 1.0f); + IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); + immDrawPixelsTex(&state, (float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect, + facx, facy, NULL); glDisable(GL_BLEND); @@ -451,43 +674,34 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w /** * Draw title and text safe areas. * - * The first 4 parameters are the offsets for the view, not the zones. + * \Note This functionn is to be used with the 2D dashed shader enabled. + * + * \param pos is a PRIM_FLOAT, 2, GWN_FETCH_FLOAT vertex attrib + * \param line_origin is a PRIM_FLOAT, 2, GWN_FETCH_FLOAT vertex attrib + * + * The next 4 parameters are the offsets for the view, not the zones. */ void UI_draw_safe_areas( - float x1, float x2, float y1, float y2, + uint pos, float x1, float x2, float y1, float y2, const float title_aspect[2], const float action_aspect[2]) { const float size_x_half = (x2 - x1) * 0.5f; const float size_y_half = (y2 - y1) * 0.5f; const float *safe_areas[] = {title_aspect, action_aspect}; - int safe_len = ARRAY_SIZE(safe_areas); - bool is_first = true; + const int safe_len = ARRAY_SIZE(safe_areas); for (int i = 0; i < safe_len; i++) { if (safe_areas[i][0] || safe_areas[i][1]) { - float margin_x, margin_y; - float minx, miny, maxx, maxy; - - if (is_first) { - UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0); - is_first = false; - } + float margin_x = safe_areas[i][0] * size_x_half; + float margin_y = safe_areas[i][1] * size_y_half; - margin_x = safe_areas[i][0] * size_x_half; - margin_y = safe_areas[i][1] * size_y_half; + float minx = x1 + margin_x; + float miny = y1 + margin_y; + float maxx = x2 - margin_x; + float maxy = y2 - margin_y; - minx = x1 + margin_x; - miny = y1 + margin_y; - maxx = x2 - margin_x; - maxy = y2 - margin_y; - - glBegin(GL_LINE_LOOP); - glVertex2f(maxx, miny); - glVertex2f(maxx, maxy); - glVertex2f(minx, maxy); - glVertex2f(minx, miny); - glEnd(); + imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy); } } } @@ -498,55 +712,63 @@ static void draw_scope_end(const rctf *rect, GLint *scissor) /* restore scissortest */ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* outline */ - glColor4f(0.f, 0.f, 0.f, 0.5f); UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f); + float color[4] = {0.0f, 0.0f, 0.0f, 0.5f}; + UI_draw_roundbox_4fv(false, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f, color); } static void histogram_draw_one( float r, float g, float b, float alpha, - float x, float y, float w, float h, const float *data, int res, const bool is_line) + float x, float y, float w, float h, const float *data, int res, const bool is_line, + unsigned int pos_attrib) { + float color[4] = {r, g, b, alpha}; + + /* that can happen */ + if (res == 0) + return; + glEnable(GL_LINE_SMOOTH); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glColor4f(r, g, b, alpha); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE); + + immUniformColor4fv(color); if (is_line) { /* curve outline */ glLineWidth(1.5); - glBegin(GL_LINE_STRIP); + immBegin(GWN_PRIM_LINE_STRIP, res); for (int i = 0; i < res; i++) { float x2 = x + i * (w / (float)res); - glVertex2f(x2, y + (data[i] * h)); + immVertex2f(pos_attrib, x2, y + (data[i] * h)); } - glEnd(); + immEnd(); } else { /* under the curve */ - glBegin(GL_TRIANGLE_STRIP); - glVertex2f(x, y); - glVertex2f(x, y + (data[0] * h)); + immBegin(GWN_PRIM_TRI_STRIP, res * 2); + immVertex2f(pos_attrib, x, y); + immVertex2f(pos_attrib, x, y + (data[0] * h)); for (int i = 1; i < res; i++) { float x2 = x + i * (w / (float)res); - glVertex2f(x2, y + (data[i] * h)); - glVertex2f(x2, y); + immVertex2f(pos_attrib, x2, y + (data[i] * h)); + immVertex2f(pos_attrib, x2, y); } - glEnd(); + immEnd(); /* curve outline */ - glColor4f(0.f, 0.f, 0.f, 0.25f); + immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBegin(GL_LINE_STRIP); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + immBegin(GWN_PRIM_LINE_STRIP, res); for (int i = 0; i < res; i++) { float x2 = x + i * (w / (float)res); - glVertex2f(x2, y + (data[i] * h)); + immVertex2f(pos_attrib, x2, y + (data[i] * h)); } - glEnd(); + immEnd(); } glDisable(GL_LINE_SMOOTH); @@ -554,7 +776,7 @@ static void histogram_draw_one( #define HISTOGRAM_TOT_GRID_LINES 4 -void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) +void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) { Histogram *hist = (Histogram *)but->poin; int res = hist->x_resolution; @@ -571,56 +793,90 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) float h = BLI_rctf_size_y(&rect) * hist->ymax; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - UI_ThemeColor4(TH_PREVIEW_BACK); + float color[4]; + UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color); /* need scissor test, histogram can draw outside of boundary */ GLint scissor[4]; - glGetIntegerv(GL_VIEWPORT, scissor); - glScissor(ar->winrct.xmin + (rect.xmin - 1), - ar->winrct.ymin + (rect.ymin - 1), + glGetIntegerv(GL_SCISSOR_BOX, scissor); + glScissor((rect.xmin - 1), + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); - glColor4f(1.f, 1.f, 1.f, 0.08f); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f); /* draw grid lines here */ for (int i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) { const float fac = (float)i / (float)HISTOGRAM_TOT_GRID_LINES; /* so we can tell the 1.0 color point */ if (i == HISTOGRAM_TOT_GRID_LINES) { - glColor4f(1.0f, 1.0f, 1.0f, 0.5f); + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); } - fdrawline(rect.xmin, rect.ymin + fac * h, rect.xmax, rect.ymin + fac * h); - fdrawline(rect.xmin + fac * w, rect.ymin, rect.xmin + fac * w, rect.ymax); + immBegin(GWN_PRIM_LINES, 4); + + immVertex2f(pos, rect.xmin, rect.ymin + fac * h); + immVertex2f(pos, rect.xmax, rect.ymin + fac * h); + + immVertex2f(pos, rect.xmin + fac * w, rect.ymin); + immVertex2f(pos, rect.xmin + fac * w, rect.ymax); + + immEnd(); } if (hist->mode == HISTO_MODE_LUMA) { - histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line); + histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line, pos); } else if (hist->mode == HISTO_MODE_ALPHA) { - histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line); + histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line, pos); } else { if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R) - histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line); + histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line, pos); if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G) - histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line); + histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line, pos); if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B) - histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line); + histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line, pos); } + immUnbindProgram(); + /* outline */ draw_scope_end(&rect, scissor); } #undef HISTOGRAM_TOT_GRID_LINES -void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) +static void waveform_draw_one(float *waveform, int nbr, const float col[3]) +{ + Gwn_VertFormat format = {0}; + unsigned int pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + + Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GWN_vertbuf_data_alloc(vbo, nbr); + + GWN_vertbuf_attr_fill(vbo, pos_id, waveform); + + /* TODO store the Gwn_Batch inside the scope */ + Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO); + GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR); + GWN_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f); + GWN_batch_draw(batch); + + GWN_batch_discard(batch); +} + +void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) { Scopes *scopes = (Scopes *)but->poin; GLint scissor[4]; @@ -642,7 +898,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), scopes->wavefrm_yfac = 0.98f; float w = BLI_rctf_size_x(&rect) - 7; float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac; - float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) / 2.0f; + float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f; float w3 = w / 3.0f; /* log scale for alpha */ @@ -657,108 +913,140 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), } } + /* Flush text cache before changing scissors. */ + BLF_batch_draw_flush(); + glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - UI_ThemeColor4(TH_PREVIEW_BACK); + float color[4]; + UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color); /* need scissor test, waveform can draw outside of boundary */ - glGetIntegerv(GL_VIEWPORT, scissor); - glScissor(ar->winrct.xmin + (rect.xmin - 1), - ar->winrct.ymin + (rect.ymin - 1), + glGetIntegerv(GL_SCISSOR_BOX, scissor); + glScissor((rect.xmin - 1), + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); - glColor4f(1.f, 1.f, 1.f, 0.08f); - /* draw grid lines here */ + /* draw scale numbers first before binding any shader */ for (int i = 0; i < 6; i++) { char str[4]; BLI_snprintf(str, sizeof(str), "%-3d", i * 20); str[3] = '\0'; - fdrawline(rect.xmin + 22, yofs + (i / 5.f) * h, rect.xmax + 1, yofs + (i / 5.f) * h); - BLF_draw_default(rect.xmin + 1, yofs - 5 + (i / 5.f) * h, 0, str, sizeof(str) - 1); - /* in the loop because blf_draw reset it */ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.08f); + BLF_draw_default(rect.xmin + 1, yofs - 5 + (i * 0.2f) * h, 0, str, sizeof(str) - 1); } + + /* Flush text cache before drawing things on top. */ + BLF_batch_draw_flush(); + + glEnable(GL_BLEND); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f); + + /* draw grid lines here */ + immBegin(GWN_PRIM_LINES, 12); + + for (int i = 0; i < 6; i++) { + immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h); + immVertex2f(pos, rect.xmax + 1, yofs + (i * 0.2f) * h); + } + + immEnd(); + /* 3 vertical separation */ if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) { + immBegin(GWN_PRIM_LINES, 4); + for (int i = 1; i < 3; i++) { - fdrawline(rect.xmin + i * w3, rect.ymin, rect.xmin + i * w3, rect.ymax); + immVertex2f(pos, rect.xmin + i * w3, rect.ymin); + immVertex2f(pos, rect.xmin + i * w3, rect.ymax); } + + immEnd(); } /* separate min max zone on the right */ - fdrawline(rect.xmin + w, rect.ymin, rect.xmin + w, rect.ymax); + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(pos, rect.xmin + w, rect.ymin); + immVertex2f(pos, rect.xmin + w, rect.ymax); + immEnd(); + /* 16-235-240 level in case of ITU-R BT601/709 */ - glColor4f(1.f, 0.4f, 0.f, 0.2f); + immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f); if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)) { - fdrawline(rect.xmin + 22, yofs + h * 16.0f / 255.0f, rect.xmax + 1, yofs + h * 16.0f / 255.0f); - fdrawline(rect.xmin + 22, yofs + h * 235.0f / 255.0f, rect.xmin + w3, yofs + h * 235.0f / 255.0f); - fdrawline(rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f, rect.xmax + 1, yofs + h * 235.0f / 255.0f); - fdrawline(rect.xmin + w3, yofs + h * 240.0f / 255.0f, rect.xmax + 1, yofs + h * 240.0f / 255.0f); + immBegin(GWN_PRIM_LINES, 8); + + immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f); + immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f); + + immVertex2f(pos, rect.xmin + 22, yofs + h * 235.0f / 255.0f); + immVertex2f(pos, rect.xmin + w3, yofs + h * 235.0f / 255.0f); + + immVertex2f(pos, rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f); + immVertex2f(pos, rect.xmax + 1, yofs + h * 235.0f / 255.0f); + + immVertex2f(pos, rect.xmin + w3, yofs + h * 240.0f / 255.0f); + immVertex2f(pos, rect.xmax + 1, yofs + h * 240.0f / 255.0f); + + immEnd(); } /* 7.5 IRE black point level for NTSC */ - if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) - fdrawline(rect.xmin, yofs + h * 0.075f, rect.xmax + 1, yofs + h * 0.075f); + if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) { + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(pos, rect.xmin, yofs + h * 0.075f); + immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f); + immEnd(); + } if (scopes->ok && scopes->waveform_1 != NULL) { - - /* LUMA (1 channel) */ glBlendFunc(GL_ONE, GL_ONE); - glColor3f(alpha, alpha, alpha); glPointSize(1.0); + /* LUMA (1 channel) */ if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) { + float col[3] = {alpha, alpha, alpha}; - glBlendFunc(GL_ONE, GL_ONE); + gpuPushMatrix(); + gpuTranslate2f(rect.xmin, yofs); + gpuScale2f(w, h); - glPushMatrix(); - glEnableClientState(GL_VERTEX_ARRAY); + waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col); - glTranslatef(rect.xmin, yofs, 0.f); - glScalef(w, h, 0.f); - glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1); - glDrawArrays(GL_POINTS, 0, scopes->waveform_tot); - - glDisableClientState(GL_VERTEX_ARRAY); - glPopMatrix(); + gpuPopMatrix(); /* min max */ - glColor3f(0.5f, 0.5f, 0.5f); + immUniformColor3f(0.5f, 0.5f, 0.5f); min = yofs + scopes->minmax[0][0] * h; max = yofs + scopes->minmax[0][1] * h; CLAMP(min, rect.ymin, rect.ymax); CLAMP(max, rect.ymin, rect.ymax); - fdrawline(rect.xmax - 3, min, rect.xmax - 3, max); + + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(pos, rect.xmax - 3, min); + immVertex2f(pos, rect.xmax - 3, max); + immEnd(); } /* RGB (3 channel) */ else if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) { - glBlendFunc(GL_ONE, GL_ONE); - - glEnableClientState(GL_VERTEX_ARRAY); - - glPushMatrix(); + gpuPushMatrix(); + gpuTranslate2f(rect.xmin, yofs); + gpuScale2f(w, h); - glTranslatef(rect.xmin, yofs, 0.f); - glScalef(w, h, 0.f); + waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, colors_alpha[0]); + waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, colors_alpha[1]); + waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, colors_alpha[2]); - glColor3fv( colors_alpha[0] ); - glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1); - glDrawArrays(GL_POINTS, 0, scopes->waveform_tot); - - glColor3fv( colors_alpha[1] ); - glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_2); - glDrawArrays(GL_POINTS, 0, scopes->waveform_tot); - - glColor3fv( colors_alpha[2] ); - glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_3); - glDrawArrays(GL_POINTS, 0, scopes->waveform_tot); - - glDisableClientState(GL_VERTEX_ARRAY); - glPopMatrix(); + gpuPopMatrix(); } /* PARADE / YCC (3 channels) */ else if (ELEM(scopes->wavefrm_mode, @@ -770,49 +1058,47 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), { int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE); - glBlendFunc(GL_ONE, GL_ONE); - - glPushMatrix(); - glEnableClientState(GL_VERTEX_ARRAY); + gpuPushMatrix(); + gpuTranslate2f(rect.xmin, yofs); + gpuScale2f(w3, h); - glTranslatef(rect.xmin, yofs, 0.f); - glScalef(w3, h, 0.f); + waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, (rgb) ? colors_alpha[0] : colorsycc_alpha[0]); - glColor3fv((rgb) ? colors_alpha[0] : colorsycc_alpha[0]); - glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1); - glDrawArrays(GL_POINTS, 0, scopes->waveform_tot); + gpuTranslate2f(1.0f, 0.0f); + waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, (rgb) ? colors_alpha[1] : colorsycc_alpha[1]); - glTranslatef(1.f, 0.f, 0.f); - glColor3fv((rgb) ? colors_alpha[1] : colorsycc_alpha[1]); - glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_2); - glDrawArrays(GL_POINTS, 0, scopes->waveform_tot); + gpuTranslate2f(1.0f, 0.0f); + waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, (rgb) ? colors_alpha[2] : colorsycc_alpha[2]); - glTranslatef(1.f, 0.f, 0.f); - glColor3fv((rgb) ? colors_alpha[2] : colorsycc_alpha[2]); - glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_3); - glDrawArrays(GL_POINTS, 0, scopes->waveform_tot); - - glDisableClientState(GL_VERTEX_ARRAY); - glPopMatrix(); + gpuPopMatrix(); } + /* min max */ if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA ) { for (int c = 0; c < 3; c++) { if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_RGB_PARADE, SCOPES_WAVEFRM_RGB)) - glColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f); + immUniformColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f); else - glColor3f(colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f); + immUniformColor3f(colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f); min = yofs + scopes->minmax[c][0] * h; max = yofs + scopes->minmax[c][1] * h; CLAMP(min, rect.ymin, rect.ymax); CLAMP(max, rect.ymin, rect.ymax); - fdrawline(rect.xmin + w + 2 + c * 2, min, rect.xmin + w + 2 + c * 2, max); + + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(pos, rect.xmin + w + 2 + c * 2, min); + immVertex2f(pos, rect.xmin + w + 2 + c * 2, max); + immEnd(); } } } + immUnbindProgram(); + /* outline */ draw_scope_end(&rect, scissor); + + glDisable(GL_BLEND); } static float polar_to_x(float center, float diam, float ampli, float angle) @@ -825,10 +1111,10 @@ static float polar_to_y(float center, float diam, float ampli, float angle) return center + diam * ampli * sinf(angle); } -static void vectorscope_draw_target(float centerx, float centery, float diam, const float colf[3]) +static void vectorscope_draw_target(unsigned int pos, float centerx, float centery, float diam, const float colf[3]) { float y, u, v; - float tangle = 0.f, tampli; + float tangle = 0.0f, tampli; float dangle, dampli, dangle2, dampli2; rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v, BLI_YUV_ITU_BT709); @@ -840,44 +1126,44 @@ static void vectorscope_draw_target(float centerx, float centery, float diam, co tampli = sqrtf(u * u + v * v); /* small target vary by 2.5 degree and 2.5 IRE unit */ - glColor4f(1.0f, 1.0f, 1.0, 0.12f); + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f); dangle = DEG2RADF(2.5f); dampli = 2.5f / 200.0f; - glBegin(GL_LINE_LOOP); - glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle)); - glEnd(); + immBegin(GWN_PRIM_LINE_LOOP, 4); + immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle)); + immEnd(); /* big target vary by 10 degree and 20% amplitude */ - glColor4f(1.0f, 1.0f, 1.0, 0.12f); + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f); dangle = DEG2RADF(10.0f); dampli = 0.2f * tampli; dangle2 = DEG2RADF(5.0f); dampli2 = 0.5f * dampli; - glBegin(GL_LINE_STRIP); - glVertex2f(polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle + dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle + dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli + dampli, tangle + dangle - dangle2)); - glEnd(); - glBegin(GL_LINE_STRIP); - glVertex2f(polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle + dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle + dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli - dampli, tangle + dangle - dangle2)); - glEnd(); - glBegin(GL_LINE_STRIP); - glVertex2f(polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle - dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle - dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli - dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli - dampli, tangle - dangle + dangle2)); - glEnd(); - glBegin(GL_LINE_STRIP); - glVertex2f(polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle - dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle - dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle)); - glVertex2f(polar_to_x(centerx, diam, tampli + dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli + dampli, tangle - dangle + dangle2)); - glEnd(); + immBegin(GWN_PRIM_LINE_STRIP, 3); + immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle + dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle + dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli + dampli, tangle + dangle - dangle2)); + immEnd(); + immBegin(GWN_PRIM_LINE_STRIP, 3); + immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle + dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle + dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli - dampli, tangle + dangle - dangle2)); + immEnd(); + immBegin(GWN_PRIM_LINE_STRIP, 3); + immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle - dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle - dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli - dampli, tangle - dangle + dangle2)); + immEnd(); + immBegin(GWN_PRIM_LINE_STRIP, 3); + immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle - dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle - dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle)); + immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli + dampli, tangle - dangle + dangle2)); + immEnd(); } -void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) +void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) { const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */ Scopes *scopes = (Scopes *)but->poin; @@ -895,114 +1181,131 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco float w = BLI_rctf_size_x(&rect); float h = BLI_rctf_size_y(&rect); - float centerx = rect.xmin + w / 2; - float centery = rect.ymin + h / 2; + float centerx = rect.xmin + w * 0.5f; + float centery = rect.ymin + h * 0.5f; float diam = (w < h) ? w : h; float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha; glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - UI_ThemeColor4(TH_PREVIEW_BACK); + float color[4]; + UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color); /* need scissor test, hvectorscope can draw outside of boundary */ GLint scissor[4]; - glGetIntegerv(GL_VIEWPORT, scissor); - glScissor(ar->winrct.xmin + (rect.xmin - 1), - ar->winrct.ymin + (rect.ymin - 1), + glGetIntegerv(GL_SCISSOR_BOX, scissor); + glScissor((rect.xmin - 1), + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); - glColor4f(1.f, 1.f, 1.f, 0.08f); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f); /* draw grid elements */ /* cross */ - fdrawline(centerx - (diam / 2) - 5, centery, centerx + (diam / 2) + 5, centery); - fdrawline(centerx, centery - (diam / 2) - 5, centerx, centery + (diam / 2) + 5); + immBegin(GWN_PRIM_LINES, 4); + + immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery); + immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery); + + immVertex2f(pos, centerx, centery - (diam * 0.5f) - 5); + immVertex2f(pos, centerx, centery + (diam * 0.5f) + 5); + + immEnd(); + /* circles */ for (int j = 0; j < 5; j++) { - glBegin(GL_LINE_LOOP); const int increment = 15; + immBegin(GWN_PRIM_LINE_LOOP, (int)(360 / increment)); for (int i = 0; i <= 360 - increment; i += increment) { const float a = DEG2RADF((float)i); - const float r = (j + 1) / 10.0f; - glVertex2f(polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a)); + const float r = (j + 1) * 0.1f; + immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a)); } - glEnd(); + immEnd(); } /* skin tone line */ - glColor4f(1.f, 0.4f, 0.f, 0.2f); - fdrawline(polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5, skin_rad), - polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1, skin_rad)); + immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f); + + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad)); + immVertex2f(pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad)); + immEnd(); + /* saturation points */ for (int i = 0; i < 6; i++) - vectorscope_draw_target(centerx, centery, diam, colors[i]); + vectorscope_draw_target(pos, centerx, centery, diam, colors[i]); if (scopes->ok && scopes->vecscope != NULL) { /* pixel point cloud */ - glBlendFunc(GL_ONE, GL_ONE); - glColor3f(alpha, alpha, alpha); + float col[3] = {alpha, alpha, alpha}; - glPushMatrix(); - glEnableClientState(GL_VERTEX_ARRAY); + glBlendFunc(GL_ONE, GL_ONE); + glPointSize(1.0); - glTranslatef(centerx, centery, 0.f); - glScalef(diam, diam, 0.f); + gpuPushMatrix(); + gpuTranslate2f(centerx, centery); + gpuScaleUniform(diam); - glVertexPointer(2, GL_FLOAT, 0, scopes->vecscope); - glPointSize(1.0); - glDrawArrays(GL_POINTS, 0, scopes->waveform_tot); + waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col); - glDisableClientState(GL_VERTEX_ARRAY); - glPopMatrix(); + gpuPopMatrix(); } + immUnbindProgram(); + /* outline */ draw_scope_end(&rect, scissor); glDisable(GL_BLEND); } -static void ui_draw_colorband_handle_tri_hlight(float x1, float y1, float halfwidth, float height) +static void ui_draw_colorband_handle_tri_hlight(unsigned int pos, float x1, float y1, float halfwidth, float height) { glEnable(GL_LINE_SMOOTH); - glBegin(GL_LINE_STRIP); - glVertex2f(x1 + halfwidth, y1); - glVertex2f(x1, y1 + height); - glVertex2f(x1 - halfwidth, y1); - glEnd(); + immBegin(GWN_PRIM_LINE_STRIP, 3); + immVertex2f(pos, x1 + halfwidth, y1); + immVertex2f(pos, x1, y1 + height); + immVertex2f(pos, x1 - halfwidth, y1); + immEnd(); glDisable(GL_LINE_SMOOTH); } -static void ui_draw_colorband_handle_tri(float x1, float y1, float halfwidth, float height, bool fill) +static void ui_draw_colorband_handle_tri(unsigned int pos, float x1, float y1, float halfwidth, float height, bool fill) { glEnable(fill ? GL_POLYGON_SMOOTH : GL_LINE_SMOOTH); - glBegin(fill ? GL_TRIANGLES : GL_LINE_LOOP); - glVertex2f(x1 + halfwidth, y1); - glVertex2f(x1, y1 + height); - glVertex2f(x1 - halfwidth, y1); - glEnd(); + immBegin(fill ? GWN_PRIM_TRIS : GWN_PRIM_LINE_LOOP, 3); + immVertex2f(pos, x1 + halfwidth, y1); + immVertex2f(pos, x1, y1 + height); + immVertex2f(pos, x1 - halfwidth, y1); + immEnd(); glDisable(fill ? GL_POLYGON_SMOOTH : GL_LINE_SMOOTH); } -static void ui_draw_colorband_handle_box(float x1, float y1, float x2, float y2, bool fill) +static void ui_draw_colorband_handle_box(unsigned int pos, float x1, float y1, float x2, float y2, bool fill) { - glBegin(fill ? GL_QUADS : GL_LINE_LOOP); - glVertex2f(x1, y1); - glVertex2f(x1, y2); - glVertex2f(x2, y2); - glVertex2f(x2, y1); - glEnd(); + immBegin(fill ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, 4); + immVertex2f(pos, x1, y1); + immVertex2f(pos, x1, y2); + immVertex2f(pos, x2, y2); + immVertex2f(pos, x2, y1); + immEnd(); } static void ui_draw_colorband_handle( - const rcti *rect, float x, + uint shdr_pos, const rcti *rect, float x, const float rgb[3], struct ColorManagedDisplay *display, bool active) { @@ -1021,18 +1324,26 @@ static void ui_draw_colorband_handle( y1 = floorf(y1 + 0.5f); if (active || half_width < min_width) { - glBegin(GL_LINES); - glColor3ub(0, 0, 0); - glVertex2f(x, y1); - glVertex2f(x, y2); - glEnd(); - setlinestyle(active ? 2 : 1); - glBegin(GL_LINES); - glColor3ub(200, 200, 200); - glVertex2f(x, y1); - glVertex2f(x, y2); - glEnd(); - setlinestyle(0); + immUnbindProgram(); + + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); + + float viewport_size[4]; + glGetFloatv(GL_VIEWPORT, viewport_size); + immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC); + + immUniform1i("num_colors", 2); /* "advanced" mode */ + immUniformArray4fv("colors", (float *)(float[][4]){{0.8f, 0.8f, 0.8f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); + immUniform1f("dash_width", active ? 4.0f : 2.0f); + + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(shdr_pos, x, y1); + immVertex2f(shdr_pos, x, y2); + immEnd(); + + immUnbindProgram(); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* hide handles when zoomed out too far */ if (half_width < min_width) { @@ -1043,45 +1354,46 @@ static void ui_draw_colorband_handle( /* shift handle down */ y1 -= half_width; - glColor3ub(0, 0, 0); - ui_draw_colorband_handle_box(x - half_width, y1 - 1, x + half_width, y1 + height, false); + immUniformColor3ub(0, 0, 0); + ui_draw_colorband_handle_box(shdr_pos, x - half_width, y1 - 1, x + half_width, y1 + height, false); /* draw all triangles blended */ glEnable(GL_BLEND); - ui_draw_colorband_handle_tri(x, y1 + height, half_width, half_width, true); + ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true); if (active) - glColor3ub(196, 196, 196); + immUniformColor3ub(196, 196, 196); else - glColor3ub(96, 96, 96); - ui_draw_colorband_handle_tri(x, y1 + height, half_width, half_width, true); + immUniformColor3ub(96, 96, 96); + ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true); if (active) - glColor3ub(255, 255, 255); + immUniformColor3ub(255, 255, 255); else - glColor3ub(128, 128, 128); - ui_draw_colorband_handle_tri_hlight(x, y1 + height - 1, (half_width - 1), (half_width - 1)); + immUniformColor3ub(128, 128, 128); + ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height - 1, (half_width - 1), (half_width - 1)); - glColor3ub(0, 0, 0); - ui_draw_colorband_handle_tri_hlight(x, y1 + height, half_width, half_width); + immUniformColor3ub(0, 0, 0); + ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height, half_width, half_width); glDisable(GL_BLEND); - glColor3ub(128, 128, 128); - ui_draw_colorband_handle_box(x - (half_width - 1), y1, x + (half_width - 1), y1 + height, true); + immUniformColor3ub(128, 128, 128); + ui_draw_colorband_handle_box(shdr_pos, x - (half_width - 1), y1, x + (half_width - 1), y1 + height, true); if (display) { IMB_colormanagement_scene_linear_to_display_v3(colf, display); } - glColor3fv(colf); - ui_draw_colorband_handle_box(x - (half_width - 2), y1 + 1, x + (half_width - 2), y1 + height - 2, true); + immUniformColor3fv(colf); + ui_draw_colorband_handle_box(shdr_pos, x - (half_width - 2), y1 + 1, x + (half_width - 2), y1 + height - 2, true); } void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect) { struct ColorManagedDisplay *display = NULL; + unsigned int position, color; ColorBand *coba = (ColorBand *)(but->editcoba ? but->editcoba : but->poin); if (coba == NULL) return; @@ -1092,20 +1404,25 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti float x1 = rect->xmin; float sizex = rect->xmax - x1; float sizey = BLI_rcti_size_y(rect); - float sizey_solid = sizey / 4; + float sizey_solid = sizey * 0.25f; float y1 = rect->ymin; - /* Drawing the checkerboard. - * This could be optimized with a single checkerboard shader, - * instead of drawing twice and using stippling the second time. */ - /* layer: background, to show tranparency */ - glColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255); - glRectf(x1, y1, x1 + sizex, rect->ymax); - GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); - glColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255); - GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_CHECKER_8PX); - glRectf(x1, y1, x1 + sizex, rect->ymax); - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); + Gwn_VertFormat *format = immVertexFormat(); + position = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_CHECKER); + + /* Drawing the checkerboard. */ + immUniform4f("color1", UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, 1.0f); + immUniform4f("color2", UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 1.0f); + immUniform1i("size", 8); + immRectf(position, x1, y1, x1 + sizex, rect->ymax); + immUnbindProgram(); + + /* New format */ + format = immVertexFormat(); + position = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); /* layer: color ramp */ glEnable(GL_BLEND); @@ -1118,7 +1435,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti v1[1] = y1 + sizey_solid; v2[1] = rect->ymax; - glBegin(GL_TRIANGLE_STRIP); + immBegin(GWN_PRIM_TRI_STRIP, (sizex + 1) * 2); for (int a = 0; a <= sizex; a++) { float pos = ((float)a) / sizex; BKE_colorband_evaluate(coba, pos, colf); @@ -1127,17 +1444,17 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti v1[0] = v2[0] = x1 + a; - glColor4fv(colf); - glVertex2fv(v1); - glVertex2fv(v2); + immAttrib4fv(color, colf); + immVertex2fv(position, v1); + immVertex2fv(position, v2); } - glEnd(); + immEnd(); /* layer: color ramp without alpha for reference when manipulating ramp properties */ v1[1] = y1; v2[1] = y1 + sizey_solid; - glBegin(GL_TRIANGLE_STRIP); + immBegin(GWN_PRIM_TRI_STRIP, (sizex + 1) * 2); for (int a = 0; a <= sizex; a++) { float pos = ((float)a) / sizex; BKE_colorband_evaluate(coba, pos, colf); @@ -1146,31 +1463,48 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti v1[0] = v2[0] = x1 + a; - glColor4f(colf[0], colf[1], colf[2], 1.0f); - glVertex2fv(v1); - glVertex2fv(v2); + immAttrib4f(color, colf[0], colf[1], colf[2], 1.0f); + immVertex2fv(position, v1); + immVertex2fv(position, v2); } - glEnd(); + immEnd(); + + immUnbindProgram(); glDisable(GL_BLEND); + /* New format */ + format = immVertexFormat(); + position = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + /* layer: box outline */ - glColor4f(0.0, 0.0, 0.0, 1.0); - fdrawbox(x1, y1, x1 + sizex, rect->ymax); + immUniformColor4f(0.0f, 0.0f, 0.0f, 1.0f); + imm_draw_box_wire_2d(position, x1, y1, x1 + sizex, rect->ymax); /* layer: box outline */ glEnable(GL_BLEND); - glColor4f(0.0f, 0.0f, 0.0f, 0.5f); - fdrawline(x1, y1, x1 + sizex, y1); - glColor4f(1.0f, 1.0f, 1.0f, 0.25f); - fdrawline(x1, y1 - 1, x1 + sizex, y1 - 1); + immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); + + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(position, x1, y1); + immVertex2f(position, x1 + sizex, y1); + immEnd(); + + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.25f); + + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(position, x1, y1 - 1); + immVertex2f(position, x1 + sizex, y1 - 1); + immEnd(); + glDisable(GL_BLEND); /* layer: draw handles */ for (int a = 0; a < coba->tot; a++, cbd++) { if (a != coba->cur) { float pos = x1 + cbd->pos * (sizex - 1) + 1; - ui_draw_colorband_handle(rect, pos, &cbd->r, display, false); + ui_draw_colorband_handle(position, rect, pos, &cbd->r, display, false); } } @@ -1178,117 +1512,100 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti if (coba->tot != 0) { cbd = &coba->data[coba->cur]; float pos = x1 + cbd->pos * (sizex - 1) + 1; - ui_draw_colorband_handle(rect, pos, &cbd->r, display, true); + ui_draw_colorband_handle(position, rect, pos, &cbd->r, display, true); } + + immUnbindProgram(); } void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect) { - static GLuint displist = 0; + /* sphere color */ float diffuse[3] = {1.0f, 1.0f, 1.0f}; + float light[3]; float size; /* backdrop */ - glColor3ubv((unsigned char *)wcol->inner); UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_gl_mode(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f); + UI_draw_roundbox_3ubAlpha(true, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f, (unsigned char *)wcol->inner, 255); - /* sphere color */ glCullFace(GL_BACK); glEnable(GL_CULL_FACE); /* setup lights */ - GPULightData light = {0}; - light.type = GPU_LIGHT_SUN; - copy_v3_v3(light.diffuse, diffuse); - zero_v3(light.specular); - ui_but_v3_get(but, light.direction); - - GPU_basic_shader_light_set(0, &light); - for (int a = 1; a < 8; a++) - GPU_basic_shader_light_set(a, NULL); - - /* setup shader */ - GPU_basic_shader_colors(diffuse, NULL, 0, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING); + ui_but_v3_get(but, light); /* transform to button */ - glPushMatrix(); - glTranslatef(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect), 0.0f); + gpuPushMatrix(); if (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect)) - size = BLI_rcti_size_x(rect) / 200.f; + size = 0.5f * BLI_rcti_size_x(rect); else - size = BLI_rcti_size_y(rect) / 200.f; + size = 0.5f * BLI_rcti_size_y(rect); - glScalef(size, size, MIN2(size, 1.0f)); + gpuTranslate2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect)); + gpuScaleUniform(size); - if (displist == 0) { - GLUquadricObj *qobj; - - displist = glGenLists(1); - glNewList(displist, GL_COMPILE); - - qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - GPU_basic_shader_bind(GPU_basic_shader_bound_options()); - gluSphere(qobj, 100.0, 32, 24); - gluDeleteQuadric(qobj); - - glEndList(); - } - - glCallList(displist); + Gwn_Batch *sphere = GPU_batch_preset_sphere(2); + GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING); + GWN_batch_uniform_4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f); + GWN_batch_uniform_3fv(sphere, "light", light); + GWN_batch_draw(sphere); /* restore */ - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - GPU_default_lights(); glDisable(GL_CULL_FACE); /* AA circle */ + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor3ubv((unsigned char *)wcol->inner); + glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); - glColor3ubv((unsigned char *)wcol->inner); - glutil_draw_lined_arc(0.0f, M_PI * 2.0, 100.0f, 32); + imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); /* matrix after circle */ - glPopMatrix(); + gpuPopMatrix(); - /* We disabled all blender lights above, so restore them here. */ - GPU_default_lights(); + immUnbindProgram(); } -static void ui_draw_but_curve_grid(const rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step) +static void ui_draw_but_curve_grid(unsigned int pos, const rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step) { - glBegin(GL_LINES); float dx = step * zoomx; float fx = rect->xmin + zoomx * (-offsx); if (fx > rect->xmin) fx -= dx * (floorf(fx - rect->xmin)); - while (fx < rect->xmax) { - glVertex2f(fx, rect->ymin); - glVertex2f(fx, rect->ymax); - fx += dx; - } float dy = step * zoomy; float fy = rect->ymin + zoomy * (-offsy); if (fy > rect->ymin) fy -= dy * (floorf(fy - rect->ymin)); + + float line_count = floorf((rect->xmax - fx) / dx) + 1.0f + + floorf((rect->ymax - fy) / dy) + 1.0f; + + immBegin(GWN_PRIM_LINES, (int)line_count * 2); + while (fx < rect->xmax) { + immVertex2f(pos, fx, rect->ymin); + immVertex2f(pos, fx, rect->ymax); + fx += dx; + } while (fy < rect->ymax) { - glVertex2f(rect->xmin, fy); - glVertex2f(rect->xmax, fy); + immVertex2f(pos, rect->xmin, fy); + immVertex2f(pos, rect->xmax, fy); fy += dy; } - glEnd(); + immEnd(); } static void gl_shaded_color(unsigned char *col, int shade) { - glColor3ub(col[0] - shade > 0 ? col[0] - shade : 0, - col[1] - shade > 0 ? col[1] - shade : 0, - col[2] - shade > 0 ? col[2] - shade : 0); + immUniformColor3ub(col[0] - shade > 0 ? col[0] - shade : 0, + col[1] - shade > 0 ? col[1] - shade : 0, + col[2] - shade > 0 ? col[2] - shade : 0); } void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti *rect) @@ -1306,14 +1623,15 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti /* need scissor test, curve can draw outside of boundary */ GLint scissor[4]; - glGetIntegerv(GL_VIEWPORT, scissor); + glGetIntegerv(GL_SCISSOR_BOX, scissor); rcti scissor_new = { - .xmin = ar->winrct.xmin + rect->xmin, - .ymin = ar->winrct.ymin + rect->ymin, - .xmax = ar->winrct.xmin + rect->xmax, - .ymax = ar->winrct.ymin + rect->ymax + .xmin = rect->xmin, + .ymin = rect->ymin, + .xmax = rect->xmax, + .ymax = rect->ymax }; - BLI_rcti_isect(&scissor_new, &ar->winrct, &scissor_new); + rcti scissor_region = {0, ar->winx, 0, ar->winy}; + BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new); glScissor(scissor_new.xmin, scissor_new.ymin, BLI_rcti_size_x(&scissor_new), @@ -1325,9 +1643,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti float offsx = cumap->curr.xmin - (1.0f / zoomx); float offsy = cumap->curr.ymin - (1.0f / zoomy); - glLineWidth(1.0f); - - /* backdrop */ + /* Do this first to not mess imm context */ if (but->a1 == UI_GRAD_H) { /* magic trigger for curve backgrounds */ float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */ @@ -1340,96 +1656,105 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti }; ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f); + } + + glLineWidth(1.0f); + + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + /* backdrop */ + if (but->a1 == UI_GRAD_H) { /* grid, hsv uses different grid */ glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4ub(0, 0, 0, 48); - ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.1666666f); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + immUniformColor4ub(0, 0, 0, 48); + ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f); glDisable(GL_BLEND); } else { if (cumap->flag & CUMA_DO_CLIP) { gl_shaded_color((unsigned char *)wcol->inner, -20); - glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax); - glColor3ubv((unsigned char *)wcol->inner); - glRectf(rect->xmin + zoomx * (cumap->clipr.xmin - offsx), - rect->ymin + zoomy * (cumap->clipr.ymin - offsy), - rect->xmin + zoomx * (cumap->clipr.xmax - offsx), - rect->ymin + zoomy * (cumap->clipr.ymax - offsy)); + immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax); + immUniformColor3ubv((unsigned char *)wcol->inner); + immRectf(pos, rect->xmin + zoomx * (cumap->clipr.xmin - offsx), + rect->ymin + zoomy * (cumap->clipr.ymin - offsy), + rect->xmin + zoomx * (cumap->clipr.xmax - offsx), + rect->ymin + zoomy * (cumap->clipr.ymax - offsy)); } else { - glColor3ubv((unsigned char *)wcol->inner); - glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax); + immUniformColor3ubv((unsigned char *)wcol->inner); + immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax); } /* grid, every 0.25 step */ gl_shaded_color((unsigned char *)wcol->inner, -16); - ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.25f); + ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f); /* grid, every 1.0 step */ gl_shaded_color((unsigned char *)wcol->inner, -24); - ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 1.0f); + ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f); /* axes */ gl_shaded_color((unsigned char *)wcol->inner, -50); - glBegin(GL_LINES); - glVertex2f(rect->xmin, rect->ymin + zoomy * (-offsy)); - glVertex2f(rect->xmax, rect->ymin + zoomy * (-offsy)); - glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymin); - glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymax); - glEnd(); + immBegin(GWN_PRIM_LINES, 4); + immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (-offsy)); + immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (-offsy)); + immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymin); + immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymax); + immEnd(); } /* cfra option */ /* XXX 2.48 */ #if 0 if (cumap->flag & CUMA_DRAW_CFRA) { - glColor3ub(0x60, 0xc0, 0x40); - glBegin(GL_LINES); - glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin); - glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax); - glEnd(); + immUniformColor3ub(0x60, 0xc0, 0x40); + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin); + immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax); + immEnd(); } #endif /* sample option */ if (cumap->flag & CUMA_DRAW_SAMPLE) { - glBegin(GL_LINES); /* will draw one of the following 3 lines */ + immBegin(GWN_PRIM_LINES, 2); /* will draw one of the following 3 lines */ if (but->a1 == UI_GRAD_H) { float tsample[3]; float hsv[3]; linearrgb_to_srgb_v3_v3(tsample, cumap->sample); rgb_to_hsv_v(tsample, hsv); - glColor3ub(240, 240, 240); + immUniformColor3ub(240, 240, 240); - glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin); - glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax); + immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin); + immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax); } else if (cumap->cur == 3) { float lum = IMB_colormanagement_get_luminance(cumap->sample); - glColor3ub(240, 240, 240); + immUniformColor3ub(240, 240, 240); - glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymin); - glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymax); + immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymin); + immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymax); } else { if (cumap->cur == 0) - glColor3ub(240, 100, 100); + immUniformColor3ub(240, 100, 100); else if (cumap->cur == 1) - glColor3ub(100, 240, 100); + immUniformColor3ub(100, 240, 100); else - glColor3ub(100, 100, 240); + immUniformColor3ub(100, 100, 240); - glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin); - glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax); + immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin); + immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax); } - glEnd(); + immEnd(); } /* the curve */ - glColor3ubv((unsigned char *)wcol->item); + immUniformColor3ubv((unsigned char *)wcol->item); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glBegin(GL_LINE_STRIP); + immBegin(GWN_PRIM_LINE_STRIP, (CM_TABLE + 1) + 2); if (cuma->table == NULL) curvemapping_changed(cumap, false); @@ -1438,55 +1763,70 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti /* first point */ if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { - glVertex2f(rect->xmin, rect->ymin + zoomy * (cmp[0].y - offsy)); + immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (cmp[0].y - offsy)); } else { float fx = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]); float fy = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]); - glVertex2f(fx, fy); + immVertex2f(pos, fx, fy); } for (int a = 0; a <= CM_TABLE; a++) { float fx = rect->xmin + zoomx * (cmp[a].x - offsx); float fy = rect->ymin + zoomy * (cmp[a].y - offsy); - glVertex2f(fx, fy); + immVertex2f(pos, fx, fy); } /* last point */ if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { - glVertex2f(rect->xmax, rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy)); + immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy)); } else { float fx = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]); float fy = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]); - glVertex2f(fx, fy); + immVertex2f(pos, fx, fy); } - glEnd(); + immEnd(); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); + immUnbindProgram(); /* the points, use aspect to make them visible on edges */ + format = immVertexFormat(); + pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); + cmp = cuma->curve; glPointSize(3.0f); - glBegin(GL_POINTS); + immBegin(GWN_PRIM_POINTS, cuma->totpoint); for (int a = 0; a < cuma->totpoint; a++) { + float color[4]; if (cmp[a].flag & CUMA_SELECT) - UI_ThemeColor(TH_TEXT_HI); + UI_GetThemeColor4fv(TH_TEXT_HI, color); else - UI_ThemeColor(TH_TEXT); + UI_GetThemeColor4fv(TH_TEXT, color); float fx = rect->xmin + zoomx * (cmp[a].x - offsx); float fy = rect->ymin + zoomy * (cmp[a].y - offsy); - glVertex2f(fx, fy); + immAttrib4fv(col, color); + immVertex2f(pos, fx, fy); } - glEnd(); + immEnd(); + immUnbindProgram(); /* restore scissortest */ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); /* outline */ - glColor3ubv((unsigned char *)wcol->outline); - fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); + format = immVertexFormat(); + pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + immUniformColor3ubv((unsigned char *)wcol->outline); + imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax); + + immUnbindProgram(); } -void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) +void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) { bool ok = false; MovieClipScopes *scopes = (MovieClipScopes *)but->poin; @@ -1502,20 +1842,20 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc int height = BLI_rctf_size_y(&rect); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* need scissor test, preview image can draw outside of boundary */ GLint scissor[4]; - glGetIntegerv(GL_VIEWPORT, scissor); - glScissor(ar->winrct.xmin + (rect.xmin - 1), - ar->winrct.ymin + (rect.ymin - 1), + glGetIntegerv(GL_SCISSOR_BOX, scissor); + glScissor((rect.xmin - 1), + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); if (scopes->track_disabled) { - glColor4f(0.7f, 0.3f, 0.3f, 0.3f); + float color[4] = {0.7f, 0.3f, 0.3f, 0.3f}; UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color); ok = true; } @@ -1542,62 +1882,72 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc } if (!ok && scopes->track_preview) { - glPushMatrix(); + gpuPushMatrix(); /* draw content of pattern area */ - glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, scissor[2], scissor[3]); + glScissor(rect.xmin, rect.ymin, scissor[2], scissor[3]); if (width > 0 && height > 0) { ImBuf *drawibuf = scopes->track_preview; + float col_sel[4], col_outline[4]; if (scopes->use_track_mask) { - glColor4f(0.0f, 0.0f, 0.0f, 0.3f); + float color[4] = {0.0f, 0.0f, 0.0f, 0.3f}; UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color); } - glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, - drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); + IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); + immDrawPixelsTex(&state, rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, drawibuf->rect, 1.0f, 1.0f, NULL); /* draw cross for pixel position */ - glTranslatef(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1], 0.f); - glScissor(ar->winrct.xmin + rect.xmin, - ar->winrct.ymin + rect.ymin, + gpuTranslate2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]); + glScissor(rect.xmin, + rect.ymin, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect)); - GPU_basic_shader_bind_enable(GPU_SHADER_LINE); - - for (int a = 0; a < 2; a++) { - if (a == 1) { - GPU_basic_shader_bind_enable(GPU_SHADER_STIPPLE); - GPU_basic_shader_line_stipple(3, 0xAAAA); - UI_ThemeColor(TH_SEL_MARKER); - } - else { - UI_ThemeColor(TH_MARKER_OUTLINE); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); + + UI_GetThemeColor4fv(TH_SEL_MARKER, col_sel); + UI_GetThemeColor4fv(TH_MARKER_OUTLINE, col_outline); + + /* Do stipple cross with geometry */ + immBegin(GWN_PRIM_LINES, 7 * 2 * 2); + float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f}; + for (int axe = 0; axe < 2; ++axe) { + for (int i = 0; i < 7; ++i) { + float x1 = pos_sel[i] * (1 - axe); + float y1 = pos_sel[i] * axe; + float x2 = pos_sel[i + 1] * (1 - axe); + float y2 = pos_sel[i + 1] * axe; + + if (i % 2 == 1) + immAttrib4fv(col, col_sel); + else + immAttrib4fv(col, col_outline); + + immVertex2f(pos, x1, y1); + immVertex2f(pos, x2, y2); } - - glBegin(GL_LINES); - glVertex2f(-10.0f, 0.0f); - glVertex2f(10.0f, 0.0f); - glVertex2f(0.0f, -10.0f); - glVertex2f(0.0f, 10.0f); - glEnd(); } + immEnd(); - GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); + immUnbindProgram(); } - glPopMatrix(); + gpuPopMatrix(); ok = true; } if (!ok) { - glColor4f(0.f, 0.f, 0.f, 0.3f); + float color[4] = {0.0f, 0.0f, 0.0f, 0.3f}; UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f); + UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color); } /* outline */ @@ -1628,88 +1978,139 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol GLint scissor[4]; /* need scissor test, can draw outside of boundary */ - glGetIntegerv(GL_VIEWPORT, scissor); + glGetIntegerv(GL_SCISSOR_BOX, scissor); rcti scissor_new = { - .xmin = ar->winrct.xmin + recti->xmin, - .ymin = ar->winrct.ymin + recti->ymin, - .xmax = ar->winrct.xmin + recti->xmax, - .ymax = ar->winrct.ymin + recti->ymax + .xmin = recti->xmin, + .ymin = recti->ymin, + .xmax = recti->xmax, + .ymax = recti->ymax }; - BLI_rcti_isect(&scissor_new, &ar->winrct, &scissor_new); + rcti scissor_region = {0, ar->winx, 0, ar->winy}; + + BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new); glScissor(scissor_new.xmin, scissor_new.ymin, BLI_rcti_size_x(&scissor_new), BLI_rcti_size_y(&scissor_new)); - glColor4ubv(but->col); - float x = 0.5f * (recti->xmin + recti->xmax); float y = 0.5f * (recti->ymin + recti->ymax); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4ubv(but->col); + glEnable(GL_BLEND); - glBegin(GL_POLYGON); + immBegin(GWN_PRIM_TRI_FAN, 16); for (int a = 0; a < 16; a++) - glVertex2f(x + size * si[a], y + size * co[a]); - glEnd(); + immVertex2f(pos, x + size * si[a], y + size * co[a]); + immEnd(); - glColor4ub(0, 0, 0, 150); + immUniformColor4ub(0, 0, 0, 150); glLineWidth(1); glEnable(GL_LINE_SMOOTH); - glBegin(GL_LINE_LOOP); + immBegin(GWN_PRIM_LINE_LOOP, 16); for (int a = 0; a < 16; a++) - glVertex2f(x + size * si[a], y + size * co[a]); - glEnd(); + immVertex2f(pos, x + size * si[a], y + size * co[a]); + immEnd(); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); + immUnbindProgram(); + /* restore scissortest */ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); } /* ****************************************************** */ +/* TODO: high quality UI drop shadows using GLSL shader and single draw call + * would replace / modify the following 3 functions - merwin + */ -static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha) +static void ui_shadowbox(unsigned pos, unsigned color, float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha) { + /* v1-_ + * | -_v2 + * | | + * | | + * | | + * v7_______v3____v4 + * \ | / + * \ | _v5 + * v8______v6_- + */ + const float v1[2] = {maxx, maxy - 0.3f * shadsize}; + const float v2[2] = {maxx + shadsize, maxy - 0.75f * shadsize}; + const float v3[2] = {maxx, miny}; + const float v4[2] = {maxx + shadsize, miny}; + + const float v5[2] = {maxx + 0.7f * shadsize, miny - 0.7f * shadsize}; + + const float v6[2] = {maxx, miny - shadsize}; + const float v7[2] = {minx + 0.3f * shadsize, miny}; + const float v8[2] = {minx + 0.5f * shadsize, miny - shadsize}; + /* right quad */ - glColor4ub(0, 0, 0, alpha); - glVertex2f(maxx, miny); - glVertex2f(maxx, maxy - 0.3f * shadsize); - glColor4ub(0, 0, 0, 0); - glVertex2f(maxx + shadsize, maxy - 0.75f * shadsize); - glVertex2f(maxx + shadsize, miny); + immAttrib4ub(color, 0, 0, 0, alpha); + immVertex2fv(pos, v3); + immVertex2fv(pos, v1); + immAttrib4ub(color, 0, 0, 0, 0); + immVertex2fv(pos, v2); + + immVertex2fv(pos, v2); + immVertex2fv(pos, v4); + immAttrib4ub(color, 0, 0, 0, alpha); + immVertex2fv(pos, v3); /* corner shape */ - glColor4ub(0, 0, 0, alpha); - glVertex2f(maxx, miny); - glColor4ub(0, 0, 0, 0); - glVertex2f(maxx + shadsize, miny); - glVertex2f(maxx + 0.7f * shadsize, miny - 0.7f * shadsize); - glVertex2f(maxx, miny - shadsize); + /* immAttrib4ub(color, 0, 0, 0, alpha); */ /* Not needed, done above in previous tri */ + immVertex2fv(pos, v3); + immAttrib4ub(color, 0, 0, 0, 0); + immVertex2fv(pos, v4); + immVertex2fv(pos, v5); + + immVertex2fv(pos, v5); + immVertex2fv(pos, v6); + immAttrib4ub(color, 0, 0, 0, alpha); + immVertex2fv(pos, v3); /* bottom quad */ - glColor4ub(0, 0, 0, alpha); - glVertex2f(minx + 0.3f * shadsize, miny); - glVertex2f(maxx, miny); - glColor4ub(0, 0, 0, 0); - glVertex2f(maxx, miny - shadsize); - glVertex2f(minx + 0.5f * shadsize, miny - shadsize); + /* immAttrib4ub(color, 0, 0, 0, alpha); */ /* Not needed, done above in previous tri */ + immVertex2fv(pos, v3); + immAttrib4ub(color, 0, 0, 0, 0); + immVertex2fv(pos, v6); + immVertex2fv(pos, v8); + + immVertex2fv(pos, v8); + immAttrib4ub(color, 0, 0, 0, alpha); + immVertex2fv(pos, v7); + immVertex2fv(pos, v3); } void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, float maxy) { glEnable(GL_BLEND); - glBegin(GL_QUADS); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); + + immBegin(GWN_PRIM_TRIS, 54); /* accumulated outline boxes to make shade not linear, is more pleasant */ - ui_shadowbox(minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8); - ui_shadowbox(minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8); - ui_shadowbox(minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8); + ui_shadowbox(pos, color, minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8); + ui_shadowbox(pos, color, minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8); + ui_shadowbox(pos, color, minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8); - glEnd(); + immEnd(); + + immUnbindProgram(); glDisable(GL_BLEND); } @@ -1719,8 +2120,8 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha { float rad; - if (radius > (BLI_rctf_size_y(rct) - 10.0f) / 2.0f) - rad = (BLI_rctf_size_y(rct) - 10.0f) / 2.0f; + if (radius > (BLI_rctf_size_y(rct) - 10.0f) * 0.5f) + rad = (BLI_rctf_size_y(rct) - 10.0f) * 0.5f; else rad = radius; @@ -1736,34 +2137,46 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha } glEnable(GL_BLEND); - const float dalpha = alpha * 2.0f / 255.0f; float calpha = dalpha; - for (; i--; a -= aspect) { + float visibility = 1.0f; + for (; i--;) { /* alpha ranges from 2 to 20 or so */ - glColor4f(0.0f, 0.0f, 0.0f, calpha); +#if 0 /* Old Method (pre 2.8) */ + float color[4] = {0.0f, 0.0f, 0.0f, calpha}; + UI_draw_roundbox_4fv(true, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a, color); +#endif + /* Compute final visibility to match old method result. */ + /* TODO we could just find a better fit function inside the shader instead of this. */ + visibility = visibility * (1.0f - calpha); calpha += dalpha; - - UI_draw_roundbox_gl_mode(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a); } + uiWidgetBaseParameters widget_params = { + .recti.xmin = rct->xmin, .recti.ymin = rct->ymin, + .recti.xmax = rct->xmax, .recti.ymax = rct->ymax - 10.0f, + .rect.xmin = rct->xmin - a, .rect.ymin = rct->ymin - a, + .rect.xmax = rct->xmax + a, .rect.ymax = rct->ymax - 10.0f + a, + .radi = rad, + .rad = rad + a, + .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f, + .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f, + .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f, + .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f, + .alpha_discard = 1.0f, + }; + + Gwn_Batch *batch = ui_batch_roundbox_shadow_get(); + GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW); + GWN_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params); + GWN_batch_uniform_1f(batch, "alpha", 1.0f - visibility); + GWN_batch_draw(batch); + /* outline emphasis */ glEnable(GL_LINE_SMOOTH); - glColor4ub(0, 0, 0, 100); - UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f); + float color[4] = {0.0f, 0.0f, 0.0f, 0.4f}; + UI_draw_roundbox_4fv(false, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f, color); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); } - -/** - * Reset GL state (keep minimal). - * - * \note Blender's internal code doesn't assume these are reset, - * but external callbacks may depend on their state. - */ -void UI_reinit_gl_state(void) -{ - glLineWidth(1.0f); - glPointSize(1.0f); -} |