From afd8ef8ef20ab633b72c1f1a532c0034eac698f2 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Fri, 4 Aug 2023 19:28:17 +0200 Subject: [PATCH 01/26] fix viewsize breaking world outlines --- src/glm_rmain.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/glm_rmain.c b/src/glm_rmain.c index 7b134ae26..fae97d783 100644 --- a/src/glm_rmain.c +++ b/src/glm_rmain.c @@ -63,13 +63,18 @@ static void GLM_DrawWorldOutlines(void) int viewport[4]; int fullscreen_viewport[4]; + R_GetViewport(viewport); + // If we are only rendering to a section of the screen then that is the only part of the texture that will be filled in if (CL_MultiviewEnabled()) { - R_GetViewport(viewport); R_GetFullScreenViewport(fullscreen_viewport); R_Viewport(fullscreen_viewport[0], fullscreen_viewport[1], fullscreen_viewport[2], fullscreen_viewport[3]); R_EnableScissorTest(viewport[0], viewport[1], viewport[2], viewport[3]); - } + } else { + // ignore viewsize and allat crap and set the viewport size to the whole window. + // previously the viewport was already resized, and then resized again later, making the outlines not align. + R_Viewport(0, 0, glConfig.vidWidth, glConfig.vidHeight); + } renderer.TextureUnitBind(0, normals); @@ -79,8 +84,8 @@ static void GLM_DrawWorldOutlines(void) GL_DrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Restore viewport + R_Viewport(viewport[0], viewport[1], viewport[2], viewport[3]); if (CL_MultiviewEnabled()) { - R_Viewport(viewport[0], viewport[1], viewport[2], viewport[3]); R_DisableScissorTest(); } } From c7d4edbd9bd6681c5368d8f79456573300daa3a2 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Fri, 4 Aug 2023 20:04:21 +0200 Subject: [PATCH 02/26] remove r_fx_geometry (its functionality has been moved to gl_outline) --- help_variables.json | 12 ++---------- src/gl_framebuffer.c | 6 +++--- src/glm_rsurf.c | 6 +++--- src/menu_options.c | 36 ++++++++++++++++-------------------- src/r_rmain.c | 3 --- src/rulesets.c | 4 ++-- 6 files changed, 26 insertions(+), 41 deletions(-) diff --git a/help_variables.json b/help_variables.json index caf1ff353..8073e063b 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5167,7 +5167,6 @@ "default": "0", "desc": "Controls outlining of models and map. Disallowed in qcon ruleset.", "group-id": "35", - "remarks": "See /r_fx_geometry for edge outlining of the map.", "type": "enum", "values": [ { @@ -5175,11 +5174,11 @@ "name": "0" }, { - "description": "Outline models to create rotoscope effect", + "description": "Outline models", "name": "1" }, { - "description": "Outline world (used only for map development)", + "description": "Outline world", "name": "2" }, { @@ -15855,13 +15854,6 @@ } ] }, - "r_fx_geometry": { - "default": "0", - "desc": "Outlines the world based on surface normals. Disallowed in qcon ruleset.", - "group-id": "35", - "remarks": "Requires vid_framebuffer 1|2 and Modern OpenGL (vid_renderer 1). See /gl_outline for model outline", - "type": "boolean" - }, "r_glstats": { "default": "0", "desc": "When enabled, it creates a window in the top right of the screen showing the number of particles and etc. in use.", diff --git a/src/gl_framebuffer.c b/src/gl_framebuffer.c index 4223da3b0..ce6eb0603 100644 --- a/src/gl_framebuffer.c +++ b/src/gl_framebuffer.c @@ -38,7 +38,7 @@ extern cvar_t vid_framebuffer_hdr; extern cvar_t vid_framebuffer_blit; extern cvar_t vid_framebuffer_smooth; extern cvar_t vid_framebuffer_multisample; -extern cvar_t r_fx_geometry; +extern cvar_t gl_outline; static framebuffer_id VID_MultisampledAlternateId(framebuffer_id id); @@ -171,7 +171,7 @@ C_ASSERT(sizeof(framebuffer_multisample_alternate) / sizeof(framebuffer_multisam static framebuffer_data_t framebuffer_data[framebuffer_count]; -// +// GL_StaticProcedureDeclaration(glGenFramebuffers, "n=%d, ids=%p", GLsizei n, GLuint* ids) GL_StaticProcedureDeclaration(glDeleteFramebuffers, "n=%d, ids=%p", GLsizei n, GLuint* ids) GL_StaticProcedureDeclaration(glBindFramebuffer, "target=%u, framebuffer=%u", GLenum target, GLuint framebuffer) @@ -477,7 +477,7 @@ qbool GL_FramebufferStartWorldNormals(framebuffer_id id) GLenum buffers[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; float clearValue[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - if (!r_fx_geometry.integer || !GL_Supported(R_SUPPORT_FRAMEBUFFERS) || !RuleSets_AllowEdgeOutline()) { + if (!(gl_outline.integer & 2) || !GL_Supported(R_SUPPORT_FRAMEBUFFERS) || !RuleSets_AllowEdgeOutline()) { return false; } diff --git a/src/glm_rsurf.c b/src/glm_rsurf.c index 26d727881..d74a94adb 100644 --- a/src/glm_rsurf.c +++ b/src/glm_rsurf.c @@ -127,7 +127,7 @@ static qbool GLM_CompileDrawWorldProgramImpl(r_program_id program_id, qbool alph { extern cvar_t gl_lumatextures; extern cvar_t gl_textureless; - extern cvar_t r_fx_geometry; + extern cvar_t gl_outline; qbool detail_textures = gl_detail.integer && R_TextureReferenceIsValid(detailtexture); qbool caustic_textures = r_refdef2.drawCaustics; @@ -147,7 +147,7 @@ static qbool GLM_CompileDrawWorldProgramImpl(r_program_id program_id, qbool alph (r_drawflat.integer == 1 || r_drawflat.integer == 2 ? DRAW_FLATFLOORS : 0) | (r_drawflat.integer == 1 || r_drawflat.integer == 3 ? DRAW_FLATWALLS : 0) | (gl_textureless.integer ? DRAW_TEXTURELESS : 0) | - (r_fx_geometry.integer ? DRAW_GEOMETRY : 0) | + ((gl_outline.integer & 2) ? DRAW_GEOMETRY : 0) | (alpha_test ? DRAW_ALPHATESTED : 0); if (R_ProgramRecompileNeeded(program_id, drawworld_desiredOptions)) { @@ -202,7 +202,7 @@ static qbool GLM_CompileDrawWorldProgramImpl(r_program_id program_id, qbool alph strlcat(included_definitions, va("#define SAMPLER_SKYDOME_TEXTURE %d\n", TEXTURE_UNIT_SKYDOME_TEXTURE), sizeof(included_definitions)); strlcat(included_definitions, va("#define SAMPLER_SKYDOME_CLOUDTEXTURE %d\n", TEXTURE_UNIT_SKYDOME_CLOUD_TEXTURE), sizeof(included_definitions)); } - if (r_fx_geometry.integer) { + if (gl_outline.integer & 2) { strlcat(included_definitions, "#define DRAW_GEOMETRY\n", sizeof(included_definitions)); } TEXTURE_UNIT_LIGHTMAPS = samplers++; diff --git a/src/menu_options.c b/src/menu_options.c index fde42f419..cb4e0e4bf 100644 --- a/src/menu_options.c +++ b/src/menu_options.c @@ -199,9 +199,6 @@ extern cvar_t mvd_autotrack, mvd_moreinfo, mvd_status, cl_weaponpreselect, cl_we enemyforceskins, teamforceskins, vid_vsync_lag_fix, cl_sayfilter_coloredtext, cl_sayfilter_sendboth, mvd_autotrack_lockteam, qtv_adjustbuffer, cl_earlypackets, cl_useimagesinfraglog, con_completion_format, menu_ingame, sys_inactivesound ; -#ifdef RENDERER_OPTION_MODERN_OPENGL -extern cvar_t r_fx_geometry; -#endif #ifdef _WIN32 extern cvar_t demo_format, sys_highpriority, cl_window_caption, vid_flashonactivity; @@ -213,15 +210,15 @@ extern cvar_t scr_autoid, crosshairalpha, amf_hidenails, amf_hiderockets, gl_ani void CL_Autotrack_f(void); -const char* bandwidth_enum[] = { - "Modem (33k)", "3800", "Modem (56k)", "5670", +const char* bandwidth_enum[] = { + "Modem (33k)", "3800", "Modem (56k)", "5670", "ISDN (112k)", "9856", "Cable (128k)", "14336", "ADSL (> 256k)", "30000" }; const char* cl_c2sImpulseBackup_enum[] = { "Perfect", "0", "Low", "2", "Medium", "4", "High", "6" }; - + const char* ignore_flood_enum[] = { "Off", "0", "say/spec", "1", "say/say_team/spec", "2" }; @@ -236,7 +233,7 @@ const char* cl_chatmode_enum[] = { const char* con_completion_format_enum[] = { "Old", "New:Current+Default", "New:Current", "New:Default", "New:Current+Default,if changed", "New:Without values" }; - + const char* scr_conback_enum[] = { "Off", "On Load", "Always", }; @@ -557,7 +554,7 @@ const char* ResolutionRead(void) } snprintf(buf, sizeof(buf), "%dx%d@%dHz", mode->w, mode->h, mode->refresh_rate); - + return buf; } @@ -661,7 +658,7 @@ extern cvar_t cfg_backup, cfg_save_aliases, cfg_save_binds, cfg_save_cmdline, void MOpt_ImportConfig(void) { MOpt_configpage_mode = MOCPM_CHOOSECONFIG; - + // hope few doubled trinary operator won't hurt your brains if (cfg_use_home.integer) FL_SetCurrentDir(&configs_filelist, (cfg_use_gamedir.integer) ? va("%s/%s", com_homedir, (strcmp(com_gamedirfile, "qw") == 0) ? "" : com_gamedirfile) : com_homedir); @@ -699,7 +696,7 @@ void MOpt_LoadCfg(void) { S_LocalSound("misc/basekey.wav"); Cbuf_AddText("cfg_load\n"); } -void MOpt_SaveCfg(void) { +void MOpt_SaveCfg(void) { S_LocalSound("doors/runeuse.wav"); Cbuf_AddText("cfg_save\n"); } @@ -902,19 +899,19 @@ setting settplayer_arr[] = { ADDSET_NUMBER ("Fullbright Skins", r_fullbrightSkins, 0, 1, 0.05), ADDSET_ENUM ("Ruleset", ruleset, ruleset_enum), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Weapon Handling"), ADDSET_CUSTOM ("Gun Autoswitch", AutoSWRead, AutoSWToggle, "Switches to the weapon picked up if it is more powerful than what you're currently holding."), ADDSET_BOOL ("Gun Preselect", cl_weaponpreselect), ADDSET_BOOL ("Gun Auto Hide", cl_weaponhide), - + ADDSET_SEPARATOR("Movement"), ADDSET_CUSTOM ("Always Run", AlwaysRunRead, AlwaysRunToggle, "Maximum forward speed at all times."), ADDSET_ADVANCED_SECTION(), ADDSET_BOOL ("Smart Jump", cl_smartjump), ADDSET_NAMED ("Movement Scripts", allow_scripts, allowscripts_enum), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Team Skin & Colors"), ADDSET_COLOR ("Shirt Color", cl_teamtopcolor), ADDSET_COLOR ("Pants Color", cl_teambottomcolor), @@ -925,7 +922,7 @@ setting settplayer_arr[] = { ADDSET_SKIN ("Pent Skin", cl_teampentskin), ADDSET_SKIN ("Quad+Pent Skin", cl_teambothskin), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Enemy Skin & Colors"), ADDSET_COLOR ("Shirt Color", cl_enemytopcolor), ADDSET_COLOR ("Pants Color", cl_enemybottomcolor), @@ -941,7 +938,7 @@ setting settplayer_arr[] = { // GRAPHICS TAB setting settfps_arr[] = { ADDSET_BOOL ("Advanced Options", menu_advanced), - + ADDSET_SEPARATOR("Presets"), ADDSET_CUSTOM ("GFX Preset", GFXPresetRead, GFXPresetToggle, "Select different graphic presets."), @@ -961,14 +958,14 @@ setting settfps_arr[] = { ADDSET_NUMBER ("View Height", v_viewheight, -7, 4, 0.5), ADDSET_BASIC_SECTION(), - ADDSET_ADVANCED_SECTION(), + ADDSET_ADVANCED_SECTION(), ADDSET_SEPARATOR("Textures"), ADDSET_BOOL ("Luma", gl_lumatextures), ADDSET_ENUM ("Detail", gl_max_size, gl_max_size_enum), ADDSET_NUMBER ("Miptex", gl_miptexLevel, 0, 3, 1), ADDSET_BOOL ("No Textures", gl_textureless), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Player & Weapon Model"), ADDSET_ADVANCED_SECTION(), ADDSET_BOOL ("Powerup Luma", gl_powerupshells), @@ -978,9 +975,8 @@ setting settfps_arr[] = { ADDSET_ADVANCED_SECTION(), ADDSET_NUMBER ("Weapon Shift", r_viewmodeloffset, -10, 10, 1), ADDSET_NAMED ("Weapon Muzzleflashes", cl_muzzleflash, muzzleflashes_enum), - ADDSET_NAMED ("Outline", gl_outline, outline_enum), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Environment"), ADDSET_ADVANCED_SECTION(), ADDSET_BOOL ("Fullbright World", r_fullbright), @@ -996,7 +992,7 @@ setting settfps_arr[] = { ADDSET_ADVANCED_SECTION(), ADDSET_NAMED ("Dead Body Filter", cl_deadbodyfilter, deadbodyfilter_enum), #ifdef RENDERER_OPTION_MODERN_OPENGL - ADDSET_BOOL ("Outline", r_fx_geometry), + ADDSET_NAMED ("Outline", gl_outline, outline_enum), #endif ADDSET_BASIC_SECTION(), diff --git a/src/r_rmain.c b/src/r_rmain.c index ddaab77c4..717e24a8d 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -221,7 +221,6 @@ cvar_t gl_simpleitems_orientation = {"gl_simpleitems_orientation", "2"} cvar_t gl_modulate = {"gl_modulate", "1"}; cvar_t gl_outline = {"gl_outline", "0"}; cvar_t gl_smoothmodels = {"gl_smoothmodels", "1"}; -cvar_t r_fx_geometry = {"r_fx_geometry", "0"}; cvar_t gl_vbo_clientmemory = {"gl_vbo_clientmemory", "0", CVAR_LATCH_GFX }; @@ -700,8 +699,6 @@ void R_Init(void) Cvar_Register(&gl_outline); Cvar_Register(&gl_smoothmodels); - Cvar_Register(&r_fx_geometry); - Cvar_Register(&gl_vbo_clientmemory); Cvar_SetCurrentGroup(CVAR_GROUP_SCREEN); diff --git a/src/rulesets.c b/src/rulesets.c index 8aa6aa67e..dcc3d5ba4 100644 --- a/src/rulesets.c +++ b/src/rulesets.c @@ -81,7 +81,7 @@ qbool RuleSets_DisallowSimpleTexture(model_t* mod) } } -// for models (gl_outline) +// for models (gl_outline 1 and 3) qbool RuleSets_DisallowModelOutline(struct model_s *mod) { if (mod == NULL) { @@ -102,7 +102,7 @@ qbool RuleSets_DisallowModelOutline(struct model_s *mod) } } -// for edges (r_fx_geometry) +// for edges (gl_outline 2 and 3) qbool RuleSets_AllowEdgeOutline(void) { switch(rulesetDef.ruleset) { From 8e689d8bd844cc7a2cbde02e1b390e3148503cec Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Fri, 4 Aug 2023 20:12:00 +0200 Subject: [PATCH 03/26] add customizable color to world outlines --- src/gl_program.c | 2 ++ src/glm_rmain.c | 6 ++++++ src/glsl/fx_world_geometry.fragment.glsl | 4 +++- src/r_program.h | 1 + src/r_rmain.c | 2 ++ 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gl_program.c b/src/gl_program.c index ec1c42500..36854ca12 100644 --- a/src/gl_program.c +++ b/src/gl_program.c @@ -326,6 +326,8 @@ static r_program_uniform_t program_uniforms[] = { { r_program_lightmap_compute, "firstLightmap", 1, false }, // r_program_uniform_turb_glc_fog_skyFogMix, { r_program_sky_glc, "skyFogMix", 1, false }, + // r_program_uniform_outline_color + { r_program_fx_world_geometry, "outline_color", 1, false }, }; #ifdef C_ASSERT diff --git a/src/glm_rmain.c b/src/glm_rmain.c index fae97d783..7e16a9d37 100644 --- a/src/glm_rmain.c +++ b/src/glm_rmain.c @@ -62,6 +62,7 @@ static void GLM_DrawWorldOutlines(void) if (R_TextureReferenceIsValid(normals) && GLM_CompileWorldGeometryProgram()) { int viewport[4]; int fullscreen_viewport[4]; + extern cvar_t gl_outline_color_world; R_GetViewport(viewport); @@ -78,6 +79,11 @@ static void GLM_DrawWorldOutlines(void) renderer.TextureUnitBind(0, normals); + R_ProgramUniform3f(r_program_uniform_outline_color, + (float)gl_outline_color_world.color[0] / 255.0f, + (float)gl_outline_color_world.color[1] / 255.0f, + (float)gl_outline_color_world.color[2] / 255.0f); + R_ProgramUse(r_program_fx_world_geometry); R_ApplyRenderingState(r_state_fx_world_geometry); diff --git a/src/glsl/fx_world_geometry.fragment.glsl b/src/glsl/fx_world_geometry.fragment.glsl index 5e027c9b0..56706b48e 100644 --- a/src/glsl/fx_world_geometry.fragment.glsl +++ b/src/glsl/fx_world_geometry.fragment.glsl @@ -4,6 +4,8 @@ layout(binding = 0) uniform sampler2D normal_texture; +uniform vec3 outline_color; + in vec2 TextureCoord; out vec4 frag_colour; @@ -27,7 +29,7 @@ void main() (up.a != 0 && dot(center.rgb, up.rgb) < 0.9) || (down.a != 0 && dot(center.rgb, down.rgb) < 0.9) )) { - frag_colour = vec4(0, 0, 0, 1.0); + frag_colour = vec4(outline_color, 1.0); } else { frag_colour = vec4(0, 0, 0, 0); diff --git a/src/r_program.h b/src/r_program.h index f9f03bee8..ac0572425 100644 --- a/src/r_program.h +++ b/src/r_program.h @@ -108,6 +108,7 @@ typedef enum { r_program_uniform_simple3d_color, r_program_uniform_lighting_firstLightmap, r_program_uniform_sky_glc_fog_skyFogMix, + r_program_uniform_outline_color, r_program_uniform_count } r_program_uniform_id; diff --git a/src/r_rmain.c b/src/r_rmain.c index 717e24a8d..b4e68242a 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -220,6 +220,7 @@ cvar_t gl_simpleitems_size = {"gl_simpleitems_size", "16"}; cvar_t gl_simpleitems_orientation = {"gl_simpleitems_orientation", "2"}; cvar_t gl_modulate = {"gl_modulate", "1"}; cvar_t gl_outline = {"gl_outline", "0"}; +cvar_t gl_outline_color_world = {"gl_outline_color_world", "0 0 0"}; cvar_t gl_smoothmodels = {"gl_smoothmodels", "1"}; cvar_t gl_vbo_clientmemory = {"gl_vbo_clientmemory", "0", CVAR_LATCH_GFX }; @@ -697,6 +698,7 @@ void R_Init(void) Cvar_Register(&gl_modulate); Cvar_Register(&gl_outline); + Cvar_Register(&gl_outline_color_world); Cvar_Register(&gl_smoothmodels); Cvar_Register(&gl_vbo_clientmemory); From 766658b6b235a3107faa0c75f8907a5c36afcc39 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Fri, 4 Aug 2023 20:28:22 +0200 Subject: [PATCH 04/26] add customizable accuracy factor for world outlines --- help_variables.json | 12 ++++++++++++ src/gl_program.c | 2 ++ src/glm_rmain.c | 5 ++++- src/glsl/fx_world_geometry.fragment.glsl | 9 +++++---- src/r_program.h | 1 + src/r_rmain.c | 2 ++ 6 files changed, 26 insertions(+), 5 deletions(-) diff --git a/help_variables.json b/help_variables.json index 8073e063b..826abfbdc 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5187,6 +5187,18 @@ } ] }, + "gl_outline_color_world": { + "default": "0 0 0", + "desc": "Determines the color of world outlines.", + "group-id": "35", + "type": "string" + }, + "gl_outline_world_accuracy": { + "default": "0.9", + "desc": "Determines the accuracy for drawing world outlines. Mainly visible on slopes and other angled surfaces.", + "group-id": "35", + "type": "float" + }, "gl_part_blobs": { "default": "0", "desc": "Determines particles used for blob explosions (EMPs).", diff --git a/src/gl_program.c b/src/gl_program.c index 36854ca12..061b6af6a 100644 --- a/src/gl_program.c +++ b/src/gl_program.c @@ -328,6 +328,8 @@ static r_program_uniform_t program_uniforms[] = { { r_program_sky_glc, "skyFogMix", 1, false }, // r_program_uniform_outline_color { r_program_fx_world_geometry, "outline_color", 1, false }, + // r_program_uniform_outline_accuracy + { r_program_fx_world_geometry, "outline_accuracy", 1, false }, }; #ifdef C_ASSERT diff --git a/src/glm_rmain.c b/src/glm_rmain.c index 7e16a9d37..a85736dea 100644 --- a/src/glm_rmain.c +++ b/src/glm_rmain.c @@ -62,7 +62,7 @@ static void GLM_DrawWorldOutlines(void) if (R_TextureReferenceIsValid(normals) && GLM_CompileWorldGeometryProgram()) { int viewport[4]; int fullscreen_viewport[4]; - extern cvar_t gl_outline_color_world; + extern cvar_t gl_outline_color_world, gl_outline_world_accuracy; R_GetViewport(viewport); @@ -79,6 +79,9 @@ static void GLM_DrawWorldOutlines(void) renderer.TextureUnitBind(0, normals); + R_ProgramUniform1f(r_program_uniform_outline_accuracy, + bound(gl_outline_world_accuracy.value, 0.0, 1.0)); + R_ProgramUniform3f(r_program_uniform_outline_color, (float)gl_outline_color_world.color[0] / 255.0f, (float)gl_outline_color_world.color[1] / 255.0f, diff --git a/src/glsl/fx_world_geometry.fragment.glsl b/src/glsl/fx_world_geometry.fragment.glsl index 56706b48e..e3ce54ca4 100644 --- a/src/glsl/fx_world_geometry.fragment.glsl +++ b/src/glsl/fx_world_geometry.fragment.glsl @@ -5,6 +5,7 @@ layout(binding = 0) uniform sampler2D normal_texture; uniform vec3 outline_color; +uniform float outline_accuracy; in vec2 TextureCoord; out vec4 frag_colour; @@ -24,10 +25,10 @@ void main() if (center.a != 0 && ( (left.a != 0 && right.a != 0 && z_diff) || (down.a != 0 && up.a != 0 && z_diff2) || - (left.a != 0 && dot(center.rgb, left.rgb) < 0.9) || - (right.a != 0 && dot(center.rgb, right.rgb) < 0.9) || - (up.a != 0 && dot(center.rgb, up.rgb) < 0.9) || - (down.a != 0 && dot(center.rgb, down.rgb) < 0.9) + (left.a != 0 && dot(center.rgb, left.rgb) < outline_accuracy) || + (right.a != 0 && dot(center.rgb, right.rgb) < outline_accuracy) || + (up.a != 0 && dot(center.rgb, up.rgb) < outline_accuracy) || + (down.a != 0 && dot(center.rgb, down.rgb) < outline_accuracy) )) { frag_colour = vec4(outline_color, 1.0); } diff --git a/src/r_program.h b/src/r_program.h index ac0572425..29c01bf1d 100644 --- a/src/r_program.h +++ b/src/r_program.h @@ -109,6 +109,7 @@ typedef enum { r_program_uniform_lighting_firstLightmap, r_program_uniform_sky_glc_fog_skyFogMix, r_program_uniform_outline_color, + r_program_uniform_outline_accuracy, r_program_uniform_count } r_program_uniform_id; diff --git a/src/r_rmain.c b/src/r_rmain.c index b4e68242a..883fb5163 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -221,6 +221,7 @@ cvar_t gl_simpleitems_orientation = {"gl_simpleitems_orientation", "2"} cvar_t gl_modulate = {"gl_modulate", "1"}; cvar_t gl_outline = {"gl_outline", "0"}; cvar_t gl_outline_color_world = {"gl_outline_color_world", "0 0 0"}; +cvar_t gl_outline_world_accuracy = {"gl_outline_world_accuracy", "0.9"}; cvar_t gl_smoothmodels = {"gl_smoothmodels", "1"}; cvar_t gl_vbo_clientmemory = {"gl_vbo_clientmemory", "0", CVAR_LATCH_GFX }; @@ -699,6 +700,7 @@ void R_Init(void) Cvar_Register(&gl_outline); Cvar_Register(&gl_outline_color_world); + Cvar_Register(&gl_outline_world_accuracy); Cvar_Register(&gl_smoothmodels); Cvar_Register(&gl_vbo_clientmemory); From 2adb43dcebe83e710c60ef0273236757477762e9 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Fri, 4 Aug 2023 20:55:44 +0200 Subject: [PATCH 05/26] add customizable color for aliasmodel outlines --- help_variables.json | 6 ++++++ src/gl_program.c | 2 ++ src/glm_aliasmodel.c | 8 ++++++++ src/glsl/draw_aliasmodel.fragment.glsl | 3 ++- src/r_program.h | 1 + src/r_rmain.c | 2 ++ 6 files changed, 21 insertions(+), 1 deletion(-) diff --git a/help_variables.json b/help_variables.json index 826abfbdc..347e92030 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5193,6 +5193,12 @@ "group-id": "35", "type": "string" }, + "gl_outline_color_model": { + "default": "0 0 0", + "desc": "Determines the color of model outlines.", + "group-id": "35", + "type": "string" + }, "gl_outline_world_accuracy": { "default": "0.9", "desc": "Determines the accuracy for drawing world outlines. Mainly visible on slopes and other angled surfaces.", diff --git a/src/gl_program.c b/src/gl_program.c index 061b6af6a..4354ab2d7 100644 --- a/src/gl_program.c +++ b/src/gl_program.c @@ -330,6 +330,8 @@ static r_program_uniform_t program_uniforms[] = { { r_program_fx_world_geometry, "outline_color", 1, false }, // r_program_uniform_outline_accuracy { r_program_fx_world_geometry, "outline_accuracy", 1, false }, + // r_program_uniform_aliasmodel_outline_color + { r_program_aliasmodel, "outline_color", 1, false }, }; #ifdef C_ASSERT diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index 465601081..921523602 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -489,10 +489,18 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) } if (type == aliasmodel_draw_std && alias_draw_instructions[aliasmodel_draw_outlines].num_calls) { + extern cvar_t gl_outline_color_model; + instr = &alias_draw_instructions[aliasmodel_draw_outlines]; R_TraceEnterNamedRegion("GLM_DrawOutlineBatch"); R_SetAliasModelUniform(EZQ_ALIAS_MODE_OUTLINES); + R_ProgramUniform3f(r_program_uniform_aliasmodel_outline_color, + (float)gl_outline_color_model.color[0] / 255.0f, + (float)gl_outline_color_model.color[1] / 255.0f, + (float)gl_outline_color_model.color[2] / 255.0f + ); + GLM_StateBeginAliasOutlineBatch(); for (i = 0; i < instr->num_calls; ++i) { diff --git a/src/glsl/draw_aliasmodel.fragment.glsl b/src/glsl/draw_aliasmodel.fragment.glsl index bb6e59f5d..27e42f0cf 100644 --- a/src/glsl/draw_aliasmodel.fragment.glsl +++ b/src/glsl/draw_aliasmodel.fragment.glsl @@ -3,6 +3,7 @@ #ezquake-definitions uniform int mode; +uniform vec3 outline_color; #ifdef DRAW_CAUSTIC_TEXTURES layout(binding=SAMPLER_CAUSTIC_TEXTURE) uniform sampler2D causticsTex; @@ -25,7 +26,7 @@ out vec4 frag_colour; void main() { - frag_colour = vec4(0, 0, 0, 1); + frag_colour = vec4(outline_color, 1.0); if (mode != EZQ_ALIAS_MODE_OUTLINES) { vec4 tex = texture(samplers[fsMaterialSampler], fsTextureCoord.st); diff --git a/src/r_program.h b/src/r_program.h index 29c01bf1d..d061a803e 100644 --- a/src/r_program.h +++ b/src/r_program.h @@ -110,6 +110,7 @@ typedef enum { r_program_uniform_sky_glc_fog_skyFogMix, r_program_uniform_outline_color, r_program_uniform_outline_accuracy, + r_program_uniform_aliasmodel_outline_color, r_program_uniform_count } r_program_uniform_id; diff --git a/src/r_rmain.c b/src/r_rmain.c index 883fb5163..0eea614d7 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -221,6 +221,7 @@ cvar_t gl_simpleitems_orientation = {"gl_simpleitems_orientation", "2"} cvar_t gl_modulate = {"gl_modulate", "1"}; cvar_t gl_outline = {"gl_outline", "0"}; cvar_t gl_outline_color_world = {"gl_outline_color_world", "0 0 0"}; +cvar_t gl_outline_color_model = {"gl_outline_color_model", "0 0 0"}; cvar_t gl_outline_world_accuracy = {"gl_outline_world_accuracy", "0.9"}; cvar_t gl_smoothmodels = {"gl_smoothmodels", "1"}; @@ -700,6 +701,7 @@ void R_Init(void) Cvar_Register(&gl_outline); Cvar_Register(&gl_outline_color_world); + Cvar_Register(&gl_outline_color_model); Cvar_Register(&gl_outline_world_accuracy); Cvar_Register(&gl_smoothmodels); From fd10e3aa02fbee148c890d95958e9b4a9f2ea32a Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Fri, 4 Aug 2023 21:00:16 +0200 Subject: [PATCH 06/26] proper outlining of liquids, fix stupid ide changing random whitespaces --- src/glsl/draw_world.fragment.glsl | 2 +- src/menu_options.c | 34 +++++++++++++++---------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/glsl/draw_world.fragment.glsl b/src/glsl/draw_world.fragment.glsl index 1706b5701..e0bc4fdaf 100644 --- a/src/glsl/draw_world.fragment.glsl +++ b/src/glsl/draw_world.fragment.glsl @@ -97,7 +97,7 @@ void main() int turbType; #ifdef DRAW_GEOMETRY - normal_texture = vec4(Normal, mix(UnClipped.z / r_zFar, 0, min(1, Flags & EZQ_SURFACE_TYPE))); + normal_texture = vec4(Normal, mix(UnClipped.z / r_zFar, 0, 0)); #endif if (draw_outlines == 1) { diff --git a/src/menu_options.c b/src/menu_options.c index cb4e0e4bf..4c9291d6d 100644 --- a/src/menu_options.c +++ b/src/menu_options.c @@ -210,15 +210,15 @@ extern cvar_t scr_autoid, crosshairalpha, amf_hidenails, amf_hiderockets, gl_ani void CL_Autotrack_f(void); -const char* bandwidth_enum[] = { - "Modem (33k)", "3800", "Modem (56k)", "5670", +const char* bandwidth_enum[] = { + "Modem (33k)", "3800", "Modem (56k)", "5670", "ISDN (112k)", "9856", "Cable (128k)", "14336", "ADSL (> 256k)", "30000" }; const char* cl_c2sImpulseBackup_enum[] = { "Perfect", "0", "Low", "2", "Medium", "4", "High", "6" }; - + const char* ignore_flood_enum[] = { "Off", "0", "say/spec", "1", "say/say_team/spec", "2" }; @@ -233,7 +233,7 @@ const char* cl_chatmode_enum[] = { const char* con_completion_format_enum[] = { "Old", "New:Current+Default", "New:Current", "New:Default", "New:Current+Default,if changed", "New:Without values" }; - + const char* scr_conback_enum[] = { "Off", "On Load", "Always", }; @@ -554,7 +554,7 @@ const char* ResolutionRead(void) } snprintf(buf, sizeof(buf), "%dx%d@%dHz", mode->w, mode->h, mode->refresh_rate); - + return buf; } @@ -658,7 +658,7 @@ extern cvar_t cfg_backup, cfg_save_aliases, cfg_save_binds, cfg_save_cmdline, void MOpt_ImportConfig(void) { MOpt_configpage_mode = MOCPM_CHOOSECONFIG; - + // hope few doubled trinary operator won't hurt your brains if (cfg_use_home.integer) FL_SetCurrentDir(&configs_filelist, (cfg_use_gamedir.integer) ? va("%s/%s", com_homedir, (strcmp(com_gamedirfile, "qw") == 0) ? "" : com_gamedirfile) : com_homedir); @@ -696,7 +696,7 @@ void MOpt_LoadCfg(void) { S_LocalSound("misc/basekey.wav"); Cbuf_AddText("cfg_load\n"); } -void MOpt_SaveCfg(void) { +void MOpt_SaveCfg(void) { S_LocalSound("doors/runeuse.wav"); Cbuf_AddText("cfg_save\n"); } @@ -899,19 +899,19 @@ setting settplayer_arr[] = { ADDSET_NUMBER ("Fullbright Skins", r_fullbrightSkins, 0, 1, 0.05), ADDSET_ENUM ("Ruleset", ruleset, ruleset_enum), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Weapon Handling"), ADDSET_CUSTOM ("Gun Autoswitch", AutoSWRead, AutoSWToggle, "Switches to the weapon picked up if it is more powerful than what you're currently holding."), ADDSET_BOOL ("Gun Preselect", cl_weaponpreselect), ADDSET_BOOL ("Gun Auto Hide", cl_weaponhide), - + ADDSET_SEPARATOR("Movement"), ADDSET_CUSTOM ("Always Run", AlwaysRunRead, AlwaysRunToggle, "Maximum forward speed at all times."), ADDSET_ADVANCED_SECTION(), ADDSET_BOOL ("Smart Jump", cl_smartjump), ADDSET_NAMED ("Movement Scripts", allow_scripts, allowscripts_enum), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Team Skin & Colors"), ADDSET_COLOR ("Shirt Color", cl_teamtopcolor), ADDSET_COLOR ("Pants Color", cl_teambottomcolor), @@ -922,7 +922,7 @@ setting settplayer_arr[] = { ADDSET_SKIN ("Pent Skin", cl_teampentskin), ADDSET_SKIN ("Quad+Pent Skin", cl_teambothskin), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Enemy Skin & Colors"), ADDSET_COLOR ("Shirt Color", cl_enemytopcolor), ADDSET_COLOR ("Pants Color", cl_enemybottomcolor), @@ -938,7 +938,7 @@ setting settplayer_arr[] = { // GRAPHICS TAB setting settfps_arr[] = { ADDSET_BOOL ("Advanced Options", menu_advanced), - + ADDSET_SEPARATOR("Presets"), ADDSET_CUSTOM ("GFX Preset", GFXPresetRead, GFXPresetToggle, "Select different graphic presets."), @@ -958,14 +958,14 @@ setting settfps_arr[] = { ADDSET_NUMBER ("View Height", v_viewheight, -7, 4, 0.5), ADDSET_BASIC_SECTION(), - ADDSET_ADVANCED_SECTION(), + ADDSET_ADVANCED_SECTION(), ADDSET_SEPARATOR("Textures"), ADDSET_BOOL ("Luma", gl_lumatextures), ADDSET_ENUM ("Detail", gl_max_size, gl_max_size_enum), ADDSET_NUMBER ("Miptex", gl_miptexLevel, 0, 3, 1), ADDSET_BOOL ("No Textures", gl_textureless), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Player & Weapon Model"), ADDSET_ADVANCED_SECTION(), ADDSET_BOOL ("Powerup Luma", gl_powerupshells), @@ -975,8 +975,9 @@ setting settfps_arr[] = { ADDSET_ADVANCED_SECTION(), ADDSET_NUMBER ("Weapon Shift", r_viewmodeloffset, -10, 10, 1), ADDSET_NAMED ("Weapon Muzzleflashes", cl_muzzleflash, muzzleflashes_enum), + ADDSET_NAMED ("Outline", gl_outline, outline_enum), ADDSET_BASIC_SECTION(), - + ADDSET_SEPARATOR("Environment"), ADDSET_ADVANCED_SECTION(), ADDSET_BOOL ("Fullbright World", r_fullbright), @@ -991,9 +992,6 @@ setting settfps_arr[] = { ADDSET_BOOL ("Gib Filter", cl_gibfilter), ADDSET_ADVANCED_SECTION(), ADDSET_NAMED ("Dead Body Filter", cl_deadbodyfilter, deadbodyfilter_enum), -#ifdef RENDERER_OPTION_MODERN_OPENGL - ADDSET_NAMED ("Outline", gl_outline, outline_enum), -#endif ADDSET_BASIC_SECTION(), ADDSET_SEPARATOR("Projectiles"), From 2856147afab459ac2394da3aeda740c08ed8eedc Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Fri, 4 Aug 2023 21:33:11 +0200 Subject: [PATCH 07/26] add aliasmodel outline scale, limited to 5x (which still might be a bit too much?) --- src/gl_program.c | 2 ++ src/glm_aliasmodel.c | 3 ++- src/glm_rmain.c | 2 +- src/glsl/draw_aliasmodel.vertex.glsl | 3 ++- src/r_program.h | 1 + src/r_rmain.c | 2 ++ 6 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/gl_program.c b/src/gl_program.c index 4354ab2d7..bd51a326d 100644 --- a/src/gl_program.c +++ b/src/gl_program.c @@ -332,6 +332,8 @@ static r_program_uniform_t program_uniforms[] = { { r_program_fx_world_geometry, "outline_accuracy", 1, false }, // r_program_uniform_aliasmodel_outline_color { r_program_aliasmodel, "outline_color", 1, false }, + // r_program_uniform_aliasmodel_outline_scale + { r_program_aliasmodel, "outline_scale", 1, false }, }; #ifdef C_ASSERT diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index 921523602..a6d0e8fa4 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -489,12 +489,13 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) } if (type == aliasmodel_draw_std && alias_draw_instructions[aliasmodel_draw_outlines].num_calls) { - extern cvar_t gl_outline_color_model; + extern cvar_t gl_outline_color_model, gl_outline_scale_model; instr = &alias_draw_instructions[aliasmodel_draw_outlines]; R_TraceEnterNamedRegion("GLM_DrawOutlineBatch"); R_SetAliasModelUniform(EZQ_ALIAS_MODE_OUTLINES); + R_ProgramUniform1f(r_program_uniform_aliasmodel_outline_scale, bound(0.0, gl_outline_scale_model.value, 5.0)); R_ProgramUniform3f(r_program_uniform_aliasmodel_outline_color, (float)gl_outline_color_model.color[0] / 255.0f, (float)gl_outline_color_model.color[1] / 255.0f, diff --git a/src/glm_rmain.c b/src/glm_rmain.c index a85736dea..e298a4070 100644 --- a/src/glm_rmain.c +++ b/src/glm_rmain.c @@ -80,7 +80,7 @@ static void GLM_DrawWorldOutlines(void) renderer.TextureUnitBind(0, normals); R_ProgramUniform1f(r_program_uniform_outline_accuracy, - bound(gl_outline_world_accuracy.value, 0.0, 1.0)); + bound(0.0, gl_outline_world_accuracy.value, 1.0)); R_ProgramUniform3f(r_program_uniform_outline_color, (float)gl_outline_color_world.color[0] / 255.0f, diff --git a/src/glsl/draw_aliasmodel.vertex.glsl b/src/glsl/draw_aliasmodel.vertex.glsl index 0fc90e57c..ce5e0c3d0 100644 --- a/src/glsl/draw_aliasmodel.vertex.glsl +++ b/src/glsl/draw_aliasmodel.vertex.glsl @@ -3,6 +3,7 @@ #ezquake-definitions uniform int mode; +uniform float outline_scale; layout(location = 0) in vec3 vboPosition; layout(location = 1) in vec2 vboTex; @@ -66,7 +67,7 @@ void main() } } else if (mode == EZQ_ALIAS_MODE_OUTLINES) { - gl_Position = projectionMatrix * models[_instanceId].modelView * vec4(position + models[_instanceId].outlineNormalScale * normalCoords, 1); + gl_Position = projectionMatrix * models[_instanceId].modelView * vec4(position + models[_instanceId].outlineNormalScale * normalCoords * outline_scale, 1); } else { gl_Position = projectionMatrix * models[_instanceId].modelView * vec4(position + normalCoords * 0.5, 1); diff --git a/src/r_program.h b/src/r_program.h index d061a803e..15bb050a3 100644 --- a/src/r_program.h +++ b/src/r_program.h @@ -111,6 +111,7 @@ typedef enum { r_program_uniform_outline_color, r_program_uniform_outline_accuracy, r_program_uniform_aliasmodel_outline_color, + r_program_uniform_aliasmodel_outline_scale, r_program_uniform_count } r_program_uniform_id; diff --git a/src/r_rmain.c b/src/r_rmain.c index 0eea614d7..a8febf154 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -222,6 +222,7 @@ cvar_t gl_modulate = {"gl_modulate", "1"}; cvar_t gl_outline = {"gl_outline", "0"}; cvar_t gl_outline_color_world = {"gl_outline_color_world", "0 0 0"}; cvar_t gl_outline_color_model = {"gl_outline_color_model", "0 0 0"}; +cvar_t gl_outline_scale_model = {"gl_outline_scale_model", "1.0"}; cvar_t gl_outline_world_accuracy = {"gl_outline_world_accuracy", "0.9"}; cvar_t gl_smoothmodels = {"gl_smoothmodels", "1"}; @@ -702,6 +703,7 @@ void R_Init(void) Cvar_Register(&gl_outline); Cvar_Register(&gl_outline_color_world); Cvar_Register(&gl_outline_color_model); + Cvar_Register(&gl_outline_scale_model); Cvar_Register(&gl_outline_world_accuracy); Cvar_Register(&gl_smoothmodels); From ec1e3bbfd64016029b23d9c6053f0a65e4192bbb Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Fri, 4 Aug 2023 22:07:48 +0200 Subject: [PATCH 08/26] fix bug with outlines on (for example) dm6 --- src/glsl/fx_world_geometry.fragment.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/glsl/fx_world_geometry.fragment.glsl b/src/glsl/fx_world_geometry.fragment.glsl index e3ce54ca4..059b77628 100644 --- a/src/glsl/fx_world_geometry.fragment.glsl +++ b/src/glsl/fx_world_geometry.fragment.glsl @@ -19,8 +19,8 @@ void main() vec4 up = texelFetchOffset(normal_texture, coords, 0, ivec2(0, -1)); vec4 down = texelFetchOffset(normal_texture, coords, 0, ivec2(0, +1)); - bool z_diff = r_zFar * abs((right.a - center.a) - (center.a - left.a)) > 8; - bool z_diff2 = r_zFar * abs((down.a - center.a) - (center.a - up.a)) > 8; + bool z_diff = r_zFar * abs((right.a - center.a) - (center.a - left.a)) > r_zNear; + bool z_diff2 = r_zFar * abs((down.a - center.a) - (center.a - up.a)) > r_zNear; if (center.a != 0 && ( (left.a != 0 && right.a != 0 && z_diff) || From 9eebbcf33d33f15424d9af735fc2c3542d2cc749 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Fri, 4 Aug 2023 22:11:02 +0200 Subject: [PATCH 09/26] forgot to take vid_framebuffer_scale into consideration --- src/glm_rmain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/glm_rmain.c b/src/glm_rmain.c index e298a4070..381163ad3 100644 --- a/src/glm_rmain.c +++ b/src/glm_rmain.c @@ -74,7 +74,8 @@ static void GLM_DrawWorldOutlines(void) } else { // ignore viewsize and allat crap and set the viewport size to the whole window. // previously the viewport was already resized, and then resized again later, making the outlines not align. - R_Viewport(0, 0, glConfig.vidWidth, glConfig.vidHeight); + R_Viewport(0, 0, VID_ScaledWidth3D(), VID_ScaledHeight3D()); + } renderer.TextureUnitBind(0, normals); From 22cba47d94e6f436f47d1757f31ec99c179a6b77 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Sat, 5 Aug 2023 15:04:17 +0200 Subject: [PATCH 10/26] tweaking --- help_variables.json | 9 ++++++++- src/glsl/draw_world.fragment.glsl | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/help_variables.json b/help_variables.json index 347e92030..52d9323e2 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5167,6 +5167,7 @@ "default": "0", "desc": "Controls outlining of models and map. Disallowed in qcon ruleset.", "group-id": "35", + "remarks": "World outlines require vid_framebuffer 1|2 and Modern OpenGL (vid_renderer 1).", "type": "enum", "values": [ { @@ -5199,9 +5200,15 @@ "group-id": "35", "type": "string" }, + "gl_outline_scale_model": { + "default": "1", + "desc": "Determines the scale of model outlines. Allows values 0 to 5.", + "group-id": "35", + "type": "float" + }, "gl_outline_world_accuracy": { "default": "0.9", - "desc": "Determines the accuracy for drawing world outlines. Mainly visible on slopes and other angled surfaces.", + "desc": "Determines the accuracy for drawing world outlines. Effects are mainly visible on slopes and other angled surfaces.", "group-id": "35", "type": "float" }, diff --git a/src/glsl/draw_world.fragment.glsl b/src/glsl/draw_world.fragment.glsl index e0bc4fdaf..1c34ae445 100644 --- a/src/glsl/draw_world.fragment.glsl +++ b/src/glsl/draw_world.fragment.glsl @@ -97,7 +97,7 @@ void main() int turbType; #ifdef DRAW_GEOMETRY - normal_texture = vec4(Normal, mix(UnClipped.z / r_zFar, 0, 0)); + normal_texture = vec4(Normal, UnClipped.z / r_zFar); // xyz = normal, a = depth #endif if (draw_outlines == 1) { From 8cdbc52d1fc3b25c19d23e2e78b6ea13b1870da7 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Sun, 6 Aug 2023 21:15:00 +0200 Subject: [PATCH 11/26] indentation fixes --- src/gl_program.c | 8 ++++---- src/glm_aliasmodel.c | 13 ++++++------- src/glm_rmain.c | 19 +++++++++---------- src/r_program.h | 8 ++++---- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/gl_program.c b/src/gl_program.c index bd51a326d..64012ea0a 100644 --- a/src/gl_program.c +++ b/src/gl_program.c @@ -326,13 +326,13 @@ static r_program_uniform_t program_uniforms[] = { { r_program_lightmap_compute, "firstLightmap", 1, false }, // r_program_uniform_turb_glc_fog_skyFogMix, { r_program_sky_glc, "skyFogMix", 1, false }, - // r_program_uniform_outline_color + // r_program_uniform_outline_color { r_program_fx_world_geometry, "outline_color", 1, false }, - // r_program_uniform_outline_accuracy + // r_program_uniform_outline_accuracy { r_program_fx_world_geometry, "outline_accuracy", 1, false }, - // r_program_uniform_aliasmodel_outline_color + // r_program_uniform_aliasmodel_outline_color { r_program_aliasmodel, "outline_color", 1, false }, - // r_program_uniform_aliasmodel_outline_scale + // r_program_uniform_aliasmodel_outline_scale { r_program_aliasmodel, "outline_scale", 1, false }, }; diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index a6d0e8fa4..9ded4732c 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -489,18 +489,17 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) } if (type == aliasmodel_draw_std && alias_draw_instructions[aliasmodel_draw_outlines].num_calls) { - extern cvar_t gl_outline_color_model, gl_outline_scale_model; + extern cvar_t gl_outline_color_model, gl_outline_scale_model; instr = &alias_draw_instructions[aliasmodel_draw_outlines]; R_TraceEnterNamedRegion("GLM_DrawOutlineBatch"); R_SetAliasModelUniform(EZQ_ALIAS_MODE_OUTLINES); - R_ProgramUniform1f(r_program_uniform_aliasmodel_outline_scale, bound(0.0, gl_outline_scale_model.value, 5.0)); - R_ProgramUniform3f(r_program_uniform_aliasmodel_outline_color, - (float)gl_outline_color_model.color[0] / 255.0f, - (float)gl_outline_color_model.color[1] / 255.0f, - (float)gl_outline_color_model.color[2] / 255.0f - ); + R_ProgramUniform1f(r_program_uniform_aliasmodel_outline_scale, bound(0.0, gl_outline_scale_model.value, 5.0)); + R_ProgramUniform3f(r_program_uniform_aliasmodel_outline_color, + (float)gl_outline_color_model.color[0] / 255.0f, + (float)gl_outline_color_model.color[1] / 255.0f, + (float)gl_outline_color_model.color[2] / 255.0f); GLM_StateBeginAliasOutlineBatch(); diff --git a/src/glm_rmain.c b/src/glm_rmain.c index 381163ad3..5403309b3 100644 --- a/src/glm_rmain.c +++ b/src/glm_rmain.c @@ -62,9 +62,9 @@ static void GLM_DrawWorldOutlines(void) if (R_TextureReferenceIsValid(normals) && GLM_CompileWorldGeometryProgram()) { int viewport[4]; int fullscreen_viewport[4]; - extern cvar_t gl_outline_color_world, gl_outline_world_accuracy; + extern cvar_t gl_outline_color_world, gl_outline_world_accuracy; - R_GetViewport(viewport); + R_GetViewport(viewport); // If we are only rendering to a section of the screen then that is the only part of the texture that will be filled in if (CL_MultiviewEnabled()) { @@ -72,18 +72,17 @@ static void GLM_DrawWorldOutlines(void) R_Viewport(fullscreen_viewport[0], fullscreen_viewport[1], fullscreen_viewport[2], fullscreen_viewport[3]); R_EnableScissorTest(viewport[0], viewport[1], viewport[2], viewport[3]); } else { - // ignore viewsize and allat crap and set the viewport size to the whole window. - // previously the viewport was already resized, and then resized again later, making the outlines not align. - R_Viewport(0, 0, VID_ScaledWidth3D(), VID_ScaledHeight3D()); - - } + // ignore viewsize and allat crap and set the viewport size to the whole window. + // previously the viewport was already resized, and then resized again later, making the outlines not align. + R_Viewport(0, 0, VID_ScaledWidth3D(), VID_ScaledHeight3D()); + } renderer.TextureUnitBind(0, normals); - R_ProgramUniform1f(r_program_uniform_outline_accuracy, + R_ProgramUniform1f(r_program_uniform_outline_accuracy, bound(0.0, gl_outline_world_accuracy.value, 1.0)); - R_ProgramUniform3f(r_program_uniform_outline_color, + R_ProgramUniform3f(r_program_uniform_outline_color, (float)gl_outline_color_world.color[0] / 255.0f, (float)gl_outline_color_world.color[1] / 255.0f, (float)gl_outline_color_world.color[2] / 255.0f); @@ -94,7 +93,7 @@ static void GLM_DrawWorldOutlines(void) GL_DrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Restore viewport - R_Viewport(viewport[0], viewport[1], viewport[2], viewport[3]); + R_Viewport(viewport[0], viewport[1], viewport[2], viewport[3]); if (CL_MultiviewEnabled()) { R_DisableScissorTest(); } diff --git a/src/r_program.h b/src/r_program.h index 15bb050a3..e9a377cec 100644 --- a/src/r_program.h +++ b/src/r_program.h @@ -108,10 +108,10 @@ typedef enum { r_program_uniform_simple3d_color, r_program_uniform_lighting_firstLightmap, r_program_uniform_sky_glc_fog_skyFogMix, - r_program_uniform_outline_color, - r_program_uniform_outline_accuracy, - r_program_uniform_aliasmodel_outline_color, - r_program_uniform_aliasmodel_outline_scale, + r_program_uniform_outline_color, + r_program_uniform_outline_accuracy, + r_program_uniform_aliasmodel_outline_color, + r_program_uniform_aliasmodel_outline_scale, r_program_uniform_count } r_program_uniform_id; From f70a435d285ac3e36cf671da14734b62eb7f282c Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Mon, 7 Aug 2023 10:24:22 +0200 Subject: [PATCH 12/26] rewrite the outline shader entirely and add world scale cvar --- src/gl_program.c | 8 ++- src/glm_local.h | 2 + src/glm_misc.c | 4 ++ src/glm_rmain.c | 9 +-- src/glsl/common.glsl | 2 + src/glsl/draw_world.fragment.glsl | 2 +- src/glsl/fx_world_geometry.fragment.glsl | 91 ++++++++++++++++++------ src/r_program.h | 4 +- src/r_rmain.c | 8 ++- 9 files changed, 100 insertions(+), 30 deletions(-) diff --git a/src/gl_program.c b/src/gl_program.c index 64012ea0a..59d050122 100644 --- a/src/gl_program.c +++ b/src/gl_program.c @@ -328,8 +328,12 @@ static r_program_uniform_t program_uniforms[] = { { r_program_sky_glc, "skyFogMix", 1, false }, // r_program_uniform_outline_color { r_program_fx_world_geometry, "outline_color", 1, false }, - // r_program_uniform_outline_accuracy - { r_program_fx_world_geometry, "outline_accuracy", 1, false }, + // r_program_uniform_outline_depth_threshold + { r_program_fx_world_geometry, "outline_depth_threshold", 1, false }, + // r_program_uniform_outline_depth_scale + { r_program_fx_world_geometry, "outline_depth_scale", 1, false }, + // r_program_uniform_outline_scale + { r_program_fx_world_geometry, "outline_scale", 1, false }, // r_program_uniform_aliasmodel_outline_color { r_program_aliasmodel, "outline_color", 1, false }, // r_program_uniform_aliasmodel_outline_scale diff --git a/src/glm_local.h b/src/glm_local.h index 59a75151e..0eb97b129 100644 --- a/src/glm_local.h +++ b/src/glm_local.h @@ -71,6 +71,8 @@ typedef struct uniform_block_frame_constants_s { float fogMinZ; float fogMaxZ; float padding; + + float camangles[3]; } uniform_block_frame_constants_t; #define MAX_WORLDMODEL_BATCH 64 diff --git a/src/glm_misc.c b/src/glm_misc.c index e2da89ad9..5454401ba 100644 --- a/src/glm_misc.c +++ b/src/glm_misc.c @@ -169,6 +169,10 @@ void GLM_SetupGL(void) memcpy(frameConstants.projectionMatrix, R_ProjectionMatrix(), sizeof(frameConstants.projectionMatrix)); VectorCopy(r_refdef.vieworg, frameConstants.position); + frameConstants.camangles[PITCH] = DEG2RAD(r_refdef.viewangles[PITCH]); + frameConstants.camangles[YAW] = DEG2RAD(r_refdef.viewangles[YAW]); + frameConstants.camangles[ROLL] = DEG2RAD(r_refdef.viewangles[ROLL]); + frameConstantsUploaded = false; } diff --git a/src/glm_rmain.c b/src/glm_rmain.c index 5403309b3..af6a0d1e4 100644 --- a/src/glm_rmain.c +++ b/src/glm_rmain.c @@ -62,7 +62,8 @@ static void GLM_DrawWorldOutlines(void) if (R_TextureReferenceIsValid(normals) && GLM_CompileWorldGeometryProgram()) { int viewport[4]; int fullscreen_viewport[4]; - extern cvar_t gl_outline_color_world, gl_outline_world_accuracy; + extern cvar_t gl_outline_color_world, gl_outline_scale_world, + gl_outline_world_depth_threshold, gl_outline_world_depth_scale; R_GetViewport(viewport); @@ -79,9 +80,9 @@ static void GLM_DrawWorldOutlines(void) renderer.TextureUnitBind(0, normals); - R_ProgramUniform1f(r_program_uniform_outline_accuracy, - bound(0.0, gl_outline_world_accuracy.value, 1.0)); - + R_ProgramUniform1f(r_program_uniform_outline_depth_threshold, gl_outline_world_depth_threshold.value); + R_ProgramUniform1f(r_program_uniform_outline_depth_scale, gl_outline_world_depth_scale.value); + R_ProgramUniform1f(r_program_uniform_outline_scale, gl_outline_scale_world.value); R_ProgramUniform3f(r_program_uniform_outline_color, (float)gl_outline_color_world.color[0] / 255.0f, (float)gl_outline_color_world.color[1] / 255.0f, diff --git a/src/glsl/common.glsl b/src/glsl/common.glsl index 5b073e552..ecb7e2cb2 100644 --- a/src/glsl/common.glsl +++ b/src/glsl/common.glsl @@ -68,6 +68,8 @@ layout(std140, binding=EZQ_GL_BINDINGPOINT_FRAMECONSTANTS) uniform GlobalState { float fogMinZ; float fogMaxZ; float padding; + + vec3 camAngles; }; struct WorldDrawInfo { diff --git a/src/glsl/draw_world.fragment.glsl b/src/glsl/draw_world.fragment.glsl index 1c34ae445..fc0c1b6b2 100644 --- a/src/glsl/draw_world.fragment.glsl +++ b/src/glsl/draw_world.fragment.glsl @@ -97,7 +97,7 @@ void main() int turbType; #ifdef DRAW_GEOMETRY - normal_texture = vec4(Normal, UnClipped.z / r_zFar); // xyz = normal, a = depth + normal_texture = vec4(Normal, abs(UnClipped.z / r_zFar)); // rgb = normal, a = depth #endif if (draw_outlines == 1) { diff --git a/src/glsl/fx_world_geometry.fragment.glsl b/src/glsl/fx_world_geometry.fragment.glsl index 059b77628..72733a2e1 100644 --- a/src/glsl/fx_world_geometry.fragment.glsl +++ b/src/glsl/fx_world_geometry.fragment.glsl @@ -1,3 +1,7 @@ +// fixme +// better edge of screen avoiding (the current one breaks when using a large outline scale) +// somehow scale the depth threshold with outline_scale also + #version 430 #ezquake-definitions @@ -5,34 +9,81 @@ layout(binding = 0) uniform sampler2D normal_texture; uniform vec3 outline_color; -uniform float outline_accuracy; +uniform float outline_scale; +uniform float outline_depth_threshold; +uniform float outline_depth_scale; in vec2 TextureCoord; out vec4 frag_colour; void main() { + ivec2 coords = ivec2(TextureCoord.x * r_width, TextureCoord.y * r_height); vec4 center = texelFetch(normal_texture, coords, 0); - vec4 left = texelFetchOffset(normal_texture, coords, 0, ivec2(-1, 0)); - vec4 right = texelFetchOffset(normal_texture, coords, 0, ivec2(+1, 0)); - vec4 up = texelFetchOffset(normal_texture, coords, 0, ivec2(0, -1)); - vec4 down = texelFetchOffset(normal_texture, coords, 0, ivec2(0, +1)); - - bool z_diff = r_zFar * abs((right.a - center.a) - (center.a - left.a)) > r_zNear; - bool z_diff2 = r_zFar * abs((down.a - center.a) - (center.a - up.a)) > r_zNear; - - if (center.a != 0 && ( - (left.a != 0 && right.a != 0 && z_diff) || - (down.a != 0 && up.a != 0 && z_diff2) || - (left.a != 0 && dot(center.rgb, left.rgb) < outline_accuracy) || - (right.a != 0 && dot(center.rgb, right.rgb) < outline_accuracy) || - (up.a != 0 && dot(center.rgb, up.rgb) < outline_accuracy) || - (down.a != 0 && dot(center.rgb, down.rgb) < outline_accuracy) - )) { - frag_colour = vec4(outline_color, 1.0); + + // avoid edges of screen + if(center.a == 0) + return; + + float hsc = int(ceil(outline_scale * 0.5f)); + float hsf = int(floor(outline_scale * 0.5f)); + + ivec2 bl = coords + ivec2(-hsf, -hsf); + ivec2 tr = coords + ivec2( hsc, hsc); + ivec2 br = coords + ivec2( hsc, -hsf); + ivec2 tl = coords + ivec2(-hsf, hsc); + + // depth values + float d0 = texelFetch(normal_texture, bl, 0).a; + float d1 = texelFetch(normal_texture, tr, 0).a; + float d2 = texelFetch(normal_texture, br, 0).a; + float d3 = texelFetch(normal_texture, tl, 0).a; + + // avoid edges of screen + if(d0 == 0.0f || d1 == 0.0f || d2 == 0.0f || d3 == 0.0f) + return; + + // normal values + vec3 n0 = texelFetch(normal_texture, bl, 0).rgb; + vec3 n1 = texelFetch(normal_texture, tr, 0).rgb; + vec3 n2 = texelFetch(normal_texture, br, 0).rgb; + vec3 n3 = texelFetch(normal_texture, tl, 0).rgb; + + // normal difference + vec3 nd0 = n1 - n0; + vec3 nd1 = n3 - n2; + float en = sqrt(dot(nd0, nd0) + dot(nd1, nd1)); + + if(en > 0.4f) { + frag_colour.rgb = outline_color; + frag_colour.a = 1; + return; } - else { - frag_colour = vec4(0, 0, 0, 0); + + // depth differece + float dd0 = d1 - d0; + float dd1 = d3 - d2; + float ed = sqrt(dd0 * dd0 + dd1 * dd1) * 100.0f; + float dt = outline_depth_threshold * center.a; + + // camera direction + float cp = cos(camAngles.x); + float sp = sin(camAngles.x); + float cy = cos(camAngles.y); + float sy = sin(camAngles.y); + vec3 dir_fwd = { cp * cy, sy * cp, sp }; + + // make the depth threshold bigger the closer the surface to camera angle is to 90 degrees + float ndv = 1.0f - dot(center.rgb, abs(dir_fwd)); + float nt0 = clamp(abs(ndv), 0.0f, 1.0f); + float nt = nt0 * outline_depth_scale + 1.0f; + dt = dt * nt; + + if(ed > dt) { + frag_colour.rgb = outline_color; + frag_colour.a = 1; + } else { + frag_colour = vec4(0); } } diff --git a/src/r_program.h b/src/r_program.h index e9a377cec..51d317699 100644 --- a/src/r_program.h +++ b/src/r_program.h @@ -109,7 +109,9 @@ typedef enum { r_program_uniform_lighting_firstLightmap, r_program_uniform_sky_glc_fog_skyFogMix, r_program_uniform_outline_color, - r_program_uniform_outline_accuracy, + r_program_uniform_outline_depth_threshold, + r_program_uniform_outline_depth_scale, + r_program_uniform_outline_scale, r_program_uniform_aliasmodel_outline_color, r_program_uniform_aliasmodel_outline_scale, r_program_uniform_count diff --git a/src/r_rmain.c b/src/r_rmain.c index a8febf154..e1e17ec5c 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -222,8 +222,10 @@ cvar_t gl_modulate = {"gl_modulate", "1"}; cvar_t gl_outline = {"gl_outline", "0"}; cvar_t gl_outline_color_world = {"gl_outline_color_world", "0 0 0"}; cvar_t gl_outline_color_model = {"gl_outline_color_model", "0 0 0"}; +cvar_t gl_outline_scale_world = {"gl_outline_scale_world", "1.0"}; cvar_t gl_outline_scale_model = {"gl_outline_scale_model", "1.0"}; -cvar_t gl_outline_world_accuracy = {"gl_outline_world_accuracy", "0.9"}; +cvar_t gl_outline_world_depth_threshold = {"gl_outline_world_depth_threshold", "0.9"}; +cvar_t gl_outline_world_depth_scale = {"gl_outline_world_depth_scale", "7.0"}; cvar_t gl_smoothmodels = {"gl_smoothmodels", "1"}; cvar_t gl_vbo_clientmemory = {"gl_vbo_clientmemory", "0", CVAR_LATCH_GFX }; @@ -703,8 +705,10 @@ void R_Init(void) Cvar_Register(&gl_outline); Cvar_Register(&gl_outline_color_world); Cvar_Register(&gl_outline_color_model); + Cvar_Register(&gl_outline_scale_world); Cvar_Register(&gl_outline_scale_model); - Cvar_Register(&gl_outline_world_accuracy); + Cvar_Register(&gl_outline_world_depth_threshold); + Cvar_Register(&gl_outline_world_depth_scale); Cvar_Register(&gl_smoothmodels); Cvar_Register(&gl_vbo_clientmemory); From 1defb3bc266b2420d74641ebf61594a6dee53a98 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Mon, 7 Aug 2023 18:54:30 +0200 Subject: [PATCH 13/26] add xray silhouettes for spectators (not really an outline but maybe will be later) --- src/cl_ents.c | 17 +++++++- src/gl_program.c | 6 ++- src/glm_aliasmodel.c | 54 ++++++++++++++++++++++---- src/glsl/constants.glsl | 10 +++-- src/glsl/draw_aliasmodel.fragment.glsl | 13 ++++++- src/glsl/draw_aliasmodel.vertex.glsl | 2 +- src/r_program.h | 4 +- src/r_rmain.c | 8 ++++ src/r_state.h | 1 + src/r_states.c | 3 ++ src/render.h | 1 + 11 files changed, 102 insertions(+), 17 deletions(-) diff --git a/src/cl_ents.c b/src/cl_ents.c index 98b8e6478..e6f91795a 100644 --- a/src/cl_ents.c +++ b/src/cl_ents.c @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "utils.h" #include "qmb_particles.h" #include "rulesets.h" +#include "teamplay.h" static int MVD_TranslateFlags(int src); void TP_ParsePlayerInfo(player_state_t *, player_state_t *, player_info_t *info); @@ -1652,6 +1653,7 @@ static qbool CL_AddVWepModel (entity_t *ent, int vw_index, int old_vw_frame) newent.colormap = vid.colormap; newent.renderfx |= RF_PLAYERMODEL; // not really, but use same lighting rules newent.effects = ent->effects; // Electro - added for shells + // newent.scoreboard = ent->scoreboard; // for team color in gl_outline if ((!cls.mvdplayback || Cam_TrackNum() >= 0) && cl.racing && !CL_SetAlphaByDistance(&newent)) { return false; @@ -1692,6 +1694,7 @@ static void CL_LinkPlayers(void) entity_t ent; centity_t *cent; frame_t *frame; + trace_t trace; customlight_t cst_lt = {0}; extern cvar_t cl_debug_antilag_ghost, cl_debug_antilag_view; @@ -1955,11 +1958,21 @@ static void CL_LinkPlayers(void) } } - if ((cl.vwep_enabled && r_drawvweps.value && state->vw_index) && (state->modelindex != cl_modelindices[mi_eyes])) + vec3_t end; + VectorCopy(cent->lerp_origin, end); + end[2] += 12; + trace = PM_TraceLine(r_refdef.vieworg, end); + if (trace.fraction != 1) { + ent.renderfx |= RF_BEHINDWALL; + } else { + ent.renderfx &= ~RF_BEHINDWALL; + } + + if ((cl.vwep_enabled && r_drawvweps.value && state->vw_index) && (state->modelindex != cl_modelindices[mi_eyes])) { qbool vwep; vwep = CL_AddVWepModel (&ent, state->vw_index, cent->old_vw_frame); - if (vwep) + if (vwep) { if (cl.vw_model_name[0][0] != '-') { diff --git a/src/gl_program.c b/src/gl_program.c index 59d050122..d1b6b6dc9 100644 --- a/src/gl_program.c +++ b/src/gl_program.c @@ -334,8 +334,12 @@ static r_program_uniform_t program_uniforms[] = { { r_program_fx_world_geometry, "outline_depth_scale", 1, false }, // r_program_uniform_outline_scale { r_program_fx_world_geometry, "outline_scale", 1, false }, - // r_program_uniform_aliasmodel_outline_color + // r_program_uniform_aliasmodel_outline_color_model { r_program_aliasmodel, "outline_color", 1, false }, + // r_program_uniform_aliasmodel_outline_color_team + { r_program_aliasmodel, "outline_color_team", 1, false }, + // r_program_uniform_aliasmodel_outline_color_enemy + { r_program_aliasmodel, "outline_color_enemy", 1, false }, // r_program_uniform_aliasmodel_outline_scale { r_program_aliasmodel, "outline_scale", 1, false }, }; diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index 9ded4732c..6409fe58c 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -45,6 +45,7 @@ typedef enum aliasmodel_draw_type_s { aliasmodel_draw_std, aliasmodel_draw_alpha, aliasmodel_draw_outlines, + aliasmodel_draw_outlines_spec, aliasmodel_draw_shells, aliasmodel_draw_postscene, aliasmodel_draw_postscene_additive, @@ -269,6 +270,7 @@ static void GLM_QueueAliasModelDrawImpl( aliasmodel_draw_type_t shelltype = aliasmodel_draw_shells; aliasmodel_draw_instructions_t* instr; int textureSampler = -1; + extern cvar_t gl_outline_xray; // Compile here so we can work out how many samplers we have free to allocate per draw-call if (!GLM_CompileAliasModelProgram()) { @@ -321,7 +323,10 @@ static void GLM_QueueAliasModelDrawImpl( (effects & EF_BLUE ? AMF_SHELLMODEL_BLUE : 0) | (R_TextureReferenceIsValid(texture) ? AMF_TEXTURE_MATERIAL : 0) | (render_effects & RF_CAUSTICS ? AMF_CAUSTICS : 0) | - (render_effects & RF_WEAPONMODEL ? AMF_WEAPONMODEL : 0); + (render_effects & RF_WEAPONMODEL ? AMF_WEAPONMODEL : 0) | + (ent->scoreboard != NULL ? ent->scoreboard->teammate ? AMF_TEAMMATE : 0 : 0) | + (ent->renderfx & RF_BEHINDWALL ? AMF_BEHINDWALL : 0) | + (ent->renderfx & RF_PLAYERMODEL ? AMF_PLAYERMODEL : 0); uniform->yaw_angle_rad = ent->angles[YAW] * M_PI / 180.0; uniform->shadelight = ent->shadelight; uniform->ambientlight = ent->ambientlight; @@ -342,6 +347,11 @@ static void GLM_QueueAliasModelDrawImpl( if (shell) { GLM_QueueDrawCall(shelltype, vbo_start, vbo_count, alias_draw_count); } + if((render_effects & RF_PLAYERMODEL) && (render_effects & RF_BEHINDWALL) && + (cls.demoplayback || cl.spectator) && gl_outline_xray.value) + { + GLM_QueueDrawCall(aliasmodel_draw_outlines_spec, vbo_start, vbo_count, alias_draw_count); + } alias_draw_count++; } @@ -444,6 +454,7 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) qbool translucent = (type != aliasmodel_draw_std && type != aliasmodel_draw_postscene_additive); qbool additive = (type == aliasmodel_draw_postscene_additive); qbool shells = (type == aliasmodel_draw_shells || type == aliasmodel_draw_postscene_shells); + extern cvar_t gl_outline_color_model, gl_outline_scale_model, gl_outline_color_team, gl_outline_color_enemy; if (!instr->num_calls || !GLM_CompileAliasModelProgram()) { return; @@ -488,18 +499,44 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) ); } - if (type == aliasmodel_draw_std && alias_draw_instructions[aliasmodel_draw_outlines].num_calls) { - extern cvar_t gl_outline_color_model, gl_outline_scale_model; +#define SETCOLORUNIFORM(colort) R_ProgramUniform3f(r_program_uniform_aliasmodel_outline_##colort,\ + (float)gl_outline_##colort.color[0] / 255.0f,\ + (float)gl_outline_##colort.color[1] / 255.0f,\ + (float)gl_outline_##colort.color[2] / 255.0f) + + if (type == aliasmodel_draw_std && alias_draw_instructions[aliasmodel_draw_outlines_spec].num_calls) { + instr = &alias_draw_instructions[aliasmodel_draw_outlines_spec]; + + R_TraceEnterNamedRegion("GLM_DrawOutlineBatch"); + R_SetAliasModelUniform(EZQ_ALIAS_MODE_OUTLINES_SPEC); + R_ProgramUniform1f(r_program_uniform_aliasmodel_outline_scale, bound(0.0, gl_outline_scale_model.value, 5.0)); + SETCOLORUNIFORM(color_model); + SETCOLORUNIFORM(color_team); + SETCOLORUNIFORM(color_enemy); + + R_ApplyRenderingState(r_state_aliasmodel_outline_spec); + for (i = 0; i < instr->num_calls; ++i) { + GL_MultiDrawArraysIndirect( + GL_TRIANGLES, + (const void*)(uintptr_t)(instr->indirect_buffer_offset + extra_offset), + instr->num_cmds[i], + 0 + ); + } + + R_TraceLeaveNamedRegion(); + } + + if (type == aliasmodel_draw_std && alias_draw_instructions[aliasmodel_draw_outlines].num_calls) { instr = &alias_draw_instructions[aliasmodel_draw_outlines]; R_TraceEnterNamedRegion("GLM_DrawOutlineBatch"); R_SetAliasModelUniform(EZQ_ALIAS_MODE_OUTLINES); R_ProgramUniform1f(r_program_uniform_aliasmodel_outline_scale, bound(0.0, gl_outline_scale_model.value, 5.0)); - R_ProgramUniform3f(r_program_uniform_aliasmodel_outline_color, - (float)gl_outline_color_model.color[0] / 255.0f, - (float)gl_outline_color_model.color[1] / 255.0f, - (float)gl_outline_color_model.color[2] / 255.0f); + SETCOLORUNIFORM(color_model); + SETCOLORUNIFORM(color_team); + SETCOLORUNIFORM(color_enemy); GLM_StateBeginAliasOutlineBatch(); @@ -514,6 +551,9 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) R_TraceLeaveNamedRegion(); } + + +#undef SETCOLORUNIFORM } void GLM_DrawAliasModelBatches(void) diff --git a/src/glsl/constants.glsl b/src/glsl/constants.glsl index 882f9925d..7556207fa 100644 --- a/src/glsl/constants.glsl +++ b/src/glsl/constants.glsl @@ -14,6 +14,9 @@ #define AMF_TEXTURE_MATERIAL 16 #define AMF_TEXTURE_LUMA 32 #define AMF_WEAPONMODEL 64 +#define AMF_PLAYERMODEL 128 +#define AMF_TEAMMATE 256 +#define AMF_BEHINDWALL 512 #define AMF_SHELLFLAGS (AMF_SHELLMODEL_RED | AMF_SHELLMODEL_BLUE | AMF_SHELLMODEL_GREEN) #define AM_VERTEX_NOLERP 1 // the alias model vertex should not be lerped, and always use lerpfraction 1 (meag: update shader if value no longer 1) @@ -50,9 +53,10 @@ #define EZQ_GL_BINDINGPOINT_FRAMECONSTANTS 0 // Alias models -#define EZQ_ALIAS_MODE_NORMAL 0 -#define EZQ_ALIAS_MODE_SHELLS 1 -#define EZQ_ALIAS_MODE_OUTLINES 2 +#define EZQ_ALIAS_MODE_NORMAL 0 +#define EZQ_ALIAS_MODE_SHELLS 1 +#define EZQ_ALIAS_MODE_OUTLINES 2 +#define EZQ_ALIAS_MODE_OUTLINES_SPEC 4 // 8x8 block #define HW_LIGHTING_BLOCK_SIZE 4 diff --git a/src/glsl/draw_aliasmodel.fragment.glsl b/src/glsl/draw_aliasmodel.fragment.glsl index 27e42f0cf..b98d7c37e 100644 --- a/src/glsl/draw_aliasmodel.fragment.glsl +++ b/src/glsl/draw_aliasmodel.fragment.glsl @@ -4,6 +4,8 @@ uniform int mode; uniform vec3 outline_color; +uniform vec3 outline_color_team; +uniform vec3 outline_color_enemy; #ifdef DRAW_CAUSTIC_TEXTURES layout(binding=SAMPLER_CAUSTIC_TEXTURE) uniform sampler2D causticsTex; @@ -26,9 +28,16 @@ out vec4 frag_colour; void main() { - frag_colour = vec4(outline_color, 1.0); + if((fsFlags & AMF_PLAYERMODEL) != 0) { + if ((fsFlags & AMF_TEAMMATE) != 0) + frag_colour = vec4(outline_color_team, 1.0f); + else + frag_colour = vec4(outline_color_enemy, 1.0f); + } else { + frag_colour = vec4(outline_color, 1.0f); + } - if (mode != EZQ_ALIAS_MODE_OUTLINES) { + if (mode != EZQ_ALIAS_MODE_OUTLINES && mode != EZQ_ALIAS_MODE_OUTLINES_SPEC) { vec4 tex = texture(samplers[fsMaterialSampler], fsTextureCoord.st); vec4 altTex = texture(samplers[fsMaterialSampler], fsAltTextureCoord.st); #ifdef DRAW_CAUSTIC_TEXTURES diff --git a/src/glsl/draw_aliasmodel.vertex.glsl b/src/glsl/draw_aliasmodel.vertex.glsl index ce5e0c3d0..40470d4b2 100644 --- a/src/glsl/draw_aliasmodel.vertex.glsl +++ b/src/glsl/draw_aliasmodel.vertex.glsl @@ -66,7 +66,7 @@ void main() fsBaseColor = models[_instanceId].color; } } - else if (mode == EZQ_ALIAS_MODE_OUTLINES) { + else if (mode == EZQ_ALIAS_MODE_OUTLINES || mode == EZQ_ALIAS_MODE_OUTLINES_SPEC) { gl_Position = projectionMatrix * models[_instanceId].modelView * vec4(position + models[_instanceId].outlineNormalScale * normalCoords * outline_scale, 1); } else { diff --git a/src/r_program.h b/src/r_program.h index 51d317699..49cb40202 100644 --- a/src/r_program.h +++ b/src/r_program.h @@ -112,7 +112,9 @@ typedef enum { r_program_uniform_outline_depth_threshold, r_program_uniform_outline_depth_scale, r_program_uniform_outline_scale, - r_program_uniform_aliasmodel_outline_color, + r_program_uniform_aliasmodel_outline_color_model, + r_program_uniform_aliasmodel_outline_color_team, + r_program_uniform_aliasmodel_outline_color_enemy, r_program_uniform_aliasmodel_outline_scale, r_program_uniform_count } r_program_uniform_id; diff --git a/src/r_rmain.c b/src/r_rmain.c index e1e17ec5c..b4173c4da 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -226,6 +226,10 @@ cvar_t gl_outline_scale_world = {"gl_outline_scale_world", "1.0"}; cvar_t gl_outline_scale_model = {"gl_outline_scale_model", "1.0"}; cvar_t gl_outline_world_depth_threshold = {"gl_outline_world_depth_threshold", "0.9"}; cvar_t gl_outline_world_depth_scale = {"gl_outline_world_depth_scale", "7.0"}; +cvar_t gl_outline_xray = {"gl_outline_xray", "0"}; +cvar_t gl_outline_xray_distance = {"gl_outline_xray_distance", "512"}; +cvar_t gl_outline_color_team = {"gl_outline_color_team", "0 255 0"}; +cvar_t gl_outline_color_enemy = {"gl_outline_color_enemy", "255 0 0"}; cvar_t gl_smoothmodels = {"gl_smoothmodels", "1"}; cvar_t gl_vbo_clientmemory = {"gl_vbo_clientmemory", "0", CVAR_LATCH_GFX }; @@ -709,6 +713,10 @@ void R_Init(void) Cvar_Register(&gl_outline_scale_model); Cvar_Register(&gl_outline_world_depth_threshold); Cvar_Register(&gl_outline_world_depth_scale); + Cvar_Register(&gl_outline_xray); + Cvar_Register(&gl_outline_xray_distance); + Cvar_Register(&gl_outline_color_team); + Cvar_Register(&gl_outline_color_enemy); Cvar_Register(&gl_smoothmodels); Cvar_Register(&gl_vbo_clientmemory); diff --git a/src/r_state.h b/src/r_state.h index 3a8483368..db62f4cb5 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -289,6 +289,7 @@ typedef enum { r_state_aliasmodel_shadows, r_state_aliasmodel_outline, + r_state_aliasmodel_outline_spec, r_state_weaponmodel_outline, r_state_aliasmodel_opaque_batch, diff --git a/src/r_states.c b/src/r_states.c index 60fd5f602..d8d03ff0c 100644 --- a/src/r_states.c +++ b/src/r_states.c @@ -293,6 +293,9 @@ static void R_InitialiseEntityStates(void) state->blendingEnabled = false; state->cullface.mode = r_cullface_back; + state = R_CopyRenderingState(r_state_aliasmodel_outline_spec, r_state_aliasmodel_outline, "aliasmodel-outline-spec"); + state->depth.test_enabled = false; + state = R_CopyRenderingState(r_state_weaponmodel_outline, r_state_aliasmodel_outline, "weaponmodel-outline"); state->depth.farRange = R_UseImmediateOpenGL() ? 0.3f : state->depth.farRange; diff --git a/src/render.h b/src/render.h index 8d503cf95..3ca36b1ee 100644 --- a/src/render.h +++ b/src/render.h @@ -42,6 +42,7 @@ typedef struct efrag_s { #define RF_ADDITIVEBLEND 128 #define RF_ROCKETPACK 256 #define RF_LGPACK 512 +#define RF_BEHINDWALL 1024 #define RF_BACKPACK_FLAGS (RF_ROCKETPACK | RF_LGPACK) From 116022bb881f4d14673d865a58d098433be92a0d Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Mon, 7 Aug 2023 20:36:27 +0200 Subject: [PATCH 14/26] outlines can use player color now + some cleanup --- src/cl_ents.c | 2 +- src/gl_program.c | 2 + src/glm_aliasmodel.c | 72 ++++++++++++++++++-------- src/glsl/common.glsl | 2 + src/glsl/draw_aliasmodel.fragment.glsl | 20 +++++-- src/glsl/draw_aliasmodel.vertex.glsl | 8 ++- src/r_program.h | 1 + src/r_rmain.c | 2 + src/r_states.c | 1 + 9 files changed, 80 insertions(+), 30 deletions(-) diff --git a/src/cl_ents.c b/src/cl_ents.c index e6f91795a..64ca1111a 100644 --- a/src/cl_ents.c +++ b/src/cl_ents.c @@ -1653,7 +1653,7 @@ static qbool CL_AddVWepModel (entity_t *ent, int vw_index, int old_vw_frame) newent.colormap = vid.colormap; newent.renderfx |= RF_PLAYERMODEL; // not really, but use same lighting rules newent.effects = ent->effects; // Electro - added for shells - // newent.scoreboard = ent->scoreboard; // for team color in gl_outline + newent.scoreboard = ent->scoreboard; // for team color in gl_outline if ((!cls.mvdplayback || Cam_TrackNum() >= 0) && cl.racing && !CL_SetAlphaByDistance(&newent)) { return false; diff --git a/src/gl_program.c b/src/gl_program.c index d1b6b6dc9..83cde7115 100644 --- a/src/gl_program.c +++ b/src/gl_program.c @@ -340,6 +340,8 @@ static r_program_uniform_t program_uniforms[] = { { r_program_aliasmodel, "outline_color_team", 1, false }, // r_program_uniform_aliasmodel_outline_color_enemy { r_program_aliasmodel, "outline_color_enemy", 1, false }, + // r_program_uniform_aliasmodel_outline_use_player_color + { r_program_aliasmodel, "outline_use_player_color", 1, false }, // r_program_uniform_aliasmodel_outline_scale { r_program_aliasmodel, "outline_scale", 1, false }, }; diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index 6409fe58c..f325b560f 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -82,6 +82,8 @@ typedef struct uniform_block_aliasmodel_s { float modelViewMatrix[16]; // offset: 16 * float float color[4]; + float plrtopcolor[4]; + float plrbotcolor[4]; int amFlags; float yaw_angle_rad; float shadelight; @@ -107,13 +109,48 @@ extern float r_framelerp; static uniform_block_aliasmodels_t aliasdata; static int cached_mode; +static float cached_scale; +static int cached_use_plr_color; +static float cached_color_model[3]; +static float cached_color_enemy[3]; +static float cached_color_team[3]; -static void R_SetAliasModelUniform(int mode) +static void R_SetAliasModelUniforms(int mode) { + extern cvar_t gl_outline_scale_model, gl_outline_use_player_color, + gl_outline_color_model, gl_outline_color_team, gl_outline_color_enemy; + float scale = bound(0.0, gl_outline_scale_model.value, 5.0); + int use_player_color = gl_outline_use_player_color.integer; + float color_model[3] = {(float)gl_outline_color_model.color[0] / 255.0f,(float)gl_outline_color_model.color[1] / 255.0f,(float)gl_outline_color_model.color[2] / 255.0f}; + float color_team[3] = {(float)gl_outline_color_team.color[0] / 255.0f,(float)gl_outline_color_team.color[1] / 255.0f,(float)gl_outline_color_team.color[2] / 255.0f}; + float color_enemy[3] = {(float)gl_outline_color_enemy.color[0] / 255.0f,(float)gl_outline_color_enemy.color[1] / 255.0f,(float)gl_outline_color_enemy.color[2] / 255.0f}; + if (cached_mode != mode) { R_ProgramUniform1i(r_program_uniform_aliasmodel_drawmode, mode); cached_mode = mode; } + + if(cached_scale != scale) { + R_ProgramUniform1f(r_program_uniform_aliasmodel_outline_scale, scale); + cached_scale = scale; + } + + if(cached_use_plr_color != use_player_color) { + R_ProgramUniform1i(r_program_uniform_aliasmodel_outline_use_player_color, use_player_color); + cached_use_plr_color = use_player_color; + } + if(!VectorCompare(cached_color_model, color_model)) { + R_ProgramUniform3fv(r_program_uniform_aliasmodel_outline_color_model, color_model); + VectorCopy(color_model, cached_color_model); + } + if(!VectorCompare(cached_color_enemy, color_enemy)) { + R_ProgramUniform3fv(r_program_uniform_aliasmodel_outline_color_enemy, color_enemy); + VectorCopy(color_enemy, cached_color_enemy); + } + if(!VectorCompare(cached_color_team, color_team)) { + R_ProgramUniform3fv(r_program_uniform_aliasmodel_outline_color_team, color_team); + VectorCopy(color_team, cached_color_team); + } } static int material_samplers_max; @@ -338,6 +375,14 @@ static void GLM_QueueAliasModelDrawImpl( uniform->materialSamplerMapping = textureSampler; uniform->minLumaMix = 1.0f - (ent->full_light ? bound(0, gl_fb_models.integer, 1) : 0); uniform->outline_normal_scale = ent->outlineScale; + if(ent->scoreboard != NULL) { + int tc = 16 * (bound(0, ent->scoreboard->topcolor, 13)) + 8; + int bc = 16 * (bound(0, ent->scoreboard->bottomcolor, 13)) + 8; + byte top[] = { host_basepal[tc * 3], host_basepal[tc * 3 + 1], host_basepal[tc * 3 + 2] }; + byte bot[] = { host_basepal[bc * 3], host_basepal[bc * 3 + 1], host_basepal[bc * 3 + 2] }; + for(int i = 0; i < 3; i++) uniform->plrtopcolor[i] = (float)top[i] / 256.0f; + for(int i = 0; i < 3; i++) uniform->plrbotcolor[i] = (float)bot[i] / 256.0f; + } // Add to queues GLM_QueueDrawCall(type, vbo_start, vbo_count, alias_draw_count); @@ -454,7 +499,6 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) qbool translucent = (type != aliasmodel_draw_std && type != aliasmodel_draw_postscene_additive); qbool additive = (type == aliasmodel_draw_postscene_additive); qbool shells = (type == aliasmodel_draw_shells || type == aliasmodel_draw_postscene_shells); - extern cvar_t gl_outline_color_model, gl_outline_scale_model, gl_outline_color_team, gl_outline_color_enemy; if (!instr->num_calls || !GLM_CompileAliasModelProgram()) { return; @@ -464,7 +508,7 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) extra_offset = buffers.BufferOffset(r_buffer_aliasmodel_drawcall_indirect); R_ProgramUse(r_program_aliasmodel); - R_SetAliasModelUniform(mode); + R_SetAliasModelUniforms(mode); // We have prepared the draw calls earlier in the frame so very trival logic here if (r_refdef2.drawCaustics) { renderer.TextureUnitBind(TEXTURE_UNIT_CAUSTICS, underwatertexture); @@ -499,20 +543,11 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) ); } -#define SETCOLORUNIFORM(colort) R_ProgramUniform3f(r_program_uniform_aliasmodel_outline_##colort,\ - (float)gl_outline_##colort.color[0] / 255.0f,\ - (float)gl_outline_##colort.color[1] / 255.0f,\ - (float)gl_outline_##colort.color[2] / 255.0f) - if (type == aliasmodel_draw_std && alias_draw_instructions[aliasmodel_draw_outlines_spec].num_calls) { instr = &alias_draw_instructions[aliasmodel_draw_outlines_spec]; R_TraceEnterNamedRegion("GLM_DrawOutlineBatch"); - R_SetAliasModelUniform(EZQ_ALIAS_MODE_OUTLINES_SPEC); - R_ProgramUniform1f(r_program_uniform_aliasmodel_outline_scale, bound(0.0, gl_outline_scale_model.value, 5.0)); - SETCOLORUNIFORM(color_model); - SETCOLORUNIFORM(color_team); - SETCOLORUNIFORM(color_enemy); + R_SetAliasModelUniforms(EZQ_ALIAS_MODE_OUTLINES_SPEC); R_ApplyRenderingState(r_state_aliasmodel_outline_spec); @@ -524,7 +559,6 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) 0 ); } - R_TraceLeaveNamedRegion(); } @@ -532,11 +566,7 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) instr = &alias_draw_instructions[aliasmodel_draw_outlines]; R_TraceEnterNamedRegion("GLM_DrawOutlineBatch"); - R_SetAliasModelUniform(EZQ_ALIAS_MODE_OUTLINES); - R_ProgramUniform1f(r_program_uniform_aliasmodel_outline_scale, bound(0.0, gl_outline_scale_model.value, 5.0)); - SETCOLORUNIFORM(color_model); - SETCOLORUNIFORM(color_team); - SETCOLORUNIFORM(color_enemy); + R_SetAliasModelUniforms(EZQ_ALIAS_MODE_OUTLINES); GLM_StateBeginAliasOutlineBatch(); @@ -548,12 +578,8 @@ static void GLM_RenderPreparedEntities(aliasmodel_draw_type_t type) 0 ); } - R_TraceLeaveNamedRegion(); } - - -#undef SETCOLORUNIFORM } void GLM_DrawAliasModelBatches(void) diff --git a/src/glsl/common.glsl b/src/glsl/common.glsl index ecb7e2cb2..5c3db54ab 100644 --- a/src/glsl/common.glsl +++ b/src/glsl/common.glsl @@ -97,6 +97,8 @@ struct AliasModelVert { struct AliasModel { mat4 modelView; vec4 color; + vec4 topcolor; + vec4 bottomcolor; int flags; float yaw_angle_rad; float shadelight; diff --git a/src/glsl/draw_aliasmodel.fragment.glsl b/src/glsl/draw_aliasmodel.fragment.glsl index b98d7c37e..136ea0d18 100644 --- a/src/glsl/draw_aliasmodel.fragment.glsl +++ b/src/glsl/draw_aliasmodel.fragment.glsl @@ -6,6 +6,7 @@ uniform int mode; uniform vec3 outline_color; uniform vec3 outline_color_team; uniform vec3 outline_color_enemy; +uniform int outline_use_player_color; #ifdef DRAW_CAUSTIC_TEXTURES layout(binding=SAMPLER_CAUSTIC_TEXTURE) uniform sampler2D causticsTex; @@ -23,16 +24,25 @@ flat in int fsFlags; flat in int fsTextureEnabled; flat in int fsMaterialSampler; flat in float fsMinLumaMix; +flat in vec4 plrtopcolor; +flat in vec4 plrbotcolor; out vec4 frag_colour; void main() { - if((fsFlags & AMF_PLAYERMODEL) != 0) { - if ((fsFlags & AMF_TEAMMATE) != 0) - frag_colour = vec4(outline_color_team, 1.0f); - else - frag_colour = vec4(outline_color_enemy, 1.0f); + if((fsFlags & AMF_PLAYERMODEL) != 0 && (fsFlags & AMF_WEAPONMODEL) == 0) { + if(outline_use_player_color != 0) { + if (fsTextureCoord.y > 0.5) + frag_colour = vec4(plrbotcolor.rgb, 1.0f); + else + frag_colour = vec4(plrtopcolor.rgb, 1.0f); + } else { + if((fsFlags & AMF_TEAMMATE) != 0) + frag_colour = vec4(outline_color_team, 1.0f); + else + frag_colour = vec4(outline_color_enemy, 1.0f); + } } else { frag_colour = vec4(outline_color, 1.0f); } diff --git a/src/glsl/draw_aliasmodel.vertex.glsl b/src/glsl/draw_aliasmodel.vertex.glsl index 40470d4b2..9711e9521 100644 --- a/src/glsl/draw_aliasmodel.vertex.glsl +++ b/src/glsl/draw_aliasmodel.vertex.glsl @@ -27,6 +27,8 @@ flat out int fsFlags; flat out int fsTextureEnabled; flat out int fsMaterialSampler; flat out float fsMinLumaMix; +flat out vec4 plrtopcolor; +flat out vec4 plrbotcolor; void main() { @@ -39,6 +41,9 @@ void main() fsFlags = models[_instanceId].flags; fsMinLumaMix = models[_instanceId].minLumaMix; + plrtopcolor = models[_instanceId].topcolor; + plrbotcolor = models[_instanceId].bottomcolor; + #ifdef EZQ_ALIASMODEL_MUZZLEHACK lerpFrac = sign(lerpFrac) * max(lerpFrac, (vboFlags & AM_VERTEX_NOLERP)); #endif @@ -67,7 +72,8 @@ void main() } } else if (mode == EZQ_ALIAS_MODE_OUTLINES || mode == EZQ_ALIAS_MODE_OUTLINES_SPEC) { - gl_Position = projectionMatrix * models[_instanceId].modelView * vec4(position + models[_instanceId].outlineNormalScale * normalCoords * outline_scale, 1); + gl_Position = projectionMatrix * models[_instanceId].modelView * vec4(position + /*models[_instanceId].outlineNormalScale **/ normalCoords * outline_scale, 1); + fsTextureCoord = vec2(tex.x, tex.y); } else { gl_Position = projectionMatrix * models[_instanceId].modelView * vec4(position + normalCoords * 0.5, 1); diff --git a/src/r_program.h b/src/r_program.h index 49cb40202..493d55c92 100644 --- a/src/r_program.h +++ b/src/r_program.h @@ -115,6 +115,7 @@ typedef enum { r_program_uniform_aliasmodel_outline_color_model, r_program_uniform_aliasmodel_outline_color_team, r_program_uniform_aliasmodel_outline_color_enemy, + r_program_uniform_aliasmodel_outline_use_player_color, r_program_uniform_aliasmodel_outline_scale, r_program_uniform_count } r_program_uniform_id; diff --git a/src/r_rmain.c b/src/r_rmain.c index b4173c4da..131bc118e 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -226,6 +226,7 @@ cvar_t gl_outline_scale_world = {"gl_outline_scale_world", "1.0"}; cvar_t gl_outline_scale_model = {"gl_outline_scale_model", "1.0"}; cvar_t gl_outline_world_depth_threshold = {"gl_outline_world_depth_threshold", "0.9"}; cvar_t gl_outline_world_depth_scale = {"gl_outline_world_depth_scale", "7.0"}; +cvar_t gl_outline_use_player_color = {"gl_outline_use_player_color", "0"}; cvar_t gl_outline_xray = {"gl_outline_xray", "0"}; cvar_t gl_outline_xray_distance = {"gl_outline_xray_distance", "512"}; cvar_t gl_outline_color_team = {"gl_outline_color_team", "0 255 0"}; @@ -713,6 +714,7 @@ void R_Init(void) Cvar_Register(&gl_outline_scale_model); Cvar_Register(&gl_outline_world_depth_threshold); Cvar_Register(&gl_outline_world_depth_scale); + Cvar_Register(&gl_outline_use_player_color); Cvar_Register(&gl_outline_xray); Cvar_Register(&gl_outline_xray_distance); Cvar_Register(&gl_outline_color_team); diff --git a/src/r_states.c b/src/r_states.c index d8d03ff0c..0bf48f0c1 100644 --- a/src/r_states.c +++ b/src/r_states.c @@ -294,6 +294,7 @@ static void R_InitialiseEntityStates(void) state->cullface.mode = r_cullface_back; state = R_CopyRenderingState(r_state_aliasmodel_outline_spec, r_state_aliasmodel_outline, "aliasmodel-outline-spec"); + state->cullface.mode = r_cullface_front; state->depth.test_enabled = false; state = R_CopyRenderingState(r_state_weaponmodel_outline, r_state_aliasmodel_outline, "weaponmodel-outline"); From 543f34048f012c2f482e63956c0a787b5892568c Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Mon, 7 Aug 2023 20:49:41 +0200 Subject: [PATCH 15/26] help texts + tweaks --- help_variables.json | 41 +++++++++++++++++++++++++++++++++++++++-- src/glm_aliasmodel.c | 11 ++++++++--- src/r_rmain.c | 6 ++++-- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/help_variables.json b/help_variables.json index 52d9323e2..fcebe565c 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5206,9 +5206,46 @@ "group-id": "35", "type": "float" }, - "gl_outline_world_accuracy": { + "gl_outline_world_depth_threshold": { "default": "0.9", - "desc": "Determines the accuracy for drawing world outlines. Effects are mainly visible on slopes and other angled surfaces.", + "desc": "Threshold for finding edges with depth values.", + "group-id": "35", + "type": "float" + }, + "gl_outline_world_depth_scale": { + "default": "7.0", + "desc": "Scaling factor for the depth threshold.", + "group-id": "35", + "type": "float" + }, + "gl_outline_use_player_color": { + "default": "0", + "desc": "Use the colors in the 'color' cvar for drawing player outlines", + "group-id": "35", + "type": "boolean" + }, + "gl_outline_color_team": { + "default": "", + "desc": "Determines the outline color of friendly players. Set to \"\" to disable.", + "group-id": "35", + "type": "string" + }, + "gl_outline_color_enemy": { + "default": "", + "desc": "Determines the outline color of enemy players. Set to \"\" to disable.", + "group-id": "35", + "type": "string" + }, + + "gl_outline_xray": { + "default": "0", + "desc": "See players through walls (spectator only, and not really an outline)", + "group-id": "35", + "type": "boolean" + }, + "gl_outline_xray_distance": { + "default": "512", + "desc": "Distance from which you can see the players through walls, see gl_outline_xray", "group-id": "35", "type": "float" }, diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index f325b560f..f5a030187 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -115,15 +115,18 @@ static float cached_color_model[3]; static float cached_color_enemy[3]; static float cached_color_team[3]; +#define GET_COLOR_VALUES(colr) (float[]){(float)gl_outline_color_##colr.color[0] / 255.0f,(float)gl_outline_color_##colr.color[1] / 255.0f,(float)gl_outline_color_##colr.color[2] / 255.0f} + static void R_SetAliasModelUniforms(int mode) { extern cvar_t gl_outline_scale_model, gl_outline_use_player_color, gl_outline_color_model, gl_outline_color_team, gl_outline_color_enemy; float scale = bound(0.0, gl_outline_scale_model.value, 5.0); + float *color_model, *color_enemy, *color_team; int use_player_color = gl_outline_use_player_color.integer; - float color_model[3] = {(float)gl_outline_color_model.color[0] / 255.0f,(float)gl_outline_color_model.color[1] / 255.0f,(float)gl_outline_color_model.color[2] / 255.0f}; - float color_team[3] = {(float)gl_outline_color_team.color[0] / 255.0f,(float)gl_outline_color_team.color[1] / 255.0f,(float)gl_outline_color_team.color[2] / 255.0f}; - float color_enemy[3] = {(float)gl_outline_color_enemy.color[0] / 255.0f,(float)gl_outline_color_enemy.color[1] / 255.0f,(float)gl_outline_color_enemy.color[2] / 255.0f}; + color_model = GET_COLOR_VALUES(model); + color_enemy = gl_outline_color_enemy.string[0] ? GET_COLOR_VALUES(enemy) : color_model; + color_team = gl_outline_color_team .string[0] ? GET_COLOR_VALUES(team) : color_model; if (cached_mode != mode) { R_ProgramUniform1i(r_program_uniform_aliasmodel_drawmode, mode); @@ -153,6 +156,8 @@ static void R_SetAliasModelUniforms(int mode) } } +#undef GET_COLOR_VALUES + static int material_samplers_max; static int TEXTURE_UNIT_MATERIAL; static int TEXTURE_UNIT_CAUSTICS; diff --git a/src/r_rmain.c b/src/r_rmain.c index 131bc118e..55bc5929f 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -219,6 +219,7 @@ cvar_t gl_simpleitems = {"gl_simpleitems", "0"}; cvar_t gl_simpleitems_size = {"gl_simpleitems_size", "16"}; cvar_t gl_simpleitems_orientation = {"gl_simpleitems_orientation", "2"}; cvar_t gl_modulate = {"gl_modulate", "1"}; + cvar_t gl_outline = {"gl_outline", "0"}; cvar_t gl_outline_color_world = {"gl_outline_color_world", "0 0 0"}; cvar_t gl_outline_color_model = {"gl_outline_color_model", "0 0 0"}; @@ -229,8 +230,9 @@ cvar_t gl_outline_world_depth_scale = {"gl_outline_world_depth_scale", "7 cvar_t gl_outline_use_player_color = {"gl_outline_use_player_color", "0"}; cvar_t gl_outline_xray = {"gl_outline_xray", "0"}; cvar_t gl_outline_xray_distance = {"gl_outline_xray_distance", "512"}; -cvar_t gl_outline_color_team = {"gl_outline_color_team", "0 255 0"}; -cvar_t gl_outline_color_enemy = {"gl_outline_color_enemy", "255 0 0"}; +cvar_t gl_outline_color_team = {"gl_outline_color_team", ""}; +cvar_t gl_outline_color_enemy = {"gl_outline_color_enemy", ""}; + cvar_t gl_smoothmodels = {"gl_smoothmodels", "1"}; cvar_t gl_vbo_clientmemory = {"gl_vbo_clientmemory", "0", CVAR_LATCH_GFX }; From 983d503cfa64983b9bd85ed4cf8ffae9adfee616 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Mon, 7 Aug 2023 21:16:15 +0200 Subject: [PATCH 16/26] fix alignment crap --- src/glm_local.h | 6 ++++-- src/glsl/common.glsl | 6 ++++-- src/glsl/fx_world_geometry.fragment.glsl | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/glm_local.h b/src/glm_local.h index 0eb97b129..5bc9a90de 100644 --- a/src/glm_local.h +++ b/src/glm_local.h @@ -70,9 +70,11 @@ typedef struct uniform_block_frame_constants_s { float skyFogMix; float fogMinZ; float fogMaxZ; - float padding; + // camangles [0] + + float camangles[3]; // [1] [2] + float padding[2]; - float camangles[3]; } uniform_block_frame_constants_t; #define MAX_WORLDMODEL_BATCH 64 diff --git a/src/glsl/common.glsl b/src/glsl/common.glsl index 5c3db54ab..dc1955711 100644 --- a/src/glsl/common.glsl +++ b/src/glsl/common.glsl @@ -67,9 +67,11 @@ layout(std140, binding=EZQ_GL_BINDINGPOINT_FRAMECONSTANTS) uniform GlobalState { float skyFogMix; float fogMinZ; float fogMaxZ; - float padding; + // camAngles.x - vec3 camAngles; + vec3 camAngles; // camAngles.yz + float padding1; + float padding2; }; struct WorldDrawInfo { diff --git a/src/glsl/fx_world_geometry.fragment.glsl b/src/glsl/fx_world_geometry.fragment.glsl index 72733a2e1..006e7e109 100644 --- a/src/glsl/fx_world_geometry.fragment.glsl +++ b/src/glsl/fx_world_geometry.fragment.glsl @@ -72,7 +72,7 @@ void main() float sp = sin(camAngles.x); float cy = cos(camAngles.y); float sy = sin(camAngles.y); - vec3 dir_fwd = { cp * cy, sy * cp, sp }; + vec3 dir_fwd = { cp * cy, -sp, sy * cp }; // make the depth threshold bigger the closer the surface to camera angle is to 90 degrees float ndv = 1.0f - dot(center.rgb, abs(dir_fwd)); From 42668e36195acfb0b28db912e257de15870da4af Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Mon, 7 Aug 2023 21:56:41 +0200 Subject: [PATCH 17/26] fix vwep model outlines and tweak bottomcolor alignment --- src/cl_ents.c | 3 +++ src/glm_aliasmodel.c | 3 ++- src/glsl/constants.glsl | 3 ++- src/glsl/draw_aliasmodel.fragment.glsl | 19 ++++++++++++++++--- src/render.h | 1 + 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/cl_ents.c b/src/cl_ents.c index 64ca1111a..9af20330b 100644 --- a/src/cl_ents.c +++ b/src/cl_ents.c @@ -1652,6 +1652,9 @@ static qbool CL_AddVWepModel (entity_t *ent, int vw_index, int old_vw_frame) newent.skinnum = 0; newent.colormap = vid.colormap; newent.renderfx |= RF_PLAYERMODEL; // not really, but use same lighting rules + newent.renderfx |= RF_VWEPMODEL; + if(ent->renderfx & RF_BEHINDWALL) + newent.renderfx |= RF_BEHINDWALL; newent.effects = ent->effects; // Electro - added for shells newent.scoreboard = ent->scoreboard; // for team color in gl_outline diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index f5a030187..1f227d1a5 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -368,7 +368,8 @@ static void GLM_QueueAliasModelDrawImpl( (render_effects & RF_WEAPONMODEL ? AMF_WEAPONMODEL : 0) | (ent->scoreboard != NULL ? ent->scoreboard->teammate ? AMF_TEAMMATE : 0 : 0) | (ent->renderfx & RF_BEHINDWALL ? AMF_BEHINDWALL : 0) | - (ent->renderfx & RF_PLAYERMODEL ? AMF_PLAYERMODEL : 0); + (ent->renderfx & RF_PLAYERMODEL ? AMF_PLAYERMODEL : 0) | + (ent->renderfx & RF_VWEPMODEL ? AMF_VWEPMODEL : 0); uniform->yaw_angle_rad = ent->angles[YAW] * M_PI / 180.0; uniform->shadelight = ent->shadelight; uniform->ambientlight = ent->ambientlight; diff --git a/src/glsl/constants.glsl b/src/glsl/constants.glsl index 7556207fa..c15ac890d 100644 --- a/src/glsl/constants.glsl +++ b/src/glsl/constants.glsl @@ -17,7 +17,8 @@ #define AMF_PLAYERMODEL 128 #define AMF_TEAMMATE 256 #define AMF_BEHINDWALL 512 -#define AMF_SHELLFLAGS (AMF_SHELLMODEL_RED | AMF_SHELLMODEL_BLUE | AMF_SHELLMODEL_GREEN) +#define AMF_VWEPMODEL 1024 +#define AMF_SHELLFLAGS (AMF_SHELLMODEL_RED | AMF_SHELLMODEL_BLUE | AMF_SHELLMODEL_GREEN) #define AM_VERTEX_NOLERP 1 // the alias model vertex should not be lerped, and always use lerpfraction 1 (meag: update shader if value no longer 1) #define AM_VERTEX_NORMALFIXED 2 // set after the alias model pose has been checked for matching vertices with different normals diff --git a/src/glsl/draw_aliasmodel.fragment.glsl b/src/glsl/draw_aliasmodel.fragment.glsl index 136ea0d18..df864e632 100644 --- a/src/glsl/draw_aliasmodel.fragment.glsl +++ b/src/glsl/draw_aliasmodel.fragment.glsl @@ -29,14 +29,27 @@ flat in vec4 plrbotcolor; out vec4 frag_colour; +bool texture_coord_is_on_legs() { + // both front and back legs at the same y level on the texture + if(fsTextureCoord.y >= 0.42 && fsTextureCoord.y <= 1) + /* front legs */ /* back legs */ + return fsTextureCoord.x >= 0.19 && fsTextureCoord.x <= 0.4 || fsTextureCoord.x >= 0.69 && fsTextureCoord.x <= 0.9; + + return false; +} + void main() { if((fsFlags & AMF_PLAYERMODEL) != 0 && (fsFlags & AMF_WEAPONMODEL) == 0) { if(outline_use_player_color != 0) { - if (fsTextureCoord.y > 0.5) - frag_colour = vec4(plrbotcolor.rgb, 1.0f); - else + if((fsFlags & AMF_VWEPMODEL) != 0) { // vwep model is top color frag_colour = vec4(plrtopcolor.rgb, 1.0f); + } else { + if (texture_coord_is_on_legs()) + frag_colour = vec4(plrbotcolor.rgb, 1.0f); + else + frag_colour = vec4(plrtopcolor.rgb, 1.0f); + } } else { if((fsFlags & AMF_TEAMMATE) != 0) frag_colour = vec4(outline_color_team, 1.0f); diff --git a/src/render.h b/src/render.h index 3ca36b1ee..90f6b89b3 100644 --- a/src/render.h +++ b/src/render.h @@ -43,6 +43,7 @@ typedef struct efrag_s { #define RF_ROCKETPACK 256 #define RF_LGPACK 512 #define RF_BEHINDWALL 1024 +#define RF_VWEPMODEL 2048 #define RF_BACKPACK_FLAGS (RF_ROCKETPACK | RF_LGPACK) From 72445c30ac6eaa5806c8eeb3b5d6bc06aa1e2771 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Tue, 8 Aug 2023 09:46:32 +0200 Subject: [PATCH 18/26] rename xray cvars, implement gl_spec_xray_distance --- help_variables.json | 11 +++++------ src/cl_ents.c | 19 ++++++++++++------- src/glm_aliasmodel.c | 6 +++--- src/r_rmain.c | 8 ++++---- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/help_variables.json b/help_variables.json index fcebe565c..2ae64010b 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5220,7 +5220,7 @@ }, "gl_outline_use_player_color": { "default": "0", - "desc": "Use the colors in the 'color' cvar for drawing player outlines", + "desc": "Use the top and bottom color for drawing player outlines", "group-id": "35", "type": "boolean" }, @@ -5236,16 +5236,15 @@ "group-id": "35", "type": "string" }, - - "gl_outline_xray": { + "gl_spec_xray": { "default": "0", - "desc": "See players through walls (spectator only, and not really an outline)", + "desc": "See players through walls (spectator only). Is affected by gl_outline_* values like color, scale, etc.", "group-id": "35", "type": "boolean" }, - "gl_outline_xray_distance": { + "gl_spec_xray_distance": { "default": "512", - "desc": "Distance from which you can see the players through walls, see gl_outline_xray", + "desc": "Distance from which you can see the players through walls, see gl_spec_xray", "group-id": "35", "type": "float" }, diff --git a/src/cl_ents.c b/src/cl_ents.c index 9af20330b..6272b15c7 100644 --- a/src/cl_ents.c +++ b/src/cl_ents.c @@ -1689,8 +1689,8 @@ void CL_StorePausePredictionLocations(void) static void CL_LinkPlayers(void) { int j, msec, i, flicker, oldphysent; - float *org; - vec3_t tmp; + float *org, distance; + vec3_t tmp, end, diff; double playertime = CL_PlayerTime(); player_info_t *info; player_state_t *state, exact; @@ -1699,7 +1699,7 @@ static void CL_LinkPlayers(void) frame_t *frame; trace_t trace; customlight_t cst_lt = {0}; - extern cvar_t cl_debug_antilag_ghost, cl_debug_antilag_view; + extern cvar_t cl_debug_antilag_ghost, cl_debug_antilag_view, gl_spec_xray_distance; frame = &cl.frames[cl.parsecount & UPDATE_MASK]; memset (&ent, 0, sizeof(entity_t)); @@ -1961,15 +1961,20 @@ static void CL_LinkPlayers(void) } } - vec3_t end; VectorCopy(cent->lerp_origin, end); end[2] += 12; trace = PM_TraceLine(r_refdef.vieworg, end); + if (trace.fraction != 1) { - ent.renderfx |= RF_BEHINDWALL; - } else { + VectorSubtract(cent->lerp_origin, r_refdef.vieworg, diff); + distance = VectorLength(diff); + + if(distance > gl_spec_xray_distance.value) + continue; + else + ent.renderfx |= RF_BEHINDWALL; + } else ent.renderfx &= ~RF_BEHINDWALL; - } if ((cl.vwep_enabled && r_drawvweps.value && state->vw_index) && (state->modelindex != cl_modelindices[mi_eyes])) { diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index 1f227d1a5..23290997a 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -312,7 +312,7 @@ static void GLM_QueueAliasModelDrawImpl( aliasmodel_draw_type_t shelltype = aliasmodel_draw_shells; aliasmodel_draw_instructions_t* instr; int textureSampler = -1; - extern cvar_t gl_outline_xray; + extern cvar_t gl_spec_xray; // Compile here so we can work out how many samplers we have free to allocate per draw-call if (!GLM_CompileAliasModelProgram()) { @@ -398,8 +398,8 @@ static void GLM_QueueAliasModelDrawImpl( if (shell) { GLM_QueueDrawCall(shelltype, vbo_start, vbo_count, alias_draw_count); } - if((render_effects & RF_PLAYERMODEL) && (render_effects & RF_BEHINDWALL) && - (cls.demoplayback || cl.spectator) && gl_outline_xray.value) + if((render_effects & RF_PLAYERMODEL) && (render_effects & RF_BEHINDWALL) && + (cls.demoplayback || cl.spectator) && gl_spec_xray.value) { GLM_QueueDrawCall(aliasmodel_draw_outlines_spec, vbo_start, vbo_count, alias_draw_count); } diff --git a/src/r_rmain.c b/src/r_rmain.c index 55bc5929f..abead903a 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -228,8 +228,8 @@ cvar_t gl_outline_scale_model = {"gl_outline_scale_model", "1.0"}; cvar_t gl_outline_world_depth_threshold = {"gl_outline_world_depth_threshold", "0.9"}; cvar_t gl_outline_world_depth_scale = {"gl_outline_world_depth_scale", "7.0"}; cvar_t gl_outline_use_player_color = {"gl_outline_use_player_color", "0"}; -cvar_t gl_outline_xray = {"gl_outline_xray", "0"}; -cvar_t gl_outline_xray_distance = {"gl_outline_xray_distance", "512"}; +cvar_t gl_spec_xray = {"gl_spec_xray", "0"}; +cvar_t gl_spec_xray_distance = {"gl_spec_xray_distance", "1500"}; cvar_t gl_outline_color_team = {"gl_outline_color_team", ""}; cvar_t gl_outline_color_enemy = {"gl_outline_color_enemy", ""}; @@ -717,8 +717,8 @@ void R_Init(void) Cvar_Register(&gl_outline_world_depth_threshold); Cvar_Register(&gl_outline_world_depth_scale); Cvar_Register(&gl_outline_use_player_color); - Cvar_Register(&gl_outline_xray); - Cvar_Register(&gl_outline_xray_distance); + Cvar_Register(&gl_spec_xray); + Cvar_Register(&gl_spec_xray_distance); Cvar_Register(&gl_outline_color_team); Cvar_Register(&gl_outline_color_enemy); Cvar_Register(&gl_smoothmodels); From 795d386dd82566eb8f8a1f6415157adbe00f62e6 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Tue, 8 Aug 2023 10:34:25 +0200 Subject: [PATCH 19/26] update help texts --- help_variables.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/help_variables.json b/help_variables.json index 2ae64010b..3606a9a56 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5197,12 +5197,14 @@ "gl_outline_color_model": { "default": "0 0 0", "desc": "Determines the color of model outlines.", + "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "string" }, "gl_outline_scale_model": { "default": "1", "desc": "Determines the scale of model outlines. Allows values 0 to 5.", + "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "float" }, @@ -5221,24 +5223,28 @@ "gl_outline_use_player_color": { "default": "0", "desc": "Use the top and bottom color for drawing player outlines", + "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "boolean" }, "gl_outline_color_team": { "default": "", "desc": "Determines the outline color of friendly players. Set to \"\" to disable.", + "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "string" }, "gl_outline_color_enemy": { "default": "", "desc": "Determines the outline color of enemy players. Set to \"\" to disable.", + "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "string" }, "gl_spec_xray": { "default": "0", "desc": "See players through walls (spectator only). Is affected by gl_outline_* values like color, scale, etc.", + "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "boolean" }, From 1f14508ef173cb6dfc5cf73d09460b73045f0858 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:36:57 +0200 Subject: [PATCH 20/26] limit model scale on smackdown and qcon, remove old world outline on the modern renderer --- help_variables.json | 8 ++-- src/glm_aliasmodel.c | 4 +- src/glm_local.h | 1 - src/glm_rsurf.c | 51 -------------------------- src/glm_state.c | 10 ----- src/glsl/draw_aliasmodel.fragment.glsl | 2 +- src/rulesets.c | 13 +++++++ src/rulesets.h | 1 + 8 files changed, 21 insertions(+), 69 deletions(-) diff --git a/help_variables.json b/help_variables.json index 3606a9a56..e2c67c722 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5167,7 +5167,7 @@ "default": "0", "desc": "Controls outlining of models and map. Disallowed in qcon ruleset.", "group-id": "35", - "remarks": "World outlines require vid_framebuffer 1|2 and Modern OpenGL (vid_renderer 1).", + "remarks": "World outlines require vid_framebuffer 1|2 and Modern OpenGL (vid_renderer 1). With vid_renderer 0, ruleset default and sv_cheats 1, gl_outline 2 draws outlines of every surface that is rendered.", "type": "enum", "values": [ { @@ -5203,7 +5203,7 @@ }, "gl_outline_scale_model": { "default": "1", - "desc": "Determines the scale of model outlines. Allows values 0 to 5.", + "desc": "Determines the scale of model outlines. Allows values 0 to 1 for rulesets smackdown and qcon, and 0 to 5 for other rulesets.", "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "float" @@ -5229,14 +5229,14 @@ }, "gl_outline_color_team": { "default": "", - "desc": "Determines the outline color of friendly players. Set to \"\" to disable.", + "desc": "Determines the outline color of friendly players. Set to \"\" to use the value of gl_outline_color_model.", "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "string" }, "gl_outline_color_enemy": { "default": "", - "desc": "Determines the outline color of enemy players. Set to \"\" to disable.", + "desc": "Determines the outline color of enemy players. Set to \"\" to use the value of gl_outline_color_model.", "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "string" diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index 23290997a..9a415f2a3 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -119,9 +119,9 @@ static float cached_color_team[3]; static void R_SetAliasModelUniforms(int mode) { - extern cvar_t gl_outline_scale_model, gl_outline_use_player_color, + extern cvar_t gl_outline_use_player_color, gl_outline_color_model, gl_outline_color_team, gl_outline_color_enemy; - float scale = bound(0.0, gl_outline_scale_model.value, 5.0); + float scale = RuleSets_ModelOutlineScale(); float *color_model, *color_enemy, *color_team; int use_player_color = gl_outline_use_player_color.integer; color_model = GET_COLOR_VALUES(model); diff --git a/src/glm_local.h b/src/glm_local.h index 5bc9a90de..64ab8cbce 100644 --- a/src/glm_local.h +++ b/src/glm_local.h @@ -117,7 +117,6 @@ void GLM_DrawAliasModelPostSceneBatches(void); void GLM_StateBeginPolyBlend(void); void GLM_StateBeginDraw3DSprites(void); -void GLM_StateBeginDrawWorldOutlines(void); void GLM_BeginDrawWorld(qbool alpha_surfaces, qbool polygon_offset); void GLM_UploadFrameConstants(void); diff --git a/src/glm_rsurf.c b/src/glm_rsurf.c index d74a94adb..0e4b66a89 100644 --- a/src/glm_rsurf.c +++ b/src/glm_rsurf.c @@ -579,53 +579,6 @@ qbool GLM_CompileSimple3dProgram(void) return R_ProgramReady(r_program_simple3d) && GLM_CompilePostProcessVAO(); } -static void GLM_DrawWorldModelOutlines(const glm_brushmodel_drawcall_t* drawcall) -{ - int begin = -1; - int i; - uintptr_t extra_offset = buffers.BufferOffset(r_buffer_brushmodel_drawcall_indirect); - float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - - if (!GLM_CompileSimple3dProgram()) { - return; - } - - // - GLM_StateBeginDrawWorldOutlines(); - R_ProgramUse(r_program_simple3d); - R_ProgramUniform4fv(r_program_uniform_simple3d_color, color); - - for (i = 0; i < drawcall->batch_count; ++i) { - if (!drawcall->worldmodel_requests[i].worldmodel) { - if (begin >= 0) { - // Draw outline models so far - GL_MultiDrawElementsIndirect( - GL_TRIANGLE_STRIP, - GL_UNSIGNED_INT, - (void*)(extra_offset + begin * sizeof(drawcall->worldmodel_requests[0])), - i - begin, - sizeof(drawcall->worldmodel_requests[0]) - ); - } - begin = -1; - continue; - } - else if (begin < 0) { - begin = i; - } - } - if (begin >= 0) { - // Draw the rest - GL_MultiDrawElementsIndirect( - GL_TRIANGLE_STRIP, - GL_UNSIGNED_INT, - (void*)(extra_offset + begin * sizeof(drawcall->worldmodel_requests[0])), - drawcall->batch_count - begin, - sizeof(drawcall->worldmodel_requests[0]) - ); - } -} - static glm_brushmodel_drawcall_t* GL_FlushWorldModelBatch(void) { const glm_brushmodel_drawcall_t* prev; @@ -790,10 +743,6 @@ void GLM_DrawWorldModelBatch(glm_brushmodel_drawcall_type type) GLM_DrawWorldExecuteCalls(drawcall, extra_offset + drawcall->indirectDrawOffset, 0, drawcall->batch_count); } - if (R_DrawWorldOutlines()) { - GLM_DrawWorldModelOutlines(drawcall); - } - R_TraceLeaveNamedRegion(); frameStats.subdraw_calls += drawcall->batch_count; diff --git a/src/glm_state.c b/src/glm_state.c index d62b9dad5..cac58c308 100644 --- a/src/glm_state.c +++ b/src/glm_state.c @@ -23,16 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "r_trace.h" #include "r_state.h" -void GLM_StateBeginDrawWorldOutlines(void) -{ - R_TraceEnterFunctionRegion; - - // FIXME: This was different for GLC & GLM, why? // disable depth-test - R_ApplyRenderingState(r_state_world_outline); - - R_TraceLeaveFunctionRegion; -} - void GLM_BeginDrawWorld(qbool alpha_surfaces, qbool polygon_offset) { if (alpha_surfaces && polygon_offset) { diff --git a/src/glsl/draw_aliasmodel.fragment.glsl b/src/glsl/draw_aliasmodel.fragment.glsl index df864e632..cf107180a 100644 --- a/src/glsl/draw_aliasmodel.fragment.glsl +++ b/src/glsl/draw_aliasmodel.fragment.glsl @@ -40,7 +40,7 @@ bool texture_coord_is_on_legs() { void main() { - if((fsFlags & AMF_PLAYERMODEL) != 0 && (fsFlags & AMF_WEAPONMODEL) == 0) { + if((fsFlags & AMF_PLAYERMODEL) != 0) { if(outline_use_player_color != 0) { if((fsFlags & AMF_VWEPMODEL) != 0) { // vwep model is top color frag_colour = vec4(plrtopcolor.rgb, 1.0f); diff --git a/src/rulesets.c b/src/rulesets.c index dcc3d5ba4..1a4c39b95 100644 --- a/src/rulesets.c +++ b/src/rulesets.c @@ -102,6 +102,19 @@ qbool RuleSets_DisallowModelOutline(struct model_s *mod) } } +// gl_outline_scale_model +// 0-1 for smackdown and qcon, 0-5 for others +float RuleSets_ModelOutlineScale(void) { + extern cvar_t gl_outline_scale_model; + switch(rulesetDef.ruleset) { + case rs_smackdown: + case rs_qcon: + return bound(0.0f, gl_outline_scale_model.value, 1.0f); + default: + return bound(0.0f, gl_outline_scale_model.value, 5.0f); + } +} + // for edges (gl_outline 2 and 3) qbool RuleSets_AllowEdgeOutline(void) { diff --git a/src/rulesets.h b/src/rulesets.h index 4ebe19a33..a09f56fb7 100644 --- a/src/rulesets.h +++ b/src/rulesets.h @@ -61,6 +61,7 @@ qbool Ruleset_BlockHudPicChange(void); qbool Ruleset_AllowPolygonOffset(entity_t* ent); qbool Rulesets_AllowAlternateModel(const char* modelName); qbool RuleSets_DisallowModelOutline(struct model_s *mod); +float RuleSets_ModelOutlineScale(void); qbool RuleSets_AllowEdgeOutline(void); qbool RuleSets_DisallowExternalTexture(struct model_s *mod); qbool Ruleset_IsLumaAllowed(struct model_s *mod); From 8844ef0ffab1e71447f955aece08ecfd309ef5be Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Wed, 9 Aug 2023 13:29:00 +0200 Subject: [PATCH 21/26] xray for qtv/demo only --- help_variables.json | 2 +- src/glm_aliasmodel.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/help_variables.json b/help_variables.json index e2c67c722..f43fc6dd4 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5243,7 +5243,7 @@ }, "gl_spec_xray": { "default": "0", - "desc": "See players through walls (spectator only). Is affected by gl_outline_* values like color, scale, etc.", + "desc": "See players through walls (demo/qtv only). Is affected by gl_outline_* values like color, scale, etc.", "remarks": "Requires vid_renderer 1", "group-id": "35", "type": "boolean" diff --git a/src/glm_aliasmodel.c b/src/glm_aliasmodel.c index 9a415f2a3..0a714113a 100644 --- a/src/glm_aliasmodel.c +++ b/src/glm_aliasmodel.c @@ -399,7 +399,7 @@ static void GLM_QueueAliasModelDrawImpl( GLM_QueueDrawCall(shelltype, vbo_start, vbo_count, alias_draw_count); } if((render_effects & RF_PLAYERMODEL) && (render_effects & RF_BEHINDWALL) && - (cls.demoplayback || cl.spectator) && gl_spec_xray.value) + (cls.demoplayback || cls.mvdplayback) && gl_spec_xray.value) { GLM_QueueDrawCall(aliasmodel_draw_outlines_spec, vbo_start, vbo_count, alias_draw_count); } From 7ac5082e34bd44ff5c8d8144f0bd2e54d692afac Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Wed, 9 Aug 2023 16:13:19 +0200 Subject: [PATCH 22/26] fix outlines drawing on sky textures --- src/glsl/draw_world.fragment.glsl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/glsl/draw_world.fragment.glsl b/src/glsl/draw_world.fragment.glsl index fc0c1b6b2..087adf054 100644 --- a/src/glsl/draw_world.fragment.glsl +++ b/src/glsl/draw_world.fragment.glsl @@ -97,7 +97,9 @@ void main() int turbType; #ifdef DRAW_GEOMETRY - normal_texture = vec4(Normal, abs(UnClipped.z / r_zFar)); // rgb = normal, a = depth + // depth of 0 means dont draw outlines + float depth = (Flags & TEXTURE_TURB_SKY) != 0 ? 0.0f : abs(UnClipped.z / r_zFar); + normal_texture = vec4(Normal, depth); #endif if (draw_outlines == 1) { From 58620b18630946600e94e7b1c914448b9d43f024 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Wed, 9 Aug 2023 17:58:27 +0200 Subject: [PATCH 23/26] fix player colors not working with r_drawvweps 0 --- src/cl_ents.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cl_ents.c b/src/cl_ents.c index 6272b15c7..7f0d151f8 100644 --- a/src/cl_ents.c +++ b/src/cl_ents.c @@ -1656,7 +1656,7 @@ static qbool CL_AddVWepModel (entity_t *ent, int vw_index, int old_vw_frame) if(ent->renderfx & RF_BEHINDWALL) newent.renderfx |= RF_BEHINDWALL; newent.effects = ent->effects; // Electro - added for shells - newent.scoreboard = ent->scoreboard; // for team color in gl_outline + newent.scoreboard = ent->scoreboard; // for team color in gl_outline FIXME: this changes the vwep model texture to the player if ((!cls.mvdplayback || Cam_TrackNum() >= 0) && cl.racing && !CL_SetAlphaByDistance(&newent)) { return false; @@ -1976,6 +1976,8 @@ static void CL_LinkPlayers(void) } else ent.renderfx &= ~RF_BEHINDWALL; + ent.renderfx |= RF_PLAYERMODEL; // FIXME: cheeck if this is used anywhere for something that r_drawvwep users only should/shoudlnt see + if ((cl.vwep_enabled && r_drawvweps.value && state->vw_index) && (state->modelindex != cl_modelindices[mi_eyes])) { qbool vwep; @@ -1985,7 +1987,6 @@ static void CL_LinkPlayers(void) if (cl.vw_model_name[0][0] != '-') { ent.model = cl.vw_model_precache[0]; - ent.renderfx |= RF_PLAYERMODEL; if (Cam_TrackNum() >= 0 && cl.racing) { CL_SetAlphaByDistance(&ent); } From f5477cf4724c4d2aa05e40f634fbc295bebe3d94 Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Wed, 9 Aug 2023 21:23:30 +0200 Subject: [PATCH 24/26] FIX VWEP HAVING A PLAYER TEXTURE --- src/cl_ents.c | 4 ++-- src/r_aliasmodel.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cl_ents.c b/src/cl_ents.c index 7f0d151f8..652372171 100644 --- a/src/cl_ents.c +++ b/src/cl_ents.c @@ -1656,7 +1656,7 @@ static qbool CL_AddVWepModel (entity_t *ent, int vw_index, int old_vw_frame) if(ent->renderfx & RF_BEHINDWALL) newent.renderfx |= RF_BEHINDWALL; newent.effects = ent->effects; // Electro - added for shells - newent.scoreboard = ent->scoreboard; // for team color in gl_outline FIXME: this changes the vwep model texture to the player + newent.scoreboard = ent->scoreboard; // for team color in gl_outline if ((!cls.mvdplayback || Cam_TrackNum() >= 0) && cl.racing && !CL_SetAlphaByDistance(&newent)) { return false; @@ -1976,7 +1976,7 @@ static void CL_LinkPlayers(void) } else ent.renderfx &= ~RF_BEHINDWALL; - ent.renderfx |= RF_PLAYERMODEL; // FIXME: cheeck if this is used anywhere for something that r_drawvwep users only should/shoudlnt see + ent.renderfx |= RF_PLAYERMODEL; if ((cl.vwep_enabled && r_drawvweps.value && state->vw_index) && (state->modelindex != cl_modelindices[mi_eyes])) { diff --git a/src/r_aliasmodel.c b/src/r_aliasmodel.c index 7dfa61a34..ad06c2a5b 100644 --- a/src/r_aliasmodel.c +++ b/src/r_aliasmodel.c @@ -264,7 +264,7 @@ void R_OverrideModelTextures(entity_t* ent, texture_ref* texture, texture_ref* f { int playernum = -1; - if (ent->scoreboard) { + if (ent->scoreboard && (ent->renderfx & RF_VWEPMODEL) == 0) { playernum = ent->scoreboard - cl.players; } From ef7396bd253e17d3aabca717b5fe1cbb2f076bfd Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:43:52 +0200 Subject: [PATCH 25/26] bring back the old shader because it was less annoying and remove world scale again --- help_variables.json | 10 +-- src/gl_program.c | 2 - src/glm_rmain.c | 6 +- src/glsl/draw_world.fragment.glsl | 5 +- src/glsl/fx_world_geometry.fragment.glsl | 84 +++++++----------------- src/r_program.h | 1 - src/r_rmain.c | 10 ++- 7 files changed, 34 insertions(+), 84 deletions(-) diff --git a/help_variables.json b/help_variables.json index f43fc6dd4..e38dbd429 100644 --- a/help_variables.json +++ b/help_variables.json @@ -5209,14 +5209,8 @@ "type": "float" }, "gl_outline_world_depth_threshold": { - "default": "0.9", - "desc": "Threshold for finding edges with depth values.", - "group-id": "35", - "type": "float" - }, - "gl_outline_world_depth_scale": { - "default": "7.0", - "desc": "Scaling factor for the depth threshold.", + "default": "4", + "desc": "Threshold for finding edges with depth values. Higher value means vanishing lines at close range. Lower value means false positives at longer range.", "group-id": "35", "type": "float" }, diff --git a/src/gl_program.c b/src/gl_program.c index 83cde7115..2e5fd244a 100644 --- a/src/gl_program.c +++ b/src/gl_program.c @@ -330,8 +330,6 @@ static r_program_uniform_t program_uniforms[] = { { r_program_fx_world_geometry, "outline_color", 1, false }, // r_program_uniform_outline_depth_threshold { r_program_fx_world_geometry, "outline_depth_threshold", 1, false }, - // r_program_uniform_outline_depth_scale - { r_program_fx_world_geometry, "outline_depth_scale", 1, false }, // r_program_uniform_outline_scale { r_program_fx_world_geometry, "outline_scale", 1, false }, // r_program_uniform_aliasmodel_outline_color_model diff --git a/src/glm_rmain.c b/src/glm_rmain.c index af6a0d1e4..8acd46d99 100644 --- a/src/glm_rmain.c +++ b/src/glm_rmain.c @@ -62,8 +62,7 @@ static void GLM_DrawWorldOutlines(void) if (R_TextureReferenceIsValid(normals) && GLM_CompileWorldGeometryProgram()) { int viewport[4]; int fullscreen_viewport[4]; - extern cvar_t gl_outline_color_world, gl_outline_scale_world, - gl_outline_world_depth_threshold, gl_outline_world_depth_scale; + extern cvar_t gl_outline_color_world, gl_outline_world_depth_threshold; //, gl_outline_scale_world; R_GetViewport(viewport); @@ -81,8 +80,7 @@ static void GLM_DrawWorldOutlines(void) renderer.TextureUnitBind(0, normals); R_ProgramUniform1f(r_program_uniform_outline_depth_threshold, gl_outline_world_depth_threshold.value); - R_ProgramUniform1f(r_program_uniform_outline_depth_scale, gl_outline_world_depth_scale.value); - R_ProgramUniform1f(r_program_uniform_outline_scale, gl_outline_scale_world.value); + // R_ProgramUniform1f(r_program_uniform_outline_scale, gl_outline_scale_world.value); R_ProgramUniform3f(r_program_uniform_outline_color, (float)gl_outline_color_world.color[0] / 255.0f, (float)gl_outline_color_world.color[1] / 255.0f, diff --git a/src/glsl/draw_world.fragment.glsl b/src/glsl/draw_world.fragment.glsl index 087adf054..e3f551cf8 100644 --- a/src/glsl/draw_world.fragment.glsl +++ b/src/glsl/draw_world.fragment.glsl @@ -97,8 +97,9 @@ void main() int turbType; #ifdef DRAW_GEOMETRY - // depth of 0 means dont draw outlines - float depth = (Flags & TEXTURE_TURB_SKY) != 0 ? 0.0f : abs(UnClipped.z / r_zFar); + int surface = Flags & EZQ_SURFACE_TYPE; + // if the texture is a turb, force outline between it and regular textures, but not between other turbs of the same type + float depth = (surface != 0) ? -float(surface) : abs(UnClipped.z / r_zFar); normal_texture = vec4(Normal, depth); #endif diff --git a/src/glsl/fx_world_geometry.fragment.glsl b/src/glsl/fx_world_geometry.fragment.glsl index 006e7e109..99e5ca473 100644 --- a/src/glsl/fx_world_geometry.fragment.glsl +++ b/src/glsl/fx_world_geometry.fragment.glsl @@ -1,7 +1,3 @@ -// fixme -// better edge of screen avoiding (the current one breaks when using a large outline scale) -// somehow scale the depth threshold with outline_scale also - #version 430 #ezquake-definitions @@ -11,79 +7,45 @@ layout(binding = 0) uniform sampler2D normal_texture; uniform vec3 outline_color; uniform float outline_scale; uniform float outline_depth_threshold; -uniform float outline_depth_scale; in vec2 TextureCoord; out vec4 frag_colour; void main() { - ivec2 coords = ivec2(TextureCoord.x * r_width, TextureCoord.y * r_height); vec4 center = texelFetch(normal_texture, coords, 0); + vec4 left = texelFetch(normal_texture, coords - ivec2(1, 0), 0); + vec4 right = texelFetch(normal_texture, coords + ivec2(1, 0), 0); + vec4 up = texelFetch(normal_texture, coords - ivec2(0, 1), 0); + vec4 down = texelFetch(normal_texture, coords + ivec2(0, 1), 0); - // avoid edges of screen - if(center.a == 0) - return; - - float hsc = int(ceil(outline_scale * 0.5f)); - float hsf = int(floor(outline_scale * 0.5f)); - - ivec2 bl = coords + ivec2(-hsf, -hsf); - ivec2 tr = coords + ivec2( hsc, hsc); - ivec2 br = coords + ivec2( hsc, -hsf); - ivec2 tl = coords + ivec2(-hsf, hsc); - - // depth values - float d0 = texelFetch(normal_texture, bl, 0).a; - float d1 = texelFetch(normal_texture, tr, 0).a; - float d2 = texelFetch(normal_texture, br, 0).a; - float d3 = texelFetch(normal_texture, tl, 0).a; - - // avoid edges of screen - if(d0 == 0.0f || d1 == 0.0f || d2 == 0.0f || d3 == 0.0f) - return; - - // normal values - vec3 n0 = texelFetch(normal_texture, bl, 0).rgb; - vec3 n1 = texelFetch(normal_texture, tr, 0).rgb; - vec3 n2 = texelFetch(normal_texture, br, 0).rgb; - vec3 n3 = texelFetch(normal_texture, tl, 0).rgb; + bool ignore = center.a == left.a && center.a == right.a && center.a == up.a && center.a == down.a; + if(ignore) + discard; - // normal difference - vec3 nd0 = n1 - n0; - vec3 nd1 = n3 - n2; - float en = sqrt(dot(nd0, nd0) + dot(nd1, nd1)); + if(center.a == 0) + discard; - if(en > 0.4f) { + if ((left.a != 0 && center.rgb != left.rgb ) || + (right.a != 0 && center.rgb != right.rgb) || + (up.a != 0 && center.rgb != up.rgb ) || + (down.a != 0 && center.rgb != down.rgb ) + ) { frag_colour.rgb = outline_color; frag_colour.a = 1; return; } - // depth differece - float dd0 = d1 - d0; - float dd1 = d3 - d2; - float ed = sqrt(dd0 * dd0 + dd1 * dd1) * 100.0f; - float dt = outline_depth_threshold * center.a; - - // camera direction - float cp = cos(camAngles.x); - float sp = sin(camAngles.x); - float cy = cos(camAngles.y); - float sy = sin(camAngles.y); - vec3 dir_fwd = { cp * cy, -sp, sy * cp }; + bool z_diff = r_zFar * abs((right.a - center.a) - (center.a - left.a)) > outline_depth_threshold; + bool z_diff2 = r_zFar * abs((down.a - center.a) - (center.a - up.a)) > outline_depth_threshold; - // make the depth threshold bigger the closer the surface to camera angle is to 90 degrees - float ndv = 1.0f - dot(center.rgb, abs(dir_fwd)); - float nt0 = clamp(abs(ndv), 0.0f, 1.0f); - float nt = nt0 * outline_depth_scale + 1.0f; - dt = dt * nt; - - if(ed > dt) { - frag_colour.rgb = outline_color; - frag_colour.a = 1; - } else { - frag_colour = vec4(0); + if (center.a != 0 && ( + (left.a != 0 && right.a != 0 && z_diff) || + (down.a != 0 && up.a != 0 && z_diff2) + )) { + frag_colour = vec4(outline_color, 1.0f); + return; } + frag_colour = vec4(0.0f); } diff --git a/src/r_program.h b/src/r_program.h index 493d55c92..0ee954dc3 100644 --- a/src/r_program.h +++ b/src/r_program.h @@ -110,7 +110,6 @@ typedef enum { r_program_uniform_sky_glc_fog_skyFogMix, r_program_uniform_outline_color, r_program_uniform_outline_depth_threshold, - r_program_uniform_outline_depth_scale, r_program_uniform_outline_scale, r_program_uniform_aliasmodel_outline_color_model, r_program_uniform_aliasmodel_outline_color_team, diff --git a/src/r_rmain.c b/src/r_rmain.c index abead903a..8b38a3083 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -223,10 +223,9 @@ cvar_t gl_modulate = {"gl_modulate", "1"}; cvar_t gl_outline = {"gl_outline", "0"}; cvar_t gl_outline_color_world = {"gl_outline_color_world", "0 0 0"}; cvar_t gl_outline_color_model = {"gl_outline_color_model", "0 0 0"}; -cvar_t gl_outline_scale_world = {"gl_outline_scale_world", "1.0"}; -cvar_t gl_outline_scale_model = {"gl_outline_scale_model", "1.0"}; -cvar_t gl_outline_world_depth_threshold = {"gl_outline_world_depth_threshold", "0.9"}; -cvar_t gl_outline_world_depth_scale = {"gl_outline_world_depth_scale", "7.0"}; +cvar_t gl_outline_scale_world = {"gl_outline_scale_world", "1"}; +cvar_t gl_outline_scale_model = {"gl_outline_scale_model", "1"}; +cvar_t gl_outline_world_depth_threshold = {"gl_outline_world_depth_threshold", "0.05"}; cvar_t gl_outline_use_player_color = {"gl_outline_use_player_color", "0"}; cvar_t gl_spec_xray = {"gl_spec_xray", "0"}; cvar_t gl_spec_xray_distance = {"gl_spec_xray_distance", "1500"}; @@ -712,10 +711,9 @@ void R_Init(void) Cvar_Register(&gl_outline); Cvar_Register(&gl_outline_color_world); Cvar_Register(&gl_outline_color_model); - Cvar_Register(&gl_outline_scale_world); + // Cvar_Register(&gl_outline_scale_world); Cvar_Register(&gl_outline_scale_model); Cvar_Register(&gl_outline_world_depth_threshold); - Cvar_Register(&gl_outline_world_depth_scale); Cvar_Register(&gl_outline_use_player_color); Cvar_Register(&gl_spec_xray); Cvar_Register(&gl_spec_xray_distance); From bc4cb0ddd366fbf67d28791515a92ceef6f44d7d Mon Sep 17 00:00:00 2001 From: krizej <60076189+krizej@users.noreply.github.com> Date: Sat, 19 Aug 2023 11:12:28 +0200 Subject: [PATCH 26/26] thanks ciscon --- src/r_rmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_rmain.c b/src/r_rmain.c index 8b38a3083..dec47ff34 100644 --- a/src/r_rmain.c +++ b/src/r_rmain.c @@ -225,7 +225,7 @@ cvar_t gl_outline_color_world = {"gl_outline_color_world", "0 0 0"} cvar_t gl_outline_color_model = {"gl_outline_color_model", "0 0 0"}; cvar_t gl_outline_scale_world = {"gl_outline_scale_world", "1"}; cvar_t gl_outline_scale_model = {"gl_outline_scale_model", "1"}; -cvar_t gl_outline_world_depth_threshold = {"gl_outline_world_depth_threshold", "0.05"}; +cvar_t gl_outline_world_depth_threshold = {"gl_outline_world_depth_threshold", "4"}; cvar_t gl_outline_use_player_color = {"gl_outline_use_player_color", "0"}; cvar_t gl_spec_xray = {"gl_spec_xray", "0"}; cvar_t gl_spec_xray_distance = {"gl_spec_xray_distance", "1500"};