group2 0.1.0
CSE 125 Group 2
Loading...
Searching...
No Matches
Renderer.hpp
Go to the documentation of this file.
1
3
4#pragma once
5
6#include "Camera.hpp"
7#include "IRenderer.hpp"
8#include "ModelLoader.hpp"
9#include "RendererTypes.hpp"
10
11#include <SDL3/SDL.h>
12
13#include <glm/glm.hpp>
14#include <glm/gtc/quaternion.hpp>
15#include <string>
16#include <vector>
17
18class ParticleSystem;
19
32
34class Renderer : public IRenderer
35{
36public:
39 [[nodiscard]] bool supports(RendererFeature /*feature*/) const override { return true; }
40
44 bool init(SDL_Window* window) override;
45
51 void drawFrame(glm::vec3 eye, float yaw, float pitch, float roll) override;
52
55 void requestScreenshot(const std::string& path) override;
56
60 bool setVSync(bool enabled) override;
61
63 void quit() override;
64
65 // Particle system integration
67 void setParticleSystem(ParticleSystem* ps) override { particleSystem = ps; }
68
70 [[nodiscard]] SDL_GPUDevice* getDevice() const override { return device; }
71
73 [[nodiscard]] const Camera& getCamera() const override { return camera; }
74
76 [[nodiscard]] SDL_GPUShaderFormat getShaderFormat() const override { return shaderFormat; }
77
79 [[nodiscard]] static constexpr SDL_GPUTextureFormat getHdrFormat()
80 {
81 return SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT;
82 }
83
84 // Entity rendering
86 void setEntityRenderList(std::vector<EntityRenderCmd> cmds) override { entityRenderCmds = std::move(cmds); }
87
92 void setPointLights(std::vector<PointLight> lights) override { pointLights = std::move(lights); }
93
98 void setModelEmissive(int modelIndex, glm::vec4 emissiveFactor) override
99 {
100 if (modelIndex >= 0 && static_cast<size_t>(modelIndex) < models.size())
101 for (auto& m : models[static_cast<size_t>(modelIndex)].meshes)
102 m.material.emissiveFactor = emissiveFactor;
103 }
104
106 void setWeaponViewmodel(const WeaponViewmodel& vm) override { weaponVM = vm; }
107
109 int loadSceneModel(const char* filename, glm::vec3 pos, float scale, bool flipUVs = false) override;
110
112 int uploadSceneModel(const LoadedModel& model) override;
113
122 void
123 updateModelMeshVertices(int modelIndex, int meshIndex, const ModelVertex* vertices, Uint32 vertexCount) override;
124
126 [[nodiscard]] int modelCount() const override { return static_cast<int>(models.size()); }
127
128 // HDR skybox
130 bool loadHDRSkybox(const std::string& path);
132 void scanHDRFiles();
134 std::vector<std::string> availableHDRFiles;
136 std::string currentHDRName = "(procedural)";
138 bool useHDRSkybox = false;
139
140private:
141 // Core GPU state
142 SDL_Window* window = nullptr;
143 SDL_GPUDevice* device = nullptr;
144 SDL_GPUTextureFormat swapchainFormat = SDL_GPU_TEXTUREFORMAT_INVALID;
145 SDL_GPUShaderFormat shaderFormat = SDL_GPU_SHADERFORMAT_INVALID;
146
147 Camera camera;
148
149 // Pipelines
150 SDL_GPUGraphicsPipeline* scenePipeline = nullptr;
151 SDL_GPUGraphicsPipeline* pbrPipeline = nullptr;
152 SDL_GPUGraphicsPipeline* pbrTransparentPipeline = nullptr;
153 SDL_GPUGraphicsPipeline* skyboxPipeline = nullptr;
154 SDL_GPUGraphicsPipeline* tonemapPipeline = nullptr;
155 SDL_GPUGraphicsPipeline* shadowPipeline = nullptr;
156 SDL_GPUGraphicsPipeline* sceneShadowPipeline = nullptr;
157
158 // Render targets
159 SDL_GPUTexture* depthTexture = nullptr;
160 SDL_GPUTexture* weaponDepthTexture = nullptr;
161 Uint32 depthWidth = 0;
162 Uint32 depthHeight = 0;
163
164 SDL_GPUTexture* hdrTarget = nullptr;
165 Uint32 hdrWidth = 0;
166 Uint32 hdrHeight = 0;
167
168 static constexpr int k_shadowCascades = 4;
169 static constexpr int k_shadowMapSize = 2048;
170 SDL_GPUTexture* shadowMap = nullptr;
171
172 // IBL textures (Phase 6)
173 SDL_GPUTexture* brdfLUT = nullptr;
174 SDL_GPUTexture* irradianceMap = nullptr;
175 SDL_GPUTexture* prefilterMap = nullptr;
176 SDL_GPUTexture* irradianceWorkMap = nullptr;
177 SDL_GPUTexture* prefilterWorkMap = nullptr;
178 SDL_GPUSampler* iblSampler = nullptr;
179 SDL_GPUTexture* envCubemap = nullptr;
180
181 // IBL compute pipelines (Phase 6) -- run once at startup, plus per HDR swap.
182 SDL_GPUComputePipeline* brdfLutPipeline = nullptr;
183 SDL_GPUComputePipeline* irradiancePipeline = nullptr;
184 SDL_GPUComputePipeline* prefilterPipeline = nullptr;
185
186 // Samplers
187 SDL_GPUSampler* pbrSampler = nullptr;
188 SDL_GPUSampler* shadowSampler = nullptr;
189 SDL_GPUSampler* tonemapSampler = nullptr;
190 SDL_GPUSampler* nearestDepthSampler = nullptr;
191
192 // Model rendering
193
195 struct GpuMesh
196 {
197 SDL_GPUBuffer* vertexBuffer = nullptr;
198 SDL_GPUBuffer* indexBuffer = nullptr;
199 Uint32 indexCount = 0;
200 int albedoTexIndex = -1;
201 int normalTexIndex = -1;
202 int metallicRoughnessTexIndex = -1;
203 int emissiveTexIndex = -1;
204 MaterialData material;
205 bool isTransparent = false;
206 };
207
209 struct ModelInstance
210 {
211 std::vector<GpuMesh> meshes;
212 std::vector<SDL_GPUTexture*> textures;
213 glm::mat4 transform{1.0f};
214 bool drawInScenePass = true;
215 };
216
217 std::vector<ModelInstance> models;
218
219 // Fallback 1x1 textures for missing PBR maps.
220 SDL_GPUTexture* fallbackWhite = nullptr;
221 SDL_GPUTexture* fallbackFlatNormal = nullptr;
222 SDL_GPUTexture* fallbackMR = nullptr;
223 SDL_GPUTexture* fallbackBlack = nullptr;
224
225 // Particle system
226 ParticleSystem* particleSystem = nullptr;
227
228 // Entity rendering
229 std::vector<EntityRenderCmd> entityRenderCmds;
230 std::vector<PointLight> pointLights;
231 WeaponViewmodel weaponVM;
232
233 // Deferred vertex re-uploads (skinned animation)
234 // Queued by updateModelMeshVertices(), flushed at the start of drawFrame()
235 // inside the main command buffer -- zero extra submits, zero pipeline stalls.
236
238 struct PendingVertexUpload
239 {
240 SDL_GPUBuffer* dstBuffer = nullptr;
241 std::vector<uint8_t> data;
242 };
243 std::vector<PendingVertexUpload> pendingVertexUploads;
244
245 SDL_GPUTransferBuffer* skinTransferBuf = nullptr;
246 Uint32 skinTransferBufSize = 0;
247
248 // Screen capture
249 SDL_GPUTexture* captureRT = nullptr;
250 Uint32 captureRTW = 0, captureRTH = 0;
251 SDL_GPUTextureFormat captureRTFmt = SDL_GPU_TEXTUREFORMAT_INVALID;
252 std::string pendingCapPath;
253
254 // Post-processing (Phases 7-12)
255 Uint32 postProcW = 0, postProcH = 0;
256
257 // Bloom (Phase 8)
258 static constexpr int k_bloomMips = 6;
259 SDL_GPUTexture* bloomMips[k_bloomMips] = {};
260 SDL_GPUComputePipeline* bloomDownsamplePipeline = nullptr;
261 SDL_GPUComputePipeline* bloomUpsamplePipeline = nullptr;
262
263 // SSAO (Phase 7)
264 SDL_GPUTexture* ssaoTexture = nullptr;
265 SDL_GPUTexture* ssaoBlurTexture = nullptr;
266 SDL_GPUComputePipeline* ssaoPipeline = nullptr;
267 SDL_GPUComputePipeline* ssaoBlurPipeline = nullptr;
268 SDL_GPUTexture* ssaoNoiseTexture = nullptr;
269
270 // SMAA + Temporal Resolve (replaces old TAA)
271 SDL_GPUGraphicsPipeline* smaaEdgePipeline = nullptr;
272 SDL_GPUGraphicsPipeline* smaaBlendPipeline = nullptr;
273 SDL_GPUGraphicsPipeline* smaaNeighborhoodPipeline =
274 nullptr;
275 SDL_GPUComputePipeline* smaaResolvePipeline = nullptr;
276 SDL_GPUTexture* smaaEdgeTex = nullptr;
277 SDL_GPUTexture* smaaBlendTex = nullptr;
278 SDL_GPUTexture* smaaOutputTex = nullptr;
279 SDL_GPUTexture* smaaAreaTex = nullptr;
280 SDL_GPUTexture* smaaSearchTex = nullptr;
281
282 // CAS (Contrast Adaptive Sharpening)
283 SDL_GPUComputePipeline* casPipeline = nullptr;
284 SDL_GPUTexture* casOutputTex = nullptr;
285
286 // Temporal history + motion vectors (reused from old TAA)
287 SDL_GPUTexture* taaHistory[2] = {};
288 int taaCurrentIdx = 0;
289 glm::mat4 previousVP{1.0f};
290 SDL_GPUTexture* motionVectorTexture = nullptr;
291 SDL_GPUComputePipeline* motionVectorPipeline = nullptr;
292
293 // Jitter
294 int frameIndex = 0;
295
296 // SSR (Phase 9) — ping-pong for temporal accumulation.
297 SDL_GPUTexture* ssrTexture[2] = {};
298 int ssrCurrentIdx = 0;
299 SDL_GPUComputePipeline* ssrPipeline = nullptr;
300
301public:
302 int ssrMode = 2;
304
305 // Anti-aliasing (live-tunable via ImGui)
307 bool casEnabled = true;
308 float casStrength = 1.0f;
309
310 // Sun / lighting (live-tunable via ImGui)
311 float sunAzimuth = 210.0f;
312 float sunElevation = 60.0f;
313 float sunIntensity = 3.0f;
314 float fillIntensity = 0.8f;
315 float ambientR = 0.08f, ambientG = 0.09f, ambientB = 0.12f;
316 float iblDiffuseIntensity = 1.0f;
321 float bloomStr = 0.3f;
322 float ssaoStr = 0.8f;
323 float ssaoRadius = 0.8f;
324 float ssaoFalloff = 2.0f;
325 float ssaoPower = 1.5f;
326 float ssrStr = 0.4f;
327 float volStr = 0.15f;
328 float sharpenStr = 0.6f;
329 float shadowBiasVal = 0.0005f;
331 float shadowDistance = 3000.0f;
332 float cascadeLambda = 0.92f;
333
336 [[nodiscard]] glm::vec3 getSunDirection() const;
337
338private:
339 // Volumetrics (Phase 10)
340 SDL_GPUTexture* volumetricTexture = nullptr;
341 SDL_GPUComputePipeline* volumetricPipeline = nullptr;
342
343 // OIT (Phase 12)
344 SDL_GPUTexture* oitAccumTexture = nullptr;
345 SDL_GPUTexture* oitRevealTexture = nullptr;
346 SDL_GPUGraphicsPipeline* oitPipeline = nullptr;
347 SDL_GPUGraphicsPipeline* oitResolvePipeline = nullptr;
348
349 // Private helpers
350 bool initScenePipeline();
351 bool initPBRPipeline();
352 bool initSkyboxPipeline();
353 bool initTonemapPipeline();
354 bool initShadowPipeline();
355 bool initSceneShadowPipeline();
356
357 bool initIBL();
358
366 bool regenerateIBLFromCubemap(SDL_GPUTexture* envCube);
367
368 bool initBloom();
369 bool initSSAO();
370 bool initSMAA();
371 bool initCAS();
372 bool initSSR();
373 bool initVolumetrics();
374
376 SDL_GPUComputePipeline* createComputePipeline(const char* shaderName,
377 Uint32 numSamplers,
378 Uint32 numReadonlyStorageTextures,
379 Uint32 numReadonlyStorageBuffers,
380 Uint32 numReadwriteStorageTextures,
381 Uint32 numReadwriteStorageBuffers,
382 Uint32 numUniformBuffers,
383 Uint32 threadCountX,
384 Uint32 threadCountY,
385 Uint32 threadCountZ);
387 bool ensureDepthTexture(Uint32 w, Uint32 h);
388
390 bool ensureHDRTarget(Uint32 w, Uint32 h);
391
393 bool ensureCaptureRT(Uint32 w, Uint32 h, SDL_GPUTextureFormat fmt);
394
396 bool uploadModel(const LoadedModel& model, ModelInstance& outInstance);
397
404 SDL_GPUTexture* uploadTexture(const uint8_t* pixels, int width, int height, bool sRGB = true);
405
407 void downloadAndSaveCapture(Uint32 w, Uint32 h);
408
410 SDL_GPUShader* loadShaderFromFile(const char* name,
411 SDL_GPUShaderStage stage,
412 Uint32 samplerCount,
413 Uint32 uniformBufferCount,
414 Uint32 storageBufferCount = 0,
415 Uint32 storageTextureCount = 0);
416};
Abstract renderer interface used by the hybrid dispatcher to route calls to either the legacy rendere...
RendererFeature
Stable identifiers for each dispatchable renderer method.
Definition IRenderer.hpp:31
Assimp-based model loading and CPU-side mesh/texture data types.
Shared data types used across renderer implementations.
AAMode
Anti-aliasing mode selection – exposed to ImGui.
Definition RendererTypes.hpp:13
@ SMAA_T2x
2-sample temporal + spatial SMAA (recommended).
Definition Camera.hpp:6
Abstract renderer contract.
Definition IRenderer.hpp:53
Top-level particle system orchestrator.
Definition ParticleSystem.hpp:35
Forward-declared to avoid circular includes.
Definition Renderer.hpp:35
float ambientB
PBR ambient color.
Definition Renderer.hpp:315
const Camera & getCamera() const override
Returns the current camera (updated every drawFrame call).
Definition Renderer.hpp:73
float sharpenStr
Post-TAA sharpening strength.
Definition Renderer.hpp:328
AAMode aaMode
Current AA mode (default: recommended T2x).
Definition Renderer.hpp:306
float sunElevation
Degrees above horizon (default 60° ≈ 11am).
Definition Renderer.hpp:312
bool casEnabled
CAS sharpening on/off.
Definition Renderer.hpp:307
float shadowNormalBiasVal
Definition Renderer.hpp:330
int uploadSceneModel(const LoadedModel &model) override
Upload a pre-built LoadedModel (e.g. from CharacterRig::templateLoadedModel()) and return its index.
Definition Renderer.cpp:3361
int modelCount() const override
Returns the number of loaded models.
Definition Renderer.hpp:126
float iblDiffuseIntensity
Multiplier on IBL diffuse term.
Definition Renderer.hpp:316
void setPointLights(std::vector< PointLight > lights) override
Set dynamic point lights for this frame.
Definition Renderer.hpp:92
void updateModelMeshVertices(int modelIndex, int meshIndex, const ModelVertex *vertices, Uint32 vertexCount) override
Queue a skinned vertex re-upload for one mesh of an animated model.
Definition Renderer.cpp:3376
bool loadHDRSkybox(const std::string &path)
Load an equirectangular HDR image as the environment skybox + IBL source.
Definition Renderer.cpp:1246
float ambientR
Definition Renderer.hpp:315
float shadowDistance
Max shadow range (world units).
Definition Renderer.hpp:331
float ssaoPower
AO power curve (1=linear, higher=softer).
Definition Renderer.hpp:325
bool setVSync(bool enabled) override
Enable or disable vertical sync.
Definition Renderer.cpp:3400
float ssaoRadius
GTAO world-space radius.
Definition Renderer.hpp:323
void drawFrame(glm::vec3 eye, float yaw, float pitch, float roll) override
Render one frame from the given camera pose.
Definition Renderer.cpp:2012
float casStrength
CAS sharpness (0.0 = minimal, 1.0 = max).
Definition Renderer.hpp:308
std::vector< std::string > availableHDRFiles
Available HDR file paths (populated by scanHDRFiles).
Definition Renderer.hpp:134
float ssaoStr
SSAO compositing strength.
Definition Renderer.hpp:322
float ssrStr
SSR compositing strength.
Definition Renderer.hpp:326
float ambientG
Definition Renderer.hpp:315
float iblSpecularIntensity
Multiplier on IBL specular term – default below 1.0 to tame the over-glossy / pseudo-metallic look di...
Definition Renderer.hpp:320
float sunIntensity
Primary directional light intensity.
Definition Renderer.hpp:313
void setModelEmissive(int modelIndex, glm::vec4 emissiveFactor) override
Update the emissive factor on every mesh of a loaded model.
Definition Renderer.hpp:98
std::string currentHDRName
Currently loaded HDR file (display name).
Definition Renderer.hpp:136
float fillIntensity
Fill/bounce light intensity.
Definition Renderer.hpp:314
float bloomStr
Bloom compositing strength.
Definition Renderer.hpp:321
SDL_GPUShaderFormat getShaderFormat() const override
Shader format selected during init() (SPIR-V or MSL).
Definition Renderer.hpp:76
void setParticleSystem(ParticleSystem *ps) override
Register a particle system to be rendered each frame (after scene, before ImGui).
Definition Renderer.hpp:67
static constexpr SDL_GPUTextureFormat getHdrFormat()
HDR render target format (RGBA16F). Particle pipelines must match this.
Definition Renderer.hpp:79
void scanHDRFiles()
Scan the assets HDR directory and populate availableHDRFiles.
Definition Renderer.cpp:1227
float volStr
Volumetric compositing strength.
Definition Renderer.hpp:327
RenderToggles toggles
Live-tunable feature toggles (checked every frame).
Definition Renderer.hpp:303
SDL_GPUDevice * getDevice() const override
Returns the SDL GPU device. Valid between init() and quit().
Definition Renderer.hpp:70
float shadowBiasVal
Definition Renderer.hpp:329
int ssrMode
0=Sharp, 1=Stochastic, 2=Masked (default).
Definition Renderer.hpp:302
float ssaoFalloff
GTAO distance falloff exponent.
Definition Renderer.hpp:324
float sunAzimuth
Degrees, 0=North, 90=East, 180=South (default ~SSW).
Definition Renderer.hpp:311
void setEntityRenderList(std::vector< EntityRenderCmd > cmds) override
Set the list of entity render commands for this frame.
Definition Renderer.hpp:86
void setWeaponViewmodel(const WeaponViewmodel &vm) override
Set the first-person weapon viewmodel for this frame.
Definition Renderer.hpp:106
float cascadeLambda
Log vs linear cascade split blend (0=linear, 1=log).
Definition Renderer.hpp:332
void quit() override
Release all GPU resources and shut down the renderer.
Definition Renderer.cpp:3416
glm::vec3 getSunDirection() const
Compute the sun direction (unit vector TO sun) from azimuth/elevation.
Definition Renderer.cpp:1870
bool useHDRSkybox
True when an HDR cubemap is loaded and should be used for skybox + IBL.
Definition Renderer.hpp:138
bool init(SDL_Window *window) override
Initialise the GPU device, pipelines, and default scene assets.
Definition Renderer.cpp:1600
int loadSceneModel(const char *filename, glm::vec3 pos, float scale, bool flipUVs=false) override
Load a model and return its index in the models[] vector, or -1 on failure.
Definition Renderer.cpp:3292
bool supports(RendererFeature) const override
Report which RendererFeature entries this renderer implements.
Definition Renderer.hpp:39
void requestScreenshot(const std::string &path) override
Queue a screenshot to be saved after the next frame.
Definition Renderer.cpp:3395
Everything returned by loadModel().
Definition ModelLoader.hpp:76
PBR material scalar parameters extracted from Assimp/glTF.
Definition ModelLoader.hpp:41
One vertex in a loaded 3-D model (PBR-ready).
Definition ModelLoader.hpp:19
Live toggles for every render system – exposed to ImGui.
Definition RendererTypes.hpp:24
First-person weapon viewmodel descriptor sent per frame.
Definition RendererTypes.hpp:65