|
group2 0.1.0
CSE 125 Group 2
|
Graphics-team's work-in-progress SDL3 GPU renderer. More...
#include <NewRenderer.hpp>
Public Member Functions | |
| bool | init (SDL_Window *window) |
| Initialise the GPU device, pipelines, and default scene assets. | |
| void | drawFrame (glm::vec3 eye, float yaw, float pitch, float roll) |
| Render one frame from the given camera pose. | |
| void | quit () |
| Release all GPU resources and shut down the renderer. | |
| SDL_GPUDevice * | getDevice () const |
| Returns the SDL GPU device. | |
| SDL_GPUShaderFormat | getShaderFormat () const |
| Shader format selected during init() (SPIR-V on Vulkan, MSL on Metal, DXIL on D3D12). | |
| const NewCamera & | getCamera () const |
| Current camera (updated every drawFrame call). | |
| int | modelCount () const |
| Number of models currently registered in the asset map. | |
| float | getLastAcquireMs () const |
| Most-recent SDL_AcquireGPUCommandBuffer cost in milliseconds. | |
| float | getLastRecordMs () const |
| Most-recent command-recording cost (between acquire and submit) in ms. | |
| float | getLastSubmitMs () const |
| Most-recent SDL_SubmitGPUCommandBuffer cost in milliseconds. | |
| void | setEntityRenderList (std::vector< EntityRenderCmd > &&entityList) |
| Set the list of entity render commands for this frame. | |
| void | setPointLights (std::vector< PointLight > pointLights) |
| Set dynamic point lights for this frame. | |
| void | setWeaponViewmodel (const WeaponViewmodel &vm) |
| Set the first-person weapon viewmodel for this frame. | |
| void | setModelEmissive (int32_t modelIdUnsanitized, glm::vec4 emissiveColor) |
| Override the emissive colour of every mesh in a registered model. | |
| void | setModelScenePass (int32_t modelIndex, bool drawInScene) |
| Toggle whether a model is drawn during the scene pass. | |
| SkinnedRenderer & | skinned () |
| Accessor for the skinned-character subsystem. | |
| const SkinnedRenderer & | skinned () const |
| int | loadSceneModel (const char *filename, glm::vec3 pos, float scale, bool flipUVs, const std::string &excludeNodesContaining="") |
| Load a model from disk and register it in Asset::models_ + create a default scene instance. | |
| void | setHudTexture (SDL_GPUTexture *hudTexture) |
| Set the HUD overlay texture to blit after the geometry pass. | |
| void | setParticleSystem (ParticleSystem *ps) |
| Register the particle system so the renderer can call its render hooks. | |
| bool | setVSync (bool enabled) |
| Enable or disable vertical sync. | |
| void | requestScreenshot (const std::string &path) |
| Request a screenshot to be saved to disk after the next frame. | |
| void | updateModelMeshVertices (int modelIndex, int meshIndex, const Vertex *vertices, Uint32 vertexCount) |
| Queue a vertex-buffer re-upload for one mesh of a loaded model. | |
| bool | loadHDRSkybox (const std::string &path) |
| Load an equirectangular HDR image as the environment skybox + IBL source. | |
| void | scanHDRFiles () |
| Scan the assets HDR directory and populate availableHDRFiles_. | |
| bool | setRig (const std::vector< RigMeshSource > &meshes, int numJoints) |
| void | setSkinnedFrame (const std::vector< glm::mat4 > &palette, const std::vector< SkinnedInstance > &instances) |
Static Public Member Functions | |
| static constexpr SDL_GPUTextureFormat | getHdrFormat () |
| Format of the HDR colour render target. | |
Public Attributes | |
| AAMode | aaMode = AAMode::SMAA_T2x |
| Anti-aliasing mode. Re-applied at the start of each frame. | |
| float | renderScale = 1.0f |
| Internal-resolution multiplier (0.5 = half-res, 2.0 = SSAA). | |
| float | mainHorizontalFovDegrees = 90.0f |
| Main camera horizontal field of view in degrees. | |
| float | scopeZoom = 1.0f |
| Per-frame scope zoom multiplier (FOV divisor). | |
| bool | imguiEnabled = true |
| Master toggle for the ImGui debug overlay. | |
| RenderToggles | toggles {} |
| Per-pass on/off toggles (see RenderToggles in RendererTypes.hpp). | |
| std::vector< std::string > | availableHDRFiles |
| Filled by scanHDRFiles(); consumed by debug UI. | |
| std::string | currentHDRName = "(procedural)" |
| Display name of the currently-loaded HDR. | |
| bool | useHDRSkybox = false |
| True after a successful loadHDRSkybox(). | |
Private Member Functions | |
| bool | createGeometryPipeline () |
| bool | createHudPipeline () |
| bool | ensureDepthTextureSize (Uint32 width, Uint32 height) |
| void | createMeshBuffers (MeshIdInt meshId) const |
| void | setMainCamera (glm::vec3 eye, float yaw, float pitch, float roll, Uint32 width, Uint32 height) |
| void | drawGeometryPass (SDL_GPUTexture *swapchain, SDL_GPUCommandBuffer *cmd) |
| void | drawUIPass (SDL_GPUTexture *swapchain, SDL_GPUCommandBuffer *cmd) |
| void | drawParticles (SDL_GPURenderPass *renderPass, SDL_GPUCommandBuffer *cmd) const |
| void | drawWeaponPass (SDL_GPUTexture *swapchain, SDL_GPUCommandBuffer *cmd) |
| void | drawWorldModelInstances (SDL_GPURenderPass *renderPass, SDL_GPUCommandBuffer *cmd) |
| void | drawWeapon (SDL_GPURenderPass *geometryPass, SDL_GPUCommandBuffer *cmd) |
| void | drawSkinnedModels (SDL_GPURenderPass *renderPass, SDL_GPUCommandBuffer *cmd) |
| void | drawModel (ModelIdInt modelId, const glm::mat4 &modelTransform, SDL_GPURenderPass *renderPass, SDL_GPUCommandBuffer *cmd) |
| void | drawEntityModels (SDL_GPURenderPass *renderPass, SDL_GPUCommandBuffer *cmd) |
| void | drawMesh (SDL_GPURenderPass *renderPass, const Asset::Mesh &mesh) const |
| void | drawHud (SDL_GPURenderPass *pass) |
Private Attributes | |
| SDL_Window * | window_ = nullptr |
| SDL_GPUDevice * | device_ = nullptr |
| SDL_GPUShaderFormat | shaderFormat_ = SDL_GPU_SHADERFORMAT_INVALID |
| SDL_GPUGraphicsPipeline * | geometryPipeline_ = nullptr |
| SDL_GPUGraphicsPipeline * | hudPipeline_ = nullptr |
| SDL_GPUGraphicsPipeline * | skinnedPipeline_ = nullptr |
| SDL_GPUTextureFormat | colorTarget_ |
| SDL_GPUDepthStencilTargetInfo | depthTarget_ {} |
| Uint32 | depthWidth_ = 0 |
| Uint32 | depthHeight_ = 0 |
| SDL_GPUTexture * | texture_ = nullptr |
| SDL_GPUSampler * | sampler_ = nullptr |
| SDL_GPUTexture * | hudTexture_ = nullptr |
| SDL_GPUSampler * | hudSampler_ = nullptr |
| NewCamera | camera_ |
| std::vector< EntityRenderCmd > | entities_ |
| WeaponViewmodel | weapon_ {} |
| std::vector< PointLight > | pointLights_ |
| ParticleSystem * | particleSystem_ = nullptr |
| bool | vsyncEnabled_ = true |
| std::string | pendingScreenshotPath_ |
| SkinnedRenderer | skinnedRenderer_ |
| float | lastAcquireMs_ = 0.0f |
| float | lastRecordMs_ = 0.0f |
| float | lastSubmitMs_ = 0.0f |
Graphics-team's work-in-progress SDL3 GPU renderer.
Pass architecture (target — current implementation only covers a subset): Pass 0 — Shadow map (depth-only directional, cascaded) [TODO] Pass 1 — Skybox (procedural / cubemap) [TODO] Pass 2 — Geometry (static models + entity models + weapon) [partial] Pass 3 — Skinned chars (instanced GPU LBS for players) [TODO] Pass 4 — Particles (delegated to ParticleSystem::render) [TODO] Pass 5 — Post (SSAO/bloom/SSR/volumetrics/tonemap) [TODO] Pass 6 — HUD + ImGui [partial]
Shaders: shaders-new/geometry.{vert,frag} + shaders-new/hud.{vert,frag}. Graphics team adds new shaders alongside these as features come online.
|
private |
|
private |
|
private |
|
private |
| void NewRenderer::drawFrame | ( | glm::vec3 | eye, |
| float | yaw, | ||
| float | pitch, | ||
| float | roll ) |
Render one frame from the given camera pose.
| eye | Camera world position. |
| yaw | Horizontal rotation in radians. |
| pitch | Vertical rotation in radians. |
| roll | Camera roll in radians (default 0). |
Reads all per-frame state previously captured by set*() calls. Game code is expected to call every relevant setter BEFORE calling drawFrame.
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
inlinenodiscard |
|
inlinenodiscard |
Returns the SDL GPU device.
Valid between init() and quit().
Used by sub-renderers (ParticleSystem, HudRenderer) and tests that need to allocate GPU resources on the same device.
|
inlinestaticnodiscardconstexpr |
Format of the HDR colour render target.
Sub-renderers that render INTO the main HDR pass (particles, beams, glow) must declare this as their pipeline's colour target format. Returning RGBA16F matches the legacy renderer; graphics team may change this if they pick a different intermediate format, BUT must update every sub-renderer pipeline to match.
|
inlinenodiscard |
Most-recent SDL_AcquireGPUCommandBuffer cost in milliseconds.
Captured by drawFrame(). Read by the debug HUD's frame-timing panel.
|
inlinenodiscard |
Most-recent command-recording cost (between acquire and submit) in ms.
|
inlinenodiscard |
Most-recent SDL_SubmitGPUCommandBuffer cost in milliseconds.
|
inlinenodiscard |
Shader format selected during init() (SPIR-V on Vulkan, MSL on Metal, DXIL on D3D12).
Sub-renderers consult this to pick the right precompiled shader binary.
| bool NewRenderer::init | ( | SDL_Window * | window | ) |
Initialise the GPU device, pipelines, and default scene assets.
| window | SDL window to render into. |
| bool NewRenderer::loadHDRSkybox | ( | const std::string & | path | ) |
Load an equirectangular HDR image as the environment skybox + IBL source.
| path | Absolute or assets-relative path to a .hdr file. |
IMPLEMENTATION: load via stb_image (float), upload as a 2D HDR texture, run an equirect→cubemap compute pass, derive the irradiance + prefilter cubemaps for IBL. Currently a no-op stub.
DATA SOURCE: debug UI's HDR picker — user selects from availableHDRFiles_.
| int NewRenderer::loadSceneModel | ( | const char * | filename, |
| glm::vec3 | pos, | ||
| float | scale, | ||
| bool | flipUVs, | ||
| const std::string & | excludeNodesContaining = "" ) |
Load a model from disk and register it in Asset::models_ + create a default scene instance.
| filename | Path under the assets dir. |
| pos | World position of the default scene instance. |
| scale | Uniform scale of the default scene instance. |
| flipUVs | True to flip V coordinate on import (glTF vs DCC convention). |
| excludeNodesContaining | (Unused on main today.) Substring filter to drop collision-only nodes. |
IMPLEMENTATION (real): delegates to AssetLoader::loadModel, then creates an Asset::ModelInstance at pos, then uploads mesh VB/IB. See cpp.
DATA SOURCE: Game.cpp's init phase, once per map asset.
|
nodiscard |
Number of models currently registered in the asset map.
Used by the debug UI to display loaded-model counts. Backed by Asset::models_, which is populated by loadSceneModel().
| void NewRenderer::quit | ( | ) |
Release all GPU resources and shut down the renderer.
| void NewRenderer::requestScreenshot | ( | const std::string & | path | ) |
Request a screenshot to be saved to disk after the next frame.
| path | Output file path (PNG). |
IMPLEMENTATION: after drawFrame's submit + present, read back the swapchain texture into a transfer buffer, map it CPU-side, write a PNG via stbi_write_png. Currently a no-op — pendingScreenshotPath_ is captured but not consumed.
DATA SOURCE: debug UI hotkey / console command.
| void NewRenderer::scanHDRFiles | ( | ) |
Scan the assets HDR directory and populate availableHDRFiles_.
IMPLEMENTATION: iterate assets/hdr/*.hdr via std::filesystem, fill the vector with the paths. Currently a no-op.
DATA SOURCE: called once at init; debug UI reads availableHDRFiles_ to populate its dropdown.
| void NewRenderer::setEntityRenderList | ( | std::vector< EntityRenderCmd > && | entityList | ) |
Set the list of entity render commands for this frame.
| entityList | One entry per visible static/dynamic entity. Moved-in. |
IMPLEMENTATION: Currently captures into entities_ and the existing drawEntityModels() loop draws them with the geometry pipeline. When adding lighting/tinting/material variation this is the call site whose data needs to surface in the shader.
DATA SOURCE: built in Game.cpp's draw-list builder from ECS view <Position, Velocity, Renderable, ...> per frame.
| void NewRenderer::setHudTexture | ( | SDL_GPUTexture * | hudTexture | ) |
Set the HUD overlay texture to blit after the geometry pass.
| hudTexture | HUD's final colour texture (RGBA8 swap-chain-format). May be null = no HUD. |
IMPLEMENTATION (real): captured into hudTexture_; drawHud() samples it in the UI pass. Sampling is linear repeat via hudSampler_.
DATA SOURCE: Hud::getOutputTexture() after Hud::draw() populates it.
|
private |
| void NewRenderer::setModelEmissive | ( | int32_t | modelIdUnsanitized, |
| glm::vec4 | emissiveColor ) |
Override the emissive colour of every mesh in a registered model.
| modelIdUnsanitized | Index returned by loadSceneModel/uploadSceneModel. |
| emissiveColor | RGB = emissive linear colour, A = ignored. |
IMPLEMENTATION: store overrides keyed by modelIndex in a map; consult the map when building per-mesh material UBOs inside drawModel(). Currently a no-op.
DATA SOURCE: Game.cpp uses this to pulse beam/cylinder/sphere glow (Game.cpp legacy: renderer.setModelEmissive(glowCylinderModelIdx_, ...)).
| void NewRenderer::setModelScenePass | ( | int32_t | modelIndex, |
| bool | drawInScene ) |
Toggle whether a model is drawn during the scene pass.
| modelIndex | Renderer-side handle. |
| drawInScene | true = draw as static world geometry; false = only via EntityRenderCmd. |
IMPLEMENTATION: sets Asset::ModelInstance::drawInScenePass on every instance backed by modelIndex. The scene-pass loop in drawWorldModelInstances already honours this flag.
DATA SOURCE: Game.cpp calls this once per static map asset right after loadSceneModel.
| void NewRenderer::setParticleSystem | ( | ParticleSystem * | ps | ) |
Register the particle system so the renderer can call its render hooks.
| ps | Pointer to ParticleSystem owned by Game. May be null = disable particles. |
IMPLEMENTATION: store in particleSystem_. During drawFrame, the renderer should call (in this order, inside the main HDR pass): ps->uploadToGpu(cmd); // BEFORE the render pass begins ps->render(pass, cmd); // INSIDE the HDR render pass Currently a no-op pointer-only stub.
DATA SOURCE: Game.cpp owns the ParticleSystem instance and registers it once after particleSystem.init(...) succeeds.
| void NewRenderer::setPointLights | ( | std::vector< PointLight > | pointLights | ) |
Set dynamic point lights for this frame.
| pointLights | Up to ~6 lights; renderer may cap silently. |
IMPLEMENTATION: store in pointLights_, then push as a UBO array to the PBR fragment shader during the geometry pass. Currently a no-op stub — pointLights_ is captured but never read.
DATA SOURCE: built in Game.cpp from ECS each frame (glow-emitting projectiles, muzzle flashes, etc).
| bool NewRenderer::setRig | ( | const std::vector< RigMeshSource > & | meshes, |
| int | numJoints ) |
| void NewRenderer::setSkinnedFrame | ( | const std::vector< glm::mat4 > & | palette, |
| const std::vector< SkinnedInstance > & | instances ) |
| bool NewRenderer::setVSync | ( | bool | enabled | ) |
Enable or disable vertical sync.
| enabled | True = VSync on (capped at refresh rate); false = uncapped. |
IMPLEMENTATION: call SDL_SetGPUSwapchainParameters with SDL_GPU_PRESENTMODE_VSYNC vs SDL_GPU_PRESENTMODE_IMMEDIATE (or MAILBOX for adaptive). Currently a no-op — stores vsyncEnabled_ but doesn't apply.
DATA SOURCE: Game.cpp toggles this when entering/leaving menus or via debug UI.
| void NewRenderer::setWeaponViewmodel | ( | const WeaponViewmodel & | vm | ) |
Set the first-person weapon viewmodel for this frame.
| vm | Model handle + viewmodel-space transform + visibility. |
IMPLEMENTATION: Captured into weapon_. drawWeapon() reads it and issues a draw call with the existing geometry pipeline. Note: the viewmodel is drawn LAST so it sits on top of the world (no depth fighting with map geometry near the camera).
DATA SOURCE: Game.cpp's runWeaponViewmodel() step, which composes the transform from camera state + recoil/sway curves.
|
inlinenodiscard |
Accessor for the skinned-character subsystem.
Use to register the shared rig once at startup, and to push the per- frame palette + instance arrays each frame. See SkinnedRenderer.hpp for the full API + data-flow notes.
|
inlinenodiscard |
| void NewRenderer::updateModelMeshVertices | ( | int | modelIndex, |
| int | meshIndex, | ||
| const Vertex * | vertices, | ||
| Uint32 | vertexCount ) |
Queue a vertex-buffer re-upload for one mesh of a loaded model.
| modelIndex | Renderer-side model handle. |
| meshIndex | Mesh index within that model. |
| vertices | New vertex data (caller retains ownership — copy if needed). |
| vertexCount | Number of vertices in vertices. |
IMPLEMENTATION: legacy used this for CPU-skinning entity meshes (now superseded by setSkinnedFrame). May not need to come back; leave as a no-op stub for API parity. If a use-case re-emerges, do the copy inside the next drawFrame's copy pass.
DATA SOURCE: legacy CPU LBS path (now defunct). No current call site.
| AAMode NewRenderer::aaMode = AAMode::SMAA_T2x |
Anti-aliasing mode. Re-applied at the start of each frame.
| std::vector<std::string> NewRenderer::availableHDRFiles |
Filled by scanHDRFiles(); consumed by debug UI.
|
private |
|
private |
| std::string NewRenderer::currentHDRName = "(procedural)" |
Display name of the currently-loaded HDR.
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
| bool NewRenderer::imguiEnabled = true |
Master toggle for the ImGui debug overlay.
|
private |
|
private |
|
private |
| float NewRenderer::mainHorizontalFovDegrees = 90.0f |
Main camera horizontal field of view in degrees.
|
private |
|
private |
|
private |
| float NewRenderer::renderScale = 1.0f |
Internal-resolution multiplier (0.5 = half-res, 2.0 = SSAA).
|
private |
| float NewRenderer::scopeZoom = 1.0f |
Per-frame scope zoom multiplier (FOV divisor).
1.0 = no zoom; 1.5 = ADS through the charge rifle scope (FOV/1.5). Game.cpp drives this each frame from the local player's ADS state.
|
private |
|
private |
|
private |
|
private |
| RenderToggles NewRenderer::toggles {} |
Per-pass on/off toggles (see RenderToggles in RendererTypes.hpp).
| bool NewRenderer::useHDRSkybox = false |
True after a successful loadHDRSkybox().
|
private |
|
private |
|
private |