workbench: initial impl wip

render: supporting changes
ui: new methods
main
Dominik Madarász 2023-09-17 22:56:51 +02:00
parent 5451fa6e9d
commit 2ec699948c
36 changed files with 836 additions and 135 deletions

View File

@ -396,7 +396,7 @@ set run=no
if "%1"=="extras" set "extras=yes" && set "hello=no" && goto loop
if "%1"=="noeditor" set "editor=no" && goto loop
if "%1"=="hello" set "hello=yes" && goto loop
if "%1"=="editor" set "editor=yes" && set "hello=no"&& goto loop
if "%1"=="editor" set "editor=yes" && set "v4k=no" && set "hello=no"&& goto loop
if "%1"=="run" set "run=yes" && goto loop
if "%1"=="all" set "v4k=yes" && set "demos=yes" && set "extras=yes" && set "editor=yes" && set "hello=yes" && goto loop
@ -600,9 +600,17 @@ if "!vis!"=="yes" echo !cc! engine\v4k.c !export! !args! ^&^& if "!dll!"=="dll"
rem editor
if "!editor!"=="yes" (
set edit=-DCOOK_ON_DEMAND -DUI_LESSER_SPACING -DUI_ICONS_SMALL
if "!vis!"=="yes" echo !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args!
!echo! editor && !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args! || set rc=1
!echo! editor2 && !cc! !o! editor2.exe tools\editor\editor2.c !edit! !args! || set rc=1
rem if "!vis!"=="yes" echo !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args!
rem !echo! editor && !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args! || set rc=1
rem !echo! editor2 && !cc! !o! editor2.exe tools\editor\editor2.c !edit! !args! || set rc=1
set "plugins="
for %%f in ("workbench\plugins\*.c") do (
echo plugin: %%~nf.c
set "plugins=!plugins! workbench\plugins\%%~nf.c"
)
!echo! workbench && !cc! !o! workbench.exe workbench\workbench.c !plugins! -Iworkbench !edit! !args! || set rc=1
)
rem demos

View File

@ -180,7 +180,7 @@ int main() {
}
// post-fxs end here
fx_end();
fx_end(0);
// font demo
do_once font_scales(FONT_FACE1, 48, 24, 18, 12, 9, 6);

View File

