GPU: Add Polyline shader (wide line emulation)

This new shader is able to emulate smooth wide lines drawing using a
geometry shader.

This shader needs viewportSize and lineWidth uniforms to be set.

There is multiple variants to replace the usage of wide lines for most
shaders.

This patch only fix the gizmo_types files and the navigation gizmo.
Other areas could be fixed afterward, I just limited the patch size.

Fix T57570.

Reviewed By: billreynish

Differential Revision: https://developer.blender.org/D7487
This commit is contained in:
Clément Foucault 2020-04-23 23:05:39 +02:00
parent d0ff3434cf
commit d712f1f83a
Notes: blender-bot 2023-02-14 11:28:39 +01:00
Referenced by issue #77466, Blender 2.83 crashing and lagging when rendering the viewport (cycles).
Referenced by issue #77455, Scale gizmos cause complete freezes in Blender 2.83 on Intel graphics
Referenced by issue #76393, Crash on assert(batch->program_in_use == 0)
Referenced by issue #76095, Liquid cache of type "Replay" doesn't get invalidated when moving participating objects
Referenced by issue #76080, Glitches Workbench and Screen Cavity
Referenced by issue #76045, Gizmo line_width does not work in latest version
Referenced by issue #76043, Select Edge Loop not working 2.83
Referenced by issue #74243, Workbench x-ray, wireframe and anti-aliasing artifacts on NVIDIA / Linux
Referenced by issue #57570, 2.8x, unreliable GL_LINE_SMOOTH / GL_POLYGON_SMOOTH behavior
13 changed files with 330 additions and 87 deletions

View File

@ -88,9 +88,14 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
const int draw_style = RNA_enum_get(arrow->gizmo.ptr, "draw_style");
const int draw_options = RNA_enum_get(arrow->gizmo.ptr, "draw_options");
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
if (draw_style == ED_GIZMO_ARROW_STYLE_CROSS) {
immUniform1f("lineWidth", U.pixelsize);
immUniformColor4fv(color);
immBegin(GPU_PRIM_LINES, 4);
@ -112,7 +117,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
{-unitx, unity, 0},
};
GPU_line_width(arrow->gizmo.line_width);
immUniform1f("lineWidth", arrow->gizmo.line_width * U.pixelsize);
wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GPU_PRIM_LINE_LOOP);
}
else {
@ -127,7 +132,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
};
if (draw_options & ED_GIZMO_ARROW_DRAW_FLAG_STEM) {
GPU_line_width(arrow->gizmo.line_width);
immUniform1f("lineWidth", arrow->gizmo.line_width * U.pixelsize);
wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GPU_PRIM_LINE_STRIP);
}
else {
@ -160,6 +165,10 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
/* translate to line end */
GPU_matrix_translate_3f(0.0f, 0.0f, arrow_length);
immUnbindProgram();
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
imm_draw_circle_fill_3d(pos, 0.0, 0.0, width, 8);
imm_draw_cylinder_fill_3d(pos, width, 0.0, len, 8, 1);
}

View File

