diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_cursor.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_cursor.c | 356 |
1 files changed, 207 insertions, 149 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 53c11e2a6a9..0e18bddc45f 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -53,13 +53,14 @@ #include "WM_api.h" -#include "BIF_gl.h" #include "BIF_glutil.h" #include "IMB_imbuf_types.h" #include "ED_view3d.h" +#include "GPU_immediate.h" +#include "GPU_matrix.h" #include "GPU_basic_shader.h" #include "UI_resources.h" @@ -605,21 +606,20 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush, glDepthFunc(GL_ALWAYS); glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); + glPushMatrix(); /* TEXTURE */ + glLoadIdentity(); /* TEXTURE */ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) { /* brush rotation */ - glTranslatef(0.5, 0.5, 0); - glRotatef((double)RAD2DEGF((primary) ? ups->brush_rotation : ups->brush_rotation_sec), - 0.0, 0.0, 1.0); - glTranslatef(-0.5f, -0.5f, 0); + glTranslatef(0.5, 0.5, 0); /* TEXTURE */ + glRotatef(RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec), 0, 0, 1); /* TEXTURE */ + glTranslatef(-0.5f, -0.5f, 0); /* TEXTURE */ /* scale based on tablet pressure */ if (primary && ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) { - glTranslatef(0.5f, 0.5f, 0); - glScalef(1.0f / ups->size_pressure_value, 1.0f / ups->size_pressure_value, 1); - glTranslatef(-0.5f, -0.5f, 0); + glTranslatef(0.5f, 0.5f, 0); /* TEXTURE */ + glScalef(1.0f / ups->size_pressure_value, 1.0f / ups->size_pressure_value, 1.0f / ups->size_pressure_value); /* TEXTURE */ + glTranslatef(-0.5f, -0.5f, 0); /* TEXTURE */ } if (ups->draw_anchored) { @@ -658,40 +658,50 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush, quad.ymax = brush->mask_stencil_dimension[1]; } glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gpuPushMatrix(); if (primary) - glTranslate2fv(brush->stencil_pos); + gpuTranslate2fv(brush->stencil_pos); else - glTranslate2fv(brush->mask_stencil_pos); - glRotatef(RAD2DEGF(mtex->rot), 0, 0, 1); + gpuTranslate2fv(brush->mask_stencil_pos); + gpuRotate2D(RAD2DEGF(mtex->rot)); glMatrixMode(GL_TEXTURE); } /* set quad color. Colored overlay does not get blending */ + VertexFormat *format = immVertexFormat(); + unsigned int pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); + unsigned int texCoord = add_attrib(format, "texCoord", GL_FLOAT, 2, KEEP_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); + if (col) { - glColor4f(1.0, 1.0, 1.0, overlay_alpha / 100.0f); + immUniform4f("color", 1.0f, 1.0f, 1.0f, overlay_alpha / 100.0f); } else { - glColor4f(UNPACK3(U.sculpt_paint_overlay_col), overlay_alpha / 100.0f); + immUniform4f("color", UNPACK3(U.sculpt_paint_overlay_col), overlay_alpha / 100.0f); } /* draw textured quad */ - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(quad.xmin, quad.ymin); - glTexCoord2f(1, 0); - glVertex2f(quad.xmax, quad.ymin); - glTexCoord2f(1, 1); - glVertex2f(quad.xmax, quad.ymax); - glTexCoord2f(0, 1); - glVertex2f(quad.xmin, quad.ymax); - glEnd(); - - glPopMatrix(); + immUniform1i("image", GL_TEXTURE0); + + immBegin(GL_QUADS, 4); + immAttrib2f(texCoord, 0.0f, 0.0f); + immVertex2f(pos, quad.xmin, quad.ymin); + immAttrib2f(texCoord, 1.0f, 0.0f); + immVertex2f(pos, quad.xmax, quad.ymin); + immAttrib2f(texCoord, 1.0f, 1.0f); + immVertex2f(pos, quad.xmax, quad.ymax); + immAttrib2f(texCoord, 0.0f, 1.0f); + immVertex2f(pos, quad.xmin, quad.ymax); + immEnd(); + + immUnbindProgram(); + + glPopMatrix(); /* TEXTURE */ if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) { glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gpuPopMatrix(); } } } @@ -739,32 +749,45 @@ static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush, /* scale based on tablet pressure */ if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) { do_pop = true; - glPushMatrix(); - glLoadIdentity(); - glTranslate2fv(center); - glScalef(ups->size_pressure_value, ups->size_pressure_value, 1); - glTranslatef(-center[0], -center[1], 0); + gpuPushMatrix(); + gpuLoadIdentity(); + gpuTranslate2fv(center); + gpuScaleUniform(ups->size_pressure_value); + gpuTranslate2f(-center[0], -center[1]); } - glColor4f(U.sculpt_paint_overlay_col[0], + VertexFormat *format = immVertexFormat(); + unsigned int pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); + unsigned int texCoord = add_attrib(format, "texCoord", GL_FLOAT, 2, KEEP_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); + + immUniform4f("color", + U.sculpt_paint_overlay_col[0], U.sculpt_paint_overlay_col[1], U.sculpt_paint_overlay_col[2], brush->cursor_overlay_alpha / 100.0f); /* draw textured quad */ - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(quad.xmin, quad.ymin); - glTexCoord2f(1, 0); - glVertex2f(quad.xmax, quad.ymin); - glTexCoord2f(1, 1); - glVertex2f(quad.xmax, quad.ymax); - glTexCoord2f(0, 1); - glVertex2f(quad.xmin, quad.ymax); - glEnd(); + + /* draw textured quad */ + immUniform1i("image", GL_TEXTURE0); + + immBegin(GL_QUADS, 4); + immAttrib2f(texCoord, 0.0f, 0.0f); + immVertex2f(pos, quad.xmin, quad.ymin); + immAttrib2f(texCoord, 1.0f, 0.0f); + immVertex2f(pos, quad.xmax, quad.ymin); + immAttrib2f(texCoord, 1.0f, 1.0f); + immVertex2f(pos, quad.xmax, quad.ymax); + immAttrib2f(texCoord, 0.0f, 1.0f); + immVertex2f(pos, quad.xmin, quad.ymax); + immEnd(); + + immUnbindProgram(); if (do_pop) - glPopMatrix(); + gpuPopMatrix(); } } @@ -809,81 +832,102 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, } -BLI_INLINE void draw_tri_point(float *co, float width, bool selected) +BLI_INLINE void draw_tri_point( + unsigned int pos, float sel_col[4], float pivot_col[4], + float *co, float width, bool selected) { + if (selected) { + immUniformColor4fv(sel_col); + } + else { + immUniformColor4fv(pivot_col); + } + glLineWidth(3.0f); + float w = width / 2.0f; - if (selected) - UI_ThemeColor4(TH_VERTEX_SELECT); - else - UI_ThemeColor4(TH_PAINT_CURVE_PIVOT); - - glLineWidth(3.0); - - glBegin(GL_LINE_LOOP); - glVertex2f(co[0], co[1] + w); - glVertex2f(co[0] - w, co[1] - w); - glVertex2f(co[0] + w, co[1] - w); - glEnd(); - - glColor4f(1.0, 1.0, 1.0, 0.5); - glLineWidth(1.0); - - glBegin(GL_LINE_LOOP); - glVertex2f(co[0], co[1] + w); - glVertex2f(co[0] - w, co[1] - w); - glVertex2f(co[0] + w, co[1] - w); - glEnd(); + float tri[3][2] = { + {co[0], co[1] + w}, + {co[0] - w, co[1] - w}, + {co[0] + w, co[1] - w}, + }; + + immBegin(PRIM_LINE_LOOP, 3); + immVertex2fv(pos, tri[0]); + immVertex2fv(pos, tri[1]); + immVertex2fv(pos, tri[2]); + immEnd(); + + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); + glLineWidth(1.0f); + + immBegin(PRIM_LINE_LOOP, 3); + immVertex2fv(pos, tri[0]); + immVertex2fv(pos, tri[1]); + immVertex2fv(pos, tri[2]); + immEnd(); } -BLI_INLINE void draw_rect_point(float *co, float width, bool selected) +BLI_INLINE void draw_rect_point( + unsigned int pos, float sel_col[4], float handle_col[4], + float *co, float width, bool selected) { + if (selected) { + immUniformColor4fv(sel_col); + } + else { + immUniformColor4fv(handle_col); + } + glLineWidth(3.0f); + float w = width / 2.0f; - if (selected) - UI_ThemeColor4(TH_VERTEX_SELECT); - else - UI_ThemeColor4(TH_PAINT_CURVE_HANDLE); - glLineWidth(3.0); - - glBegin(GL_LINE_LOOP); - glVertex2f(co[0] + w, co[1] + w); - glVertex2f(co[0] - w, co[1] + w); - glVertex2f(co[0] - w, co[1] - w); - glVertex2f(co[0] + w, co[1] - w); - glEnd(); - - glColor4f(1.0, 1.0, 1.0, 0.5); - glLineWidth(1.0); - - glBegin(GL_LINE_LOOP); - glVertex2f(co[0] + w, co[1] + w); - glVertex2f(co[0] - w, co[1] + w); - glVertex2f(co[0] - w, co[1] - w); - glVertex2f(co[0] + w, co[1] - w); - glEnd(); + float minx = co[0] - w; + float miny = co[1] - w; + float maxx = co[0] + w; + float maxy = co[1] + w; + + imm_draw_line_box(pos, minx, miny, maxx, maxy); + + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); + glLineWidth(1.0f); + + imm_draw_line_box(pos, minx, miny, maxx, maxy); } -BLI_INLINE void draw_bezier_handle_lines(BezTriple *bez) +BLI_INLINE void draw_bezier_handle_lines(unsigned int pos, float sel_col[4], BezTriple *bez) { - short line1[] = {0, 1}; - short line2[] = {1, 2}; - - glVertexPointer(2, GL_FLOAT, 3 * sizeof(float), bez->vec); - glColor4f(0.0, 0.0, 0.0, 0.5); - glLineWidth(3.0); - glDrawArrays(GL_LINE_STRIP, 0, 3); - - glLineWidth(1.0); - if (bez->f1 || bez->f2) - UI_ThemeColor4(TH_VERTEX_SELECT); - else - glColor4f(1.0, 1.0, 1.0, 0.5); - glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, line1); - if (bez->f3 || bez->f2) - UI_ThemeColor4(TH_VERTEX_SELECT); - else - glColor4f(1.0, 1.0, 1.0, 0.5); - glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, line2); + immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); + glLineWidth(3.0f); + + immBegin(GL_LINE_STRIP, 3); + immVertex2fv(pos, bez->vec[0]); + immVertex2fv(pos, bez->vec[1]); + immVertex2fv(pos, bez->vec[2]); + immEnd(); + + glLineWidth(1.0f); + + if (bez->f1 || bez->f2) { + immUniformColor4fv(sel_col); + } + else { + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); + } + immBegin(GL_LINES, 2); + immVertex2fv(pos, bez->vec[0]); + immVertex2fv(pos, bez->vec[1]); + immEnd(); + + if (bez->f3 || bez->f2) { + immUniformColor4fv(sel_col); + } + else { + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); + } + immBegin(GL_LINES, 2); + immVertex2fv(pos, bez->vec[1]); + immVertex2fv(pos, bez->vec[2]); + immEnd(); } static void paint_draw_curve_cursor(Brush *brush) @@ -895,18 +939,26 @@ static void paint_draw_curve_cursor(Brush *brush) glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glEnableClientState(GL_VERTEX_ARRAY); /* draw the bezier handles and the curve segment between the current and next point */ + unsigned int pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 2, KEEP_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + float selec_col[4], handle_col[4], pivot_col[4]; + UI_GetThemeColor4fv(TH_VERTEX_SELECT, selec_col); + UI_GetThemeColor4fv(TH_PAINT_CURVE_HANDLE, handle_col); + UI_GetThemeColor4fv(TH_PAINT_CURVE_PIVOT, pivot_col); + for (i = 0; i < pc->tot_points - 1; i++, cp++) { int j; PaintCurvePoint *cp_next = cp + 1; float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2]; /* use color coding to distinguish handles vs curve segments */ - draw_bezier_handle_lines(&cp->bez); - draw_tri_point(&cp->bez.vec[1][0], 10.0, cp->bez.f2); - draw_rect_point(&cp->bez.vec[0][0], 8.0, cp->bez.f1 || cp->bez.f2); - draw_rect_point(&cp->bez.vec[2][0], 8.0, cp->bez.f3 || cp->bez.f2); + draw_bezier_handle_lines(pos, selec_col, &cp->bez); + draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2); + draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2); + draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2); for (j = 0; j < 2; j++) BKE_curve_forward_diff_bezier( @@ -916,25 +968,35 @@ static void paint_draw_curve_cursor(Brush *brush) cp_next->bez.vec[1][j], data + j, PAINT_CURVE_NUM_SEGMENTS, sizeof(float[2])); - glVertexPointer(2, GL_FLOAT, 0, data); - glLineWidth(3.0); - glColor4f(0.0, 0.0, 0.0, 0.5); - glDrawArrays(GL_LINE_STRIP, 0, PAINT_CURVE_NUM_SEGMENTS + 1); + float (*v)[2] = (float(*)[2])data; + + immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); + glLineWidth(3.0f); + immBegin(GL_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1); + for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) { + immVertex2fv(pos, v[j]); + } + immEnd(); - glLineWidth(1.0); - glColor4f(0.9, 0.9, 1.0, 0.5); - glDrawArrays(GL_LINE_STRIP, 0, PAINT_CURVE_NUM_SEGMENTS + 1); + immUniformColor4f(0.9f, 0.9f, 1.0f, 0.5f); + glLineWidth(1.0f); + immBegin(GL_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1); + for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) { + immVertex2fv(pos, v[j]); + } + immEnd(); } /* draw last line segment */ - draw_bezier_handle_lines(&cp->bez); - draw_tri_point(&cp->bez.vec[1][0], 10.0, cp->bez.f2); - draw_rect_point(&cp->bez.vec[0][0], 8.0, cp->bez.f1 || cp->bez.f2); - draw_rect_point(&cp->bez.vec[2][0], 8.0, cp->bez.f3 || cp->bez.f2); + draw_bezier_handle_lines(pos, selec_col, &cp->bez); + draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2); + draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2); + draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); - glDisableClientState(GL_VERTEX_ARRAY); + + immUnbindProgram(); } } @@ -988,11 +1050,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); PaintMode mode = BKE_paintmode_get_active_from_context(C); - ViewContext vc; - float final_radius; - float translation[2]; - float outline_alpha, *outline_col; - float zoomx, zoomy; /* check that brush drawing is enabled */ if (ommit_cursor_drawing(paint, mode, brush)) @@ -1000,8 +1057,10 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) /* can't use stroke vc here because this will be called during * mouse over too, not just during a stroke */ + ViewContext vc; view3d_set_viewcontext(C, &vc); + float zoomx, zoomy; get_imapaint_zoom(C, &zoomx, &zoomy); zoomx = max_ff(zoomx, zoomy); @@ -1012,11 +1071,10 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) } /* set various defaults */ - translation[0] = x; - translation[1] = y; - outline_alpha = 0.5; - outline_col = brush->add_col; - final_radius = (BKE_brush_size_get(scene, brush) * zoomx); + const float *outline_col = brush->add_col; + const float outline_alpha = 0.5f; + float translation[2] = { x, y }; + float final_radius = (BKE_brush_size_get(scene, brush) * zoomx); /* don't calculate rake angles while a stroke is active because the rake variables are global and * we may get interference with the stroke itself. For line strokes, such interference is visible */ @@ -1032,10 +1090,9 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) if ((mode == ePaintSculpt) && vc.obact->sculpt) { float location[3]; int pixel_radius; - bool hit; /* test if brush is over the mesh */ - hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location, ups); + bool hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location, ups); if (BKE_brush_use_locked_size(scene, brush)) BKE_brush_size_set(scene, brush, pixel_radius); @@ -1065,24 +1122,25 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) /* make lines pretty */ glLineWidth(1.0f); - glEnable(GL_BLEND); + glEnable(GL_BLEND); /* TODO: also set blend mode? */ glEnable(GL_LINE_SMOOTH); + unsigned int pos = add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + /* set brush color */ - glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha); + immUniformColor3fvAlpha(outline_col, outline_alpha); /* draw brush outline */ - glTranslate2fv(translation); - - /* draw an inner brush */ if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) { /* inner at full alpha */ - glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius * ups->size_pressure_value, 40); + imm_draw_lined_circle(pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40); /* outer at half alpha */ - glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha * 0.5f); + immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f); } - glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius, 40); - glTranslatef(-translation[0], -translation[1], 0); + imm_draw_lined_circle(pos, translation[0], translation[1], final_radius, 40); + + immUnbindProgram(); /* restore GL state */ glDisable(GL_BLEND); |