stage6: port baryon background effect

This commit is contained in:
Andrei Alexeyev 2023-02-04 06:19:00 +01:00
parent bf3df74eda
commit 3230d378c1
No known key found for this signature in database
GPG key ID: 72D26128040B9690
3 changed files with 128 additions and 155 deletions

View file

@ -183,136 +183,6 @@ void stage6_draw(void) {
stage3d_draw(&stage_3d_context, 100, ARRAY_SIZE(segs), segs);
}
static void draw_baryon_connector(cmplx a, cmplx b) {
Sprite *spr = res_sprite("stage6/baryon_connector");
r_draw_sprite(&(SpriteParams) {
.sprite_ptr = spr,
.pos = { creal(a + b) * 0.5, cimag(a + b) * 0.5 },
.rotation.vector = { 0, 0, 1 },
.rotation.angle = carg(a - b),
.scale = { (cabs(a - b) - 70) / spr->w, 20 / spr->h },
});
}
void baryon(Enemy *e, int t, bool render) {
if(render) {
// the center piece draws the nodes; applying the postprocessing effect is easier this way.
return;
}
}
static void draw_baryons(Enemy *bcenter, int t) {
// r_color4(1, 1, 1, 0.8);
r_mat_mv_push();
r_mat_mv_translate(creal(bcenter->pos), cimag(bcenter->pos), 0);
r_draw_sprite(&(SpriteParams) {
.sprite = "stage6/baryon_center",
.rotation.angle = DEG2RAD * 2 * t,
.rotation.vector = { 0, 0, 1 },
});
r_draw_sprite(&(SpriteParams) {
.sprite = "stage6/baryon",
});
r_mat_mv_pop();
r_color4(1, 1, 1, 1);
Enemy *link0 = REF(creal(bcenter->args[1]));
Enemy *link1 = REF(cimag(bcenter->args[1]));
if(link0 && link1) {
draw_baryon_connector(bcenter->pos, link0->pos);
draw_baryon_connector(bcenter->pos, link1->pos);
}
for(Enemy *e = global.enemies.first; e; e = e->next) {
if(e->visual_rule == baryon) {
r_draw_sprite(&(SpriteParams) {
.pos = { creal(e->pos), cimag(e->pos) },
.sprite = "stage6/baryon",
});
Enemy *n = REF(e->args[1]);
if(n != NULL) {
draw_baryon_connector(e->pos, n->pos);
}
}
}
}
void baryon_center_draw(Enemy *bcenter, int t, bool render) {
if(!render) {
return;
}
if(config_get_int(CONFIG_POSTPROCESS) < 1) {
draw_baryons(bcenter, t);
return;
}
stage_draw_begin_noshake();
r_state_push();
r_shader("baryon_feedback");
r_uniform_vec2("blur_resolution", 0.5*VIEWPORT_W, 0.5*VIEWPORT_H);
r_uniform_float("hue_shift", 0);
r_uniform_float("time", t/60.0);
r_framebuffer(stage6_draw_data->baryon.aux_fb);
r_blend(BLEND_NONE);
r_uniform_vec2("blur_direction", 1, 0);
r_uniform_float("hue_shift", 0.01);
r_color4(0.95, 0.88, 0.9, 0.5);
draw_framebuffer_tex(stage6_draw_data->baryon.fbpair.front, VIEWPORT_W, VIEWPORT_H);
fbpair_swap(&stage6_draw_data->baryon.fbpair);
r_framebuffer(stage6_draw_data->baryon.fbpair.back);
r_uniform_vec2("blur_direction", 0, 1);
r_color4(1, 1, 1, 1);
draw_framebuffer_tex(stage6_draw_data->baryon.aux_fb, VIEWPORT_W, VIEWPORT_H);
r_state_pop();
stage_draw_end_noshake();
r_shader("sprite_default");
draw_baryons(bcenter, t);
stage_draw_begin_noshake();
r_shader_standard();
fbpair_swap(&stage6_draw_data->baryon.fbpair);
r_color4(0.7, 0.7, 0.7, 0.7);
draw_framebuffer_tex(stage6_draw_data->baryon.fbpair.front, VIEWPORT_W, VIEWPORT_H);
stage_draw_end_noshake();
r_color4(1, 1, 1, 1);
r_framebuffer(stage6_draw_data->baryon.fbpair.front);
r_shader("sprite_default");
draw_baryons(bcenter, t);
for(Enemy *e = global.enemies.first; e; e = e->next) {
if(e->visual_rule == baryon) {
cmplx p = e->pos; //+10*frand()*cexp(2.0*I*M_PI*frand());
r_draw_sprite(&(SpriteParams) {
.sprite = "part/myon",
.color = RGBA(1, 0.2, 1.0, 0.7),
.pos = { creal(p), cimag(p) },
.rotation.angle = (creal(e->args[0]) - t) / 16.0, // frand()*M_PI*2,
.scale.both = 2,
});
}
}
}
void elly_spellbg_classic(Boss *b, int t) {
fill_viewport(0,0,0.7,"stage6/spellbg_classic");
r_blend(BLEND_MOD);

View file

@ -55,9 +55,6 @@ void stage6_drawsys_init(void);
void stage6_drawsys_shutdown(void);
void stage6_draw(void);
void baryon_center_draw(Enemy*, int, bool);
void baryon(Enemy*, int, bool);
extern ShaderRule stage6_bg_effects[];
extern ShaderRule stage6_postprocess[];

View file

@ -97,78 +97,185 @@ DEFINE_EXTERN_TASK(stage6_elly_scythe_spin) {
}
}
static void baryons_connector_particles(cmplx a, cmplx b) {
static void baryons_connector_particles(cmplx a, cmplx b, BoxedProjectileArray *particles) {
Sprite *spr = res_sprite("stage6/baryon_connector");
cmplx connector_pos = (a + b)/2;
real connector_angle = carg(a - b) + M_PI/2;
cmplx connector_scale = (cabs(a - b) - 70) / spr->w + I * 20 / spr->h;
PARTICLE(
ENT_ARRAY_ADD(particles, PARTICLE(
.sprite_ptr = spr,
.pos = connector_pos,
.draw_rule = pdraw_timeout_fade(1, 0),
.timeout = 4,
.draw_rule = pdraw_timeout_fade(0.5, 0),
.timeout = 2,
.angle = connector_angle,
.flags = PFLAG_REQUIREDPARTICLE | PFLAG_MANUALANGLE,
.scale = connector_scale
);
));
}
static void baryons_particles(EllyBaryons *baryons) {
static void baryons_particles(EllyBaryons *baryons, BoxedProjectileArray *particles) {
if(baryons->scale == 0) {
return;
}
PARTICLE(
ENT_ARRAY_ADD(particles, PARTICLE(
.sprite_ptr = res_sprite("stage6/baryon_center"),
.pos = baryons->center_pos,
.draw_rule = pdraw_timeout_fade(1, 0),
.draw_rule = pdraw_timeout_fade(0.75, 0),
.timeout = 4,
.angle = baryons->center_angle,
.scale = baryons->scale,
.flags = PFLAG_REQUIREDPARTICLE | PFLAG_MANUALANGLE,
);
));
PARTICLE(
ENT_ARRAY_ADD(particles, PARTICLE(
.sprite_ptr = res_sprite("stage6/baryon"),
.pos = baryons->center_pos,
.angle = M_TAU/12,
.draw_rule = pdraw_timeout_fade(1, 0),
.draw_rule = pdraw_timeout_fade(0.75, 0),
.timeout = 4,
.flags = PFLAG_REQUIREDPARTICLE | PFLAG_MANUALANGLE,
);
));
for(int i = 0; i < NUM_BARYONS; i++) {
cmplx pos = baryons->poss[i];
cmplx pos_next = baryons->poss[(i+1) % NUM_BARYONS];
PARTICLE(
ENT_ARRAY_ADD(particles, PARTICLE(
.sprite_ptr = res_sprite("stage6/baryon"),
.pos = pos,
.draw_rule = pdraw_timeout_fade(1, 0),
.draw_rule = pdraw_timeout_fade(0.75, 0),
.timeout = 4,
.scale = baryons->scale,
.angle = baryons->angles[i]+M_TAU/12,
.flags = PFLAG_REQUIREDPARTICLE | PFLAG_MANUALANGLE,
);
));
baryons_connector_particles(pos, pos_next);
baryons_connector_particles(pos, pos_next, particles);
}
baryons_connector_particles(baryons->center_pos, baryons->poss[0]);
baryons_connector_particles(baryons->center_pos, baryons->poss[3]);
baryons_connector_particles(baryons->center_pos, baryons->poss[0], particles);
baryons_connector_particles(baryons->center_pos, baryons->poss[3], particles);
}
TASK(baryons_visuals, { BoxedEllyBaryons baryons; }) {
static void baryons_bg_feedback(Stage6DrawData *draw_data, int t) {
stage_draw_begin_noshake();
r_state_push();
r_shader("baryon_feedback");
r_uniform_vec2("blur_resolution", 0.5*VIEWPORT_W, 0.5*VIEWPORT_H);
r_uniform_float("hue_shift", 0);
r_uniform_float("time", t/60.0);
r_framebuffer(draw_data->baryon.aux_fb);
r_blend(BLEND_NONE);
r_uniform_vec2("blur_direction", 1, 0);
r_uniform_float("hue_shift", 0.01);
r_color4(0.95, 0.88, 0.9, 0.5);
draw_framebuffer_tex(draw_data->baryon.fbpair.front, VIEWPORT_W, VIEWPORT_H);
fbpair_swap(&draw_data->baryon.fbpair);
r_framebuffer(draw_data->baryon.fbpair.back);
r_uniform_vec2("blur_direction", 0, 1);
r_color4(1, 1, 1, 1);
draw_framebuffer_tex(draw_data->baryon.aux_fb, VIEWPORT_W, VIEWPORT_H);
r_state_pop();
stage_draw_end_noshake();
}
static void baryons_bg_blend(Stage6DrawData *draw_data) {
stage_draw_begin_noshake();
r_state_push();
r_blend(BLEND_PREMUL_ALPHA);
r_shader_standard();
fbpair_swap(&draw_data->baryon.fbpair);
r_color4(0.7, 0.7, 0.7, 0.7);
draw_framebuffer_tex(draw_data->baryon.fbpair.front, VIEWPORT_W, VIEWPORT_H);
r_state_pop();
stage_draw_end_noshake();
}
static void baryons_bg_fill(Stage6DrawData *draw_data, int t, EllyBaryons *baryons, BoxedProjectileArray *particles) {
if(!particles->size) {
return;
}
r_state_push();
r_color4(1, 1, 1, 1);
r_framebuffer(draw_data->baryon.fbpair.front);
ENT_ARRAY_FOREACH(particles, Projectile *p, {
r_state_push();
p->ent.draw_func(&p->entity_interface);
r_state_pop();
});
if(baryons) {
ShaderProgram *shader = res_shader("sprite_default");
Sprite *sprite = res_sprite("part/myon");
for(int i = 0; i < NUM_BARYONS; ++i) {
r_draw_sprite(&(SpriteParams) {
.sprite_ptr = sprite,
.shader_ptr = shader,
.color = RGBA(1, 0.2, 1.0, 0.7),
.pos.as_cmplx = baryons->poss[i], //+10*frand()*cexp(2.0*I*M_PI*frand());
.rotation.angle = (i - t) / 16.0, // frand()*M_PI*2,
.scale.both = 2,
});
}
r_flush_sprites();
}
r_state_pop();
}
TASK(baryons_particle_spawner, { BoxedEllyBaryons baryons; BoxedProjectileArray *particles; }) {
EllyBaryons *baryons = TASK_BIND(ARGS.baryons);
for (;;) {
baryons_particles(baryons);
baryons_particles(baryons, ARGS.particles);
ENT_ARRAY_COMPACT(ARGS.particles);
YIELD;
}
}
TASK(baryons_visuals, { BoxedEllyBaryons baryons; }) {
DECLARE_ENT_ARRAY(Projectile, particles, MAX_BARYON_PARTICLES);
CoEvent *draw_event = &stage_get_draw_events()->background_drawn;
Stage6DrawData *draw_data = stage6_get_draw_data();
INVOKE_SUBTASK(baryons_particle_spawner, ARGS.baryons, &particles);
int timeout = 60;
int endtime = timeout;
for(int t = 0; t < endtime; ++t) {
WAIT_EVENT_OR_DIE(draw_event);
EllyBaryons *baryons = ENT_UNBOX(ARGS.baryons);
if(baryons != NULL) {
endtime = t + timeout;
}
if(config_get_int(CONFIG_POSTPROCESS) < 1) {
continue;
}
baryons_bg_feedback(draw_data, t);
baryons_bg_blend(draw_data);
baryons_bg_fill(draw_data, t, baryons, &particles);
}
}
TASK(baryons_update, { BoxedEllyBaryons baryons; }) {
EllyBaryons *baryons = TASK_BIND(ARGS.baryons);
@ -206,8 +313,8 @@ void stage6_init_elly_baryons(BoxedEllyBaryons baryons, BoxedBoss boss) {
eb->center_pos = b->pos;
eb->scale = 0;
eb->relaxation_rate = 0.5;
INVOKE_TASK(baryons_visuals, baryons);
INVOKE_TASK(baryons_update, baryons);
INVOKE_TASK(baryons_visuals, baryons);
}
Boss *stage6_elly_init_baryons_attack(BaryonsAttackTaskArgs *args) {
@ -220,7 +327,6 @@ Boss *stage6_elly_init_baryons_attack(BaryonsAttackTaskArgs *args) {
return INIT_BOSS_ATTACK(&args->base);
}
EllyBaryons *stage6_host_elly_baryons(BoxedBoss boss) {
EllyBaryons *baryons = TASK_HOST_ENT(EllyBaryons);
TASK_HOST_EVENTS(baryons->events);