@ -124,7 +124,7 @@ int main() {
);
// post-fxs end here
fx_end();
fx_end(0);
// ui
if( ui_panel("Audio", 0)) {

View File

@ -88,7 +88,7 @@ int main() {
collide_demo();
}
fx_end();
fx_end(0);
// ui
if( ui_panel("App", 0) ) {

View File

@ -86,7 +86,7 @@ int main() {
}
}
fx_end();
fx_end(0);
if( ui_panel("Animation", 0) ) {
if( ui_bool("Show aabb", &do_showaabb) );

View File

@ -125,7 +125,7 @@ int main() {
}
// post-fxs end here
fx_end();
fx_end(0);
// queue ui
if( ui_panel("Camera", 0)) {

View File

@ -69,7 +69,7 @@ int main() {
model_render(witch, cam.proj, cam.view, witch.pivot, 0);
// render end (postfx)
fx_end();
fx_end(0);
// input controllers

View File

@ -43,7 +43,7 @@ int main(int argc, char** argv) {
initialized = 1;
sky = skybox(flag("--mie") ? 0 : SKY_DIRS[SKY_DIR], 0);
mdl = model(OBJ_MDLS[OBJ_MDL], 0);
// rotation44(mdl.pivot, 0, 1,0,0); // @fixme: -90,1,0,0 -> should we rotate SHMs as well? compensate rotation in shader?
rotation44(mdl.pivot, 0, 1,0,0); // @fixme: -90,1,0,0 -> should we rotate SHMs as well? compensate rotation in shader?
}
// fps camera

View File

@ -169,7 +169,7 @@ int main() {
skybox_render(&sky, cam.proj, cam.view);
draw_world();
fx_end();
fx_end(0);
}
return 0;

View File

@ -577,7 +577,7 @@ int main( int argc, const char *argv[] ) {
glDepthFunc( GL_LESS );
}
fx_end();
fx_end(0);
// ---------------------------------------------------------------------
// UI

View File

@ -70,6 +70,6 @@ int main() {
model_render(sponza, cam.proj, cam.view, M, 0);
// post-fxs end here
fx_end();
fx_end(0);
}
}

View File

@ -191,7 +191,7 @@ int main(int argc, char **argv) {
}
// post-fxs end here
fx_end();
fx_end(0);
// draw pixel-art hud, 16x16 ui element, scaled and positioned in resolution-independant way
{

View File

@ -1,40 +0,0 @@
# Blender v2.64 (sub 0) OBJ File: ''
# www.blender.org
mtllib data/cube.mtl
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.666667 0.500000
vt 0.666667 1.000000
vt 0.333333 1.000000
vt 1.000000 0.500000
vt 1.000000 1.000000
vt 0.998981 0.000000
vt 0.666667 0.001019
vt 0.333333 0.500000
vt 0.333333 0.001020
vt 0.000000 1.000000
vt 0.333333 0.000000
vt 0.000000 0.500000
vt 0.665647 0.000000
vt 0.000000 0.001020
usemtl Material
s off
f 1/1 2/2 3/3
f 5/4 8/5 6/1
f 1/6 5/4 2/7
f 2/8 6/9 3/1
f 3/8 7/3 8/10
f 5/11 1/8 4/12
f 4/8 1/1 3/3
f 8/5 7/2 6/1
f 5/4 6/1 2/7
f 6/9 7/13 3/1
f 4/12 3/8 8/10
f 8/14 5/11 4/12

View File

@ -584,7 +584,7 @@ void game_loop(void *userdata) {
//fx_begin();
//ddraw_flush();
//fx_end();
//fx_end(0);
if( ui_panel("Vis", 0) ) {
ui_bool("Skybox render", &draw_skybox);

View File

@ -0,0 +1,12 @@
# Blender 3.6.2 MTL File: 'None'
# www.blender.org
newmtl Material.001
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.000000 0.000000 0.000000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 1

View File

@ -0,0 +1,49 @@
# Blender 3.6.2
# www.blender.org
mtllib cube.mtl
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 1.000000 0.000001
vt 0.000000 0.000000
vt 0.999999 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000001
vt 0.000000 1.000000
vt 1.000000 0.000000
vt 0.999999 1.000000
vt 0.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
s 0
usemtl Material.001
f 1/1/1 2/2/1 3/3/1
f 5/4/2 8/5/2 6/6/2
f 1/7/3 5/8/3 2/9/3
f 2/10/4 6/11/4 3/12/4
f 3/9/5 7/13/5 8/14/5
f 5/15/6 1/10/6 4/12/6
f 4/5/1 1/1/1 3/3/1
f 8/5/2 7/3/2 6/6/2
f 5/8/3 6/16/3 2/9/3
f 6/11/4 7/17/4 3/12/4
f 4/7/5 3/9/5 8/14/5
f 8/17/6 5/15/6 4/12/6

View File

@ -1185,6 +1185,7 @@ ffi.cdef([[
//lcpp INF [0000] vec3: macro name but used as C declaration in:vec3* in_vertex3;
//lcpp INF [0000] vec3: macro name but used as C declaration in:vec3* out_vertex3;
//lcpp INF [0000] vec4: macro name but used as C declaration in:vec4 color;
//lcpp INF [0000] vec2i: macro name but used as C declaration in:vec2i dims;
//lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 pose;
//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 pose(bool forward, float curframe, int minframe, int maxframe, bool loop, float *opt_retframe);
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 pose(bool forward, float curframe, int minframe, int maxframe, bool loop, float *opt_retframe);
@ -1391,6 +1392,9 @@ ffi.cdef([[
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void object_scale(object_t *obj, vec3 sca);
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void object_scale(object_t *obj, vec3 sca);
//lcpp INF [0000] vec3: macro name but used as C declaration in: void object_scale(object_t *obj, vec3 sca);
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 ui_get_dims();
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 ui_get_dims();
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 ui_get_dims();
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 window_canvas();
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 window_canvas();
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 window_canvas();
@ -2290,7 +2294,9 @@ float specular_shininess;
bool pbr_material(pbr_material_t *pbr, const char *material);
void pbr_material_destroy(pbr_material_t *m);
void fullscreen_quad_rgb( texture_t texture_rgb, float gamma );
void fullscreen_quad_rgb_flipped( texture_t texture, float gamma );
void fullscreen_quad_ycbcr( texture_t texture_YCbCr[3], float gamma );
void fullscreen_quad_ycbcr_flipped( texture_t texture_YCbCr[3], float gamma );
void sprite( texture_t texture, float position[3], float rotation , uint32_t color );
void sprite_rect( texture_t t, vec4 rect, float zindex, vec3 pos, float tilt_deg, unsigned tint_rgba);
void sprite_sheet( texture_t texture, float sheet[3], float position[3], float rotation, float offset[2], float scale[2], int is_additive, uint32_t rgba, int resolution_independant);
@ -2463,6 +2469,11 @@ float value;
vec4 color;
} layer[MAX_CHANNELS_PER_MATERIAL];
} material_t;
enum {
SHADERTOY_FLIP_Y = 2,
SHADERTOY_IGNORE_FBO = 4,
SHADERTOY_IGNORE_MOUSE = 8,
};
typedef struct shadertoy_t {
handle vao, program;
int uniforms[32];
@ -2471,7 +2482,8 @@ int frame;
float clickx, clicky;
uint64_t t;
texture_t tx;
unsigned dims;
vec2i dims;
int flags;
} shadertoy_t;
shadertoy_t shadertoy( const char *shaderfile, unsigned flags );
shadertoy_t* shadertoy_render( shadertoy_t *s, float delta );
@ -2566,7 +2578,8 @@ float *pixels;
int fx_load(const char *file);
int fx_load_from_mem(const char *nameid, const char *content);
void fx_begin();
void fx_end();
void fx_begin_res(int w, int h);
void fx_end(handle fb);
void fx_enable(int pass, int enabled);
int fx_enabled(int pass);
void fx_enable_all(int enabled);
@ -2800,6 +2813,7 @@ PANEL_OPEN = 1,
int ui_double(const char *label, double *value);
int ui_buffer(const char *label, char *buffer, int buflen);
int ui_string(const char *label, char **string);
int ui_text_wrap(const char *label, char *text);
int ui_color3(const char *label, float *color3);
int ui_color3f(const char *label, float *color3);
int ui_color4(const char *label, float *color4);
@ -2839,9 +2853,11 @@ PANEL_OPEN = 1,
int ui_panel_end();
int ui_window_end();
int ui_show(const char *panel_or_window_title, int enabled);
int ui_dims(const char *panel_or_window_title, float width, float height);
int ui_visible(const char *panel_or_window_title);
int ui_enable();
int ui_disable();
vec2 ui_get_dims();
int ui_has_menubar();
int ui_menu(const char *items);
int ui_menu_editbox(char *buf, int bufcap);

View File

@ -16537,7 +16537,9 @@ API void pbr_material_destroy(pbr_material_t *m);
// fullscreen quads
API void fullscreen_quad_rgb( texture_t texture_rgb, float gamma );
API void fullscreen_quad_rgb_flipped( texture_t texture, float gamma );
API void fullscreen_quad_ycbcr( texture_t texture_YCbCr[3], float gamma );
API void fullscreen_quad_ycbcr_flipped( texture_t texture_YCbCr[3], float gamma );
// -----------------------------------------------------------------------------
// sprites
@ -16863,6 +16865,12 @@ typedef struct material_t {
// -----------------------------------------------------------------------------
// shadertoys
enum {
SHADERTOY_FLIP_Y = 2,
SHADERTOY_IGNORE_FBO = 4,
SHADERTOY_IGNORE_MOUSE = 8,
};
typedef struct shadertoy_t {
handle vao, program;
int uniforms[32];
@ -16871,7 +16879,8 @@ typedef struct shadertoy_t {
float clickx, clicky;
uint64_t t;
texture_t tx;
unsigned dims;
vec2i dims;
int flags;
} shadertoy_t;
API shadertoy_t shadertoy( const char *shaderfile, unsigned flags );
@ -17006,7 +17015,8 @@ API void viewport_clip(vec2 from, vec2 to);
API int fx_load(const char *file);
API int fx_load_from_mem(const char *nameid, const char *content);
API void fx_begin();
API void fx_end();
API void fx_begin_res(int w, int h);
API void fx_end(handle fb);
API void fx_enable(int pass, int enabled);
API int fx_enabled(int pass);
API void fx_enable_all(int enabled);
@ -17391,6 +17401,7 @@ API int ui_float4(const char *label, float value[4]);
API int ui_double(const char *label, double *value);
API int ui_buffer(const char *label, char *buffer, int buflen);
API int ui_string(const char *label, char **string);
API int ui_text_wrap(const char *label, char *text);
API int ui_color3(const char *label, float *color3); //[0..255]
API int ui_color3f(const char *label, float *color3); //[0..1]
API int ui_color4(const char *label, float *color4); //[0..255]
@ -17431,9 +17442,11 @@ API int ui_panel_end();
API int ui_window_end();
API int ui_show(const char *panel_or_window_title, int enabled);
API int ui_dims(const char *panel_or_window_title, float width, float height);
API int ui_visible(const char *panel_or_window_title); // @todo: include ui_collapse() items that are open as well?
API int ui_enable();
API int ui_disable();
API vec2 ui_get_dims();
API int ui_has_menubar();
API int ui_menu(const char *items); // semicolon-separated or comma-separated items
@ -340575,6 +340588,37 @@ void fullscreen_quad_rgb( texture_t texture, float gamma ) {
// glDisable( GL_BLEND );
}
void fullscreen_quad_rgb_flipped( texture_t texture, float gamma ) {
static int program = -1, vao = -1, u_inv_gamma = -1;
if( program < 0 ) {
const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B.glsl");
const char* fs = vfs_read("shaders/fs_2_4_texel_inv_gamma.glsl");
program = shader(vs, fs, "", "fragcolor" );
u_inv_gamma = glGetUniformLocation(program, "u_inv_gamma");
glGenVertexArrays( 1, (GLuint*)&vao );
}
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
// glEnable( GL_BLEND );
glUseProgram( program );
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) );
glBindVertexArray( vao );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( texture_type, texture.id );
glDrawArrays( GL_TRIANGLES, 0, 6 );
profile_incstat("Render.num_drawcalls", +1);
profile_incstat("Render.num_triangles", +2);
glBindTexture( texture_type, 0 );
glBindVertexArray( 0 );
glUseProgram( 0 );
// glDisable( GL_BLEND );
}
void fullscreen_quad_ycbcr( texture_t textureYCbCr[3], float gamma ) {
static int program = -1, vao = -1, u_gamma = -1, uy = -1, ucb = -1, ucr = -1;
if( program < 0 ) {
@ -340619,6 +340663,50 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3], float gamma ) {
// glDisable( GL_BLEND );
}
void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3], float gamma ) {
static int program = -1, vao = -1, u_gamma = -1, uy = -1, ucb = -1, ucr = -1;
if( program < 0 ) {
const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B.glsl");
const char* fs = vfs_read("shaders/fs_2_4_texel_ycbr_gamma_saturation.glsl");
program = shader(vs, fs, "", "fragcolor" );
u_gamma = glGetUniformLocation(program, "u_gamma");
uy = glGetUniformLocation(program, "u_texture_y");
ucb = glGetUniformLocation(program, "u_texture_cb");
ucr = glGetUniformLocation(program, "u_texture_cr");
glGenVertexArrays( 1, (GLuint*)&vao );
}
// glEnable( GL_BLEND );
glUseProgram( program );
glUniform1f( u_gamma, gamma );
glBindVertexArray( vao );
glUniform1i(uy, 0);
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, textureYCbCr[0].id );
glUniform1i(ucb, 1);
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, textureYCbCr[1].id );
glUniform1i(ucr, 2);
glActiveTexture( GL_TEXTURE2 );
glBindTexture( GL_TEXTURE_2D, textureYCbCr[2].id );
glDrawArrays( GL_TRIANGLES, 0, 6 );
profile_incstat("Render.num_drawcalls", +1);
profile_incstat("Render.num_triangles", +2);
glBindTexture( GL_TEXTURE_2D, 0 );
glBindVertexArray( 0 );
glUseProgram( 0 );
// glDisable( GL_BLEND );
}
// ----------------------------------------------------------------------------
// sprites
@ -342380,7 +342468,7 @@ void postfx_destroy(postfx *fx);
bool postfx_load(postfx *fx, const char *name, const char *fragment);
bool postfx_begin(postfx *fx, int width, int height);
bool postfx_end(postfx *fx);
bool postfx_end(postfx *fx, handle fb);
bool postfx_enabled(postfx *fx, int pass_number);
bool postfx_enable(postfx *fx, int pass_number, bool enabled);
@ -342535,6 +342623,10 @@ bool postfx_begin(postfx *fx, int width, int height) {
width += !width;
height += !height;
int last_fb;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
fbo_bind(last_fb);
// resize if needed
if( fx->diffuse[0].w != width || fx->diffuse[0].h != height ) {
texture_destroy(&fx->diffuse[0]);
@ -342558,7 +342650,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
uint64_t num_active_passes = popcnt64(fx->mask);
bool active = fx->enabled && num_active_passes;
if( !active ) {
fbo_unbind();
fbo_bind(last_fb);
return false;
}
@ -342575,14 +342667,14 @@ bool postfx_begin(postfx *fx, int width, int height) {
return true;
}
bool postfx_end(postfx *fx) {
bool postfx_end(postfx *fx, handle fb) {
uint64_t num_active_passes = popcnt64(fx->mask);
bool active = fx->enabled && num_active_passes;
if( !active ) {
return false;
}
fbo_unbind();
fbo_bind(fb);
// disable depth test in 2d rendering
bool is_depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
@ -342636,7 +342728,7 @@ bool postfx_end(postfx *fx) {
profile_incstat("Render.num_triangles", +2);
glBindVertexArray(0);
if( bound ) fbo_unbind();
if( bound ) fbo_bind(fb);
else glUseProgram(0);
}
}
@ -342644,6 +342736,8 @@ bool postfx_end(postfx *fx) {
if(is_depth_test_enabled);
glEnable(GL_DEPTH_TEST);
fbo_bind(fb);
return true;
}
@ -342665,8 +342759,11 @@ int fx_load(const char *filemask) {
void fx_begin() {
postfx_begin(&fx, window_width(), window_height());
}
void fx_end() {
postfx_end(&fx);
void fx_begin_res(int w, int h) {
postfx_begin(&fx, w, h);
}
void fx_end(handle fb) {
postfx_end(&fx,fb);
}
int fx_enabled(int pass) {
return postfx_enabled(&fx, pass);
@ -342821,7 +342918,7 @@ enum shadertoy_uniforms {
shadertoy_t shadertoy( const char *shaderfile, unsigned flags ) {
shadertoy_t s = {0};
s.dims = flags;
s.flags = flags;
char *file = vfs_read(shaderfile);
if( !file ) return s;
@ -342829,7 +342926,7 @@ shadertoy_t shadertoy( const char *shaderfile, unsigned flags ) {
glGenVertexArrays(1, &s.vao);
char *fs = stringf("%s%s", vfs_read("header_shadertoy.glsl"), file);
s.program = shader(flags ? vfs_read("shaders/vs_shadertoy_flip.glsl") : vfs_read("shaders/vs_shadertoy.glsl"), fs, "", "fragColor");
s.program = shader((flags&SHADERTOY_FLIP_Y) ? vfs_read("shaders/vs_shadertoy_flip.glsl") : vfs_read("shaders/vs_shadertoy.glsl"), fs, "", "fragColor");
FREE(fs);
if( strstr(file, "noise3.jpg"))
@ -342861,7 +342958,7 @@ shadertoy_t shadertoy( const char *shaderfile, unsigned flags ) {
shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) {
if( s->program && s->vao ) {
if( s->dims && !texture_rec_begin(&s->tx, s->dims, s->dims / 2) ) {
if( s->dims.x && !(s->flags&SHADERTOY_IGNORE_FBO) && !texture_rec_begin(&s->tx, s->dims.x, s->dims.y) ) {
return s;
}
@ -342876,8 +342973,8 @@ shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) {
glUniform1f(s->uniforms[iGlobalTime], s->t / 1000.f );
glUniform1f(s->uniforms[iGlobalFrame], s->frame++);
glUniform1f(s->uniforms[iGlobalDelta], delta / 1000.f );
glUniform2f(s->uniforms[iResolution], window_width(), window_height());
glUniform4f(s->uniforms[iMouse], mx, my, s->clickx, s->clicky );
glUniform2f(s->uniforms[iResolution], s->dims.x ? s->dims.x : window_width(), s->dims.y ? s->dims.y : window_height());
if (!(s->flags&SHADERTOY_IGNORE_MOUSE)) glUniform4f(s->uniforms[iMouse], mx, my, s->clickx, s->clicky );
glUniform1i(s->uniforms[iFrame], (int)window_frame());
glUniform1f(s->uniforms[iTime], time_ss());
@ -342896,7 +342993,7 @@ shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) {
glBindVertexArray(s->vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
if(s->dims) texture_rec_end(&s->tx); // texture_rec
if(s->dims.x && !(s->flags&SHADERTOY_IGNORE_FBO)) texture_rec_end(&s->tx); // texture_rec
}
return s;
}
@ -344031,7 +344128,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f};
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
// config vertex data
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
// feed vertex data
glDrawArrays(mode, 0, count);
@ -344063,7 +344160,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f};
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
// config vertex data
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
// feed vertex data
glDrawArrays(mode, 0, count);
@ -346860,6 +346957,12 @@ int ui_show(const char *panel_or_window_title, int enabled) {
}
return !!enabled;
}
int ui_dims(const char *panel_or_window_title, float width, float height) {
nk_window_set_size(ui_ctx, panel_or_window_title, (struct nk_vec2){width, height});
}
vec2 ui_get_dims() {
return (vec2){nk_window_get_width(ui_ctx), nk_window_get_height(ui_ctx)};
}
static char *ui_build_window_list() {
char *build_windows_menu = 0;
strcatf(&build_windows_menu, "%s;", ICON_MD_VIEW_QUILT); // "Windows");
@ -348338,6 +348441,13 @@ int ui_buffer(const char *label, char *buffer, int buflen) {
return !!(active & NK_EDIT_COMMITED) ? nk_edit_unfocus(ui_ctx), 1 : 0;
}
int ui_text_wrap(const char *label, char *text) {
nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1));
ui_label_(label, NK_TEXT_LEFT);
nk_text_wrap(ui_ctx, text, strlen(text));
return 0;
}
int ui_string(const char *label, char **str) {
char *bak = va("%s%c", *str ? *str : "", '\0');
int rc = ui_buffer(label, bak, strlen(bak)+2);

View File

@ -1060,6 +1060,37 @@ void fullscreen_quad_rgb( texture_t texture, float gamma ) {
// glDisable( GL_BLEND );
}
void fullscreen_quad_rgb_flipped( texture_t texture, float gamma ) {
static int program = -1, vao = -1, u_inv_gamma = -1;
if( program < 0 ) {
const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B.glsl");
const char* fs = vfs_read("shaders/fs_2_4_texel_inv_gamma.glsl");
program = shader(vs, fs, "", "fragcolor" );
u_inv_gamma = glGetUniformLocation(program, "u_inv_gamma");
glGenVertexArrays( 1, (GLuint*)&vao );
}
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
// glEnable( GL_BLEND );
glUseProgram( program );
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) );
glBindVertexArray( vao );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( texture_type, texture.id );
glDrawArrays( GL_TRIANGLES, 0, 6 );
profile_incstat("Render.num_drawcalls", +1);
profile_incstat("Render.num_triangles", +2);
glBindTexture( texture_type, 0 );
glBindVertexArray( 0 );
glUseProgram( 0 );
// glDisable( GL_BLEND );
}
void fullscreen_quad_ycbcr( texture_t textureYCbCr[3], float gamma ) {
static int program = -1, vao = -1, u_gamma = -1, uy = -1, ucb = -1, ucr = -1;
if( program < 0 ) {
@ -1104,6 +1135,50 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3], float gamma ) {
// glDisable( GL_BLEND );
}
void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3], float gamma ) {
static int program = -1, vao = -1, u_gamma = -1, uy = -1, ucb = -1, ucr = -1;
if( program < 0 ) {
const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B.glsl");
const char* fs = vfs_read("shaders/fs_2_4_texel_ycbr_gamma_saturation.glsl");
program = shader(vs, fs, "", "fragcolor" );
u_gamma = glGetUniformLocation(program, "u_gamma");
uy = glGetUniformLocation(program, "u_texture_y");
ucb = glGetUniformLocation(program, "u_texture_cb");
ucr = glGetUniformLocation(program, "u_texture_cr");
glGenVertexArrays( 1, (GLuint*)&vao );
}
// glEnable( GL_BLEND );
glUseProgram( program );
glUniform1f( u_gamma, gamma );
glBindVertexArray( vao );
glUniform1i(uy, 0);
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, textureYCbCr[0].id );
glUniform1i(ucb, 1);
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, textureYCbCr[1].id );
glUniform1i(ucr, 2);
glActiveTexture( GL_TEXTURE2 );
glBindTexture( GL_TEXTURE_2D, textureYCbCr[2].id );
glDrawArrays( GL_TRIANGLES, 0, 6 );
profile_incstat("Render.num_drawcalls", +1);
profile_incstat("Render.num_triangles", +2);
glBindTexture( GL_TEXTURE_2D, 0 );
glBindVertexArray( 0 );
glUseProgram( 0 );
// glDisable( GL_BLEND );
}
// ----------------------------------------------------------------------------
// sprites
@ -2865,7 +2940,7 @@ void postfx_destroy(postfx *fx);
bool postfx_load(postfx *fx, const char *name, const char *fragment);
bool postfx_begin(postfx *fx, int width, int height);
bool postfx_end(postfx *fx);
bool postfx_end(postfx *fx, handle fb);
bool postfx_enabled(postfx *fx, int pass_number);
bool postfx_enable(postfx *fx, int pass_number, bool enabled);
@ -3020,6 +3095,10 @@ bool postfx_begin(postfx *fx, int width, int height) {
width += !width;
height += !height;
int last_fb;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
fbo_bind(last_fb);
// resize if needed
if( fx->diffuse[0].w != width || fx->diffuse[0].h != height ) {
texture_destroy(&fx->diffuse[0]);
@ -3043,7 +3122,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
uint64_t num_active_passes = popcnt64(fx->mask);
bool active = fx->enabled && num_active_passes;
if( !active ) {
fbo_unbind();
fbo_bind(last_fb);
return false;
}
@ -3060,14 +3139,14 @@ bool postfx_begin(postfx *fx, int width, int height) {
return true;
}
bool postfx_end(postfx *fx) {
bool postfx_end(postfx *fx, handle fb) {
uint64_t num_active_passes = popcnt64(fx->mask);
bool active = fx->enabled && num_active_passes;
if( !active ) {
return false;
}
fbo_unbind();
fbo_bind(fb);
// disable depth test in 2d rendering
bool is_depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
@ -3121,7 +3200,7 @@ bool postfx_end(postfx *fx) {
profile_incstat("Render.num_triangles", +2);
glBindVertexArray(0);
if( bound ) fbo_unbind();
if( bound ) fbo_bind(fb);
else glUseProgram(0);
}
}
@ -3129,6 +3208,8 @@ bool postfx_end(postfx *fx) {
if(is_depth_test_enabled);
glEnable(GL_DEPTH_TEST);
fbo_bind(fb);
return true;
}
@ -3150,8 +3231,11 @@ int fx_load(const char *filemask) {
void fx_begin() {
postfx_begin(&fx, window_width(), window_height());
}
void fx_end() {
postfx_end(&fx);
void fx_begin_res(int w, int h) {
postfx_begin(&fx, w, h);
}
void fx_end(handle fb) {
postfx_end(&fx,fb);
}
int fx_enabled(int pass) {
return postfx_enabled(&fx, pass);
@ -3306,7 +3390,7 @@ enum shadertoy_uniforms {
shadertoy_t shadertoy( const char *shaderfile, unsigned flags ) {
shadertoy_t s = {0};
s.dims = flags;
s.flags = flags;
char *file = vfs_read(shaderfile);
if( !file ) return s;
@ -3314,7 +3398,7 @@ shadertoy_t shadertoy( const char *shaderfile, unsigned flags ) {
glGenVertexArrays(1, &s.vao);
char *fs = stringf("%s%s", vfs_read("header_shadertoy.glsl"), file);
s.program = shader(flags ? vfs_read("shaders/vs_shadertoy_flip.glsl") : vfs_read("shaders/vs_shadertoy.glsl"), fs, "", "fragColor");
s.program = shader((flags&SHADERTOY_FLIP_Y) ? vfs_read("shaders/vs_shadertoy_flip.glsl") : vfs_read("shaders/vs_shadertoy.glsl"), fs, "", "fragColor");
FREE(fs);
if( strstr(file, "noise3.jpg"))
@ -3346,7 +3430,7 @@ shadertoy_t shadertoy( const char *shaderfile, unsigned flags ) {
shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) {
if( s->program && s->vao ) {
if( s->dims && !texture_rec_begin(&s->tx, s->dims, s->dims / 2) ) {
if( s->dims.x && !(s->flags&SHADERTOY_IGNORE_FBO) && !texture_rec_begin(&s->tx, s->dims.x, s->dims.y) ) {
return s;
}
@ -3361,8 +3445,8 @@ shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) {
glUniform1f(s->uniforms[iGlobalTime], s->t / 1000.f );
glUniform1f(s->uniforms[iGlobalFrame], s->frame++);
glUniform1f(s->uniforms[iGlobalDelta], delta / 1000.f );
glUniform2f(s->uniforms[iResolution], window_width(), window_height());
glUniform4f(s->uniforms[iMouse], mx, my, s->clickx, s->clicky );
glUniform2f(s->uniforms[iResolution], s->dims.x ? s->dims.x : window_width(), s->dims.y ? s->dims.y : window_height());
if (!(s->flags&SHADERTOY_IGNORE_MOUSE)) glUniform4f(s->uniforms[iMouse], mx, my, s->clickx, s->clicky );
glUniform1i(s->uniforms[iFrame], (int)window_frame());
glUniform1f(s->uniforms[iTime], time_ss());
@ -3381,7 +3465,7 @@ shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) {
glBindVertexArray(s->vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
if(s->dims) texture_rec_end(&s->tx); // texture_rec
if(s->dims.x && !(s->flags&SHADERTOY_IGNORE_FBO)) texture_rec_end(&s->tx); // texture_rec
}
return s;
}

View File

@ -184,7 +184,9 @@ API void pbr_material_destroy(pbr_material_t *m);
// fullscreen quads
API void fullscreen_quad_rgb( texture_t texture_rgb, float gamma );
API void fullscreen_quad_rgb_flipped( texture_t texture, float gamma );
API void fullscreen_quad_ycbcr( texture_t texture_YCbCr[3], float gamma );
API void fullscreen_quad_ycbcr_flipped( texture_t texture_YCbCr[3], float gamma );
// -----------------------------------------------------------------------------
// sprites
@ -510,6 +512,12 @@ typedef struct material_t {
// -----------------------------------------------------------------------------
// shadertoys
enum {
SHADERTOY_FLIP_Y = 2,
SHADERTOY_IGNORE_FBO = 4,
SHADERTOY_IGNORE_MOUSE = 8,
};
typedef struct shadertoy_t {
handle vao, program;
int uniforms[32];
@ -518,7 +526,8 @@ typedef struct shadertoy_t {
float clickx, clicky;
uint64_t t;
texture_t tx;
unsigned dims;
vec2i dims;
int flags;
} shadertoy_t;
API shadertoy_t shadertoy( const char *shaderfile, unsigned flags );
@ -653,7 +662,8 @@ API void viewport_clip(vec2 from, vec2 to);
API int fx_load(const char *file);
API int fx_load_from_mem(const char *nameid, const char *content);
API void fx_begin();
API void fx_end();
API void fx_begin_res(int w, int h);
API void fx_end(handle fb);
API void fx_enable(int pass, int enabled);
API int fx_enabled(int pass);
API void fx_enable_all(int enabled);

View File

@ -95,7 +95,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f};
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
// config vertex data
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
// feed vertex data
glDrawArrays(mode, 0, count);
@ -127,7 +127,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f};
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
// config vertex data
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
// feed vertex data
glDrawArrays(mode, 0, count);

View File

@ -434,6 +434,12 @@ int ui_show(const char *panel_or_window_title, int enabled) {
}
return !!enabled;
}
int ui_dims(const char *panel_or_window_title, float width, float height) {
nk_window_set_size(ui_ctx, panel_or_window_title, (struct nk_vec2){width, height});
}
vec2 ui_get_dims() {
return (vec2){nk_window_get_width(ui_ctx), nk_window_get_height(ui_ctx)};
}
static char *ui_build_window_list() {
char *build_windows_menu = 0;
strcatf(&build_windows_menu, "%s;", ICON_MD_VIEW_QUILT); // "Windows");
@ -1912,6 +1918,13 @@ int ui_buffer(const char *label, char *buffer, int buflen) {
return !!(active & NK_EDIT_COMMITED) ? nk_edit_unfocus(ui_ctx), 1 : 0;
}
int ui_text_wrap(const char *label, char *text) {
nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1));
ui_label_(label, NK_TEXT_LEFT);
nk_text_wrap(ui_ctx, text, strlen(text));
return 0;
}
int ui_string(const char *label, char **str) {
char *bak = va("%s%c", *str ? *str : "", '\0');
int rc = ui_buffer(label, bak, strlen(bak)+2);

View File

@ -25,6 +25,7 @@ API int ui_float4(const char *label, float value[4]);
API int ui_double(const char *label, double *value);
API int ui_buffer(const char *label, char *buffer, int buflen);
API int ui_string(const char *label, char **string);
API int ui_text_wrap(const char *label, char *text);
API int ui_color3(const char *label, float *color3); //[0..255]
API int ui_color3f(const char *label, float *color3); //[0..1]
API int ui_color4(const char *label, float *color4); //[0..255]
@ -65,9 +66,11 @@ API int ui_panel_end();
API int ui_window_end();
API int ui_show(const char *panel_or_window_title, int enabled);
API int ui_dims(const char *panel_or_window_title, float width, float height);
API int ui_visible(const char *panel_or_window_title); // @todo: include ui_collapse() items that are open as well?
API int ui_enable();
API int ui_disable();
API vec2 ui_get_dims();
API int ui_has_menubar();
API int ui_menu(const char *items); // semicolon-separated or comma-separated items

View File

@ -11284,6 +11284,37 @@ void fullscreen_quad_rgb( texture_t texture, float gamma ) {
// glDisable( GL_BLEND );
}
void fullscreen_quad_rgb_flipped( texture_t texture, float gamma ) {
static int program = -1, vao = -1, u_inv_gamma = -1;
if( program < 0 ) {
const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B.glsl");
const char* fs = vfs_read("shaders/fs_2_4_texel_inv_gamma.glsl");
program = shader(vs, fs, "", "fragcolor" );
u_inv_gamma = glGetUniformLocation(program, "u_inv_gamma");
glGenVertexArrays( 1, (GLuint*)&vao );
}
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
// glEnable( GL_BLEND );
glUseProgram( program );
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) );
glBindVertexArray( vao );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( texture_type, texture.id );
glDrawArrays( GL_TRIANGLES, 0, 6 );
profile_incstat("Render.num_drawcalls", +1);
profile_incstat("Render.num_triangles", +2);
glBindTexture( texture_type, 0 );
glBindVertexArray( 0 );
glUseProgram( 0 );
// glDisable( GL_BLEND );
}
void fullscreen_quad_ycbcr( texture_t textureYCbCr[3], float gamma ) {
static int program = -1, vao = -1, u_gamma = -1, uy = -1, ucb = -1, ucr = -1;
if( program < 0 ) {
@ -11328,6 +11359,50 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3], float gamma ) {
// glDisable( GL_BLEND );
}
void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3], float gamma ) {
static int program = -1, vao = -1, u_gamma = -1, uy = -1, ucb = -1, ucr = -1;
if( program < 0 ) {
const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B.glsl");
const char* fs = vfs_read("shaders/fs_2_4_texel_ycbr_gamma_saturation.glsl");
program = shader(vs, fs, "", "fragcolor" );
u_gamma = glGetUniformLocation(program, "u_gamma");
uy = glGetUniformLocation(program, "u_texture_y");
ucb = glGetUniformLocation(program, "u_texture_cb");
ucr = glGetUniformLocation(program, "u_texture_cr");
glGenVertexArrays( 1, (GLuint*)&vao );
}
// glEnable( GL_BLEND );
glUseProgram( program );
glUniform1f( u_gamma, gamma );
glBindVertexArray( vao );
glUniform1i(uy, 0);
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, textureYCbCr[0].id );
glUniform1i(ucb, 1);
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, textureYCbCr[1].id );
glUniform1i(ucr, 2);
glActiveTexture( GL_TEXTURE2 );
glBindTexture( GL_TEXTURE_2D, textureYCbCr[2].id );
glDrawArrays( GL_TRIANGLES, 0, 6 );
profile_incstat("Render.num_drawcalls", +1);
profile_incstat("Render.num_triangles", +2);
glBindTexture( GL_TEXTURE_2D, 0 );
glBindVertexArray( 0 );
glUseProgram( 0 );
// glDisable( GL_BLEND );
}
// ----------------------------------------------------------------------------
// sprites
@ -13089,7 +13164,7 @@ void postfx_destroy(postfx *fx);
bool postfx_load(postfx *fx, const char *name, const char *fragment);
bool postfx_begin(postfx *fx, int width, int height);
bool postfx_end(postfx *fx);
bool postfx_end(postfx *fx, handle fb);
bool postfx_enabled(postfx *fx, int pass_number);
bool postfx_enable(postfx *fx, int pass_number, bool enabled);
@ -13244,6 +13319,10 @@ bool postfx_begin(postfx *fx, int width, int height) {
width += !width;
height += !height;
int last_fb;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
fbo_bind(last_fb);
// resize if needed
if( fx->diffuse[0].w != width || fx->diffuse[0].h != height ) {
texture_destroy(&fx->diffuse[0]);
@ -13267,7 +13346,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
uint64_t num_active_passes = popcnt64(fx->mask);
bool active = fx->enabled && num_active_passes;
if( !active ) {
fbo_unbind();
fbo_bind(last_fb);
return false;
}
@ -13284,14 +13363,14 @@ bool postfx_begin(postfx *fx, int width, int height) {
return true;
}
bool postfx_end(postfx *fx) {
bool postfx_end(postfx *fx, handle fb) {
uint64_t num_active_passes = popcnt64(fx->mask);
bool active = fx->enabled && num_active_passes;
if( !active ) {
return false;
}
fbo_unbind();
fbo_bind(fb);
// disable depth test in 2d rendering
bool is_depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
@ -13345,7 +13424,7 @@ bool postfx_end(postfx *fx) {
profile_incstat("Render.num_triangles", +2);
glBindVertexArray(0);
if( bound ) fbo_unbind();
if( bound ) fbo_bind(fb);
else glUseProgram(0);
}
}
@ -13353,6 +13432,8 @@ bool postfx_end(postfx *fx) {
if(is_depth_test_enabled);
glEnable(GL_DEPTH_TEST);
fbo_bind(fb);
return true;
}
@ -13374,8 +13455,11 @@ int fx_load(const char *filemask) {
void fx_begin() {
postfx_begin(&fx, window_width(), window_height());
}
void fx_end() {
postfx_end(&fx);
void fx_begin_res(int w, int h) {
postfx_begin(&fx, w, h);
}
void fx_end(handle fb) {
postfx_end(&fx,fb);
}
int fx_enabled(int pass) {
return postfx_enabled(&fx, pass);
@ -13530,7 +13614,7 @@ enum shadertoy_uniforms {
shadertoy_t shadertoy( const char *shaderfile, unsigned flags ) {
shadertoy_t s = {0};
s.dims = flags;
s.flags = flags;
char *file = vfs_read(shaderfile);
if( !file ) return s;
@ -13538,7 +13622,7 @@ shadertoy_t shadertoy( const char *shaderfile, unsigned flags ) {
glGenVertexArrays(1, &s.vao);
char *fs = stringf("%s%s", vfs_read("header_shadertoy.glsl"), file);
s.program = shader(flags ? vfs_read("shaders/vs_shadertoy_flip.glsl") : vfs_read("shaders/vs_shadertoy.glsl"), fs, "", "fragColor");
s.program = shader((flags&SHADERTOY_FLIP_Y) ? vfs_read("shaders/vs_shadertoy_flip.glsl") : vfs_read("shaders/vs_shadertoy.glsl"), fs, "", "fragColor");
FREE(fs);
if( strstr(file, "noise3.jpg"))
@ -13570,7 +13654,7 @@ shadertoy_t shadertoy( const char *shaderfile, unsigned flags ) {
shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) {
if( s->program && s->vao ) {
if( s->dims && !texture_rec_begin(&s->tx, s->dims, s->dims / 2) ) {
if( s->dims.x && !(s->flags&SHADERTOY_IGNORE_FBO) && !texture_rec_begin(&s->tx, s->dims.x, s->dims.y) ) {
return s;
}
@ -13585,8 +13669,8 @@ shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) {
glUniform1f(s->uniforms[iGlobalTime], s->t / 1000.f );
glUniform1f(s->uniforms[iGlobalFrame], s->frame++);
glUniform1f(s->uniforms[iGlobalDelta], delta / 1000.f );
glUniform2f(s->uniforms[iResolution], window_width(), window_height());
glUniform4f(s->uniforms[iMouse], mx, my, s->clickx, s->clicky );
glUniform2f(s->uniforms[iResolution], s->dims.x ? s->dims.x : window_width(), s->dims.y ? s->dims.y : window_height());
if (!(s->flags&SHADERTOY_IGNORE_MOUSE)) glUniform4f(s->uniforms[iMouse], mx, my, s->clickx, s->clicky );
glUniform1i(s->uniforms[iFrame], (int)window_frame());
glUniform1f(s->uniforms[iTime], time_ss());
@ -13605,7 +13689,7 @@ shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) {
glBindVertexArray(s->vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
if(s->dims) texture_rec_end(&s->tx); // texture_rec
if(s->dims.x && !(s->flags&SHADERTOY_IGNORE_FBO)) texture_rec_end(&s->tx); // texture_rec
}
return s;
}
@ -14740,7 +14824,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f};
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
// config vertex data
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
// feed vertex data
glDrawArrays(mode, 0, count);
@ -14772,7 +14856,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f};
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
// config vertex data
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
// feed vertex data
glDrawArrays(mode, 0, count);
@ -17569,6 +17653,12 @@ int ui_show(const char *panel_or_window_title, int enabled) {
}
return !!enabled;
}
int ui_dims(const char *panel_or_window_title, float width, float height) {
nk_window_set_size(ui_ctx, panel_or_window_title, (struct nk_vec2){width, height});
}
vec2 ui_get_dims() {
return (vec2){nk_window_get_width(ui_ctx), nk_window_get_height(ui_ctx)};
}
static char *ui_build_window_list() {
char *build_windows_menu = 0;
strcatf(&build_windows_menu, "%s;", ICON_MD_VIEW_QUILT); // "Windows");
@ -19047,6 +19137,13 @@ int ui_buffer(const char *label, char *buffer, int buflen) {
return !!(active & NK_EDIT_COMMITED) ? nk_edit_unfocus(ui_ctx), 1 : 0;
}
int ui_text_wrap(const char *label, char *text) {
nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1));
ui_label_(label, NK_TEXT_LEFT);
nk_text_wrap(ui_ctx, text, strlen(text));
return 0;
}
int ui_string(const char *label, char **str) {
char *bak = va("%s%c", *str ? *str : "", '\0');
int rc = ui_buffer(label, bak, strlen(bak)+2);

View File

@ -2620,7 +2620,9 @@ API void pbr_material_destroy(pbr_material_t *m);
// fullscreen quads
API void fullscreen_quad_rgb( texture_t texture_rgb, float gamma );
API void fullscreen_quad_rgb_flipped( texture_t texture, float gamma );
API void fullscreen_quad_ycbcr( texture_t texture_YCbCr[3], float gamma );
API void fullscreen_quad_ycbcr_flipped( texture_t texture_YCbCr[3], float gamma );
// -----------------------------------------------------------------------------
// sprites
@ -2946,6 +2948,12 @@ typedef struct material_t {
// -----------------------------------------------------------------------------
// shadertoys
enum {
SHADERTOY_FLIP_Y = 2,
SHADERTOY_IGNORE_FBO = 4,
SHADERTOY_IGNORE_MOUSE = 8,
};
typedef struct shadertoy_t {
handle vao, program;
int uniforms[32];
@ -2954,7 +2962,8 @@ typedef struct shadertoy_t {
float clickx, clicky;
uint64_t t;
texture_t tx;
unsigned dims;
vec2i dims;
int flags;
} shadertoy_t;
API shadertoy_t shadertoy( const char *shaderfile, unsigned flags );
@ -3089,7 +3098,8 @@ API void viewport_clip(vec2 from, vec2 to);
API int fx_load(const char *file);
API int fx_load_from_mem(const char *nameid, const char *content);
API void fx_begin();
API void fx_end();
API void fx_begin_res(int w, int h);
API void fx_end(handle fb);
API void fx_enable(int pass, int enabled);
API int fx_enabled(int pass);
API void fx_enable_all(int enabled);
@ -3474,6 +3484,7 @@ API int ui_float4(const char *label, float value[4]);
API int ui_double(const char *label, double *value);
API int ui_buffer(const char *label, char *buffer, int buflen);
API int ui_string(const char *label, char **string);
API int ui_text_wrap(const char *label, char *text);
API int ui_color3(const char *label, float *color3); //[0..255]
API int ui_color3f(const char *label, float *color3); //[0..1]
API int ui_color4(const char *label, float *color4); //[0..255]
@ -3514,9 +3525,11 @@ API int ui_panel_end();
API int ui_window_end();
API int ui_show(const char *panel_or_window_title, int enabled);
API int ui_dims(const char *panel_or_window_title, float width, float height);
API int ui_visible(const char *panel_or_window_title); // @todo: include ui_collapse() items that are open as well?
API int ui_enable();
API int ui_disable();
API vec2 ui_get_dims();
API int ui_has_menubar();
API int ui_menu(const char *items); // semicolon-separated or comma-separated items

View File

@ -80,7 +80,7 @@ int main() {
model_render(girl, cam.proj, cam.view, girl.pivot, 0);
// post-fxs end here
fx_end();
fx_end(0);
gizmo(&pos, &rot, &sca);
model_render_skeleton(girl, girl.pivot);

View File

@ -1772,7 +1772,7 @@ int main() {
editor_obj_call0(obj, fn_draw);
}
fx_end();
fx_end(0);
// draw gizmos, aabbs, markers, etc
for each_set_ptr(editor_selection, void*, o) {

View File

@ -0,0 +1,26 @@
#pragma once
struct asset_t;
typedef int (*ed_proc)(struct asset_t *asset);
typedef struct {
ed_proc init;
ed_proc tick;
ed_proc quit;
char* (*ext)();
} editor_vtable_t;
typedef struct {
char *name;
editor_vtable_t f;
} editor_t;
typedef struct {
char *name;
editor_t *ed;
int slot; //<< internal, used by plugin
} asset_t;
#define PLUG_DECLARE(name) editor_vtable_t name##__procs = { name##_init, name##_tick, name##_quit, name##_ext };

View File

@ -0,0 +1,173 @@
#include "v4k.h"
#include "pluginapi.h"
enum { WIDTH = 1024, HEIGHT = 1024 };
enum { UI_WIDTH = 512, UI_HEIGHT = 512 };
enum { VS, FS, FX, SHADERTOY };
typedef struct {
char kind;
bool reload;
// preview
handle fb, flipFB;
texture_t tex, flipTex;
texture_t texDepth;
union {
struct {
shadertoy_t shadertoy;
bool flip_y;
bool allow_mouse;
};
struct {
int model;
int fx_slot;
};
};
} shader_asset_t;
array(shader_asset_t) shaders = 0;
char *shader_editor_ext() {
return "fx,glsl,vs,fs";
}
static inline
void reload_shader(asset_t *f, shader_asset_t *s) {
if (s->kind == SHADERTOY) {
s->shadertoy = shadertoy(f->name, (s->flip_y?SHADERTOY_FLIP_Y:0)|(s->allow_mouse?0:SHADERTOY_IGNORE_MOUSE)|SHADERTOY_IGNORE_FBO);
s->shadertoy.dims.x = WIDTH;
s->shadertoy.dims.y = HEIGHT;
}
else if (s->kind == FX) {
s->fx_slot = fx_load_from_mem(f->name, vfs_read(f->name));
}
s->reload = 0;
}
int shader_editor_init(asset_t *f) {
shader_asset_t a = {0};
a.reload = 1;
if (strstri(f->name, "shadertoys")) {
a.kind = SHADERTOY;
}
// else if (strbegi(file_name(f->name), "vs_") || strendi(f->name, ".vs")) {
// a.kind = VS;
// }
// else if (strbegi(file_name(f->name), "fs_") || strendi(f->name, ".fs")) {
// a.kind = FS;
// }
else if (strbegi(file_name(f->name), "fx") && strendi(f->name, ".fs")) {
a.kind = FX;
} else {
PRINTF("unsupported shader: %s\n", f->name);
return 1;
}
a.tex = texture_create(WIDTH, HEIGHT, 4, NULL, TEXTURE_RGBA);
a.flipTex = texture_create(WIDTH, HEIGHT, 4, NULL, TEXTURE_RGBA);
a.texDepth = texture_create(WIDTH, HEIGHT, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT);
a.fb = fbo(a.tex.id, a.texDepth.id, 0);
a.flipFB = fbo(a.flipTex.id, 0, 0);
f->slot = array_count(shaders);
array_push(shaders, a);
return 0;
}
int shader_editor_tick(asset_t *f) {
shader_asset_t *s = (shaders+f->slot);
if (s->reload) {
reload_shader(f, s);
ui_dims(f->name, UI_WIDTH, UI_HEIGHT*1.45);
}
fx_enable_all(0);
// vec2 win_dims = ui_get_dims();
// ui_dims(f->name, win_dims.x, win_dims.x*1.45);
fbo_bind(s->fb);
glViewport(0,0,WIDTH,HEIGHT);
glClearDepth(1);
glClearColor(0.0f,0.0f,0.0f,0.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
if (s->kind == SHADERTOY) {
shadertoy_render(&s->shadertoy, window_delta());
}
else if (s->kind == FX) {
fx_enable(s->fx_slot, 1);
// fx_begin();
fx_begin_res(WIDTH, HEIGHT);
enum { CUBE, SPHERE, SUZANNE, SHADERBALL, MAX_MODELS };
static camera_t cam;
static skybox_t sky;
static model_t models[MAX_MODELS];
do_once {
cam = camera();
sky = skybox(0,0);
camera_fps(&cam, 0,45);
models[CUBE] = model("meshes/cube.obj", MODEL_NO_ANIMATIONS);
// model_set_texture(models[CUBE], texture_checker());
rotation44(models[CUBE].pivot, -90, 1,0,0);
models[SPHERE] = model("meshes/sphere.obj", MODEL_NO_ANIMATIONS);
rotation44(models[SPHERE].pivot, -90, 1,0,0);
models[SUZANNE] = model("meshes/suzanne.obj", MODEL_NO_ANIMATIONS);
rotation44(models[SUZANNE].pivot, -90, 1,0,0);
models[SHADERBALL] = model("meshes/shaderBall.glb", MODEL_NO_ANIMATIONS);
mat44 sca; scale44(sca, 1,1,1);
mat44 rot; rotation44(rot, -90, 1,0,0);
multiply44x2(models[SHADERBALL].pivot, sca, rot);
}
bool active = (ui_active() || ui_hover()) && input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R);
vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active);
// camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z);
camera_orbit(&cam, mouse.x,mouse.y, input_diff(MOUSE_W));
perspective44(cam.proj, cam.fov, UI_WIDTH/(float)UI_HEIGHT, 0.1f, 100.f);
skybox_render(&sky, cam.proj, cam.view);
ddraw_grid(0);
ddraw_flush();
model_render(models[s->model], cam.proj, cam.view, models[s->model].pivot, 0);
fx_end(s->fb);
// fbo_bind(s->fb);
// fullscreen_quad_rgb(s->tex, 1.0);
// fbo_unbind();
}
fbo_bind(s->flipFB);
fullscreen_quad_rgb(s->tex, 1.0);
fbo_unbind();
ui_image(0, s->flipTex.id, UI_WIDTH, UI_HEIGHT);
if (s->kind == SHADERTOY) {
if (ui_bool("Flip Y", &s->flip_y)) {
s->reload = 1;
}
if (ui_bool("Allow mouse", &s->allow_mouse)) {
s->reload = 1;
}
}
else if (s->kind == FX) {
static char* model_selections[] = {"Cube", "Sphere", "Suzanne", "Shader ball"};
ui_list("Model", model_selections, 4, &s->model);
}
return 0;
}
int shader_editor_quit(asset_t *f) {
shader_asset_t *s = (shaders+f->slot);
fbo_destroy(s->fb);
fbo_destroy(s->flipFB);
return 0;
}
PLUG_DECLARE(shader_editor);

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,127 @@
#define COOK_ON_DEMAND 1
#include "v4k.c"
#include "pluginapi.h"
array(editor_t) editors = 0;
array(asset_t) assets = 0;
#define PLUGINS\
X(shader_editor)
#define X(name) extern editor_vtable_t name##__procs;
PLUGINS
#undef X
void load_editor(char *pname, editor_vtable_t f) {
char *name = STRDUP(pname); // @leak
editor_t ed = {0};
ed.f = f;
ed.name = file_base(STRDUP(name)); // @leak
PRINTF("loaded plugin: '%s'\n", ed.name);
array_push(editors, ed);
}
void load_editors() {
#define X(name) load_editor(#name, name##__procs);
PLUGINS
#undef X
}
map(char*, editor_t*) assocs;
void register_extensions() {
map_init(assocs, less_str, hash_str);
for (int i=0; i<array_count(editors); i++) {
char *types = editors[i].f.ext();
for each_substring(types, ",", ext) {
map_find_or_add(assocs, STRDUP(ext), (editors+i));
PRINTF("extension '%s' mapped to '%s'\n", ext, editors[i].name);
}
}
}
void edit_asset(char *fname) {
app_exec(va("%s %s", ifdef(win32, "start", ifdef(osx, "open", "xdg-open")), fname));
}
void load_asset(const char *fname) {
char *ext = (file_ext(fname)+1);
PRINTF("opened asset: %s (%s)\n", fname, ext);
// see if we have a supported editor plugin registered
editor_t **ed = map_find(assocs, ext);
if (!ed) {
PRINTF("fallback exec %s\n", fname);
edit_asset(fname);
return;
}
asset_t asset = {0};
asset.name = STRDUP(fname);
asset.ed = *ed;
array_push(assets, asset);
if (asset.ed->f.init((struct asset_t*)array_back(assets))) {
FREE(asset.name);
array_pop(assets);
PRINTF("fallback exec %s\n", fname);
edit_asset(fname);
}
}
int main() {
window_create(75.0, WINDOW_MSAA8);
window_fps_unlock();
camera_t cam = camera();
camera_enable(&cam);
load_editors();
register_extensions();
#if 1
load_asset("demos/art/shadertoys/!default.fs");
load_asset("demos/art/fx/fxDithering.fs");
#endif
while( window_swap() && !input(KEY_ESC) ) {
static int wb_enabled = 1;
if (ui_window("Workbench", &wb_enabled)) {
static const char *file;
static bool show_browser = 1;
if( ui_browse(&file, &show_browser) ) {
load_asset(file);
show_browser = 1;
}
ui_window_end();
}
for (int i=0; i<array_count(assets); i++) {
asset_t *f = (assets+i);
int open = 1;
if (ui_window(f->name, &open)) {
f->ed->f.tick(f);
ui_separator();
if (ui_button("reload asset") || !open) {
f->ed->f.quit(f);
f->ed->f.init(f);
}
if (ui_button("edit asset") || !open) {
edit_asset(assets[i].name);
}
if (ui_button("close asset") || !open) {
f->ed->f.quit(f);
FREE(assets[i].name);
array_erase(assets, i);
--i;
}
ui_window_end();
}
}
}
return 0;
}