Skip to content

unify(ww3d2): Merge dx8renderer, dx8rendererdebugger#2600

Merged
xezon merged 14 commits intoTheSuperHackers:mainfrom
stephanmeesters:unify/dx8renderer
Apr 16, 2026
Merged

unify(ww3d2): Merge dx8renderer, dx8rendererdebugger#2600
xezon merged 14 commits intoTheSuperHackers:mainfrom
stephanmeesters:unify/dx8renderer

Conversation

@stephanmeesters
Copy link
Copy Markdown

@stephanmeesters stephanmeesters commented Apr 14, 2026

Summary of additions/fixes added to Generals (AI generated):

Source Change
dx8rendererdebugger The DX8 renderer debugger was moved into Core/ so it can be shared.
dx8renderer Texture-stage handling was aligned with MeshMatDescClass.
dx8renderer Delayed procedural material-pass support was added for rigid meshes.
dx8renderer Delayed translucent passes are now rendered during the final flush.
dx8renderer Logging and renderer-debugger support were added.
dx8renderer A skin-container allocation leak was fixed.
dx8renderer Decal rendering was guarded against an empty visible-decal list.
dx8renderer Sorting criteria were updated for meshes with explicit sort levels.
dx8renderer Unregistering a mesh now also removes its gap filler.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 14, 2026

Greptile Summary

This PR moves dx8rendererdebugger to Core/ so it can be shared, aligns texture-stage loops to MeshMatDescClass::MAX_TEX_STAGES, adds a delayed procedural material-pass pipeline for rigid meshes (so translucent-only passes render after all base geometry), fixes a skin-container double-allocation, guards decal rendering against an empty list, updates sort-level criteria, and removes gap fillers on mesh unregister.

  • P1 — render state leak: In DX8TextureCategoryClass::Render(), D3DRS_NORMALIZENORMALS is set TRUE before the new debugger guard but reset FALSE inside it (lines 1862-1863 vs. 1929-1930). Any scaled mesh that the renderer debugger disables leaves the state dirty, corrupting lighting on all subsequent meshes.

Confidence Score: 4/5

Safe to merge after fixing the D3DRS_NORMALIZENORMALS state leak introduced by the new debugger guard.

One P1 finding: the NORMALIZENORMALS reset is now inside the new debugger if-block while the set remains outside, creating a dirty render state when the debug tool is active on a scaled mesh. All other changes (delayed pass infrastructure, decal guard, gap-filler cleanup, sort-level fix, texture stage alignment, file move) are correct and well-structured.

Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp — specifically the NORMALIZENORMALS state bracketing around the new debugger guard in DX8TextureCategoryClass::Render().

Important Files Changed

Filename Overview
Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp Major feature additions — delayed procedural pass system, debugger guard, decal null guard, gap-filler cleanup, sort-level fix. Contains a P1 render state leak: D3DRS_NORMALIZENORMALS is set TRUE before the new debugger if-block but reset FALSE inside it, leaving dirty state when a scaled mesh is disabled by the debugger.
Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.h Adds AnyDelayedPassesToRender flag, pure-virtual Add_Delayed_Visible_Material_Pass/Render_Delayed_Procedural_Material_Passes to the base class, implements them in Rigid and Skin containers, and switches texture array size to MeshMatDescClass::MAX_TEX_STAGES. Clean changes.
Core/Libraries/Source/WWVegas/WW3D2/dx8rendererdebugger.h Renamed/moved from GeneralsMD/ to Core/ with no content changes; uses #pragma once correctly.
Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt Enables dx8rendererdebugger.cpp/.h in the Core WW3D2 build by removing the comment-out markers.
GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt Comments out dx8rendererdebugger in the GeneralsMD local build now that it lives in Core/.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[DX8MeshRendererClass::Flush] --> B[Render rigid FVF containers]
    B --> C[DX8FVFCategoryContainer::Render]
    C --> D[Render visible texture categories]
    D --> E{Debugger enabled AND mesh disabled?}
    E -- No --> F[Render mesh: sorting or immediate]
    E -- Yes --> G[Skip mesh render]
    F --> H[Render_Procedural_Material_Passes]
    G --> H
    H --> I[Render skin FVF containers]
    I --> J[Render_Decal_Meshes guarded: early return if empty]
    J --> K[Render_FVF_Category_Container_List_Delayed_Passes NEW]
    K --> L[DX8RigidFVFCategoryContainer::Render_Delayed_Procedural_Material_Passes]
    L --> M[Clear vertex/index buffers]
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp
Line: 1869-1936

Comment:
**D3DRS_NORMALIZENORMALS state leak when debugger skips a mesh**

`D3DRS_NORMALIZENORMALS` is set to `TRUE` at line 1862-1863 (before the new debugger guard), but the corresponding reset to `FALSE` lives at lines 1929-1930 — inside the new `if (!DX8RendererDebugger::Is_Enabled() || !mesh->Is_Disabled_By_Debugger())` block. When the debugger is active and disables a mesh whose `ObjectScale != 1.0f`, the `FALSE` path is never reached, leaving the render state dirty for all subsequent meshes in the loop (causing their normals to be re-normalized, which visibly alters lighting/shading).

Move the `NORMALIZENORMALS` reset outside the debugger guard so it mirrors the unconditional set:

```cpp
if (!DX8RendererDebugger::Is_Enabled() || !mesh->Is_Disabled_By_Debugger()) {
    // ... existing render code ...
}
//--------------------------------------------------------------------
if (mesh->Get_ObjectScale() != 1.0f)
    DX8Wrapper::Set_DX8_Render_State(D3DRS_NORMALIZENORMALS, FALSE);
//--------------------------------------------------------------------
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (2): Last reviewed commit: "Remove empty line" | Re-trigger Greptile

@xezon
Copy link
Copy Markdown

xezon commented Apr 14, 2026

Merging and moving need to be at least 2 separate commits that go into main branch. Meaning it is not legal to squash and merge this change.

@stephanmeesters
Copy link
Copy Markdown
Author

stephanmeesters commented Apr 14, 2026

Merging and moving need to be at least 2 separate commits that go into main branch. Meaning it is not legal to squash and merge this change.

OK that did not happen with shdlib.h in #2499 unfortunately.

Do you want to split this into two PR's or shall I turn the it into two commits for merge by rebase (after review)?

@xezon
Copy link
Copy Markdown

xezon commented Apr 15, 2026

After looking more closely I see that the debugger files existed in ZH only. So moving them in one change is fine.

@xezon xezon added Gen Relates to Generals Unify Unifies code between Generals and Zero Hour labels Apr 16, 2026
Copy link
Copy Markdown

@xezon xezon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok.

Comment thread Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp Outdated
@xezon
Copy link
Copy Markdown

xezon commented Apr 16, 2026

greptile has raised 2 potential issues. Perhaps address them in a follow up change if necessary.

Comment thread Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp
@stephanmeesters
Copy link
Copy Markdown
Author

greptile has raised 2 potential issues. Perhaps address them in a follow up change if necessary.

See #2610

@xezon xezon merged commit 65e52a2 into TheSuperHackers:main Apr 16, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Gen Relates to Generals Unify Unifies code between Generals and Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants