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>2018-04-30 23:35:30 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-05-02 21:49:38 +0300
commita76d27f6942ce4497e95462fd57ca67ab5c9cc6d (patch)
tree3e5b68d5bd55296993160df72717c9e5fe91c538 /source/blender/draw/intern/draw_cache.c
parent01cec3e0c52184f288a9af28b67d09965ebb0b03 (diff)
Armature: Add envelope outline shader.
Diffstat (limited to 'source/blender/draw/intern/draw_cache.c')
-rw-r--r--source/blender/draw/intern/draw_cache.c93
1 files changed, 40 insertions, 53 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 1b41ff311a8..db0f891c730 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -86,8 +86,7 @@ static struct DRWShapeCache {
Gwn_Batch *drw_bone_wire_wire;
Gwn_Batch *drw_bone_envelope;
Gwn_Batch *drw_bone_envelope_distance;
- Gwn_Batch *drw_bone_envelope_wire;
- Gwn_Batch *drw_bone_envelope_head_wire;
+ Gwn_Batch *drw_bone_envelope_outline;
Gwn_Batch *drw_bone_point;
Gwn_Batch *drw_bone_point_wire;
Gwn_Batch *drw_bone_arrows;
@@ -1959,71 +1958,59 @@ Gwn_Batch *DRW_cache_bone_envelope_solid_get(void)
return SHC.drw_bone_envelope;
}
-/* Bone body. */
-Gwn_Batch *DRW_cache_bone_envelope_wire_outline_get(void)
+Gwn_Batch *DRW_cache_bone_envelope_outline_get(void)
{
- if (!SHC.drw_bone_envelope_wire) {
- unsigned int v_idx = 0;
-
- static Gwn_VertFormat format = { 0 };
- static unsigned int pos_id;
- if (format.attrib_ct == 0) {
- pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
- }
-
- /* Vertices */
- Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, 4);
-
- /* Two lines between head and tail circles. */
- /* Encoded lines, vertex shader gives them final correct value. */
- /* { X, Y, head/tail, inner/outer border } */
- GWN_vertbuf_attr_set(vbo, pos_id, v_idx++, (const float[4]){ 1.0f, 0.0f, 0.0f, 0.0f});
- GWN_vertbuf_attr_set(vbo, pos_id, v_idx++, (const float[4]){ 1.0f, 0.0f, 1.0f, 0.0f});
- GWN_vertbuf_attr_set(vbo, pos_id, v_idx++, (const float[4]){-1.0f, 0.0f, 0.0f, 0.0f});
- GWN_vertbuf_attr_set(vbo, pos_id, v_idx++, (const float[4]){-1.0f, 0.0f, 1.0f, 0.0f});
-
- SHC.drw_bone_envelope_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
- }
- return SHC.drw_bone_envelope_wire;
-}
-
-
-/* Bone head and tail. */
-Gwn_Batch *DRW_cache_bone_envelope_head_wire_outline_get(void)
-{
-#define CIRCLE_RESOL 32 /* Must be multiple of 2 */
- if (!SHC.drw_bone_envelope_head_wire) {
- unsigned int v_idx = 0;
+ if (!SHC.drw_bone_envelope_outline) {
+# define CIRCLE_RESOL 64
+ float v0[2], v1[2], v2[2];
+ const float radius = 1.0f;
+ /* Position Only 2D format */
static Gwn_VertFormat format = { 0 };
- static unsigned int pos_id;
+ static struct { uint pos0, pos1, pos2; } attr_id;
if (format.attrib_ct == 0) {
- pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ attr_id.pos0 = GWN_vertformat_attr_add(&format, "pos0", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ attr_id.pos1 = GWN_vertformat_attr_add(&format, "pos1", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ attr_id.pos2 = GWN_vertformat_attr_add(&format, "pos2", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
}
- /* Vertices */
Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL);
+ GWN_vertbuf_data_alloc(vbo, (CIRCLE_RESOL + 1) * 2);
- /* Encoded lines, vertex shader gives them final correct value. */
- /* Only head circle (tail is drawn in disp_tail_mat space as a head one by draw_armature.c's draw_point()). */
- for (int i = 0; i < CIRCLE_RESOL; i++) {
- const float alpha = 2.0f * M_PI * i / CIRCLE_RESOL;
- const float x = cosf(alpha);
- const float y = -sinf(alpha);
+ v0[0] = radius * sinf((2.0f * M_PI * -2) / ((float)CIRCLE_RESOL));
+ v0[1] = radius * cosf((2.0f * M_PI * -2) / ((float)CIRCLE_RESOL));
+ v1[0] = radius * sinf((2.0f * M_PI * -1) / ((float)CIRCLE_RESOL));
+ v1[1] = radius * cosf((2.0f * M_PI * -1) / ((float)CIRCLE_RESOL));
- /* { X, Y, head/tail, inner/outer border } */
- GWN_vertbuf_attr_set(vbo, pos_id, v_idx++, (const float[4]){ x, y, 0.0f, 0.0f});
+ /* Output 4 verts for each position. See shader for explanation. */
+ unsigned int v = 0;
+ for (int a = 0; a < CIRCLE_RESOL; a++) {
+ v2[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ v2[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+ GWN_vertbuf_attr_set(vbo, attr_id.pos0, v , v0);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos1, v , v1);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos0, v , v0);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos1, v , v1);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2);
+ copy_v2_v2(v0, v1);
+ copy_v2_v2(v1, v2);
}
+ v2[0] = 0.0f;
+ v2[1] = radius;
+ GWN_vertbuf_attr_set(vbo, attr_id.pos0, v , v0);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos1, v , v1);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos0, v , v0);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos1, v , v1);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2);
- SHC.drw_bone_envelope_head_wire = GWN_batch_create_ex(GWN_PRIM_LINE_LOOP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ SHC.drw_bone_envelope_outline = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+# undef CIRCLE_RESOL
}
- return SHC.drw_bone_envelope_head_wire;
-#undef CIRCLE_RESOL
+ return SHC.drw_bone_envelope_outline;
}
-
Gwn_Batch *DRW_cache_bone_point_get(void)
{
if (!SHC.drw_bone_point) {