Skip to content

Commit

Permalink
[rtx] proper player shadows - rename flag to 'no_playershadow'
Browse files Browse the repository at this point in the history
use commandline arg `-no_playershadow` to disable player shadow casting
  • Loading branch information
xoxor4d committed Apr 7, 2024
1 parent a573d34 commit 5974331
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ or directly run `iw3xo.exe`
- `-no_default_sky` :: disable sky spawning (map settings)
- `-no_sun` :: disable sun spawning (map settings)
- `-no_fog` :: disable fog (map settings)
- `-no_playershadow` :: disable player shadow casting
- `-stock_effects` :: render effects using shaders
- `-old_anti_culling` :: use the old anti culling system
- `-no_forced_lod` :: do not set `r_forceLod` to `high` by default
Expand Down
Binary file modified assets-remix/main/xcommon_rtx.iwd
Binary file not shown.
28 changes: 14 additions & 14 deletions assets-remix/rtx.conf

Large diffs are not rendered by default.

Binary file modified assets-remix/zone/english/xcommon_rtx.ff
Binary file not shown.
80 changes: 75 additions & 5 deletions src/components/modules/rtx/rtx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ namespace components
rtx_lights::spawn_light();
rtx::force_dvars_on_frame();

if (flags::has_flag("thirdperson"))
/*if (flags::has_flag("thirdperson"))
{
rtx::player_origin_model();
}
}*/

rtx_gui::skysphere_frame();

Expand Down Expand Up @@ -104,11 +104,14 @@ namespace components

void post_scene_rendering_stub()
{
const auto dev = game::glob::d3d9_device;
const auto dev = game::get_device();

// disable fog before rendering UI (who wants foggy UI elements right?)
// ^ can happen if no skysphere is rendered, which is rendered last and thus disables fog for everything afterwards
dev->SetRenderState(D3DRS_FOGENABLE, FALSE);

// normally done in R_ToggleSmpFrame but should be fine here
rtx::textureOverrideCount = 0;
}

// stub at the beginning of 'RB_CallExecuteRenderCommands' (before UI)
Expand Down Expand Up @@ -278,7 +281,7 @@ namespace components
/**
* @brief spawns a little triangle at the origin of the player that is marked as 'player model body texture'
* - triangle then acts as the origin for the bounding box that culls meshes marked with the 'player model' category
* - not really working ..
* - not really working .. better technique below this func
*/
void rtx::player_origin_model()
{
Expand Down Expand Up @@ -321,6 +324,71 @@ namespace components
}
}

int R_AllocTextureOverride(game::Material* material, std::uint32_t model_index_mask, game::GfxImage* img1, int prev_override)
{
const auto override_idx = rtx::textureOverrideCount++;
if (override_idx < 256u)
{
rtx::textureOverrides[override_idx].material = material;
rtx::textureOverrides[override_idx].img1 = img1;
rtx::textureOverrides[override_idx].img2 = img1; //img2;
rtx::textureOverrides[override_idx].dobjModelMask = static_cast<std::uint16_t>(model_index_mask);
rtx::textureOverrides[override_idx].prev = static_cast<std::int16_t>(prev_override);
return override_idx;
}

//R_WarnOncePerFrame(R_WARN_TEXTURE_OVERRIDES, 256);
rtx::textureOverrideCount = 256;
return -1;
}

// this adds a unique material on the playermodel dobj and all of its submodels including the worldmodel of the gun
// textureoverride is then checked and set via rtx_fixed_function::apply_texture_overrides
int cg_player_add_obj_to_scene(const game::DObj_s* obj)
{
int tex_override = -1;

if (const auto material = game::Material_RegisterHandle("rtx_player_shadow", 3); material
&& material->textureTable
&& material->textureTable->u.image
&& material->textureTable->u.image->name
&& !std::string_view(material->textureTable->u.image->name)._Equal("default"))
{
std::uint16_t model_hash = 1337u;
for (auto i = 0u; i < static_cast<std::uint8_t>(obj->numModels); i++)
{
tex_override = R_AllocTextureOverride(material, model_hash, material->textureTable->u.image, /*material->textureTable[1].u.image,*/ i == 0 ? -1 : tex_override);
model_hash += 2;
}
}

return tex_override;
}

int m_cg_player_stub_helper = 0;
__declspec(naked) void cg_player_stub()
{
const static uint32_t retn_addr = 0x445478;
__asm
{
// og
mov ecx, [ebp + 0];

pushad;
push esi; // dobj
call cg_player_add_obj_to_scene;
mov m_cg_player_stub_helper, eax;
add esp, 4;
popad;

fild m_cg_player_stub_helper;
jmp retn_addr;
}
}