@ -76,7 +76,8 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
const float fill_alpha,
const bool select)
{
GPU_line_width(gz->line_width);
float viewport[4];
GPU_viewport_size_get_f(viewport);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@ -85,10 +86,14 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
if (color[3] == 1.0 && fill_alpha == 1.0 && select == false) {
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
GPU_polygon_smooth(0);
imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
immUnbindProgram();
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", gz->line_width * U.pixelsize);
immUniformColor4fv(color);
imm_draw_circle_wire_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
GPU_polygon_smooth(1);
immUnbindProgram();
}
else {
@ -103,9 +108,10 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
/* Draw outline. */
if ((fill_alpha != 1.0f) && (select == false)) {
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", gz->line_width * U.pixelsize);
immUniformColor4fv(color);
GPU_line_width(gz->line_width);
imm_draw_circle_wire_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
immUnbindProgram();
}
@ -152,12 +158,13 @@ static void button2d_draw_intern(const bContext *C,
bool is_3d = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) != 0;
if ((select == false) && (draw_options & ED_GIZMO_BUTTON_SHOW_HELPLINE)) {
float matrix_final_no_offset[4][4];
float matrix_final_no_offset[4][4], viewport[4];
WM_gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
GPU_line_width(gz->line_width);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", gz->line_width * U.pixelsize);
immUniformColor4fv(color);
immBegin(GPU_PRIM_LINE_STRIP, 2);
immVertex3fv(pos, matrix_final[3]);
@ -197,7 +204,6 @@ static void button2d_draw_intern(const bContext *C,
if (button->shape_batch[0] != NULL) {
GPU_line_smooth(true);
GPU_polygon_smooth(false);
GPU_line_width(1.0f);
for (uint i = 0; i < ARRAY_SIZE(button->shape_batch) && button->shape_batch[i]; i++) {
/* Invert line color for wire. */
GPU_batch_program_set_builtin(button->shape_batch[i], GPU_SHADER_2D_UNIFORM_COLOR);
@ -216,7 +222,7 @@ static void button2d_draw_intern(const bContext *C,
GPU_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color));
}
GPU_batch_draw(button->shape_batch[i]);
// GPU_batch_draw(button->shape_batch[i]);
if (draw_options & ED_GIZMO_BUTTON_SHOW_OUTLINE) {
color[0] = 1.0f - color[0];

View File

@ -162,13 +162,22 @@ static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[2], bool r_con
* Useful for 3D views, see: #ED_GIZMO_CAGE2D_STYLE_BOX
* \{ */
static void cage2d_draw_box_corners(const rctf *r, const float margin[2], const float color[3])
static void cage2d_draw_box_corners(const rctf *r,
const float margin[2],
const float color[3],
const float line_width)
{
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniformColor3fv(color);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", line_width * U.pixelsize);
immBegin(GPU_PRIM_LINES, 16);
immVertex2f(pos, r->xmin, r->ymin + margin[1]);
@ -445,7 +454,7 @@ static void cage2d_draw_box_interaction(const float color[4],
.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT),
.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT),
};
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
immBindBuiltinProgram(is_solid ? GPU_SHADER_2D_FLAT_COLOR : GPU_SHADER_3D_POLYLINE_FLAT_COLOR);
{
if (is_solid) {
@ -459,7 +468,12 @@ static void cage2d_draw_box_interaction(const float color[4],
}
else {
BLI_assert(ELEM(prim_type, GPU_PRIM_LINE_STRIP, GPU_PRIM_LINES));
GPU_line_width(line_width + 3.0f);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", (line_width * 3.0f) * U.pixelsize);
immBegin(prim_type, verts_len);
immAttr3f(attr_id.col, 0.0f, 0.0f, 0.0f);
@ -468,7 +482,7 @@ static void cage2d_draw_box_interaction(const float color[4],
}
immEnd();
GPU_line_width(line_width);
immUniform1f("lineWidth", line_width * U.pixelsize);
immBegin(prim_type, verts_len);
immAttr3fv(attr_id.col, color);
@ -505,13 +519,19 @@ static void cage2d_draw_circle_wire(const rctf *r,
const float margin[2],
const float color[3],
const int transform_flag,
const int draw_options)
const int draw_options,
const float line_width)
{
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniformColor3fv(color);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", line_width * U.pixelsize);
immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2f(pos, r->xmin, r->ymin);
immVertex2f(pos, r->xmax, r->ymin);
@ -662,15 +682,14 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
.ymax = size_real[1],
};
if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX) {
/* corner gizmos */
GPU_line_width(gz->line_width + 3.0f);
cage2d_draw_box_corners(&r, margin, (const float[3]){0, 0, 0});
float color[4], black[3] = {0, 0, 0};
gizmo_color_get(gz, highlight, color);
/* corner gizmos */
float color[4];
gizmo_color_get(gz, highlight, color);
GPU_line_width(gz->line_width);
cage2d_draw_box_corners(&r, margin, color);
cage2d_draw_box_corners(&r, margin, black, gz->line_width + 3.0f);
/* corner gizmos */
cage2d_draw_box_corners(&r, margin, color, gz->line_width);
bool show = false;
if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) {
@ -700,30 +719,26 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
}
}
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
float color[4];
float color[4], black[3] = {0, 0, 0};
gizmo_color_get(gz, highlight, color);
GPU_line_smooth(true);
GPU_blend(true);
GPU_line_width(gz->line_width + 3.0f);
cage2d_draw_circle_wire(&r, margin, (const float[3]){0, 0, 0}, transform_flag, draw_options);
GPU_line_width(gz->line_width);
cage2d_draw_circle_wire(&r, margin, color, transform_flag, draw_options);
float outline_line_width = gz->line_width + 3.0f;
cage2d_draw_circle_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
cage2d_draw_circle_wire(&r, margin, color, transform_flag, draw_options, gz->line_width);
/* corner gizmos */
cage2d_draw_circle_handles(&r, margin, color, transform_flag, true);
cage2d_draw_circle_handles(&r, margin, (const float[3]){0, 0, 0}, transform_flag, false);
GPU_blend(false);
GPU_line_smooth(false);
}
else {
BLI_assert(0);
}
}
GPU_line_width(1.0);
GPU_matrix_pop();
}

View File

@ -130,14 +130,22 @@ static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[3], bool r_con
* Useful for 3D views, see: #ED_GIZMO_CAGE2D_STYLE_BOX
* \{ */
static void cage3d_draw_box_corners(const float r[3], const float margin[3], const float color[3])
static void cage3d_draw_box_corners(const float r[3],
const float margin[3],
const float color[3],
const float line_width)
{
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
UNUSED_VARS(margin);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniformColor3fv(color);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", line_width * U.pixelsize);
imm_draw_cube_wire_3d(pos, (float[3]){0}, r);
immUnbindProgram();
@ -199,13 +207,19 @@ static void cage3d_draw_circle_wire(const float r[3],
const float margin[3],
const float color[3],
const int transform_flag,
const int draw_options)
const int draw_options,
const float line_width)
{
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniformColor3fv(color);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", line_width * U.pixelsize);
imm_draw_cube_wire_3d(pos, (float[3]){0}, r);
#if 0
@ -339,15 +353,14 @@ static void gizmo_cage3d_draw_intern(
};
#endif
if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX) {
/* corner gizmos */
GPU_line_width(gz->line_width + 3.0f);
cage3d_draw_box_corners(size_real, margin, (const float[3]){0, 0, 0});
float color[4], black[3] = {0, 0, 0};
gizmo_color_get(gz, highlight, color);
/* corner gizmos */
float color[4];
gizmo_color_get(gz, highlight, color);
GPU_line_width(gz->line_width);
cage3d_draw_box_corners(size_real, margin, color);
cage3d_draw_box_corners(size_real, margin, black, gz->line_width + 3.0f);
/* corner gizmos */
cage3d_draw_box_corners(size_real, margin, color, gz->line_width);
bool show = false;
if (gz->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) {
@ -366,34 +379,29 @@ static void gizmo_cage3d_draw_intern(
}
}
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
float color[4];
float color[4], black[3] = {0, 0, 0};
gizmo_color_get(gz, highlight, color);
GPU_line_smooth(true);
GPU_polygon_smooth(true);
GPU_blend(true);
GPU_line_width(gz->line_width + 3.0f);
cage3d_draw_circle_wire(
size_real, margin, (const float[3]){0, 0, 0}, transform_flag, draw_options);
GPU_line_width(gz->line_width);
cage3d_draw_circle_wire(size_real, margin, color, transform_flag, draw_options);
size_real, margin, black, transform_flag, draw_options, gz->line_width + 3.0f);
cage3d_draw_circle_wire(
size_real, margin, color, transform_flag, draw_options, gz->line_width);
/* corner gizmos */
cage3d_draw_circle_handles(
rv3d, matrix_final, size_real, margin, (const float[3]){0, 0, 0}, true, 60);
GPU_polygon_smooth(true);
cage3d_draw_circle_handles(rv3d, matrix_final, size_real, margin, black, true, 60);
cage3d_draw_circle_handles(rv3d, matrix_final, size_real, margin, color, true, 40);
GPU_polygon_smooth(false);
GPU_blend(false);
GPU_polygon_smooth(false);
GPU_line_smooth(false);
}
else {
BLI_assert(0);
}
}
GPU_line_width(1.0);
GPU_matrix_pop();
}

