Fix #133699: Overlay: Empty as Bone custom shape display error
Add workaround path to process the vertices the same way as the `overlay_extra_vert` shader. We nudge the non-origin vertices in the batch to be able to not require loading the VCLASS attribute. Thus making the change local to the shader and not requiring another shader variant.
This commit is contained in:
@@ -288,6 +288,7 @@ class Armatures : Overlay {
|
||||
sub.shader_set(res.shaders.armature_shape_wire.get());
|
||||
sub.push_constant("alpha", 1.0f);
|
||||
sub.push_constant("do_smooth_wire", do_smooth_wire);
|
||||
sub.push_constant("use_arrow_drawing", false);
|
||||
opaque_.shape_wire = ⊂
|
||||
}
|
||||
if (use_wire_alpha) {
|
||||
@@ -297,6 +298,7 @@ class Armatures : Overlay {
|
||||
sub.bind_texture("depthTex", depth_tex);
|
||||
sub.push_constant("alpha", wire_alpha * 0.6f);
|
||||
sub.push_constant("do_smooth_wire", do_smooth_wire);
|
||||
sub.push_constant("use_arrow_drawing", false);
|
||||
transparent_.shape_wire = ⊂
|
||||
}
|
||||
else {
|
||||
@@ -309,6 +311,7 @@ class Armatures : Overlay {
|
||||
sub.shader_set(res.shaders.armature_shape_wire_strip.get());
|
||||
sub.push_constant("alpha", 1.0f);
|
||||
sub.push_constant("do_smooth_wire", do_smooth_wire);
|
||||
sub.push_constant("use_arrow_drawing", false);
|
||||
opaque_.shape_wire_strip = ⊂
|
||||
}
|
||||
if (use_wire_alpha) {
|
||||
@@ -318,6 +321,7 @@ class Armatures : Overlay {
|
||||
sub.bind_texture("depthTex", depth_tex);
|
||||
sub.push_constant("alpha", wire_alpha * 0.6f);
|
||||
sub.push_constant("do_smooth_wire", do_smooth_wire);
|
||||
sub.push_constant("use_arrow_drawing", false);
|
||||
transparent_.shape_wire_strip = ⊂
|
||||
}
|
||||
else {
|
||||
@@ -593,6 +597,7 @@ class Armatures : Overlay {
|
||||
|
||||
using CustomShapeBuf = MutableMapItem<gpu::Batch *, std::unique_ptr<BoneInstanceBuf>>;
|
||||
|
||||
gpu::Batch *arrow_batch = res.shapes.arrows.get();
|
||||
for (CustomShapeBuf item : bb.custom_shape_fill.items()) {
|
||||
item.value->end_sync(*bb.shape_fill, item.key);
|
||||
}
|
||||
@@ -600,7 +605,19 @@ class Armatures : Overlay {
|
||||
item.value->end_sync(*bb.shape_outline, item.key, GPU_PRIM_LINES, 1);
|
||||
}
|
||||
for (CustomShapeBuf item : bb.custom_shape_wire.items()) {
|
||||
/* WORKAROUND: This shape needs a special vertex shader path that should be triggered by
|
||||
* its vclass attribute. However, to avoid many changes in the primitive expansion API,
|
||||
* we create a specific path inside the shader only for this shape batch and infer the
|
||||
* value of the `vclass` attribute based on the vertex index. */
|
||||
if (item.key == arrow_batch) {
|
||||
bb.shape_wire->push_constant("use_arrow_drawing", true);
|
||||
}
|
||||
|
||||
item.value->end_sync(*bb.shape_wire, item.key, GPU_PRIM_TRIS, 2);
|
||||
|
||||
if (item.key == arrow_batch) {
|
||||
bb.shape_wire->push_constant("use_arrow_drawing", false);
|
||||
}
|
||||
}
|
||||
for (CustomShapeBuf item : bb.custom_shape_wire_strip.items()) {
|
||||
item.value->end_sync(*bb.shape_wire_strip, item.key, GPU_PRIM_TRIS, 2);
|
||||
|
||||
@@ -867,20 +867,23 @@ ShapeCache::ShapeCache()
|
||||
* Fractional part of Z is a positive offset at axis unit position. */
|
||||
int flag = VCLASS_EMPTY_AXES | VCLASS_SCREENALIGNED;
|
||||
/* Center to axis line. */
|
||||
/* NOTE: overlay_armature_shape_wire_vert.glsl expects the axis verts at the origin to be the
|
||||
* only ones with this coordinates (it derives the VCLASS from it). */
|
||||
float pos_on_axis = float(axis) + 1e-8f;
|
||||
verts.append({{0.0f, 0.0f, 0.0f}, 0});
|
||||
verts.append({{0.0f, 0.0f, float(axis)}, flag});
|
||||
verts.append({{0.0f, 0.0f, pos_on_axis}, flag});
|
||||
/* Axis end marker. */
|
||||
constexpr int marker_fill_layer = 6;
|
||||
for (int j = 1; j < marker_fill_layer + 1; j++) {
|
||||
for (float2 axis_marker_vert : axis_marker) {
|
||||
verts.append({{axis_marker_vert * ((4.0f * j) / marker_fill_layer), float(axis)}, flag});
|
||||
verts.append({{axis_marker_vert * ((4.0f * j) / marker_fill_layer), pos_on_axis}, flag});
|
||||
}
|
||||
}
|
||||
/* Axis name. */
|
||||
const Vector<float2> *axis_names[3] = {&x_axis_name, &y_axis_name, &z_axis_name};
|
||||
for (float2 axis_name_vert : *(axis_names[axis])) {
|
||||
int flag = VCLASS_EMPTY_AXES | VCLASS_EMPTY_AXES_NAME | VCLASS_SCREENALIGNED;
|
||||
verts.append({{axis_name_vert * 4.0f, axis + 0.25f}, flag});
|
||||
verts.append({{axis_name_vert * 4.0f, pos_on_axis + 0.25f}, flag});
|
||||
}
|
||||
}
|
||||
arrows = BatchPtr(
|
||||
|
||||
@@ -134,6 +134,7 @@ PUSH_CONSTANT(BOOL, do_smooth_wire)
|
||||
STORAGE_BUF_FREQ(0, READ, float, pos[], GEOMETRY)
|
||||
STORAGE_BUF(1, READ, mat4, data_buf[])
|
||||
PUSH_CONSTANT(IVEC2, gpu_attr_0)
|
||||
PUSH_CONSTANT(BOOL, use_arrow_drawing)
|
||||
VERTEX_OUT(overlay_armature_shape_wire_iface)
|
||||
VERTEX_SOURCE("overlay_armature_shape_wire_vert.glsl")
|
||||
FRAGMENT_SOURCE("overlay_armature_shape_wire_frag.glsl")
|
||||
|
||||
@@ -38,7 +38,30 @@ VertOut vertex_main(VertIn v_in)
|
||||
mat4 model_mat = extract_matrix_packed_data(v_in.inst_matrix, state_color, bone_color);
|
||||
|
||||
VertOut v_out;
|
||||
v_out.world_pos = (model_mat * vec4(v_in.lP, 1.0)).xyz;
|
||||
|
||||
/* WORKAROUND: This shape needs a special vertex shader path that should be triggered by
|
||||
* its vclass attribute. However, to avoid many changes in the primitive expansion API,
|
||||
* we create a specific path inside the shader only for this shape batch and infer the
|
||||
* value of the `vclass` attribute based on the vertex index. */
|
||||
if (use_arrow_drawing) {
|
||||
/* Keep in sync with the arrows shape batch creation. */
|
||||
/* Adapted from overlay_extra_vert.glsl. */
|
||||
vec3 vpos = v_in.lP;
|
||||
vec3 vofs = vec3(0.0);
|
||||
uint axis = uint(vpos.z);
|
||||
/* Assumes origin vertices are the only one at Z=0. */
|
||||
if (vpos.z > 0.0) {
|
||||
vofs[axis] = (1.0 + fract(vpos.z));
|
||||
}
|
||||
/* Scale uniformly by axis length */
|
||||
vpos *= length(model_mat[axis].xyz);
|
||||
/* World sized, camera facing geometry. */
|
||||
vec3 screen_pos = ViewMatrixInverse[0].xyz * vpos.x + ViewMatrixInverse[1].xyz * vpos.y;
|
||||
v_out.world_pos = (model_mat * vec4(vofs, 1.0)).xyz + screen_pos;
|
||||
}
|
||||
else {
|
||||
v_out.world_pos = (model_mat * vec4(v_in.lP, 1.0)).xyz;
|
||||
}
|
||||
v_out.gpu_position = drw_point_world_to_homogenous(v_out.world_pos);
|
||||
|
||||
v_out.finalColor.rgb = mix(state_color.rgb, bone_color.rgb, 0.5);
|
||||
|
||||
Reference in New Issue
Block a user