// *
// material related

void rtx::sky_material_update(std::string_view buffer, bool use_dvar)
{
Expand Down Expand Up @@ -1150,7 +1218,7 @@ namespace components
// hook beginning of 'RB_CallExecuteRenderCommands' (before UI)
utils::hook(0x6155E1, rb_call_execute_render_commands_stub, HOOK_JUMP).install()->quick();

if (flags::has_flag("thirdperson"))
if (!flags::has_flag("no_playershadow"))
{
// render third person model in first person
utils::hook::nop(0x42E187, 6); // CG_DrawFriendlyNames: do not disable name drawing
Expand All @@ -1164,6 +1232,8 @@ namespace components
utils::hook::set<BYTE>(0x456D36, 0xEB); // CG_AddPlayerWeapon: do not disable bolt effects
utils::hook::nop(0x457054, 6); // CG_AddViewWeapon: do not disable viewmodel
utils::hook::nop(0x451D8E, 2); // CG_UpdateThirdPerson: always enable "thirdperson"

utils::hook(0x445473, cg_player_stub, HOOK_JUMP).install()->quick(); // set unique texture for all parts of the model incl. gun
}

// un-cheat + saved flag for fx_enable
Expand Down
3 changes: 3 additions & 0 deletions src/components/modules/rtx/rtx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ namespace components
static inline auto loc_disable_entity_culling = 0u;


static inline std::uint16_t textureOverrideCount = 0;
static inline game::GfxTextureOverride textureOverrides[256] = {};


static inline std::vector rtx_disable_world_culling_enum = { "default", "less", "all", "all-but-models" };

Expand Down
26 changes: 25 additions & 1 deletion src/components/modules/rtx/rtx_fixed_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,27 @@ namespace components
out[2] = (static_cast<float>(static_cast<std::uint8_t>(packed->array[2])) * (1.0f / 127.0f) + -1.0f) * scale;
}

// overrides materials on specified meshes (rtx::R_AllocTextureOverride)
bool apply_texture_overrides(const game::GfxModelSkinnedSurface* surf, const game::GfxCmdBufSourceState* source, const game::GfxCmdBufState* state [[maybe_unused]] )
{
const auto dev = game::get_device();
if (surf && surf->info.gfxEntIndex)
{
if (const auto idx = static_cast<int>(source->input.data->gfxEnts[surf->info.gfxEntIndex].materialTime);
idx > 0 && idx < 256)
{
const auto mask = rtx::textureOverrides[idx].dobjModelMask;
if (mask != 0xffff && mask >= 1337 && mask < 1400 && rtx::textureOverrides[idx].img2)
{
dev->SetTexture(0, rtx::textureOverrides[idx].img2->texture.basemap);
return true;
}
}
}

return false;
}


// *
// static models (rigid)
Expand Down Expand Up @@ -355,7 +376,8 @@ namespace components
float mtx[4][4] = {};
rtx_fixed_function::build_worldmatrix_for_object(&mtx[0], model->placement.base.quat, model->placement.base.origin, model->placement.scale * custom_scalar);
dev->SetTransform(D3DTS_WORLD, reinterpret_cast<D3DMATRIX*>(&mtx));


apply_texture_overrides(&model->surf, source, state); // player shadow

if (dvars::r_showTess && dvars::r_showTess->current.enabled && dvars::r_showTess->current.integer <= 2)
{
Expand Down Expand Up @@ -507,6 +529,8 @@ namespace components
// vertex format
dev->SetFVF(MODEL_VERTEX_FORMAT);

apply_texture_overrides(skinned_surf, source, state); // player shadow

//transform model into the scene by updating the worldmatrix
float mtx[4][4] = {};
rtx_fixed_function::build_worldmatrix_for_object(&mtx[0], source->skinnedPlacement.base.quat, source->skinnedPlacement.base.origin, source->skinnedPlacement.scale);
Expand Down
8 changes: 8 additions & 0 deletions src/game/structs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7726,6 +7726,14 @@ namespace game
float dist;
};

struct GfxTextureOverride
{
Material* material;
GfxImage* img1;
GfxImage* img2;
std::uint16_t dobjModelMask;
std::int16_t prev;
};

#ifdef __cplusplus
}
Expand Down

0 comments on commit 5974331

Please sign in to comment.