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/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])