Make thruster smoke look like fire, rendertarget

main
Cameron Murphy Reikes 2 years ago
parent 058336c756
commit e98c524ac0

@ -0,0 +1,48 @@
@module fire
@vs vs
in vec4 coord;
out vec2 texUV;
void main() {
gl_Position = vec4(coord.xy, 0.0, 1.0);
texUV = coord.zw;
}
@end
@fs fs
uniform sampler2D iChannel0;
uniform fs_params {
vec4 iColor;
};
in vec2 texUV;
out vec4 fragColor;
void main() {
vec4 tex_color = texture(iChannel0,texUV);
// https://airtightinteractive.com/util/hex-to-glsl/
float how_faded = clamp((1.0 - tex_color.a) - 0.32, 0.0, 1.0);
vec3 edge_color = mix(vec3(1.0, 0.0, 0.0), vec3(0.929,0.624,0.439), how_faded);
vec3 body_color = vec3(0.933,0.788,0.69);
if(tex_color.a <= 0.05)
{
fragColor = vec4(0.0);
} else {
fragColor = vec4(mix(edge_color, body_color, tex_color.a), mix(1.0, 0.0, clamp((1.0 - tex_color.a) - 0.2, 0.0, 1.0)));
}
/*
vec3 smoke_body =
vec3 smoke_edge = tex_color.rgb;
if(tex_color.a <= 0.05)
{
fragColor = vec4(0.0);
} else {
fragColor = vec4(mix(smoke_edge, smoke_body, tex_color.a), 1.0);
}
*/
}
@end
@program program vs fs

Binary file not shown.

171
main.c

