Merge pull request #48402 from lawnjelly/ewok_skin_basexform
Fix 2d software skinning relative transforms
This commit is contained in:
commit
2d1aeac6fd
3 changed files with 33 additions and 12 deletions
|
@ -2194,7 +2194,7 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
|
||||||
_set_uniforms();
|
_set_uniforms();
|
||||||
|
|
||||||
if (unshaded || (state.uniforms.final_modulate.a > 0.001 && (!r_ris.shader_cache || r_ris.shader_cache->canvas_item.light_mode != RasterizerStorageGLES2::Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY) && !ci->light_masked))
|
if (unshaded || (state.uniforms.final_modulate.a > 0.001 && (!r_ris.shader_cache || r_ris.shader_cache->canvas_item.light_mode != RasterizerStorageGLES2::Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY) && !ci->light_masked))
|
||||||
render_joined_item_commands(p_bij, NULL, reclip, material_ptr, false);
|
render_joined_item_commands(p_bij, NULL, reclip, material_ptr, false, r_ris);
|
||||||
|
|
||||||
r_ris.rebind_shader = true; // hacked in for now.
|
r_ris.rebind_shader = true; // hacked in for now.
|
||||||
|
|
||||||
|
@ -2288,10 +2288,10 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
|
||||||
// this can greatly reduce fill rate ..
|
// this can greatly reduce fill rate ..
|
||||||
// at the cost of glScissor commands, so is optional
|
// at the cost of glScissor commands, so is optional
|
||||||
if (!bdata.settings_scissor_lights || r_ris.current_clip) {
|
if (!bdata.settings_scissor_lights || r_ris.current_clip) {
|
||||||
render_joined_item_commands(p_bij, NULL, reclip, material_ptr, true);
|
render_joined_item_commands(p_bij, NULL, reclip, material_ptr, true, r_ris);
|
||||||
} else {
|
} else {
|
||||||
bool scissor = _light_scissor_begin(p_bij.bounding_rect, light->xform_cache, light->rect_cache);
|
bool scissor = _light_scissor_begin(p_bij.bounding_rect, light->xform_cache, light->rect_cache);
|
||||||
render_joined_item_commands(p_bij, NULL, reclip, material_ptr, true);
|
render_joined_item_commands(p_bij, NULL, reclip, material_ptr, true, r_ris);
|
||||||
if (scissor) {
|
if (scissor) {
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1487,7 +1487,7 @@ void RasterizerCanvasGLES3::render_joined_item(const BItemJoined &p_bij, RenderI
|
||||||
}
|
}
|
||||||
if (unshaded || (state.canvas_item_modulate.a > 0.001 && (!r_ris.shader_cache || r_ris.shader_cache->canvas_item.light_mode != RasterizerStorageGLES3::Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY) && !p_ci->light_masked)) {
|
if (unshaded || (state.canvas_item_modulate.a > 0.001 && (!r_ris.shader_cache || r_ris.shader_cache->canvas_item.light_mode != RasterizerStorageGLES3::Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY) && !p_ci->light_masked)) {
|
||||||
RasterizerStorageGLES3::Material *material_ptr = nullptr;
|
RasterizerStorageGLES3::Material *material_ptr = nullptr;
|
||||||
render_joined_item_commands(p_bij, NULL, reclip, material_ptr, false);
|
render_joined_item_commands(p_bij, NULL, reclip, material_ptr, false, r_ris);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((blend_mode == RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX || blend_mode == RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA) && r_ris.item_group_light && !unshaded) {
|
if ((blend_mode == RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX || blend_mode == RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA) && r_ris.item_group_light && !unshaded) {
|
||||||
|
@ -1602,10 +1602,10 @@ void RasterizerCanvasGLES3::render_joined_item(const BItemJoined &p_bij, RenderI
|
||||||
// this can greatly reduce fill rate ..
|
// this can greatly reduce fill rate ..
|
||||||
// at the cost of glScissor commands, so is optional
|
// at the cost of glScissor commands, so is optional
|
||||||
if (!bdata.settings_scissor_lights || r_ris.current_clip) {
|
if (!bdata.settings_scissor_lights || r_ris.current_clip) {
|
||||||
render_joined_item_commands(p_bij, NULL, reclip, nullptr, true);
|
render_joined_item_commands(p_bij, NULL, reclip, nullptr, true, r_ris);
|
||||||
} else {
|
} else {
|
||||||
bool scissor = _light_scissor_begin(p_bij.bounding_rect, light->xform_cache, light->rect_cache);
|
bool scissor = _light_scissor_begin(p_bij.bounding_rect, light->xform_cache, light->rect_cache);
|
||||||
render_joined_item_commands(p_bij, NULL, reclip, nullptr, true);
|
render_joined_item_commands(p_bij, NULL, reclip, nullptr, true, r_ris);
|
||||||
if (scissor) {
|
if (scissor) {
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,6 +504,7 @@ public:
|
||||||
bool extra_matrix_sent; // whether sent on this item (in which case sofware transform can't be used untl end of item)
|
bool extra_matrix_sent; // whether sent on this item (in which case sofware transform can't be used untl end of item)
|
||||||
int transform_extra_command_number_p1; // plus one to allow fast checking against zero
|
int transform_extra_command_number_p1; // plus one to allow fast checking against zero
|
||||||
Transform2D transform_combined; // final * extra
|
Transform2D transform_combined; // final * extra
|
||||||
|
Transform2D skeleton_base_inverse_xform; // used in software skinning
|
||||||
};
|
};
|
||||||
|
|
||||||
// used during try_join
|
// used during try_join
|
||||||
|
@ -587,7 +588,7 @@ protected:
|
||||||
bool _detect_item_batch_break(RenderItemState &r_ris, RasterizerCanvas::Item *p_ci, bool &r_batch_break);
|
bool _detect_item_batch_break(RenderItemState &r_ris, RasterizerCanvas::Item *p_ci, bool &r_batch_break);
|
||||||
|
|
||||||
// drives the loop filling batches and flushing
|
// drives the loop filling batches and flushing
|
||||||
void render_joined_item_commands(const BItemJoined &p_bij, RasterizerCanvas::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, bool p_lit);
|
void render_joined_item_commands(const BItemJoined &p_bij, RasterizerCanvas::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, bool p_lit, const RenderItemState &p_ris);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// flush once full or end of joined item
|
// flush once full or end of joined item
|
||||||
|
@ -1824,9 +1825,12 @@ PREAMBLE(bool)::_software_skin_poly(RasterizerCanvas::Item::CommandPolygon *p_po
|
||||||
Vector2 *pTemps = (Vector2 *)alloca(num_verts * sizeof(Vector2));
|
Vector2 *pTemps = (Vector2 *)alloca(num_verts * sizeof(Vector2));
|
||||||
memset((void *)pTemps, 0, num_verts * sizeof(Vector2));
|
memset((void *)pTemps, 0, num_verts * sizeof(Vector2));
|
||||||
|
|
||||||
// these are used in the shader but don't appear to be needed for software transform
|
// only the inverse appears to be needed
|
||||||
// const Transform2D &skel_trans = get_this()->state.skeleton_transform;
|
const Transform2D &skel_trans_inv = p_fill_state.skeleton_base_inverse_xform;
|
||||||
// const Transform2D &skel_trans_inv = get_this()->state.skeleton_transform_inverse;
|
// we can't get this from the state, because more than one skeleton item may have been joined together..
|
||||||
|
// we need to handle the base skeleton on a per item basis as the joined item is rendered.
|
||||||
|
// const Transform2D &skel_trans = get_this()->state.skeleton_transform;
|
||||||
|
// const Transform2D &skel_trans_inv = get_this()->state.skeleton_transform_inverse;
|
||||||
|
|
||||||
// get the bone transforms.
|
// get the bone transforms.
|
||||||
// this is not ideal because we don't know in advance which bones are needed
|
// this is not ideal because we don't know in advance which bones are needed
|
||||||
|
@ -1838,7 +1842,10 @@ PREAMBLE(bool)::_software_skin_poly(RasterizerCanvas::Item::CommandPolygon *p_po
|
||||||
|
|
||||||
if (num_verts && (p_poly->bones.size() == num_verts * 4) && (p_poly->weights.size() == p_poly->bones.size())) {
|
if (num_verts && (p_poly->bones.size() == num_verts * 4) && (p_poly->weights.size() == p_poly->bones.size())) {
|
||||||
|
|
||||||
const Transform2D &item_transform = p_item->xform;
|
// instead of using the p_item->xform we use the final transform,
|
||||||
|
// because we want the poly transform RELATIVE to the base skeleton.
|
||||||
|
Transform2D item_transform = skel_trans_inv * p_item->final_transform;
|
||||||
|
|
||||||
Transform2D item_transform_inv = item_transform.affine_inverse();
|
Transform2D item_transform_inv = item_transform.affine_inverse();
|
||||||
|
|
||||||
for (int n = 0; n < num_verts; n++) {
|
for (int n = 0; n < num_verts; n++) {
|
||||||
|
@ -2534,7 +2541,7 @@ PREAMBLE(void)::flush_render_batches(RasterizerCanvas::Item *p_first_item, Raste
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
PREAMBLE(void)::render_joined_item_commands(const BItemJoined &p_bij, RasterizerCanvas::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, bool p_lit) {
|
PREAMBLE(void)::render_joined_item_commands(const BItemJoined &p_bij, RasterizerCanvas::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, bool p_lit, const RenderItemState &p_ris) {
|
||||||
|
|
||||||
RasterizerCanvas::Item *item = 0;
|
RasterizerCanvas::Item *item = 0;
|
||||||
RasterizerCanvas::Item *first_item = bdata.item_refs[p_bij.first_item_ref].item;
|
RasterizerCanvas::Item *first_item = bdata.item_refs[p_bij.first_item_ref].item;
|
||||||
|
@ -2581,6 +2588,20 @@ PREAMBLE(void)::render_joined_item_commands(const BItemJoined &p_bij, Rasterizer
|
||||||
// prefill_joined_item()
|
// prefill_joined_item()
|
||||||
fill_state.transform_combined = item->final_transform;
|
fill_state.transform_combined = item->final_transform;
|
||||||
|
|
||||||
|
// calculate skeleton base inverse transform if required for software skinning
|
||||||
|
// put in the fill state as this is readily accessible from the software skinner
|
||||||
|
if (item->skeleton.is_valid() && bdata.settings_use_software_skinning && get_storage()->skeleton_owner.owns(item->skeleton)) {
|
||||||
|
typename T_STORAGE::Skeleton *skeleton = nullptr;
|
||||||
|
skeleton = get_storage()->skeleton_owner.get(item->skeleton);
|
||||||
|
|
||||||
|
if (skeleton->use_2d) {
|
||||||
|
// with software skinning we still need to know the skeleton inverse transform, the other two aren't needed
|
||||||
|
// but are left in for simplicity here
|
||||||
|
Transform2D skeleton_transform = p_ris.item_group_base_transform * skeleton->base_transform_2d;
|
||||||
|
fill_state.skeleton_base_inverse_xform = skeleton_transform.affine_inverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// decide the initial transform mode, and make a backup
|
// decide the initial transform mode, and make a backup
|
||||||
// in orig_transform_mode in case we need to switch back
|
// in orig_transform_mode in case we need to switch back
|
||||||
if (fill_state.use_software_transform) {
|
if (fill_state.use_software_transform) {
|
||||||
|
|
Loading…
Reference in a new issue