Parts: Fix Z-order of 3DLayer and Movie parts

3DLayer and Movie parts use a SACT sprite as their render target (for
SealEngine output or movie frames). That sprite was registered into
the scene at z=0, so the content was drawn at z=0 instead of (or in
addition to) the parts engine's render path at the parts' configured Z.

Hide the bound SACT sprite from the scene so the parts engine is the
sole renderer of its texture, and add a parts_render case for 3DLayer
that composites the bound sprite's texture through parts_render_cg.
This commit is contained in:
kichikuou
2026-05-16 12:44:17 +09:00
parent 33d07c190e
commit 224db2f9cc
2 changed files with 29 additions and 1 deletions
+6
View File
@@ -2185,6 +2185,9 @@ bool PE_init_parts_movie(int parts_no, int width, int height, int bg_r, int bg_g
struct sact_sprite *sp = sact_create_sprite(sp_no, width, height, bg_r, bg_g, bg_b, 255);
if (!sp)
return false;
// The movie frames are composited by the parts engine via parts_render(),
// so hide the bound sprite from the scene to avoid double-drawing.
sprite_set_show(sp, false);
struct texture *tex = sprite_get_texture(sp);
movie->sprite_no = sp_no;
@@ -2232,6 +2235,9 @@ bool PE_CreateParts3DLayerPluginID(int parts_no, int state)
ReignEngine_ReleasePlugin(handle);
return false;
}
// The 3D content is composited by the parts engine via parts_render(), so
// hide the bound sprite from the scene to avoid double-drawing.
sprite_set_show(sp, false);
l->plugin = handle;
l->sprite_no = sp_no;
+23 -1
View File
@@ -25,7 +25,9 @@
#include "system4/flat.h"
#include "gfx/gfx.h"
#include "sact.h"
#include "scene.h"
#include "sprite.h"
#include "xsystem4.h"
#include "parts_internal.h"
@@ -329,6 +331,24 @@ static void parts_render_flat(struct parts *parts, struct parts_flat *f)
f->flat->timelines, f->flat->nr_timelines, &ctx);
}
static void parts_render_3dlayer(struct parts *parts, struct parts_3dlayer *l)
{
if (l->sprite_no < 0)
return;
struct sact_sprite *sp = sact_try_get_sprite(l->sprite_no);
if (!sp)
return;
struct texture *tex = sprite_get_texture(sp);
if (!tex->handle)
return;
// The bound sprite's texture is recreated by RE_set_viewport, so
// refresh the parts_common's view of it each frame.
l->common.texture = *tex;
l->common.w = tex->w;
l->common.h = tex->h;
parts_render_cg(parts, &l->common);
}
static void parts_render_flash_shape(struct parts *parts, struct parts_flash *f, struct parts_flash_object *obj, struct swf_tag_define_shape *tag)
{
struct texture *src = ht_get_int(f->bitmaps, tag->fill_style.bitmap_id, NULL);
@@ -449,7 +469,6 @@ void parts_render(struct parts *parts)
case PARTS_UNINITIALIZED:
case PARTS_RECT_DETECTION:
case PARTS_LAYOUT_BOX:
case PARTS_3DLAYER:
break;
case PARTS_CG:
case PARTS_ANIMATION:
@@ -470,6 +489,9 @@ void parts_render(struct parts *parts)
case PARTS_FLAT:
parts_render_flat(parts, &state->flat);
break;
case PARTS_3DLAYER:
parts_render_3dlayer(parts, &state->layer3d);
break;
}
}