@ -37,6 +37,7 @@
#include "profiling.h" #include "profiling.h"
// shaders // shaders
#include "fire.gen.h"
#include "goodpixel.gen.h" #include "goodpixel.gen.h"
#include "horizontal_lightning.gen.h" #include "horizontal_lightning.gen.h"
#include "hueshift.gen.h" #include "hueshift.gen.h"
@ -45,6 +46,7 @@ static sg_pipeline hueshift_pipeline;
static sg_pipeline goodpixel_pipeline; static sg_pipeline goodpixel_pipeline;
static sg_pipeline lightning_pipeline; static sg_pipeline lightning_pipeline;
static sg_pipeline horizontal_lightning_pipeline; static sg_pipeline horizontal_lightning_pipeline;
static sg_pipeline fire_pipeline;
static struct GameState gs = {0}; static struct GameState gs = {0};
static int my_player_index = -1; static int my_player_index = -1;
@ -139,6 +141,9 @@ static sg_image image_orb_frozen;
static sg_image image_radardot; static sg_image image_radardot;
static sg_image image_pip; static sg_image image_pip;
static sg_image fire_rendertarget;
static sg_pass fire_pass;
static enum BoxType toolbar[TOOLBAR_SLOTS] = { static enum BoxType toolbar[TOOLBAR_SLOTS] = {
BoxHullpiece, BoxHullpiece,
BoxThruster, BoxThruster,
@ -452,8 +457,6 @@ void recalculate_camera_pos()
} }
} }
// drawing
#define WHITE \ #define WHITE \
(Color) \ (Color) \
{ \ { \
@ -519,7 +522,7 @@ void set_color_values(double r, double g, double b, double a)
} }
// @Robust make the transform stack actually use double precision logic, and // @Robust make the transform stack actually use double precision logic, and
// fix the debug drawing after that as well // fix the debug draw after that as well
void translate(double x, double y) void translate(double x, double y)
{ {
sgp_translate((float)x, (float)y); sgp_translate((float)x, (float)y);
@ -547,6 +550,17 @@ void draw_textured_rect(double x, double y, double w, double h)
sgp_draw_textured_rect((float)x, (float)y, (float)w, (float)h); sgp_draw_textured_rect((float)x, (float)y, (float)w, (float)h);
} }
static void transform_worldspace_zoom(double width, double height)
{
translate(width / 2, height / 2);
scale_at(zoom, -zoom, 0.0, 0.0);
}
static void transform_worldspace_camera()
{
translate(-camera_pos.x, -camera_pos.y);
}
static void init(void) static void init(void)
{ {
fopen_s(&log_file, "astris_log.txt", "a"); fopen_s(&log_file, "astris_log.txt", "a");
@ -747,6 +761,55 @@ static void init(void)
quit_with_popup("Couldn't make a shader! Uhhh ooooohhhhhh!!!", "Shader error BONED"); quit_with_popup("Couldn't make a shader! Uhhh ooooohhhhhh!!!", "Shader error BONED");
} }
} }
{
sgp_pipeline_desc pip_desc = {
.shader = *fire_program_shader_desc(sg_query_backend()),
.blend_mode = SGP_BLENDMODE_BLEND,
};
fire_pipeline = sgp_make_pipeline(&pip_desc);
sg_resource_state errstate = sg_query_pipeline_state(fire_pipeline);
if (errstate != SG_RESOURCESTATE_VALID)
{
Log("Failed to make fire pipeline\n");
quit_with_popup("Couldn't make a shader! Uhhh ooooohhhhhh!!!", "Shader error BONED");
}
}
}
// initialize buffers
{
fire_rendertarget = sg_make_image(
&(sg_image_desc){
.width = sapp_width(),
.height = sapp_height(),
.pixel_format = SG_PIXELFORMAT_BGRA8,
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
.wrap_u = SG_WRAP_CLAMP_TO_EDGE,
.render_target = true,
});
sg_image fire_depth = sg_make_image(
&(sg_image_desc){
.width = sapp_width(),
.height = sapp_height(),
.pixel_format = SG_PIXELFORMAT_DEPTH_STENCIL,
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
.wrap_u = SG_WRAP_CLAMP_TO_EDGE,
.render_target = true,
});
flight_assert(fire_rendertarget.id != SG_INVALID_ID);
fire_pass = sg_make_pass(&(sg_pass_desc){
.color_attachments[0] = (sg_pass_attachment_desc){
.image = fire_rendertarget,
},
.depth_stencil_attachment = (sg_pass_attachment_desc){
.image = fire_depth,
}
});
} }
// images loading // images loading
@ -1652,8 +1715,7 @@ static void frame(void)
case ENET_EVENT_TYPE_RECEIVE: case ENET_EVENT_TYPE_RECEIVE:
{ {
total_bytes_received += event.packet->dataLength; total_bytes_received += event.packet->dataLength;
unsigned char *decompressed = malloc( unsigned char *decompressed = malloc(sizeof *decompressed * MAX_SERVER_TO_CLIENT); // @Robust no malloc
sizeof *decompressed * MAX_SERVER_TO_CLIENT); // @Robust no malloc
size_t decompressed_max_len = MAX_SERVER_TO_CLIENT; size_t decompressed_max_len = MAX_SERVER_TO_CLIENT;
flight_assert(LZO1X_MEM_DECOMPRESS == 0); flight_assert(LZO1X_MEM_DECOMPRESS == 0);
@ -1987,7 +2049,7 @@ static void frame(void)
{ {
if (p->alive) if (p->alive)
{ {
p->alive_for += dt; p->alive_for += dt*1.5;
p->pos = cpvadd(p->pos, cpvmult(p->vel, dt)); p->pos = cpvadd(p->pos, cpvmult(p->vel, dt));
if (p->alive_for > 1.0) if (p->alive_for > 1.0)
{ {
@ -2081,24 +2143,70 @@ static void frame(void)
// drawing // drawing
PROFILE_SCOPE("drawing") PROFILE_SCOPE("drawing")
{
// draw particles in separate buffer so shader can operate on the buffer as a whole
PROFILE_SCOPE("drawing particles")
{ {
sgp_begin((int)width, (int)height); sgp_begin((int)width, (int)height);
sgp_viewport(0, 0, (int)width, (int)height); sgp_viewport(0, 0, (int)width, (int)height);
sgp_project(0.0f, (float)width, 0.0f, (float)height); sgp_project(0.0f, (float)width, 0.0f, (float)height);
sgp_set_blend_mode(SGP_BLENDMODE_BLEND); sgp_set_blend_mode(SGP_BLENDMODE_BLEND);
set_color_values(1.0, 1.0, 1.0, 0.0);
sgp_clear();
// actually draw them
transform_scope()
{
transform_worldspace_zoom(width, height);
transform_worldspace_camera();
set_color(WHITE);
PARTICLES_ITER(p)
{
if (p->alive)
{
// Color birth_col = colhexcode(0xc32c69);
// Color death_col = colhexcode(0xeca274);
// Color col = Collerp(birth_col, death_col, p->alive_for);
// set_color_values(col.r, col.g, col.b, 1.0 - clamp01(p->alive_for));
set_color_values(1.0, 1.0, 1.0, 1.0 - clamp01(p->alive_for));
// pipeline_scope(goodpixel_pipeline)
{
sgp_set_image(0, image_pip);
draw_texture_centered(p->pos, 0.2 * p->scaling);
sgp_reset_image(0);
}
}
}
}
sg_pass_action pass_action = {0};
sg_begin_pass(fire_pass, &pass_action);
// sg_begin_default_pass(&pass_action, (int)width, (int)height);
sgp_flush();
sgp_end();
sg_end_pass();
sg_commit();
}
sgp_begin((int)width, (int)height);
sgp_viewport(0, 0, (int)width, (int)height);
sgp_project(0.0f, (float)width, 0.0f, (float)height);
sgp_set_blend_mode(SGP_BLENDMODE_BLEND);
// Draw background color // Draw background color
set_color(colhexcode(0x000000)); set_color(colhexcode(0x000000));
// set_color_values(0.1, 0.1, 0.1, 1.0);
sgp_clear(); sgp_clear();
// WORLD SPACE draw_circle(cpv(10, 10), 100);
// world space coordinates are +Y up, -Y down. Like normal cartesian coords
// draw background stuff
transform_scope() transform_scope()
{ {
translate(width / 2, height / 2); transform_worldspace_zoom(width, height);
scale_at(zoom, -zoom, 0.0, 0.0);
// parllax layers, just the zooming, but not 100% of the camera panning // parllax layers, just the zooming, but not 100% of the camera panning
#if 1 // space background #if 1 // space background
transform_scope() transform_scope()
@ -2153,10 +2261,27 @@ static void frame(void)
draw_dots(scaled_camera_pos, 2.0); draw_dots(scaled_camera_pos, 2.0);
} }
#endif #endif
}
// camera go to player // draw particles pass in screen space
translate(-camera_pos.x, -camera_pos.y);
#if 1 // whether to apply fire shader to the buffer
pipeline_scope(fire_pipeline)
#endif
{
sgp_set_image(0, fire_rendertarget);
set_color(WHITE);
sgp_draw_textured_rect(0.0f, 0.0f, (float)width, (float)height);
sgp_reset_image(0);
}
// WORLD SPACE
// world space coordinates are +Y up, -Y down. Like normal cartesian coords
transform_scope()
{
transform_worldspace_zoom(width, height);
// camera go to player
transform_worldspace_camera();
draw_dots(camera_pos, 1.5); // in plane dots draw_dots(camera_pos, 1.5); // in plane dots
// hand reached limit circle // hand reached limit circle
@ -2206,22 +2331,6 @@ static void frame(void)
player_scaling = lerp(player_scaling, player_scaling_target, dt * 15.0); player_scaling = lerp(player_scaling, player_scaling_target, dt * 15.0);
hovering_this_player = (EntityID){0}; hovering_this_player = (EntityID){0};
// draw particles drawn in world space
set_color(WHITE);
PARTICLES_ITER(p)
{
if (p->alive)
{
set_color_values(1.0, 1.0, 1.0, 1.0 - clamp01(p->alive_for));
pipeline_scope(goodpixel_pipeline)
{
sgp_set_image(0, image_pip);
draw_texture_centered(p->pos, 0.2 * p->scaling);
sgp_reset_image(0);
}
}
}
// draw all types of entities // draw all types of entities
ENTITIES_ITER(e) ENTITIES_ITER(e)
{ {
@ -2258,6 +2367,7 @@ static void frame(void)
particle_vel = cpvadd(particle_vel, additional_vel); particle_vel = cpvadd(particle_vel, additional_vel);
new_particle(cpvadd(entity_pos(b), cpvmult(box_facing_vector(b), BOX_SIZE * 0.5)), particle_vel); new_particle(cpvadd(entity_pos(b), cpvmult(box_facing_vector(b), BOX_SIZE * 0.5)), particle_vel);
} }
/*
transform_scope() transform_scope()
{ {
set_color_values(1.0, 1.0, 1.0, 1.0); set_color_values(1.0, 1.0, 1.0, 1.0);
@ -2270,6 +2380,7 @@ static void frame(void)
} }
sgp_reset_image(0); sgp_reset_image(0);
} }
*/
} }
sg_image img = boxinfo(b->box_type).image; sg_image img = boxinfo(b->box_type).image;
if (b->box_type == BoxCockpit) if (b->box_type == BoxCockpit)

@ -8,3 +8,4 @@ sokol-shdc.exe --format sokol --input hueshift.glsl --output hueshift.gen.h --sl
sokol-shdc.exe --format sokol --input lightning.glsl --output lightning.gen.h --slang glsl330:hlsl5:metal_macos sokol-shdc.exe --format sokol --input lightning.glsl --output lightning.gen.h --slang glsl330:hlsl5:metal_macos
sokol-shdc.exe --format sokol --input horizontal_lightning.glsl --output horizontal_lightning.gen.h --slang glsl330:hlsl5:metal_macos sokol-shdc.exe --format sokol --input horizontal_lightning.glsl --output horizontal_lightning.gen.h --slang glsl330:hlsl5:metal_macos
sokol-shdc.exe --format sokol --input goodpixel.glsl --output goodpixel.gen.h --slang glsl330:hlsl5:metal_macos sokol-shdc.exe --format sokol --input goodpixel.glsl --output goodpixel.gen.h --slang glsl330:hlsl5:metal_macos
sokol-shdc.exe --format sokol --input fire.glsl --output fire.gen.h --slang glsl330:hlsl5:metal_macos
Loading…
Cancel
Save