2023-09-04 09:48:44 -05:00
|
|
|
#include "render.h"
|
2021-11-30 21:29:18 -06:00
|
|
|
|
2023-05-12 13:22:05 -05:00
|
|
|
#include "config.h"
|
|
|
|
#include "datastream.h"
|
2021-11-30 21:29:18 -06:00
|
|
|
#include "debugdraw.h"
|
2023-05-12 13:22:05 -05:00
|
|
|
#include "font.h"
|
|
|
|
#include "gameobject.h"
|
2021-11-30 21:29:18 -06:00
|
|
|
#include "log.h"
|
2023-05-12 13:22:05 -05:00
|
|
|
#include "sprite.h"
|
2023-12-29 19:08:53 -06:00
|
|
|
#include "particle.h"
|
2023-05-12 13:22:05 -05:00
|
|
|
#include "window.h"
|
|
|
|
#include "model.h"
|
|
|
|
#include "stb_ds.h"
|
2023-09-04 09:48:44 -05:00
|
|
|
#include "resources.h"
|
2023-09-12 00:02:57 -05:00
|
|
|
#include "yugine.h"
|
2023-09-18 07:36:07 -05:00
|
|
|
#include "sokol/sokol_app.h"
|
2024-03-03 16:49:34 -06:00
|
|
|
#define SOKOL_GLUE_IMPL
|
|
|
|
#include "sokol/sokol_glue.h"
|
2023-11-22 03:51:43 -06:00
|
|
|
#include "stb_image_write.h"
|
2023-05-12 13:22:05 -05:00
|
|
|
|
2023-09-11 15:07:36 -05:00
|
|
|
#include "sokol/sokol_gfx.h"
|
2024-03-03 16:49:34 -06:00
|
|
|
#include "sokol_gfx_ext.h"
|
2023-09-12 00:02:57 -05:00
|
|
|
|
2024-04-01 08:13:57 -05:00
|
|
|
#include "crt.sglsl.h"
|
|
|
|
|
2023-09-11 15:07:36 -05:00
|
|
|
#include "msf_gif.h"
|
|
|
|
|
2024-03-20 16:48:03 -05:00
|
|
|
HMM_Vec2 campos = {0,0};
|
|
|
|
float camzoom = 1;
|
|
|
|
|
2024-04-23 15:58:08 -05:00
|
|
|
sg_sampler std_sampler;
|
2024-04-28 13:33:37 -05:00
|
|
|
sg_sampler tex_sampler;
|
2024-04-23 15:58:08 -05:00
|
|
|
|
2023-09-12 00:02:57 -05:00
|
|
|
static struct {
|
2024-03-03 16:49:34 -06:00
|
|
|
sg_swapchain swap;
|
2023-09-12 00:02:57 -05:00
|
|
|
sg_pipeline pipe;
|
|
|
|
sg_bindings bind;
|
|
|
|
sg_shader shader;
|
|
|
|
sg_image img;
|
|
|
|
sg_image depth;
|
|
|
|
} sg_gif;
|
|
|
|
|
2024-04-01 08:13:57 -05:00
|
|
|
static struct {
|
|
|
|
sg_pipeline pipe;
|
|
|
|
sg_bindings bind;
|
|
|
|
sg_shader shader;
|
|
|
|
} sg_crt;
|
|
|
|
|
2023-09-12 07:56:40 -05:00
|
|
|
static struct {
|
|
|
|
int w;
|
|
|
|
int h;
|
|
|
|
int cpf;
|
|
|
|
int depth;
|
|
|
|
double timer;
|
|
|
|
double spf;
|
|
|
|
int rec;
|
2023-12-21 17:21:01 -06:00
|
|
|
uint8_t *buffer;
|
2023-09-12 07:56:40 -05:00
|
|
|
} gif;
|
|
|
|
|
2023-09-11 15:07:36 -05:00
|
|
|
MsfGifState gif_state = {};
|
2023-09-12 00:02:57 -05:00
|
|
|
void gif_rec_start(int w, int h, int cpf, int bitdepth)
|
2023-09-11 15:07:36 -05:00
|
|
|
{
|
2023-09-12 07:56:40 -05:00
|
|
|
gif.w = w;
|
|
|
|
gif.h = h;
|
|
|
|
gif.depth = bitdepth;
|
|
|
|
msf_gif_begin(&gif_state, gif.w, gif.h);
|
|
|
|
gif.cpf = cpf;
|
|
|
|
gif.spf = cpf/100.0;
|
|
|
|
gif.rec = 1;
|
2023-10-30 17:41:32 -05:00
|
|
|
gif.timer = apptime();
|
2023-09-12 07:56:40 -05:00
|
|
|
if (gif.buffer) free(gif.buffer);
|
|
|
|
gif.buffer = malloc(gif.w*gif.h*4);
|
2023-09-12 00:02:57 -05:00
|
|
|
|
|
|
|
sg_destroy_image(sg_gif.img);
|
|
|
|
sg_destroy_image(sg_gif.depth);
|
|
|
|
|
|
|
|
sg_gif.img = sg_make_image(&(sg_image_desc){
|
|
|
|
.render_target = true,
|
2023-09-12 07:56:40 -05:00
|
|
|
.width = gif.w,
|
|
|
|
.height = gif.h,
|
2023-09-25 12:29:04 -05:00
|
|
|
.pixel_format = SG_PIXELFORMAT_RGBA8,
|
2023-09-25 08:21:02 -05:00
|
|
|
.label = "gif rt",
|
2023-09-12 00:02:57 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
sg_gif.depth = sg_make_image(&(sg_image_desc){
|
|
|
|
.render_target = true,
|
2023-09-12 07:56:40 -05:00
|
|
|
.width = gif.w,
|
|
|
|
.height = gif.h,
|
2023-09-25 08:21:02 -05:00
|
|
|
.label = "gif depth",
|
2023-09-12 00:02:57 -05:00
|
|
|
});
|
2024-03-03 16:49:34 -06:00
|
|
|
|
|
|
|
sg_gif.swap = sglue_swapchain();
|
2023-09-11 15:07:36 -05:00
|
|
|
}
|
|
|
|
|
2023-12-21 17:21:01 -06:00
|
|
|
void gif_rec_end(const char *path)
|
2023-09-11 15:07:36 -05:00
|
|
|
{
|
2023-09-12 17:19:46 -05:00
|
|
|
if (!gif.rec) return;
|
|
|
|
|
2023-09-12 07:56:40 -05:00
|
|
|
MsfGifResult gif_res = msf_gif_end(&gif_state);
|
|
|
|
if (gif_res.data) {
|
2023-09-11 15:07:36 -05:00
|
|
|
FILE *f = fopen(path, "wb");
|
2023-09-12 07:56:40 -05:00
|
|
|
fwrite(gif_res.data, gif_res.dataSize, 1, f);
|
2023-09-11 15:07:36 -05:00
|
|
|
fclose(f);
|
|
|
|
}
|
2023-09-12 07:56:40 -05:00
|
|
|
msf_gif_free(gif_res);
|
|
|
|
gif.rec = 0;
|
2023-09-11 15:07:36 -05:00
|
|
|
}
|
|
|
|
|
2023-12-21 17:21:01 -06:00
|
|
|
void capture_screen(int x, int y, int w, int h, const char *path)
|
2023-11-22 03:51:43 -06:00
|
|
|
{
|
|
|
|
int n = 4;
|
|
|
|
void *data = malloc(w*h*n);
|
|
|
|
sg_query_pixels(0,0,w,h,1,data,w*h*sizeof(char)*n);
|
|
|
|
// sg_query_image_pixels(crt_post.img, crt_post.bind.fs.samplers[0], data, w*h*4);
|
|
|
|
stbi_write_png("cap.png", w, h, n, data, n*w);
|
|
|
|
// stbi_write_bmp("cap.bmp", w, h, n, data);
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
|
2023-08-31 17:23:24 -05:00
|
|
|
#include "sokol/sokol_app.h"
|
|
|
|
|
2023-05-12 13:22:05 -05:00
|
|
|
#include "HandmadeMath.h"
|
2022-12-22 16:58:06 -06:00
|
|
|
|
2023-05-04 17:07:00 -05:00
|
|
|
sg_pass_action pass_action = {0};
|
|
|
|
|
2023-09-25 12:29:04 -05:00
|
|
|
void trace_apply_pipeline(sg_pipeline pip, void *data)
|
|
|
|
{
|
2024-03-14 14:10:06 -05:00
|
|
|
// YughSpam("Applying pipeline %u %s.", pip, sg_query_pipeline_desc(pip).label);
|
2023-09-25 12:29:04 -05:00
|
|
|
}
|
|
|
|
|
2024-04-09 16:48:15 -05:00
|
|
|
void trace_begin_pass(sg_pass pass, const sg_pass_action *action, void *data)
|
2023-09-25 12:29:04 -05:00
|
|
|
{
|
2024-04-09 16:48:15 -05:00
|
|
|
// YughSpam("Begin pass %s", pass.label);
|
2023-09-25 12:29:04 -05:00
|
|
|
}
|
|
|
|
|
2024-04-09 16:48:15 -05:00
|
|
|
#define SG_TRACE_SET(NAME) \
|
|
|
|
void trace_alloc_##NAME (sg_##NAME id, void *data) \
|
|
|
|
{ \
|
|
|
|
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
|
|
|
|
YughSpam("Alloc " #NAME " %d [%s]", id, desc.label); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void trace_dealloc_##NAME(sg_##NAME id, void *data) \
|
|
|
|
{ \
|
|
|
|
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
|
|
|
|
YughSpam("Dealloc " #NAME " %d [%s]", id, desc.label); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void trace_make_##NAME(sg_##NAME##_desc *desc, void *data) \
|
|
|
|
{ \
|
|
|
|
YughSpam("Make " #NAME " [%s]", desc->label); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void trace_destroy_##NAME(sg_##NAME id, void *data) \
|
|
|
|
{ \
|
|
|
|
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
|
|
|
|
YughSpam("Destroy " #NAME " %d [%s]", id, desc.label); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void trace_init_##NAME(sg_##NAME id, sg_##NAME##_desc *desc, void *data) \
|
|
|
|
{ \
|
|
|
|
YughSpam("Init " #NAME " %d [%s]", id, desc->label); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void trace_uninit_##NAME(sg_##NAME id, void *data) \
|
|
|
|
{ \
|
|
|
|
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
|
|
|
|
YughSpam("Init " #NAME " %d [%s]", id, desc.label); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void trace_fail_##NAME(sg_##NAME id, void *data) \
|
|
|
|
{ \
|
|
|
|
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
|
|
|
|
YughError("Failed " #NAME " %d: %s", id, desc.label); \
|
|
|
|
} \
|
|
|
|
|
|
|
|
SG_TRACE_SET(buffer)
|
|
|
|
SG_TRACE_SET(image)
|
|
|
|
SG_TRACE_SET(sampler)
|
|
|
|
SG_TRACE_SET(shader)
|
|
|
|
SG_TRACE_SET(pipeline)
|
|
|
|
SG_TRACE_SET(attachments)
|
|
|
|
|
|
|
|
#define SG_HOOK_SET(NAME) \
|
|
|
|
.alloc_##NAME = trace_alloc_##NAME, \
|
|
|
|
.dealloc_##NAME = trace_dealloc_##NAME, \
|
|
|
|
.init_##NAME = trace_init_##NAME, \
|
|
|
|
.uninit_##NAME = trace_uninit_##NAME, \
|
|
|
|
.fail_##NAME = trace_fail_##NAME, \
|
|
|
|
.destroy_##NAME = trace_destroy_##NAME, \
|
|
|
|
.make_##NAME = trace_make_##NAME \
|
|
|
|
|
|
|
|
void trace_append_buffer(sg_buffer id, sg_range *data, void *user)
|
2023-09-25 12:29:04 -05:00
|
|
|
{
|
2024-04-09 16:48:15 -05:00
|
|
|
sg_buffer_desc desc = sg_query_buffer_desc(id);
|
2024-04-11 17:17:49 -05:00
|
|
|
// YughSpam("Appending buffer %d [%s]", id, desc.label);
|
2023-09-25 08:21:02 -05:00
|
|
|
}
|
|
|
|
|
2023-05-24 20:45:50 -05:00
|
|
|
static sg_trace_hooks hooks = {
|
2023-09-25 12:29:04 -05:00
|
|
|
.apply_pipeline = trace_apply_pipeline,
|
|
|
|
.begin_pass = trace_begin_pass,
|
2024-04-09 16:48:15 -05:00
|
|
|
SG_HOOK_SET(buffer),
|
|
|
|
SG_HOOK_SET(image),
|
|
|
|
SG_HOOK_SET(shader),
|
|
|
|
SG_HOOK_SET(sampler),
|
|
|
|
SG_HOOK_SET(pipeline),
|
|
|
|
SG_HOOK_SET(attachments),
|
|
|
|
.append_buffer = trace_append_buffer
|
2023-05-24 20:45:50 -05:00
|
|
|
};
|
|
|
|
|
2023-09-04 09:48:44 -05:00
|
|
|
void render_init() {
|
2024-03-13 16:30:55 -05:00
|
|
|
mainwin.size = (HMM_Vec2){sapp_width(), sapp_height()};
|
2023-08-31 13:00:33 -05:00
|
|
|
sg_setup(&(sg_desc){
|
2024-03-03 16:49:34 -06:00
|
|
|
.environment = sglue_environment(),
|
|
|
|
.logger = { .func = sg_logging },
|
|
|
|
.buffer_pool_size = 1024
|
2023-08-31 13:00:33 -05:00
|
|
|
});
|
2024-04-23 15:58:08 -05:00
|
|
|
|
|
|
|
std_sampler = sg_make_sampler(&(sg_sampler_desc){});
|
2024-04-28 13:33:37 -05:00
|
|
|
tex_sampler = sg_make_sampler(&(sg_sampler_desc){
|
|
|
|
.min_filter = SG_FILTER_LINEAR,
|
|
|
|
.mag_filter = SG_FILTER_LINEAR,
|
|
|
|
.mipmap_filter = SG_FILTER_LINEAR,
|
|
|
|
.wrap_u = SG_WRAP_REPEAT,
|
|
|
|
.wrap_v = SG_WRAP_REPEAT
|
|
|
|
});
|
2023-08-31 13:00:33 -05:00
|
|
|
|
2024-04-16 07:51:22 -05:00
|
|
|
#ifndef NDEBUG
|
2023-05-24 20:45:50 -05:00
|
|
|
sg_trace_hooks hh = sg_install_trace_hooks(&hooks);
|
2024-04-16 07:51:22 -05:00
|
|
|
#endif
|
2023-05-24 20:45:50 -05:00
|
|
|
|
2023-09-04 09:48:44 -05:00
|
|
|
font_init();
|
2023-05-12 13:22:05 -05:00
|
|
|
debugdraw_init();
|
|
|
|
|
2024-04-17 08:57:45 -05:00
|
|
|
sg_color c = (sg_color){0,0,0,1};
|
2023-05-12 13:22:05 -05:00
|
|
|
pass_action = (sg_pass_action){
|
2024-03-03 16:49:34 -06:00
|
|
|
.colors[0] = {.load_action = SG_LOADACTION_CLEAR, .clear_value = c},
|
2023-05-12 13:22:05 -05:00
|
|
|
};
|
2023-05-24 20:45:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
HMM_Mat4 projection = {0.f};
|
|
|
|
HMM_Mat4 hudproj = {0.f};
|
2024-03-27 15:00:59 -05:00
|
|
|
HMM_Mat4 useproj = {0};
|
2023-05-04 17:07:00 -05:00
|
|
|
|
2024-03-05 00:11:34 -06:00
|
|
|
#define MODE_STRETCH 0
|
|
|
|
#define MODE_KEEP 1
|
|
|
|
#define MODE_WIDTH 2
|
|
|
|
#define MODE_HEIGHT 3
|
|
|
|
#define MODE_EXPAND 4
|
|
|
|
#define MODE_FULL 5
|
|
|
|
|
2024-05-02 17:13:09 -05:00
|
|
|
void openglRender(struct window *window, transform2d *cam, float zoom) {
|
2024-03-18 14:27:52 -05:00
|
|
|
sg_swapchain sch = sglue_swapchain();
|
|
|
|
sg_begin_pass(&(sg_pass){
|
|
|
|
.action = pass_action,
|
|
|
|
.swapchain = sglue_swapchain(),
|
|
|
|
.label = "window pass"
|
|
|
|
});
|
|
|
|
|
2024-03-13 16:30:55 -05:00
|
|
|
HMM_Vec2 usesize = window->rendersize;
|
|
|
|
|
|
|
|
switch(window->mode) {
|
2024-03-05 00:11:34 -06:00
|
|
|
case MODE_STRETCH:
|
2024-03-13 16:30:55 -05:00
|
|
|
sg_apply_viewportf(0,0,window->size.x,window->size.y,1);
|
2024-03-05 00:11:34 -06:00
|
|
|
break;
|
|
|
|
case MODE_WIDTH:
|
2024-03-13 16:30:55 -05:00
|
|
|
sg_apply_viewportf(0, window->top, window->size.x, window->psize.y,1); // keep width
|
2024-03-05 00:11:34 -06:00
|
|
|
break;
|
|
|
|
case MODE_HEIGHT:
|
2024-03-13 16:30:55 -05:00
|
|
|
sg_apply_viewportf(window->left,0,window->psize.x, window->size.y,1); // keep height
|
2024-03-05 00:11:34 -06:00
|
|
|
break;
|
|
|
|
case MODE_KEEP:
|
2024-03-13 16:30:55 -05:00
|
|
|
sg_apply_viewportf(0,0,window->rendersize.x, window->rendersize.y, 1); // no scaling
|
2024-03-05 00:11:34 -06:00
|
|
|
break;
|
|
|
|
case MODE_EXPAND:
|
2024-03-13 16:30:55 -05:00
|
|
|
if (window->aspect < window->raspect)
|
|
|
|
sg_apply_viewportf(0, window->top, window->size.x, window->psize.y,1); // keep width
|
2024-03-05 00:11:34 -06:00
|
|
|
else
|
2024-03-13 16:30:55 -05:00
|
|
|
sg_apply_viewportf(window->left,0,window->psize.x, window->size.y,1); // keep height
|
2024-03-05 00:11:34 -06:00
|
|
|
break;
|
|
|
|
case MODE_FULL:
|
2024-03-13 16:30:55 -05:00
|
|
|
usesize = window->size;
|
2024-03-09 18:22:06 -06:00
|
|
|
break;
|
2024-03-05 00:11:34 -06:00
|
|
|
}
|
|
|
|
|
2024-03-04 15:18:11 -06:00
|
|
|
// 2D projection
|
2024-05-02 17:13:09 -05:00
|
|
|
campos = cam->pos;
|
2024-03-20 16:48:03 -05:00
|
|
|
camzoom = zoom;
|
2023-05-12 13:22:05 -05:00
|
|
|
|
2024-04-20 12:55:20 -05:00
|
|
|
projection = HMM_Orthographic_RH_NO(
|
2024-03-20 16:48:03 -05:00
|
|
|
campos.x - camzoom * usesize.x / 2,
|
|
|
|
campos.x + camzoom * usesize.x / 2,
|
|
|
|
campos.y - camzoom * usesize.y / 2,
|
|
|
|
campos.y + camzoom * usesize.y / 2, -10000.f, 10000.f);
|
2023-08-31 02:05:06 -05:00
|
|
|
|
2024-03-03 16:49:34 -06:00
|
|
|
/* if (gif.rec && (apptime() - gif.timer) > gif.spf) {
|
|
|
|
sg_begin_pass(&(sg_pass){
|
|
|
|
.action = pass_action,
|
|
|
|
.swapchain = sg_gif.swap
|
|
|
|
});
|
2023-09-12 00:02:57 -05:00
|
|
|
sg_apply_pipeline(sg_gif.pipe);
|
2023-09-18 21:55:37 -05:00
|
|
|
sg_apply_bindings(&sg_gif.bind);
|
2023-09-12 00:02:57 -05:00
|
|
|
sg_draw(0,6,1);
|
|
|
|
sg_end_pass();
|
|
|
|
|
2023-10-30 17:41:32 -05:00
|
|
|
gif.timer = apptime();
|
2023-09-15 12:31:31 -05:00
|
|
|
sg_query_image_pixels(sg_gif.img, crt_post.bind.fs.samplers[0], gif.buffer, gif.w*gif.h*4);
|
2023-09-12 07:56:40 -05:00
|
|
|
msf_gif_frame(&gif_state, gif.buffer, gif.cpf, gif.depth, gif.w * -4);
|
2023-09-12 00:02:57 -05:00
|
|
|
}
|
2024-03-03 16:49:34 -06:00
|
|
|
*/
|
2021-11-30 21:29:18 -06:00
|
|
|
}
|
2023-05-24 20:45:50 -05:00
|
|
|
|
2023-12-22 11:50:03 -06:00
|
|
|
struct boundingbox cwh2bb(HMM_Vec2 c, HMM_Vec2 wh) {
|
|
|
|
struct boundingbox bb = {
|
|
|
|
.t = c.Y + wh.Y/2,
|
|
|
|
.b = c.Y - wh.Y/2,
|
|
|
|
.r = c.X + wh.X/2,
|
|
|
|
.l = c.X - wh.X/2
|
|
|
|
};
|
|
|
|
|
|
|
|
return bb;
|
|
|
|
}
|
|
|
|
|
|
|
|
float *rgba2floats(float *r, struct rgba c)
|
|
|
|
{
|
|
|
|
r[0] = (float)c.r / RGBA_MAX;
|
|
|
|
r[1] = (float)c.g / RGBA_MAX;
|
|
|
|
r[2] = (float)c.b / RGBA_MAX;
|
|
|
|
r[3] = (float)c.a / RGBA_MAX;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
sg_blend_state blend_trans = {
|
|
|
|
.enabled = true,
|
|
|
|
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
|
|
|
|
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
|
|
|
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
|
|
|
|
.dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
|
|
|
|
};
|