diff --git a/MAKE.bat b/MAKE.bat index 9589856..f3172b5 100644 --- a/MAKE.bat +++ b/MAKE.bat @@ -599,14 +599,14 @@ 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 -DMAX_CACHED_FILES=0 +set edit=-DCOOK_ON_DEMAND -DUI_LESSER_SPACING -DUI_ICONS_SMALL -DVFS_ALWAYS_PACK 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 +del .art[00].zip > nul !echo! v4k && !cc! engine\v4k.c !export! !edit! !args! || set rc=1 - if "!cc!"=="cl" ( set plug_export=/LD ) else if "!cc!"=="clang-cl" ( diff --git a/demos/03-anims.c b/demos/03-anims.c index 7792360..103113e 100644 --- a/demos/03-anims.c +++ b/demos/03-anims.c @@ -22,7 +22,7 @@ int main() { camera_t cam = camera(); skybox_t sky = skybox("cubemaps/stardust", 0); - model_t mdl = model("Stan.fbx", 0); + model_t mdl = model("Stan.fbx", MODEL_RIMLIGHT); anims_t a = animations("Stan.fbx", 0); // load all postfx files in all subdirs diff --git a/demos/04-lod.c b/demos/04-lod.c index c6ba35e..270ea9a 100644 --- a/demos/04-lod.c +++ b/demos/04-lod.c @@ -130,7 +130,7 @@ void DrawModel(mesh_t *m) { "fragcolor = vec4(v_normal, 1.0);\n" // diffuse "}"; - static unsigned program; do_once program = shader(vs, fs, "att_position,att_normal", "fragcolor"); + static unsigned program; do_once program = shader(vs, fs, "att_position,att_normal", "fragcolor", ""); shader_bind(program); shader_mat44("VP", VP); shader_mat44("M", M); diff --git a/demos/99-dung.c b/demos/99-dung.c index bb9dc27..e0b21fe 100644 --- a/demos/99-dung.c +++ b/demos/99-dung.c @@ -112,7 +112,7 @@ void draw_world() { "fragcolor = vec4(v_normal, 1.0);\n" // diffuse "}"; - static unsigned program; do_once program = shader(vs, fs, "att_position,att_normal", "fragcolor"); + static unsigned program; do_once program = shader(vs, fs, "att_position,att_normal", "fragcolor", ""); shader_bind(program); shader_mat44("VP", VP); shader_mat44("M", M); diff --git a/demos/99-pbr.c b/demos/99-pbr.c index 1436532..f4ea965 100644 --- a/demos/99-pbr.c +++ b/demos/99-pbr.c @@ -363,7 +363,7 @@ unsigned gShader = ~0u; unsigned gShaderConfig = ~0u; bool LoadShaderConfig( int slot ) { // name,vs,fs - unsigned newShader = shader( vfs_read(shaders[slot][0]), vfs_read(shaders[slot][1]), NULL, NULL ); + unsigned newShader = shader( vfs_read(shaders[slot][0]), vfs_read(shaders[slot][1]), NULL, NULL , ""); if( newShader == ~0u ) return false; shader_destroy( gShader ); @@ -418,7 +418,7 @@ int main( int argc, const char *argv[] ) { lightYaw = g_skybox.sunYaw; lightPitch = g_skybox.sunPitch; - unsigned skysphereShader = shader( vfs_read("Skyboxes/skysphere.vs"), vfs_read("Skyboxes/skysphere.fs"), NULL, NULL ); + unsigned skysphereShader = shader( vfs_read("Skyboxes/skysphere.vs"), vfs_read("Skyboxes/skysphere.fs"), NULL, NULL , ""); Model skysphere = { 0 }; ModelLoad(&skysphere, "Skyboxes/skysphere.fbx"); ModelRebind(&skysphere, skysphereShader); if( ModelLoad( &gModel, argc > 1 && argv[1][0] != '-' ? argv[ 1 ] : "damagedhelmet.gltf" ) ) { diff --git a/demos/99-spot.c b/demos/99-spot.c index 090fdca..24cad90 100644 --- a/demos/99-spot.c +++ b/demos/99-spot.c @@ -202,8 +202,8 @@ void shadow_create(int RESOLUTION) { lightAimPos = vec3(0.0, 0, -5.0); // Create programs - shadowProgram = shader(vs_shadow_vsm, fs_shadow_vsm, "position", "outColor"); - blurProgram = shader(vs_shadow_blur, fs_shadow_blur, "position,,texcoord", "outColor"); + shadowProgram = shader(vs_shadow_vsm, fs_shadow_vsm, "position", "outColor", ""); + blurProgram = shader(vs_shadow_blur, fs_shadow_blur, "position,,texcoord", "outColor", ""); // ShadowMap-textures and FBO // @todo: GL_RG32F+GL_RG also GL_CLAMP to remove artifacts shadowMapTex = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 2, NULL, TEXTURE_FLOAT).id; @@ -483,7 +483,7 @@ int main(int argc, char **argv) const char *tpl[] = { "{{include-shadowmap}}", fs_0_0_shadowmap_lit, }; - vsm_program = shader(strlerp(1,tpl,vs_323444143_16_332_model), strlerp(1,tpl,fs_32_4_model), "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent", "fragColor"); + vsm_program = shader(strlerp(1,tpl,vs_323444143_16_332_model), strlerp(1,tpl,fs_32_4_model), "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent", "fragColor", ""); #endif while (window_swap()) diff --git a/engine/art/shaders/fs_32_4_model.glsl b/engine/art/shaders/fs_32_4_model.glsl index 1a3f997..c877a59 100644 --- a/engine/art/shaders/fs_32_4_model.glsl +++ b/engine/art/shaders/fs_32_4_model.glsl @@ -6,9 +6,11 @@ uniform bool u_lit = false; uniform bool u_matcaps = false; uniform vec4 u_diffuse = vec4(1.0,1.0,1.0,1.0); - #ifdef RIM in vec3 v_position; +uniform mat4 M; // RIM +uniform vec3 u_rimcolor = vec3(0.2,0.2,0.2); +uniform vec3 u_rimrange = vec3(0.11,0.98,0.5); #endif in vec3 v_normal, v_normal_ws; in vec2 v_texcoord; @@ -66,9 +68,9 @@ if(u_matcaps) { #ifdef RIM {vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space - vec3 v = normalize(-p); // eye vector - float rim = 1.0 - max(dot(v, n), 0.0); // rimlight - rim = smoothstep(1.0-0.01, 1.0, rim); // intensity (0.01) - fragcolor += vec4(0.0, 0.0, rim, 1.0);} // blue + vec3 v = normalize(vpeye.xyz-p); // eye vector + float rim = 1.0 - max(dot(v,n), 0.0); + vec3 col = u_rimcolor*(pow(smoothstep(1.0-u_rimrange.x,u_rimrange.y,rim), u_rimrange.z)); + fragcolor += vec4(col, 1.0);} #endif } \ No newline at end of file diff --git a/engine/art/shaders/vs_323444143_16_332_model.glsl b/engine/art/shaders/vs_323444143_16_332_model.glsl index 4d76dd1..9dcebfd 100644 --- a/engine/art/shaders/vs_323444143_16_332_model.glsl +++ b/engine/art/shaders/vs_323444143_16_332_model.glsl @@ -3,7 +3,7 @@ #endif uniform mat3x4 vsBoneMatrix[MAX_BONES]; uniform bool SKINNED = false; -// uniform mat4 M; // RIM +uniform mat4 M; // RIM uniform mat4 VP; diff --git a/engine/bind/v4k.lua b/engine/bind/v4k.lua index 333df75..23fd4d5 100644 --- a/engine/bind/v4k.lua +++ b/engine/bind/v4k.lua @@ -2371,8 +2371,8 @@ int texture_width; void shadowmap_end(shadowmap_t *s); void shadowmatrix_proj(mat44 shm_proj, float aLightFov, float znear, float zfar); void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float bottom, float top, float znear, float zfar); - unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor); - unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor); + unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines); + unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines); unsigned shader_bind(unsigned program); void shader_bool(const char *uniform, bool i ); void shader_int(const char *uniform, int i); @@ -2511,6 +2511,7 @@ MODEL_NO_ANIMATIONS = 1, MODEL_NO_MESHES = 2, MODEL_NO_TEXTURES = 4, MODEL_MATCAPS = 8, +MODEL_RIMLIGHT = 16 }; typedef struct model_t { struct iqm_t *iqm; diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index a1b0c7e..b3bf388 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -16668,8 +16668,8 @@ API void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float botto // ----------------------------------------------------------------------------- // shaders -API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor); -API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor); +API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines); +API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines); API unsigned shader_bind(unsigned program); API void shader_bool(const char *uniform, bool i ); API void shader_int(const char *uniform, int i); @@ -16918,6 +16918,7 @@ enum MODEL_FLAGS { MODEL_NO_MESHES = 2, MODEL_NO_TEXTURES = 4, MODEL_MATCAPS = 8, + MODEL_RIMLIGHT = 16 }; typedef struct model_t { @@ -336155,7 +336156,7 @@ void font_face_from_mem(const char *tag, const void *ttf_bufferv, unsigned ttf_l const char *vs_filename = 0, *fs_filename = 0; const char *vs = vs_filename ? file_read(vs_filename) : mv_vs_source; const char *fs = fs_filename ? file_read(fs_filename) : mv_fs_source; - f->program = shader(vs, fs, "vertexPosition,instanceGlyph", "outColor"); + f->program = shader(vs, fs, "vertexPosition,instanceGlyph", "outColor", ""); // figure out what ranges we're about to bake #define MERGE_TABLE(table) do { \ @@ -339650,18 +339651,25 @@ GLuint shader_compile( GLenum type, const char *source ) { return shader; } -unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor){ - return shader_geom(NULL, vs, fs, attribs, fragcolor); +unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines){ + return shader_geom(NULL, vs, fs, attribs, fragcolor, defines); } -unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor) { +unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines) { PRINTF(/*"!"*/"Compiling shader\n"); + char *glsl_defines = ""; + if (defines) { + for each_substring(defines, ",", def) { + glsl_defines = va("%s#define %s\n", glsl_defines, def); + } + } + const char *glsl_version = ifdef(ems, "300 es", "150"); - vs = vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s", glsl_version, vs ? vs : ""); - fs = fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s", glsl_version, fs ? fs : ""); - if (gs) gs = gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s", glsl_version, gs ? gs : ""); + vs = vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, vs ? vs : ""); + fs = fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, fs ? fs : ""); + if (gs) gs = gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, gs ? gs : ""); #if is(ems) { @@ -340600,7 +340608,7 @@ void fullscreen_quad_rgb( texture_t texture, float gamma ) { const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B_flipped.glsl"); const char* fs = vfs_read("shaders/fs_2_4_texel_inv_gamma.glsl"); - program = shader(vs, fs, "", "fragcolor" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_inv_gamma = glGetUniformLocation(program, "u_inv_gamma"); glGenVertexArrays( 1, (GLuint*)&vao ); } @@ -340631,7 +340639,7 @@ void fullscreen_quad_rgb_flipped( texture_t texture, float gamma ) { 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" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_inv_gamma = glGetUniformLocation(program, "u_inv_gamma"); glGenVertexArrays( 1, (GLuint*)&vao ); } @@ -340662,7 +340670,7 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3], float gamma ) { const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B_flipped.glsl"); const char* fs = vfs_read("shaders/fs_2_4_texel_ycbr_gamma_saturation.glsl"); - program = shader(vs, fs, "", "fragcolor" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_gamma = glGetUniformLocation(program, "u_gamma"); uy = glGetUniformLocation(program, "u_texture_y"); @@ -340706,7 +340714,7 @@ void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3], float gamma ) { 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" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_gamma = glGetUniformLocation(program, "u_gamma"); uy = glGetUniformLocation(program, "u_texture_y"); @@ -340997,7 +341005,7 @@ static void sprite_render_meshes() { if( sprite_program < 0 ) { sprite_program = shader( vfs_read("shaders/vs_324_24_sprite.glsl"), vfs_read("shaders/fs_24_4_sprite.glsl"), "att_Position,att_TexCoord,att_Color", - "fragColor" + "fragColor", "" ); } @@ -342014,7 +342022,7 @@ skybox_t skybox(const char *asset, int flags) { sky.flags = flags ? flags : !!asset; // either cubemap or rayleigh sky.program = shader(vfs_read("shaders/vs_3_3_skybox.glsl"), sky.flags ? vfs_read("fs_3_4_skybox.glsl") : vfs_read("shaders/fs_3_4_skybox_rayleigh.glsl"), - "att_position", "fragcolor"); + "att_position", "fragcolor", ""); // sky cubemap & SH if( asset ) { @@ -342596,7 +342604,7 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) { strcat(fs2, fs); - p->program = shader(vs, fs2, "vtexcoord", "fragColor" ); + p->program = shader(vs, fs2, "vtexcoord", "fragColor" , ""); FREE(fs2); @@ -342963,7 +342971,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&SHADERTOY_FLIP_Y) ? 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")) @@ -343674,7 +343682,8 @@ model_t model_from_mem(const void *mem, int len, int flags) { if( shaderprog < 0 ) { const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_332_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs, - "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor"); + "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor", + (flags&MODEL_RIMLIGHT)?"RIM":NULL); } iqm_t *q = CALLOC(1, sizeof(iqm_t)); @@ -344827,7 +344836,7 @@ void ddraw_init() { do_once { for( int i = 0; i < 2; ++i ) for( int j = 0; j < 3; ++j ) map_init(dd_lists[i][j], less_int, hash_int); - dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor"); + dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor", ""); dd_u_color = glGetUniformLocation(dd_program, "u_color"); ddraw_flush(); // alloc vao & vbo, also resets color } @@ -345151,7 +345160,7 @@ scene_t* scene_get_active() { scene_t* scene_push() { scene_t *s = REALLOC(0, sizeof(scene_t)), clear = {0}; *s = clear; const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; - s->program = shader(strlerp(1, symbols, vfs_read("shaders/vs_332_32.glsl")), strlerp(1, symbols, vfs_read("shaders/fs_32_4_model.glsl")), "att_position,att_normal,att_texcoord,att_color", "fragcolor"); + s->program = shader(strlerp(1, symbols, vfs_read("shaders/vs_332_32.glsl")), strlerp(1, symbols, vfs_read("shaders/fs_32_4_model.glsl")), "att_position,att_normal,att_texcoord,att_color", "fragcolor", ""); s->skybox = skybox(NULL, 0); array_push(scenes, s); last_scene = s; diff --git a/engine/split/v4k_font.c b/engine/split/v4k_font.c index 28612fc..1829185 100644 --- a/engine/split/v4k_font.c +++ b/engine/split/v4k_font.c @@ -1694,7 +1694,7 @@ void font_face_from_mem(const char *tag, const void *ttf_bufferv, unsigned ttf_l const char *vs_filename = 0, *fs_filename = 0; const char *vs = vs_filename ? file_read(vs_filename) : mv_vs_source; const char *fs = fs_filename ? file_read(fs_filename) : mv_fs_source; - f->program = shader(vs, fs, "vertexPosition,instanceGlyph", "outColor"); + f->program = shader(vs, fs, "vertexPosition,instanceGlyph", "outColor", ""); // figure out what ranges we're about to bake #define MERGE_TABLE(table) do { \ diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index fef65b4..0379055 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -85,18 +85,25 @@ GLuint shader_compile( GLenum type, const char *source ) { return shader; } -unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor){ - return shader_geom(NULL, vs, fs, attribs, fragcolor); +unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines){ + return shader_geom(NULL, vs, fs, attribs, fragcolor, defines); } -unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor) { +unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines) { PRINTF(/*"!"*/"Compiling shader\n"); + char *glsl_defines = ""; + if (defines) { + for each_substring(defines, ",", def) { + glsl_defines = va("%s#define %s\n", glsl_defines, def); + } + } + const char *glsl_version = ifdef(ems, "300 es", "150"); - vs = vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s", glsl_version, vs ? vs : ""); - fs = fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s", glsl_version, fs ? fs : ""); - if (gs) gs = gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s", glsl_version, gs ? gs : ""); + vs = vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, vs ? vs : ""); + fs = fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, fs ? fs : ""); + if (gs) gs = gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, gs ? gs : ""); #if is(ems) { @@ -1035,7 +1042,7 @@ void fullscreen_quad_rgb( texture_t texture, float gamma ) { const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B_flipped.glsl"); const char* fs = vfs_read("shaders/fs_2_4_texel_inv_gamma.glsl"); - program = shader(vs, fs, "", "fragcolor" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_inv_gamma = glGetUniformLocation(program, "u_inv_gamma"); glGenVertexArrays( 1, (GLuint*)&vao ); } @@ -1066,7 +1073,7 @@ void fullscreen_quad_rgb_flipped( texture_t texture, float gamma ) { 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" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_inv_gamma = glGetUniformLocation(program, "u_inv_gamma"); glGenVertexArrays( 1, (GLuint*)&vao ); } @@ -1097,7 +1104,7 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3], float gamma ) { const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B_flipped.glsl"); const char* fs = vfs_read("shaders/fs_2_4_texel_ycbr_gamma_saturation.glsl"); - program = shader(vs, fs, "", "fragcolor" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_gamma = glGetUniformLocation(program, "u_gamma"); uy = glGetUniformLocation(program, "u_texture_y"); @@ -1141,7 +1148,7 @@ void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3], float gamma ) { 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" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_gamma = glGetUniformLocation(program, "u_gamma"); uy = glGetUniformLocation(program, "u_texture_y"); @@ -1432,7 +1439,7 @@ static void sprite_render_meshes() { if( sprite_program < 0 ) { sprite_program = shader( vfs_read("shaders/vs_324_24_sprite.glsl"), vfs_read("shaders/fs_24_4_sprite.glsl"), "att_Position,att_TexCoord,att_Color", - "fragColor" + "fragColor", "" ); } @@ -2449,7 +2456,7 @@ skybox_t skybox(const char *asset, int flags) { sky.flags = flags ? flags : !!asset; // either cubemap or rayleigh sky.program = shader(vfs_read("shaders/vs_3_3_skybox.glsl"), sky.flags ? vfs_read("fs_3_4_skybox.glsl") : vfs_read("shaders/fs_3_4_skybox_rayleigh.glsl"), - "att_position", "fragcolor"); + "att_position", "fragcolor", ""); // sky cubemap & SH if( asset ) { @@ -3031,7 +3038,7 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) { strcat(fs2, fs); - p->program = shader(vs, fs2, "vtexcoord", "fragColor" ); + p->program = shader(vs, fs2, "vtexcoord", "fragColor" , ""); FREE(fs2); @@ -3398,7 +3405,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&SHADERTOY_FLIP_Y) ? 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")) @@ -4109,7 +4116,8 @@ model_t model_from_mem(const void *mem, int len, int flags) { if( shaderprog < 0 ) { const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_332_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs, - "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor"); + "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor", + (flags&MODEL_RIMLIGHT)?"RIM":NULL); } iqm_t *q = CALLOC(1, sizeof(iqm_t)); diff --git a/engine/split/v4k_render.h b/engine/split/v4k_render.h index 27afe9f..424d3e8 100644 --- a/engine/split/v4k_render.h +++ b/engine/split/v4k_render.h @@ -319,8 +319,8 @@ API void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float botto // ----------------------------------------------------------------------------- // shaders -API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor); -API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor); +API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines); +API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines); API unsigned shader_bind(unsigned program); API void shader_bool(const char *uniform, bool i ); API void shader_int(const char *uniform, int i); @@ -569,6 +569,7 @@ enum MODEL_FLAGS { MODEL_NO_MESHES = 2, MODEL_NO_TEXTURES = 4, MODEL_MATCAPS = 8, + MODEL_RIMLIGHT = 16 }; typedef struct model_t { diff --git a/engine/split/v4k_renderdd.c b/engine/split/v4k_renderdd.c index 5187841..0d664f9 100644 --- a/engine/split/v4k_renderdd.c +++ b/engine/split/v4k_renderdd.c @@ -757,7 +757,7 @@ void ddraw_init() { do_once { for( int i = 0; i < 2; ++i ) for( int j = 0; j < 3; ++j ) map_init(dd_lists[i][j], less_int, hash_int); - dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor"); + dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor", ""); dd_u_color = glGetUniformLocation(dd_program, "u_color"); ddraw_flush(); // alloc vao & vbo, also resets color } diff --git a/engine/split/v4k_scene.c b/engine/split/v4k_scene.c index b053a87..0678778 100644 --- a/engine/split/v4k_scene.c +++ b/engine/split/v4k_scene.c @@ -257,7 +257,7 @@ scene_t* scene_get_active() { scene_t* scene_push() { scene_t *s = REALLOC(0, sizeof(scene_t)), clear = {0}; *s = clear; const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; - s->program = shader(strlerp(1, symbols, vfs_read("shaders/vs_332_32.glsl")), strlerp(1, symbols, vfs_read("shaders/fs_32_4_model.glsl")), "att_position,att_normal,att_texcoord,att_color", "fragcolor"); + s->program = shader(strlerp(1, symbols, vfs_read("shaders/vs_332_32.glsl")), strlerp(1, symbols, vfs_read("shaders/fs_32_4_model.glsl")), "att_position,att_normal,att_texcoord,att_color", "fragcolor", ""); s->skybox = skybox(NULL, 0); array_push(scenes, s); last_scene = s; diff --git a/engine/v4k.c b/engine/v4k.c index ac9d5f3..724d5e1 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -6854,7 +6854,7 @@ void font_face_from_mem(const char *tag, const void *ttf_bufferv, unsigned ttf_l const char *vs_filename = 0, *fs_filename = 0; const char *vs = vs_filename ? file_read(vs_filename) : mv_vs_source; const char *fs = fs_filename ? file_read(fs_filename) : mv_fs_source; - f->program = shader(vs, fs, "vertexPosition,instanceGlyph", "outColor"); + f->program = shader(vs, fs, "vertexPosition,instanceGlyph", "outColor", ""); // figure out what ranges we're about to bake #define MERGE_TABLE(table) do { \ @@ -10349,18 +10349,25 @@ GLuint shader_compile( GLenum type, const char *source ) { return shader; } -unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor){ - return shader_geom(NULL, vs, fs, attribs, fragcolor); +unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines){ + return shader_geom(NULL, vs, fs, attribs, fragcolor, defines); } -unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor) { +unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines) { PRINTF(/*"!"*/"Compiling shader\n"); + char *glsl_defines = ""; + if (defines) { + for each_substring(defines, ",", def) { + glsl_defines = va("%s#define %s\n", glsl_defines, def); + } + } + const char *glsl_version = ifdef(ems, "300 es", "150"); - vs = vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s", glsl_version, vs ? vs : ""); - fs = fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s", glsl_version, fs ? fs : ""); - if (gs) gs = gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s", glsl_version, gs ? gs : ""); + vs = vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, vs ? vs : ""); + fs = fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, fs ? fs : ""); + if (gs) gs = gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, gs ? gs : ""); #if is(ems) { @@ -11299,7 +11306,7 @@ void fullscreen_quad_rgb( texture_t texture, float gamma ) { const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B_flipped.glsl"); const char* fs = vfs_read("shaders/fs_2_4_texel_inv_gamma.glsl"); - program = shader(vs, fs, "", "fragcolor" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_inv_gamma = glGetUniformLocation(program, "u_inv_gamma"); glGenVertexArrays( 1, (GLuint*)&vao ); } @@ -11330,7 +11337,7 @@ void fullscreen_quad_rgb_flipped( texture_t texture, float gamma ) { 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" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_inv_gamma = glGetUniformLocation(program, "u_inv_gamma"); glGenVertexArrays( 1, (GLuint*)&vao ); } @@ -11361,7 +11368,7 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3], float gamma ) { const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B_flipped.glsl"); const char* fs = vfs_read("shaders/fs_2_4_texel_ycbr_gamma_saturation.glsl"); - program = shader(vs, fs, "", "fragcolor" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_gamma = glGetUniformLocation(program, "u_gamma"); uy = glGetUniformLocation(program, "u_texture_y"); @@ -11405,7 +11412,7 @@ void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3], float gamma ) { 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" ); + program = shader(vs, fs, "", "fragcolor" , ""); u_gamma = glGetUniformLocation(program, "u_gamma"); uy = glGetUniformLocation(program, "u_texture_y"); @@ -11696,7 +11703,7 @@ static void sprite_render_meshes() { if( sprite_program < 0 ) { sprite_program = shader( vfs_read("shaders/vs_324_24_sprite.glsl"), vfs_read("shaders/fs_24_4_sprite.glsl"), "att_Position,att_TexCoord,att_Color", - "fragColor" + "fragColor", "" ); } @@ -12713,7 +12720,7 @@ skybox_t skybox(const char *asset, int flags) { sky.flags = flags ? flags : !!asset; // either cubemap or rayleigh sky.program = shader(vfs_read("shaders/vs_3_3_skybox.glsl"), sky.flags ? vfs_read("fs_3_4_skybox.glsl") : vfs_read("shaders/fs_3_4_skybox_rayleigh.glsl"), - "att_position", "fragcolor"); + "att_position", "fragcolor", ""); // sky cubemap & SH if( asset ) { @@ -13295,7 +13302,7 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) { strcat(fs2, fs); - p->program = shader(vs, fs2, "vtexcoord", "fragColor" ); + p->program = shader(vs, fs2, "vtexcoord", "fragColor" , ""); FREE(fs2); @@ -13662,7 +13669,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&SHADERTOY_FLIP_Y) ? 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")) @@ -14373,7 +14380,8 @@ model_t model_from_mem(const void *mem, int len, int flags) { if( shaderprog < 0 ) { const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_332_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs, - "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor"); + "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor", + (flags&MODEL_RIMLIGHT)?"RIM":NULL); } iqm_t *q = CALLOC(1, sizeof(iqm_t)); @@ -15526,7 +15534,7 @@ void ddraw_init() { do_once { for( int i = 0; i < 2; ++i ) for( int j = 0; j < 3; ++j ) map_init(dd_lists[i][j], less_int, hash_int); - dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor"); + dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor", ""); dd_u_color = glGetUniformLocation(dd_program, "u_color"); ddraw_flush(); // alloc vao & vbo, also resets color } @@ -15850,7 +15858,7 @@ scene_t* scene_get_active() { scene_t* scene_push() { scene_t *s = REALLOC(0, sizeof(scene_t)), clear = {0}; *s = clear; const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; - s->program = shader(strlerp(1, symbols, vfs_read("shaders/vs_332_32.glsl")), strlerp(1, symbols, vfs_read("shaders/fs_32_4_model.glsl")), "att_position,att_normal,att_texcoord,att_color", "fragcolor"); + s->program = shader(strlerp(1, symbols, vfs_read("shaders/vs_332_32.glsl")), strlerp(1, symbols, vfs_read("shaders/fs_32_4_model.glsl")), "att_position,att_normal,att_texcoord,att_color", "fragcolor", ""); s->skybox = skybox(NULL, 0); array_push(scenes, s); last_scene = s; diff --git a/engine/v4k.h b/engine/v4k.h index 95d8f0b..8d80f1b 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -2751,8 +2751,8 @@ API void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float botto // ----------------------------------------------------------------------------- // shaders -API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor); -API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor); +API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines); +API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines); API unsigned shader_bind(unsigned program); API void shader_bool(const char *uniform, bool i ); API void shader_int(const char *uniform, int i); @@ -3001,6 +3001,7 @@ enum MODEL_FLAGS { MODEL_NO_MESHES = 2, MODEL_NO_TEXTURES = 4, MODEL_MATCAPS = 8, + MODEL_RIMLIGHT = 16 }; typedef struct model_t {