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:
authorBastien Montagne <montagne29@wanadoo.fr>2017-05-18 12:41:59 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2017-05-18 13:13:19 +0300
commit23f256b24bed34bb25d1d66ec9ba0726f7a71659 (patch)
tree7dfb39a8a493ff015ac0dae82e07cb6c9795d08f /source/blender/gpu
parent5919919955f6ec40f881705e587355d0334c00ea (diff)
DwM: Armature: add solid envelope bone drawing.
Envelope bones are now pretty much identical to old drawing code. Note that currently new DwM drawing code does not seem to care about wire/solid drawing modes at all, guess this is still TODO... For now we hence just get both wire and solid for envelope bones, this can be refined later.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/CMakeLists.txt1
-rw-r--r--source/blender/gpu/GPU_shader.h1
-rw-r--r--source/blender/gpu/intern/gpu_shader.c4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl127
4 files changed, 133 insertions, 0 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 0a76f5da2ba..fcd50fa30e6 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -172,6 +172,7 @@ data_to_c_simple(shaders/gpu_shader_instance_distance_line_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_groundline_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_groundpoint_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 076ca08cf6e..342608032ab 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -169,6 +169,7 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR,
GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE,
+ GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID,
GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */
} GPUBuiltinShader;
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 62f787b72ab..9c6a16dc180 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -93,6 +93,7 @@ extern char datatoc_gpu_shader_instance_distance_line_vert_glsl[];
extern char datatoc_gpu_shader_instance_edges_variying_color_geom_glsl[];
extern char datatoc_gpu_shader_instance_edges_variying_color_vert_glsl[];
extern char datatoc_gpu_shader_instance_bone_envelope_vert_glsl[];
+extern char datatoc_gpu_shader_instance_bone_envelope_solid_vert_glsl[];
extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[];
extern char datatoc_gpu_shader_3D_groundline_geom_glsl[];
@@ -790,6 +791,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
[GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE] = { datatoc_gpu_shader_instance_bone_envelope_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl },
+ [GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID] = { datatoc_gpu_shader_instance_bone_envelope_solid_vert_glsl,
+ datatoc_gpu_shader_simple_lighting_frag_glsl },
};
if (builtin_shaders[shader] == NULL) {
@@ -806,6 +809,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
defines = "#define AXIS_NAME;\n";
break;
case GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR:
+ case GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID:
defines = "#define USE_INSTANCE_COLOR;\n";
break;
case GPU_SHADER_3D_FLAT_COLOR_U32:
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl
new file mode 100644
index 00000000000..f2e562c3b4a
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl
@@ -0,0 +1,127 @@
+
+
+/* This shader takes a 2D shape, puts it in 3D Object space such that is stays aligned with view and bone,
+ * and scales head/tail/distance according to per-instance attributes
+ * (and 'role' of current vertex, encoded in zw input, head or tail, and inner or outer for distance outline).
+ * It is used for both the distance outline drawing, and the wire version of envelope bone. */
+
+
+uniform mat4 ViewMatrix;
+uniform mat4 ObjectModelMatrix;
+uniform mat4 ViewProjectionMatrix;
+
+
+/* ---- Instanciated Attribs ---- */
+in vec4 pos; /* w encodes head (== 0.0f), tail (== 1.0f) or in-between. */
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+in vec4 color;
+
+in float radius_head;
+in float radius_tail;
+
+
+out vec3 normal;
+flat out vec4 finalColor;
+
+
+void main()
+{
+// gl_Position = ViewProjectionMatrix * ObjectModelMatrix * InstanceModelMatrix * vec4(pos.xyz, 1.0f);
+// normal = pos.xyz;
+// finalColor = color;
+// return;
+
+ /* We get head/tail in object space. */
+ vec4 head = InstanceModelMatrix * vec4(0.0f, 0.0f, 0.0f, 1.0f);
+ vec4 tail = InstanceModelMatrix * vec4(0.0f, 1.0f, 0.0f, 1.0f);
+
+ /* We need rotation from bone mat, but not scaling. */
+ mat3 bone_mat = mat3(InstanceModelMatrix);
+ bone_mat[0] = normalize(bone_mat[0]);
+ bone_mat[1] = normalize(bone_mat[1]);
+ bone_mat[2] = normalize(bone_mat[2]);
+
+ mat3 nor_mat = transpose(inverse(mat3(ViewMatrix * ObjectModelMatrix) * bone_mat));
+
+ /* Where does this comes from???? Don't know why, but is mandatory anyway... :/ */
+ const float size = 2.0f;
+
+ head.xyz *= size;
+ tail.xyz *= size;
+
+ bool head_only = (radius_tail < 0.0f);
+ bool tail_only = (radius_head < 0.0f);
+ /* == 0: head; == 1: tail; in-between: along bone. */
+ float head_fac = head_only ? 0.0f : (tail_only ? 1.0f : pos.w);
+
+ vec4 ob_pos;
+ vec4 ob_bone_origin;
+ float radius;
+
+ /* head */
+ if (head_fac <= 0.0f) {
+ if (!head_only) {
+ /* We are drawing the body itself, need to adjust start/end positions and radius! */
+ vec3 bone_vec = tail.xyz - head.xyz;
+ float len = length(bone_vec);
+
+ if (len > (radius_head + radius_tail)) {
+ float fac = (len - radius_head) / len;
+ radius = fac * radius_head + (1.0f - fac) * radius_tail;
+ bone_vec /= len;
+ ob_bone_origin = vec4(head.xyz + bone_vec * radius_head * size, 1.0f);
+ }
+ else {
+ radius = (radius_head + radius_tail) / 2.0f;
+ ob_bone_origin = (head + tail) / 2.0f;
+ }
+ }
+ else {
+ radius = radius_head;
+ ob_bone_origin = head;
+ }
+ }
+ /* tail */
+ else if (head_fac >= 1.0f) {
+ if (!tail_only) {
+ /* We are drawing the body itself, need to adjust start/end positions and radius! */
+ vec3 bone_vec = tail.xyz - head.xyz;
+ float len = length(bone_vec);
+
+ if (len > (radius_head + radius_tail)) {
+ float fac = (len - radius_tail) / len;
+ radius = fac * radius_tail + (1.0f - fac) * radius_head;
+ bone_vec /= len;
+ ob_bone_origin = vec4(tail.xyz - bone_vec * radius_tail * size, 1.0f);
+ }
+ else {
+ radius = (radius_head + radius_tail) / 2.0f;
+ ob_bone_origin = (head + tail) / 2.0f;
+ }
+ }
+ else {
+ radius = radius_tail;
+ ob_bone_origin = tail;
+ }
+ }
+ /* Body of the bone */
+#if 0 /* Note: not used currently! */
+ else {
+ float tail_fac = 1.0f - head_fac;
+ radius = radius_head * head_fac + radius_tail * tail_fac;
+ ob_bone_origin = head * head_fac + tail * tail_fac;
+ }
+#endif
+
+ /* Yep, since input pos is unit sphere coordinates, it's also our normal. */
+ vec3 nor = pos.xyz;
+ ob_pos = pos * radius * size;
+ ob_pos.xyz = bone_mat * ob_pos.xyz;
+ ob_pos.w = 1.0f;
+
+ gl_Position = ViewProjectionMatrix * ObjectModelMatrix * (ob_pos + ob_bone_origin);
+ normal = normalize(nor_mat * nor);
+ finalColor = color;
+}