View File

@ -111,19 +111,18 @@ static void dial_geom_draw(const float color[4],
ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT) :
ED_GIZMO_DIAL_DRAW_FLAG_FILL)));
GPU_line_width(line_width);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (clip_plane) {
immBindBuiltinProgram(GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR);
immBindBuiltinProgram(filled ? GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR :
GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR);
immUniform4fv("ClipPlane", clip_plane);
immUniformMatrix4fv("ModelMatrix", axis_modal_mat);
glEnable(GL_CLIP_DISTANCE0);
}
else {
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immBindBuiltinProgram(filled ? GPU_SHADER_3D_UNIFORM_COLOR :
GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
}
immUniformColor4fv(color);
@ -151,6 +150,11 @@ static void dial_geom_draw(const float color[4],
}
}
else {
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", line_width * U.pixelsize);
if (arc_partial_angle == 0.0f) {
imm_draw_circle_wire_2d(pos, 0, 0, 1.0, DIAL_RESOLUTION);
if (arc_inner_factor != 0.0f) {
@ -171,10 +175,6 @@ static void dial_geom_draw(const float color[4],
immUnbindProgram();
if (clip_plane) {
glDisable(GL_CLIP_DISTANCE0);
}
UNUSED_VARS(select);
#endif
}
@ -184,14 +184,20 @@ static void dial_geom_draw(const float color[4],
*/
static void dial_ghostarc_draw_helpline(const float angle,
const float co_outer[3],
const float color[4])
const float color[4],
const float line_width)
{
GPU_matrix_push();
GPU_matrix_rotate_3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", line_width * U.pixelsize);
immUniformColor4fv(color);
@ -211,11 +217,17 @@ static void dial_ghostarc_draw_helpline(const float angle,
static void dial_ghostarc_draw_incremental_angle(const float incremental_angle, const float offset)
{
const int tot_incr = (2 * M_PI) / incremental_angle;
GPU_line_width(1.0f);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniformColor3f(1.0f, 1.0f, 1.0f);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", U.pixelsize);
immBegin(GPU_PRIM_LINES, tot_incr * 2);
float v[3] = {0};
@ -369,14 +381,12 @@ static void dial_ghostarc_draw_with_helplines(const float angle_ofs,
{
/* Coordinate at which the arc drawing will be started. */
const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f};
dial_ghostarc_draw(
angle_ofs, angle_delta, arc_inner_factor, (const float[4]){0.8f, 0.8f, 0.8f, 0.4f});
GPU_line_width(1.0f);
dial_ghostarc_draw_helpline(angle_ofs, co_outer, color_helpline);
if (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE) {
GPU_line_width(3.0f);
}
dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, color_helpline);
const float color_arc_inner[4] = {0.8f, 0.8f, 0.8f, 0.4f};
dial_ghostarc_draw(angle_ofs, angle_delta, arc_inner_factor, color_arc_inner);
float line_width = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE) ? 3.0f : 1.0f;
dial_ghostarc_draw_helpline(angle_ofs, co_outer, color_helpline, 1.0f);
dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, color_helpline, line_width);
}
static void dial_draw_intern(

View File

@ -110,12 +110,16 @@ static void move_geom_draw(const wmGizmo *gz,
ED_GIZMO_MOVE_DRAW_FLAG_FILL_SELECT) :
ED_GIZMO_MOVE_DRAW_FLAG_FILL)));
GPU_line_width(gz->line_width);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immBindBuiltinProgram(filled ? GPU_SHADER_3D_UNIFORM_COLOR :
GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", gz->line_width * U.pixelsize);
immUniformColor4fv(color);

View File

@ -197,8 +197,8 @@ static void axis_geom_draw(const wmGizmo *gz,
const bool select,
const struct AxisDrawInfo *draw_info)
{
GPU_line_width(gz->line_width);
float viewport[4];
GPU_viewport_size_get_f(viewport);
GPUVertFormat *format = immVertexFormat();
const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@ -341,8 +341,13 @@ static void axis_geom_draw(const wmGizmo *gz,
/* Axis Line. */
if (is_pos) {
float v_start[3];
GPU_line_width(2.0f);
immUnbindProgram();
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", 2.0f * U.pixelsize);
immUniformColor4fv(is_pos_color ? color_current : color_current_fade);
immBegin(GPU_PRIM_LINES, 2);
if (axis_align == -1) {
zero_v3(v_start);
@ -358,6 +363,10 @@ static void axis_geom_draw(const wmGizmo *gz,
immVertex3fv(pos_id, v_start);
immVertex3fv(pos_id, v_final);
immEnd();
immUnbindProgram();
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
}
/* Axis Ball. */

View File

@ -181,6 +181,9 @@ data_to_c_simple(shaders/gpu_shader_3D_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_normal_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_flat_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_line_dashed_uniform_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_polyline_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_polyline_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_polyline_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_passthrough_vert.glsl SRC)

View File

@ -156,6 +156,7 @@ typedef enum eGPUBuiltinShader {
* \param pos: in vec3
*/
GPU_SHADER_3D_UNIFORM_COLOR,
GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
/**
* Take a 3D position and color for each vertex without color interpolation.
*
@ -170,13 +171,38 @@ typedef enum eGPUBuiltinShader {
* \param pos: in vec3
*/
GPU_SHADER_3D_SMOOTH_COLOR,
/**
* Take a single color for all the vertices and a 3D position for each vertex.
* Used for drawing wide lines.
*
* \param color: uniform vec4
* \param pos: in vec3
*/
GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR,
GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR,
/**
* Take a 3D position and color for each vertex without color interpolation.
* Used for drawing wide lines.
*
* \param color: in vec4
* \param pos: in vec3
*/
GPU_SHADER_3D_POLYLINE_FLAT_COLOR,
/**
* Take a 3D position and color for each vertex with perspective correct interpolation.
* Used for drawing wide lines.
*
* \param color: in vec4
* \param pos: in vec3
*/
GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR,
/**
* Take a 3D position for each vertex and output only depth.
* Used for drawing wide lines.
*
* \param pos: in vec3
*/
GPU_SHADER_3D_DEPTH_ONLY,
GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
/* basic image drawing */
GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE,
GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE,

View File

@ -88,6 +88,9 @@ extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[];
extern char datatoc_gpu_shader_3D_vert_glsl[];
extern char datatoc_gpu_shader_3D_normal_vert_glsl[];
extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_polyline_frag_glsl[];
extern char datatoc_gpu_shader_3D_polyline_geom_glsl[];
extern char datatoc_gpu_shader_3D_polyline_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
extern char datatoc_gpu_shader_3D_passthrough_vert_glsl[];
@ -1026,6 +1029,36 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.frag = datatoc_gpu_shader_uniform_color_frag_glsl,
},
[GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR] =
{
.vert = datatoc_gpu_shader_3D_polyline_vert_glsl,
.geom = datatoc_gpu_shader_3D_polyline_geom_glsl,
.frag = datatoc_gpu_shader_3D_polyline_frag_glsl,
.defs = "#define UNIFORM\n",
},
[GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR] =
{
.vert = datatoc_gpu_shader_3D_polyline_vert_glsl,
.geom = datatoc_gpu_shader_3D_polyline_geom_glsl,
.frag = datatoc_gpu_shader_3D_polyline_frag_glsl,
.defs = "#define UNIFORM\n"
"#define CLIP\n",
},
[GPU_SHADER_3D_POLYLINE_FLAT_COLOR] =
{
.vert = datatoc_gpu_shader_3D_polyline_vert_glsl,
.geom = datatoc_gpu_shader_3D_polyline_geom_glsl,
.frag = datatoc_gpu_shader_3D_polyline_frag_glsl,
.defs = "#define FLAT\n",
},
[GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR] =
{
.vert = datatoc_gpu_shader_3D_polyline_vert_glsl,
.geom = datatoc_gpu_shader_3D_polyline_geom_glsl,
.frag = datatoc_gpu_shader_3D_polyline_frag_glsl,
.defs = "#define SMOOTH\n",
},
[GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR] =
{
.vert = datatoc_gpu_shader_2D_line_dashed_uniform_color_vert_glsl,

View File

@ -0,0 +1,24 @@
uniform float lineWidth;
in vec4 finalColor;
noperspective in float smoothline;
#ifdef CLIP
in float clip;
#endif
out vec4 fragColor;
#define SMOOTH_WIDTH 1.0
void main()
{
#ifdef CLIP
if (clip < 0.0) {
discard;
}
#endif
fragColor = finalColor;
fragColor.a *= clamp((lineWidth + SMOOTH_WIDTH) * 0.5 - abs(smoothline), 0.0, 1.0);
fragColor = blender_srgb_to_framebuffer_space(fragColor);
}

View File

@ -0,0 +1,68 @@
layout(lines) in;
layout(triangle_strip, max_vertices = 4) out;
uniform vec4 color;
uniform vec2 viewportSize;
uniform float lineWidth;
#if !defined(UNIFORM)
in vec4 finalColor_g[];
#endif
#ifdef CLIP
in float clip_g[];
out float clip;
#endif
out vec4 finalColor;
noperspective out float smoothline;
#define SMOOTH_WIDTH 1.0
void do_vertex(const int i, vec2 ofs)
{
#if defined(UNIFORM)
finalColor = color;
#elif defined(FLAT)
finalColor = finalColor_g[0];
#elif defined(SMOOTH)
finalColor = finalColor_g[i];
#endif
#ifdef CLIP
clip = clip_g[i];
#endif
smoothline = (lineWidth + SMOOTH_WIDTH) * 0.5;
gl_Position = gl_in[i].gl_Position;
gl_Position.xy += ofs * gl_Position.w;
EmitVertex();
smoothline = -(lineWidth + SMOOTH_WIDTH) * 0.5;
gl_Position = gl_in[i].gl_Position;
gl_Position.xy -= ofs * gl_Position.w;
EmitVertex();
}
void main(void)
{
vec2 p0 = gl_in[0].gl_Position.xy / gl_in[0].gl_Position.w;
vec2 p1 = gl_in[1].gl_Position.xy / gl_in[1].gl_Position.w;
vec2 e = normalize((p1 - p0) * viewportSize.xy);
#if 0 /* Hard turn when line direction changes quadrant. */
e = abs(e);
vec2 ofs = (e.x > e.y) ? vec2(0.0, 1.0 / e.x) : vec2(1.0 / e.y, 0.0);
#else /* Use perpendicular direction. */
vec2 ofs = vec2(-e.y, e.x);
#endif
ofs /= viewportSize.xy;
ofs *= lineWidth + SMOOTH_WIDTH;
do_vertex(0, ofs);
do_vertex(1, ofs);
EndPrimitive();
}

View File

@ -0,0 +1,28 @@
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelMatrix;
uniform vec4 ClipPlane;
in vec3 pos;
#if !defined(UNIFORM)
in vec4 color;
out vec4 finalColor_g;
#endif
#ifdef CLIP
out float clip_g;
#endif
void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
#if !defined(UNIFORM)
finalColor_g = color;
#endif
#ifdef CLIP
clip_g = dot(ModelMatrix * vec4(pos, 1.0), ClipPlane);
#endif
}