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:
authorClément Foucault <foucault.clem@gmail.com>2020-09-18 20:59:51 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-09-18 23:41:49 +0300
commit649b0ccac8b514b471cdeede97b1a2839c2176b9 (patch)
treec76ff75bb16c3e022d1df201639d407ea531611d /source/blender/gpu/intern/gpu_immediate.cc
parentf17302be6b716ea5bc6b1ddfd09a2cf3b4969e37 (diff)
GPUImmediate: Add system wide workaround for wide line
This makes wide line supported on MacOS and other implementation that does not support wide line by default. This workaround works for all Line types but only if using one of the 5 default shaders. The workaround is completely isolated and invisible to the outside. It has no side effect. Note: This does not affect the GPUBatch drawing.
Diffstat (limited to 'source/blender/gpu/intern/gpu_immediate.cc')
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc83
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])