Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/interface/interface_draw.c')
-rw-r--r--source/blender/editors/interface/interface_draw.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 72c31c7b39e..499842a570b 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -27,16 +27,21 @@
#include "DNA_color_types.h"
#include "DNA_screen_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_curveprofile_types.h"
#include "BLI_math.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BLI_polyfill_2d.h"
+
+#include "MEM_guardedalloc.h"
#include "BKE_colorband.h"
#include "BKE_colortools.h"
#include "BKE_node.h"
#include "BKE_tracking.h"
+#include "BKE_curveprofile.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -1814,6 +1819,8 @@ static void ui_draw_but_curve_grid(
immVertex2f(pos, rect->xmax, fy);
fy += dy;
}
+ /* Note: Assertion fails with here when the view is moved farther below the center.
+ * Missing two points from the number given with immBegin. */
immEnd();
}
@@ -2113,6 +2120,231 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, const uiWidgetColors *wcol, cons
immUnbindProgram();
}
+/** Used to draw a curve profile widget. Somewhat similar to ui_draw_but_CURVE */
+void ui_draw_but_CURVEPROFILE(ARegion *ar,
+ uiBut *but,
+ const uiWidgetColors *wcol,
+ const rcti *rect)
+{
+ uint i;
+ float fx, fy;
+ CurveProfile *profile;
+ if (but->editprofile) {
+ profile = but->editprofile;
+ }
+ else {
+ profile = (CurveProfile *)but->poin;
+ }
+
+ /* Calculate offset and zoom */
+ float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / BLI_rctf_size_x(&profile->view_rect);
+ float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / BLI_rctf_size_y(&profile->view_rect);
+ float offsx = profile->view_rect.xmin - (1.0f / zoomx);
+ float offsy = profile->view_rect.ymin - (1.0f / zoomy);
+
+ /* Exit early if too narrow */
+ if (zoomx == 0.0f) {
+ return;
+ }
+
+ /* Test needed because path can draw outside of boundary */
+ int scissor[4];
+ GPU_scissor_get_i(scissor);
+ rcti scissor_new = {
+ .xmin = rect->xmin,
+ .ymin = rect->ymin,
+ .xmax = rect->xmax,
+ .ymax = rect->ymax,
+ };
+ rcti scissor_region = {0, ar->winx, 0, ar->winy};
+ BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
+ GPU_scissor(scissor_new.xmin,
+ scissor_new.ymin,
+ BLI_rcti_size_x(&scissor_new),
+ BLI_rcti_size_y(&scissor_new));
+
+ GPU_line_width(1.0f);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* Backdrop */
+ float color_backdrop[4] = {0, 0, 0, 1};
+ if (profile->flag & PROF_USE_CLIP) {
+ gl_shaded_color_get_fl((uchar *)wcol->inner, -20, color_backdrop);
+ immUniformColor3fv(color_backdrop);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ immUniformColor3ubv((uchar *)wcol->inner);
+ immRectf(pos,
+ rect->xmin + zoomx * (profile->clip_rect.xmin - offsx),
+ rect->ymin + zoomy * (profile->clip_rect.ymin - offsy),
+ rect->xmin + zoomx * (profile->clip_rect.xmax - offsx),
+ rect->ymin + zoomy * (profile->clip_rect.ymax - offsy));
+ }
+ else {
+ rgb_uchar_to_float(color_backdrop, (uchar *)wcol->inner);
+ immUniformColor3fv(color_backdrop);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ }
+
+ /* 0.25 step grid */
+ gl_shaded_color((uchar *)wcol->inner, -16);
+ ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
+ /* 1.0 step grid */
+ gl_shaded_color((uchar *)wcol->inner, -24);
+ ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
+
+ /* Draw the path's fill */
+ if (profile->table == NULL) {
+ BKE_curveprofile_update(profile, false);
+ }
+ CurveProfilePoint *pts = profile->table;
+ /* Also add the last points on the right and bottom edges to close off the fill polygon */
+ bool add_left_tri = profile->view_rect.xmin < 0.0f;
+ bool add_bottom_tri = profile->view_rect.ymin < 0.0f;
+ uint tot_points = (uint)PROF_N_TABLE(profile->path_len) + 1 + add_left_tri + add_bottom_tri;
+ uint tot_triangles = tot_points - 2;
+
+ /* Create array of the positions of the table's points */
+ float(*table_coords)[2] = MEM_mallocN(sizeof(*table_coords) * tot_points, "table x coords");
+ for (i = 0; i < (uint)PROF_N_TABLE(profile->path_len);
+ i++) { /* Only add the points from the table here */
+ table_coords[i][0] = pts[i].x;
+ table_coords[i][1] = pts[i].y;
+ }
+ if (add_left_tri && add_bottom_tri) {
+ /* Add left side, bottom left corner, and bottom side points */
+ table_coords[tot_points - 3][0] = profile->view_rect.xmin;
+ table_coords[tot_points - 3][1] = 1.0f;
+ table_coords[tot_points - 2][0] = profile->view_rect.xmin;
+ table_coords[tot_points - 2][1] = profile->view_rect.ymin;
+ table_coords[tot_points - 1][0] = 1.0f;
+ table_coords[tot_points - 1][1] = profile->view_rect.ymin;
+ }
+ else if (add_left_tri) {
+ /* Add the left side and bottom left corner points */
+ table_coords[tot_points - 2][0] = profile->view_rect.xmin;
+ table_coords[tot_points - 2][1] = 1.0f;
+ table_coords[tot_points - 1][0] = profile->view_rect.xmin;
+ table_coords[tot_points - 1][1] = 0.0f;
+ }
+ else if (add_bottom_tri) {
+ /* Add the bottom side and bottom left corner points */
+ table_coords[tot_points - 2][0] = 0.0f;
+ table_coords[tot_points - 2][1] = profile->view_rect.ymin;
+ table_coords[tot_points - 1][0] = 1.0f;
+ table_coords[tot_points - 1][1] = profile->view_rect.ymin;
+ }
+ else {
+ /* Just add the bottom corner point. Side points would be redundant anyway */
+ table_coords[tot_points - 1][0] = 0.0f;
+ table_coords[tot_points - 1][1] = 0.0f;
+ }
+
+ /* Calculate the table point indices of the triangles for the profile's fill */
+ uint(*tri_indices)[3] = MEM_mallocN(sizeof(*tri_indices) * tot_triangles, "return tri indices");
+ BLI_polyfill_calc(table_coords, tot_points, -1, tri_indices);
+
+ /* Draw the triangles for the profile fill */
+ immUniformColor3ubvAlpha((const uchar *)wcol->item, 128);
+ GPU_blend(true);
+ GPU_polygon_smooth(false);
+ immBegin(GPU_PRIM_TRIS, 3 * tot_triangles);
+ for (i = 0; i < tot_triangles; i++) {
+ for (uint j = 0; j < 3; j++) {
+ uint *tri = tri_indices[i];
+ fx = rect->xmin + zoomx * (table_coords[tri[j]][0] - offsx);
+ fy = rect->ymin + zoomy * (table_coords[tri[j]][1] - offsy);
+ immVertex2f(pos, fx, fy);
+ }
+ }
+ immEnd();
+ MEM_freeN(tri_indices);
+
+ /* Draw the profile's path so the edge stands out a bit */
+ tot_points -= (add_left_tri + add_left_tri);
+ GPU_line_width(1.0f);
+ immUniformColor3ubvAlpha((const uchar *)wcol->item, 255);
+ GPU_line_smooth(true);
+ immBegin(GPU_PRIM_LINE_STRIP, tot_points - 1);
+ for (i = 0; i < tot_points - 1; i++) {
+ fx = rect->xmin + zoomx * (table_coords[i][0] - offsx);
+ fy = rect->ymin + zoomy * (table_coords[i][1] - offsy);
+ immVertex2f(pos, fx, fy);
+ }
+ immEnd();
+ immUnbindProgram();
+ MEM_freeN(table_coords);
+
+ /* New GPU instructions for control points and sampled points. */
+ format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ /* Calculate vertex colors based on text theme. */
+ float color_vert[4], color_vert_select[4], color_sample[4];
+ UI_GetThemeColor4fv(TH_TEXT_HI, color_vert);
+ UI_GetThemeColor4fv(TH_TEXT, color_vert_select);
+ color_sample[0] = (float)wcol->item[0] / 255.0f;
+ color_sample[1] = (float)wcol->item[1] / 255.0f;
+ color_sample[2] = (float)wcol->item[2] / 255.0f;
+ color_sample[3] = (float)wcol->item[3] / 255.0f;
+ if (len_squared_v3v3(color_vert, color_vert_select) < 0.1f) {
+ interp_v3_v3v3(color_vert, color_vert_select, color_backdrop, 0.75f);
+ }
+ if (len_squared_v3(color_vert) > len_squared_v3(color_vert_select)) {
+ /* Ensure brightest text color is used for selection. */
+ swap_v3_v3(color_vert, color_vert_select);
+ }
+
+ /* Draw the control points. */
+ pts = profile->path;
+ tot_points = (uint)profile->path_len;
+ GPU_line_smooth(false);
+ GPU_blend(false);
+ GPU_point_size(max_ff(3.0f, min_ff(UI_DPI_FAC / but->block->aspect * 5.0f, 5.0f)));
+ immBegin(GPU_PRIM_POINTS, tot_points);
+ for (i = 0; i < tot_points; i++) {
+ fx = rect->xmin + zoomx * (pts[i].x - offsx);
+ fy = rect->ymin + zoomy * (pts[i].y - offsy);
+ immAttr4fv(col, (pts[i].flag & PROF_SELECT) ? color_vert_select : color_vert);
+ immVertex2f(pos, fx, fy);
+ }
+ immEnd();
+
+ /* Draw the sampled points in addition to the control points if they have been created */
+ pts = profile->segments;
+ tot_points = (uint)profile->segments_len;
+ if (tot_points > 0 && pts) {
+ GPU_point_size(max_ff(2.0f, min_ff(UI_DPI_FAC / but->block->aspect * 3.0f, 3.0f)));
+ immBegin(GPU_PRIM_POINTS, tot_points);
+ for (i = 0; i < tot_points; i++) {
+ fx = rect->xmin + zoomx * (pts[i].x - offsx);
+ fy = rect->ymin + zoomy * (pts[i].y - offsy);
+ immAttr4fv(col, color_sample);
+ immVertex2f(pos, fx, fy);
+ }
+ immEnd();
+ }
+
+ immUnbindProgram();
+
+ /* restore scissortest */
+ GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+
+ /* Outline */
+ format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3ubv((const uchar *)wcol->outline);
+ imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+ immUnbindProgram();
+}
+
void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar),
uiBut *but,
const uiWidgetColors *UNUSED(wcol),