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/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/intern/draw_armature.c74
-rw-r--r--source/blender/draw/intern/draw_cache.c77
-rw-r--r--source/blender/draw/intern/draw_cache.h1
-rw-r--r--source/blender/draw/intern/draw_common.c28
-rw-r--r--source/blender/draw/intern/draw_common.h1
-rw-r--r--source/blender/draw/modes/shaders/armature_stick_frag.glsl13
-rw-r--r--source/blender/draw/modes/shaders/armature_stick_vert.glsl88
8 files changed, 280 insertions, 4 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 53d46575a62..71285d7ba04 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -236,6 +236,8 @@ data_to_c_simple(modes/shaders/armature_shape_solid_vert.glsl SRC)
data_to_c_simple(modes/shaders/armature_shape_solid_frag.glsl SRC)
data_to_c_simple(modes/shaders/armature_shape_outline_vert.glsl SRC)
data_to_c_simple(modes/shaders/armature_shape_outline_geom.glsl SRC)
+data_to_c_simple(modes/shaders/armature_stick_vert.glsl SRC)
+data_to_c_simple(modes/shaders/armature_stick_frag.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_frag.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_vert.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_geom_tri.glsl SRC)
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
index 1a2ff70624b..efbf1143c16 100644
--- a/source/blender/draw/intern/draw_armature.c
+++ b/source/blender/draw/intern/draw_armature.c
@@ -82,6 +82,7 @@ static struct {
DRWShadingGroup *bone_box_wire;
DRWShadingGroup *bone_box_outline;
DRWShadingGroup *bone_wire_wire;
+ DRWShadingGroup *bone_stick;
DRWShadingGroup *bone_envelope_solid;
DRWShadingGroup *bone_envelope_distance;
DRWShadingGroup *bone_envelope_wire;
@@ -181,6 +182,20 @@ static void drw_shgroup_bone_wire_wire(const float (*bone_mat)[4], const float c
DRW_shgroup_call_dynamic_add(g_data.bone_wire_wire, final_bonemat, color);
}
+static void drw_shgroup_bone_stick(
+ const float (*bone_mat)[4],
+ const float col_wire[4], const float col_bone[4], const float col_head[4], const float col_tail[4])
+{
+ if (g_data.bone_stick == NULL) {
+ g_data.bone_stick = shgroup_instance_bone_stick(g_data.passes.bone_wire);
+ }
+ float final_bonemat[4][4], tail[4];
+ mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
+ add_v3_v3v3(tail, final_bonemat[3], final_bonemat[1]);
+ DRW_shgroup_call_dynamic_add(g_data.bone_stick, final_bonemat[3], tail, col_wire, col_bone, col_head, col_tail);
+}
+
+
/* Envelope */
static void drw_shgroup_bone_envelope_distance(
const float (*bone_mat)[4],
@@ -1192,11 +1207,62 @@ static void draw_bone_envelope(
}
static void draw_bone_line(
- EditBone *UNUSED(eBone), bPoseChannel *UNUSED(pchan), bArmature *UNUSED(arm),
- const int UNUSED(boneflag), const short UNUSED(constflag),
- const int UNUSED(select_id))
+ EditBone *eBone, bPoseChannel *pchan, bArmature *arm,
+ const int boneflag, const short constflag, const int select_id)
{
- /* work in progress -- fclem */
+ const float *col_bone = get_bone_solid_with_consts_color(eBone, pchan, arm, boneflag, constflag);
+ const float *col_wire = get_bone_wire_color(eBone, pchan, arm, boneflag, constflag);
+ const float no_display[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float *col_head = no_display;
+ const float *col_tail = col_bone;
+
+ if (eBone) {
+ if (eBone->flag & BONE_TIPSEL) {
+ col_tail = g_theme.vertex_select_color;
+ }
+ if (boneflag & BONE_SELECTED) {
+ col_bone = g_theme.edge_select_color;
+ }
+ col_wire = g_theme.wire_color;
+ }
+
+ /* Draw root point if we are not connected and parent are not hidden */
+ if ((BONE_FLAG(eBone, pchan) & BONE_CONNECTED) == 0) {
+ if (eBone && !(eBone->parent && !EBONE_VISIBLE(arm, eBone->parent))) {
+ col_head = (eBone->flag & BONE_ROOTSEL) ? g_theme.vertex_select_color : col_bone;
+ }
+ else if (pchan) {
+ Bone *bone = pchan->bone;
+ if (!(bone->parent && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)))) {
+ col_head = col_bone;
+ }
+ }
+ }
+
+ if (g_theme.const_color != NULL) {
+ col_wire = no_display; /* actually shrink the display. */
+ col_bone = col_head = col_tail = g_theme.const_color;
+ }
+
+ if (select_id == -1) {
+ /* Not in selection mode, draw everything at once. */
+ drw_shgroup_bone_stick(BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, col_head, col_tail);
+ }
+ else {
+ /* In selection mode, draw bone, root and tip separatly. */
+ DRW_select_load_id(select_id | BONESEL_BONE);
+ drw_shgroup_bone_stick(BONE_VAR(eBone, pchan, disp_mat), col_wire, col_bone, no_display, no_display);
+
+ if (col_head[3] > 0.0f) {
+ DRW_select_load_id(select_id | BONESEL_ROOT);
+ drw_shgroup_bone_stick(BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, col_head, no_display);
+ }
+
+ DRW_select_load_id(select_id | BONESEL_TIP);
+ drw_shgroup_bone_stick(BONE_VAR(eBone, pchan, disp_mat), col_wire, no_display, no_display, col_tail);
+
+ DRW_select_load_id(-1);
+ }
}
static void draw_bone_wire(
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 1a4a9be00bd..2366fa556b9 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -88,6 +88,7 @@ static struct DRWShapeCache {
Gwn_Batch *drw_bone_envelope_outline;
Gwn_Batch *drw_bone_point;
Gwn_Batch *drw_bone_point_wire;
+ Gwn_Batch *drw_bone_stick;
Gwn_Batch *drw_bone_arrows;
Gwn_Batch *drw_camera;
Gwn_Batch *drw_camera_frame;
@@ -2104,6 +2105,82 @@ Gwn_Batch *DRW_cache_bone_point_wire_outline_get(void)
return SHC.drw_bone_point_wire;
}
+/* keep in sync with armature_stick_vert.glsl */
+#define COL_WIRE (1 << 0)
+#define COL_HEAD (1 << 1)
+#define COL_TAIL (1 << 2)
+#define COL_BONE (1 << 3)
+
+#define POS_HEAD (1 << 4)
+#define POS_TAIL (1 << 5)
+#define POS_BONE (1 << 6)
+
+Gwn_Batch *DRW_cache_bone_stick_get(void)
+{
+ if (!SHC.drw_bone_stick) {
+#define CIRCLE_RESOL 12
+ unsigned int v = 0;
+ unsigned int flag;
+ const float radius = 2.0f; /* head/tail radius */
+ float pos[2];
+
+ /* Position Only 2D format */
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, flag; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ attr_id.flag = GWN_vertformat_attr_add(&format, "flag", GWN_COMP_U32, 1, GWN_FETCH_INT);
+ }
+
+ const unsigned int vcount = (CIRCLE_RESOL + 1) * 2 + 6;
+
+ Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vcount);
+
+ Gwn_IndexBufBuilder elb;
+ GWN_indexbuf_init_ex(&elb, GWN_PRIM_TRI_FAN, (CIRCLE_RESOL + 2) * 2 + 6 + 2, vcount, true);
+
+ /* head/tail points */
+ for (int i = 0; i < 2; ++i) {
+ /* center vertex */
+ copy_v2_fl(pos, 0.0f);
+ flag = (i == 0) ? POS_HEAD : POS_TAIL;
+ flag |= (i == 0) ? COL_HEAD : COL_TAIL;
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, v, pos);
+ GWN_vertbuf_attr_set(vbo, attr_id.flag, v, &flag);
+ GWN_indexbuf_add_generic_vert(&elb, v++);
+ /* circle vertices */
+ flag |= COL_WIRE;
+ for (int a = 0; a < CIRCLE_RESOL; a++) {
+ pos[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ pos[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, v, pos);
+ GWN_vertbuf_attr_set(vbo, attr_id.flag, v, &flag);
+ GWN_indexbuf_add_generic_vert(&elb, v++);
+ }
+ /* Close the circle */
+ GWN_indexbuf_add_generic_vert(&elb, v - CIRCLE_RESOL);
+
+ GWN_indexbuf_add_primitive_restart(&elb);
+ }
+
+ /* Bone rectangle */
+ pos[0] = 0.0f;
+ for (int i = 0; i < 6; ++i) {
+ pos[1] = (i == 0 || i == 3) ? 0.0f : ((i < 3) ? 1.0f : -1.0f);
+ flag = ((i < 2 || i > 4) ? POS_HEAD : POS_TAIL) |
+ ((i == 0 || i == 3) ? 0 : COL_WIRE) | COL_BONE | POS_BONE;
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, v, pos);
+ GWN_vertbuf_attr_set(vbo, attr_id.flag, v, &flag);
+ GWN_indexbuf_add_generic_vert(&elb, v++);
+ }
+
+ SHC.drw_bone_stick = GWN_batch_create_ex(GWN_PRIM_TRI_FAN, vbo, GWN_indexbuf_build(&elb), GWN_BATCH_OWNS_VBO);
+#undef CIRCLE_RESOL
+ }
+ return SHC.drw_bone_stick;
+}
+
static void set_bone_axis_vert(
Gwn_VertBuf *vbo, uint axis, uint pos, uint col,
unsigned int *v, const float *a, const float *p, const float *c)
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 22a5588599f..18bff56920e 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -105,6 +105,7 @@ struct Gwn_Batch *DRW_cache_bone_envelope_outline_get(void);
struct Gwn_Batch *DRW_cache_bone_envelope_head_wire_outline_get(void);
struct Gwn_Batch *DRW_cache_bone_point_get(void);
struct Gwn_Batch *DRW_cache_bone_point_wire_outline_get(void);
+struct Gwn_Batch *DRW_cache_bone_stick_get(void);
struct Gwn_Batch *DRW_cache_bone_arrows_get(void);
/* Meshes */
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index 2c606aa57d7..ba5e04df512 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -165,6 +165,8 @@ extern char datatoc_armature_shape_solid_vert_glsl[];
extern char datatoc_armature_shape_solid_frag_glsl[];
extern char datatoc_armature_shape_outline_vert_glsl[];
extern char datatoc_armature_shape_outline_geom_glsl[];
+extern char datatoc_armature_stick_vert_glsl[];
+extern char datatoc_armature_stick_frag_glsl[];
extern char datatoc_gpu_shader_flat_color_frag_glsl[];
extern char datatoc_object_mball_handles_vert_glsl[];
@@ -178,6 +180,7 @@ static struct {
struct GPUShader *bone_envelope_outline;
struct GPUShader *bone_sphere;
struct GPUShader *bone_sphere_outline;
+ struct GPUShader *bone_stick;
struct GPUShader *mball_handles;
} g_shaders = {NULL};
@@ -194,6 +197,7 @@ static struct {
struct Gwn_VertFormat *instance_distance_lines;
struct Gwn_VertFormat *instance_spot;
struct Gwn_VertFormat *instance_bone;
+ struct Gwn_VertFormat *instance_bone_stick;
struct Gwn_VertFormat *instance_bone_outline;
struct Gwn_VertFormat *instance_bone_envelope;
struct Gwn_VertFormat *instance_bone_envelope_distance;
@@ -638,6 +642,30 @@ DRWShadingGroup *shgroup_instance_bone_sphere_outline(DRWPass *pass)
return grp;
}
+DRWShadingGroup *shgroup_instance_bone_stick(DRWPass *pass)
+{
+ if (g_shaders.bone_stick == NULL) {
+ g_shaders.bone_stick = DRW_shader_create(
+ datatoc_armature_stick_vert_glsl, NULL,
+ datatoc_armature_stick_frag_glsl, NULL);
+ }
+
+ DRW_shgroup_instance_format(g_formats.instance_bone_stick, {
+ {"boneStart", DRW_ATTRIB_FLOAT, 3},
+ {"boneEnd" , DRW_ATTRIB_FLOAT, 3},
+ {"wireColor", DRW_ATTRIB_FLOAT, 4}, /* TODO port theses to uchar color */
+ {"boneColor", DRW_ATTRIB_FLOAT, 4},
+ {"headColor", DRW_ATTRIB_FLOAT, 4},
+ {"tailColor", DRW_ATTRIB_FLOAT, 4}
+ });
+
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_stick,
+ pass, DRW_cache_bone_stick_get(),
+ g_formats.instance_bone_stick);
+ DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
+
+ return grp;
+}
/* ******************************************** COLOR UTILS *********************************************** */
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 8730be54d93..dca92188ca7 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -124,6 +124,7 @@ struct DRWShadingGroup *shgroup_instance_bone_shape_outline(struct DRWPass *pass
struct DRWShadingGroup *shgroup_instance_bone_shape_solid(struct DRWPass *pass, struct Gwn_Batch *geom);
struct DRWShadingGroup *shgroup_instance_bone_sphere_outline(struct DRWPass *pass);
struct DRWShadingGroup *shgroup_instance_bone_sphere_solid(struct DRWPass *pass);
+struct DRWShadingGroup *shgroup_instance_bone_stick(struct DRWPass *pass);
int DRW_object_wire_theme_get(
struct Object *ob, struct ViewLayer *view_layer, float **r_color);
diff --git a/source/blender/draw/modes/shaders/armature_stick_frag.glsl b/source/blender/draw/modes/shaders/armature_stick_frag.glsl
new file mode 100644
index 00000000000..d03cf4c0366
--- /dev/null
+++ b/source/blender/draw/modes/shaders/armature_stick_frag.glsl
@@ -0,0 +1,13 @@
+
+noperspective in float colorFac;
+flat in vec4 finalWireColor;
+flat in vec4 finalInnerColor;
+
+out vec4 fragColor;
+
+void main()
+{
+ float fac = smoothstep(1.0, 0.2, colorFac);
+ fragColor.rgb = mix(finalInnerColor.rgb, finalWireColor.rgb, fac);
+ fragColor.a = 1.0;
+}
diff --git a/source/blender/draw/modes/shaders/armature_stick_vert.glsl b/source/blender/draw/modes/shaders/armature_stick_vert.glsl
new file mode 100644
index 00000000000..eb14239bc6f
--- /dev/null
+++ b/source/blender/draw/modes/shaders/armature_stick_vert.glsl
@@ -0,0 +1,88 @@
+
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewProjectionMatrix;
+uniform mat4 ViewMatrix;
+uniform vec2 viewportSize;
+
+/* ---- Instanciated Attribs ---- */
+in vec2 pos; /* bone aligned screen space */
+in uint flag;
+
+#define COL_WIRE (1u << 0u)
+#define COL_HEAD (1u << 1u)
+#define COL_TAIL (1u << 2u)
+#define COL_BONE (1u << 3u)
+
+#define POS_HEAD (1u << 4u)
+#define POS_TAIL (1u << 5u) /* UNUSED */
+#define POS_BONE (1u << 6u)
+
+/* ---- Per instance Attribs ---- */
+in vec3 boneStart;
+in vec3 boneEnd;
+in vec4 wireColor; /* alpha encode if we do wire. If 0.0 we dont. */
+in vec4 boneColor; /* alpha encode if we do bone. If 0.0 we dont. */
+in vec4 headColor; /* alpha encode if we do head. If 0.0 we dont. */
+in vec4 tailColor; /* alpha encode if we do tail. If 0.0 we dont. */
+
+#define do_wire (wireColor.a > 0.0)
+#define is_head ((flag & POS_HEAD) != 0u)
+#define is_bone ((flag & POS_BONE) != 0u)
+
+noperspective out float colorFac;
+flat out vec4 finalWireColor;
+flat out vec4 finalInnerColor;
+
+uniform float stickSize = 5.0; /* might be dependant on DPI setting in the future. */
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+void main()
+{
+ finalInnerColor = ((flag & COL_HEAD) != 0u) ? headColor : tailColor;
+ finalInnerColor = ((flag & COL_BONE) != 0u) ? boneColor : finalInnerColor;
+ finalWireColor = (do_wire) ? wireColor : finalInnerColor;
+ /* Make the color */
+ colorFac = ((flag & COL_WIRE) == 0u) ? ((flag & COL_BONE) != 0u) ? 1.0 : 2.0 : 0.0;
+
+ vec4 v0 = ViewMatrix * vec4(boneStart, 1.0);
+ vec4 v1 = ViewMatrix * vec4(boneEnd, 1.0);
+
+ /* Clip the bone to the camera origin plane (not the clip plane)
+ * to avoid glitches if one end is behind the camera origin (in persp). */
+ const float clip_dist = -1e-7; /* hardcoded, -1e-8 is giving gliches. */
+ vec3 bvec = v1.xyz - v0.xyz;
+ vec3 clip_pt = v0.xyz + bvec * ((v0.z - clip_dist) / -bvec.z);
+ if (v0.z > clip_dist) {
+ v0.xyz = clip_pt;
+ }
+ else if (v1.z > clip_dist) {
+ v1.xyz = clip_pt;
+ }
+
+ vec4 p0 = ProjectionMatrix * v0;
+ vec4 p1 = ProjectionMatrix * v1;
+
+ float h = (is_head) ? p0.w : p1.w;
+
+ vec2 x_screen_vec = normalize(proj(p1) - proj(p0) + 1e-8);
+ vec2 y_screen_vec = vec2(x_screen_vec.y, -x_screen_vec.x);
+
+ /* 2D screen aligned pos at the point */
+ vec2 vpos = pos.x * x_screen_vec + pos.y * y_screen_vec;
+ vpos *= (ProjectionMatrix[3][3] == 0.0) ? h : 1.0;
+ vpos *= (do_wire) ? 1.0 : 0.5;
+
+ if (finalInnerColor.a > 0.0) {
+ gl_Position = (is_head) ? p0 : p1;
+ gl_Position.xy += stickSize * (vpos / viewportSize);
+ gl_Position.z += (is_bone) ? 0.0 : 1e-6; /* Avoid Z fighting of head/tails. */
+ }
+ else {
+ gl_Position = vec4(0.0);
+ }
+}