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:
EnderTheCoder
2026-09-29 18:08:11 +08:00
parent 6e5df350c7
commit 70f35d8382
18 changed files with 2027 additions and 45 deletions
+15 -2
View File
@@ -255,6 +255,15 @@ target_sources(ra3_terrain PUBLIC FILE_SET CXX_MODULES FILES src/terrain/ra3.ter
target_link_libraries(ra3_terrain PUBLIC ra3_core ra3_fs ra3_render)
openra3_target_defaults(ra3_terrain)
# --- map static art (compiled W3D meshes) ------------------------------------
add_library(ra3_models STATIC)
target_sources(ra3_models PUBLIC FILE_SET CXX_MODULES FILES src/models/ra3.models.cppm)
target_link_libraries(ra3_models PUBLIC ra3_core ra3_fs ra3_render)
openra3_target_defaults(ra3_models)
# A map's terrain carries the objects placed on it (props/buildings).
target_link_libraries(ra3_terrain PUBLIC ra3_models)
# The presentation facade imports render + terrain (for the terrain capability).
target_link_libraries(ra3_client PUBLIC ra3_render ra3_terrain)
@@ -278,13 +287,17 @@ if(OPENRA3_HAS_VULKAN AND OPENRA3_HAS_SDL3)
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/scene.frag.spv"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/terrain.vert.spv"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/terrain.frag.spv"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/object.vert.spv"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/object.frag.spv"
)
# The blobs are read at configure time, so re-run CMake when they change.
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/scene.vert.spv"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/scene.frag.spv"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/terrain.vert.spv"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/terrain.frag.spv")
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/terrain.frag.spv"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/object.vert.spv"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/generated/object.frag.spv")
target_sources(ra3_vulkan PUBLIC FILE_SET CXX_MODULES FILES src/vulkan/ra3.vulkan.sdl.cppm)
target_include_directories(ra3_vulkan PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/generated")
target_link_libraries(ra3_vulkan PUBLIC ra3_core ra3_render ra3_terrain ra3_client openra3_sdl3 ra3_volk)
@@ -410,7 +423,7 @@ openra3_target_defaults(ra3_display)
# --- umbrella -----------------------------------------------------------------
add_library(ra3 STATIC)
target_sources(ra3 PUBLIC FILE_SET CXX_MODULES FILES src/ra3.cppm)
target_link_libraries(ra3 PUBLIC ra3_core ra3_logic ra3_client ra3_data ra3_game ra3_fs ra3_map ra3_skirmish ra3_render ra3_terrain ra3_display
target_link_libraries(ra3 PUBLIC ra3_core ra3_logic ra3_client ra3_data ra3_game ra3_fs ra3_map ra3_skirmish ra3_render ra3_terrain ra3_models ra3_display
ra3_ui ra3_vulkan ra3_dx ra3_wasmgl ra3_webgpu ra3_enderlog)
openra3_target_defaults(ra3)