render map objects: decode compiled W3DMesh art, skin and draw over terrain
Read the buildings and props a map places from its compiled art (the uncompressed worldbuilder stream + embedded DDS textures): - ra3.models: BAB asset-stream parser (lazy slices), W3DMesh + D3DHierarchy decode, DDS (DXT1/3/5 + uncompressed) decode, per-mesh bone remap and bind-pose single-joint skinning, flattened to one world-space triangle soup. - ra3.map: parse the ObjectsList chunk into (type, x, y, z, angle). - ra3.terrain: render3d rasterises the scene over the raymarched terrain with a z-buffer; gpu_terrain carries the scene for the GPU backends. - ra3.vulkan: second pipeline + depth attachment, terrain.frag writes gl_FragDepth, and a small depth bias keeps ground decals from z-fighting. - objects.fx shaders (compiled to SPIR-V), embedded like scene/terrain. Only opaque parts are drawn: FX-light billboards (DefaultW3D.fx / BasicW3D.fx) and damage-fill shells (BuildingsGenericDamageFill.fx) are skipped, since the latter paint the wrecked interior (e.g. orange CBBuilding_Wood) over the shell. Ground-decal meshes with no diffuse role and the Road templates themselves are still not drawn.
This commit is contained in:
@@ -18,7 +18,7 @@ Ghidra.
|
||||
|
||||
## Status
|
||||
|
||||
OpenRA3 is at **v0.6.0**. The engine compiles and runs headless, and a **minimal
|
||||
OpenRA3 is at **v0.7.0**. The engine compiles and runs headless, and a **minimal
|
||||
skirmish** is playable: it reads a real multiplayer map out of your install,
|
||||
recovers the player start waypoints, and simulates two sides building a base,
|
||||
extracting ore and fighting until one side is wiped out. The balance is the
|
||||
@@ -31,7 +31,10 @@ software blit and null fallbacks; the backend is selectable from the in-game men
|
||||
and the software renderer still produces headless images. Terrain tiles
|
||||
cross-fade the way the retail `Terrain.fx` does (a per-cell blend ramp plus a
|
||||
gutter-padded atlas), so material boundaries are smooth instead of a grid of
|
||||
hard lines. An in-window **menu** lists the maps by their localized name and
|
||||
hard lines; the **buildings and props a map places** are decoded from the retail
|
||||
compiled `W3DMesh` art (the uncompressed `worldbuilder.bin` stream and its
|
||||
embedded DDS textures) and drawn with a depth test over the terrain. An
|
||||
in-window **menu** lists the maps by their localized name and
|
||||
exposes every render/skirmish option for tweaking before launch. The whole tree
|
||||
builds for **Linux** (clang + libc++) and cross-compiles to **Windows**
|
||||
(`openra3.exe` + `SDL3.dll`) with llvm-mingw — both using C++26 modules and
|
||||
@@ -93,6 +96,7 @@ built-in test map so the project still builds and runs in CI.
|
||||
| `src/map/ra3.map.cppm` | map catalog, `EAR`/RefPack unwrap, start waypoints, `gamestrings.csf` display names |
|
||||
| `src/skirmish/ra3.skirmish.cppm` | base building, economy, AI, combat, win condition |
|
||||
| `src/terrain/ra3.terrain.cppm` | `CkMp` terrain: `HeightMapData`, `BlendTileData` (tiles + blends), `Terrain.big` tiles |
|
||||
| `src/models/ra3.models.cppm` | compiled `W3DMesh` art (BAB stream + DDS textures) for the objects a map places |
|
||||
| `src/render/ra3.render.cppm` | ARGB framebuffer, TGA decode, BMP encode, map compositing, bitmap-font text |
|
||||
| `src/ui/ra3.ui.*.cppm` | SDL3 window viewer and menu (null backend when SDL3 is absent) |
|
||||
| `src/vulkan/ra3.vulkan.*.cppm` | Vulkan presentation backend and menu (null fallback without a loader) |
|
||||
@@ -290,9 +294,22 @@ textures from `Data\Terrain.big` (RefPack + TGA), and rasterises the map with an
|
||||
elevation shade. Each cell cross-fades into its blend neighbour with the same
|
||||
linear ramp the retail `Terrain.fx` uses, so material transitions are smooth; on
|
||||
the GPU path the tile atlas is padded with a replicated gutter so filtering
|
||||
never bleeds between tiles. Match state is overlaid (start markers in yellow,
|
||||
player 0 in blue, player 1 in red). `--thumbnail` uses the old `<map>_art.tga`
|
||||
overview instead.
|
||||
never bleeds between tiles. It also draws the **buildings and props the map
|
||||
places**: the `ObjectsList` chunk is decoded into `(type, position, angle)`
|
||||
instances, the type resolves to its compiled `W3DMesh` parts in the map's art
|
||||
stream (`Data\WBData.big`'s uncompressed `worldbuilder.bin`), the embedded DDS
|
||||
textures are decoded, bind-pose skinning places each mesh's bone-space vertices
|
||||
(`W3DHierarchy`), and the scene is flattened into one world-space triangle soup.
|
||||
The terrain raymarcher writes a depth value so the model pass depth-tests
|
||||
against the relief; the GPU path draws it in a second pipeline (shared camera
|
||||
basis, with a small depth bias so ground decals do not z-fight) and the software
|
||||
path rasterises it with a z-buffer. Match state is
|
||||
overlaid (start markers in yellow, player 0 in blue, player 1 in red).
|
||||
`--thumbnail` uses the old `<map>_art.tga` overview instead.
|
||||
|
||||
> **Not yet drawn:** the map's `Road` objects (the sidewalk/road segments that
|
||||
> reference a `Road` template rather than a mesh) need the retail road-network
|
||||
> mesher and are skipped; they are reported in the `objects: … missing` count.
|
||||
|
||||
**Offscreen image** (works anywhere, no display needed):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user