diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_immediate.cc')
-rw-r--r-- | source/blender/gpu/intern/gpu_immediate.cc | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc index 8d781978857..38d206ec3ad 100644 --- a/source/blender/gpu/intern/gpu_immediate.cc +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -62,6 +62,7 @@ void immBindShader(GPUShader *shader) BLI_assert(imm->shader == NULL); imm->shader = shader; + imm->builtin_shader_bound = GPU_SHADER_TEXT; /* Default value. */ if (!imm->vertex_format.packed) { VertexFormat_pack(&imm->vertex_format); @@ -77,6 +78,7 @@ void immBindBuiltinProgram(eGPUBuiltinShader shader_id) { GPUShader *shader = GPU_shader_get_builtin_shader(shader_id); immBindShader(shader); + imm->builtin_shader_bound = shader_id; } void immUnbindProgram(void) @@ -122,11 +124,88 @@ static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType } #endif +/* -------------------------------------------------------------------- */ +/** \name Wide line workaround + * + * Some systems do not support wide lines. + * We workaround this by using specialized shaders. + * \{ */ + +static void wide_line_workaround_start(GPUPrimType prim_type) +{ + if (!ELEM(prim_type, GPU_PRIM_LINES, GPU_PRIM_LINE_STRIP, GPU_PRIM_LINE_LOOP)) { + return; + } + + float line_width = GPU_line_width_get(); + + if (line_width == 1.0f) { + /* No need to change the shader. */ + return; + } + + eGPUBuiltinShader polyline_sh; + switch (imm->builtin_shader_bound) { + case GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR: + polyline_sh = GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR; + break; + case GPU_SHADER_2D_UNIFORM_COLOR: + case GPU_SHADER_3D_UNIFORM_COLOR: + polyline_sh = GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR; + break; + case GPU_SHADER_2D_FLAT_COLOR: + case GPU_SHADER_3D_FLAT_COLOR: + polyline_sh = GPU_SHADER_3D_POLYLINE_FLAT_COLOR; + break; + case GPU_SHADER_2D_SMOOTH_COLOR: + case GPU_SHADER_3D_SMOOTH_COLOR: + polyline_sh = GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR; + break; + default: + /* Cannot replace the current shader with a polyline shader. */ + return; + } + + imm->prev_shader = imm->shader; + + immUnbindProgram(); + + /* TODO(fclem) Don't use geometry shader and use quad instancing with double load. */ + // GPU_vertformat_multiload_enable(imm->vertex_format, 2); + + immBindBuiltinProgram(polyline_sh); + + float viewport[4]; + GPU_viewport_size_get_f(viewport); + immUniform2fv("viewportSize", &viewport[2]); + immUniform1f("lineWidth", line_width); + + if (ELEM(polyline_sh, + GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR, + GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR)) { + immUniformColor4fv(imm->uniform_color); + } +} + +static void wide_line_workaround_end(void) +{ + if (imm->prev_shader) { + immUnbindProgram(); + + immBindShader(imm->prev_shader); + imm->prev_shader = NULL; + } +} + +/** \} */ + void immBegin(GPUPrimType prim_type, uint vertex_len) { BLI_assert(imm->prim_type == GPU_PRIM_NONE); /* Make sure we haven't already begun. */ BLI_assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); + wide_line_workaround_start(prim_type); + imm->prim_type = prim_type; imm->vertex_len = vertex_len; imm->vertex_idx = 0; @@ -201,6 +280,8 @@ void immEnd(void) imm->prim_type = GPU_PRIM_NONE; imm->strict_vertex_len = true; imm->vertex_data = NULL; + + wide_line_workaround_end(); } static void setAttrValueBit(uint attr_id) @@ -549,6 +630,8 @@ void immUniformColor4f(float r, float g, float b, float a) BLI_assert(uniform_loc != -1); float data[4] = {r, g, b, a}; GPU_shader_uniform_vector(imm->shader, uniform_loc, 4, 1, data); + /* For wide Line workaround. */ + copy_v4_v4(imm->uniform_color, data); } void immUniformColor4fv(const float rgba[4]) |