4#include "EngineBuffers.h"
6#include "RenderTarget.h"
8#include "Services/Time.h"
9#include "Services/Random.h"
10#include "Systems/Core/LightSystem.h"
11#include "Systems/Core/FogSystem.h"
12#include "Systems/Core/EnvironmentSystem.h"
13#include "Tasks/RenderTask.h"
14#include "Systems/Core/CameraArraySystem.h"
16#include "Rendering/IBuffers.h"
17#include "Rendering/ICapabilities.h"
19void Cogs::Core::initializeEngineBuffers(IBuffers * buffers, ICapabilities* capabilites,
EngineBuffers & engineBuffers)
21 engineBuffers.viewBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
ViewBufferEntry) * 2, Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
22 engineBuffers.sceneBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
SceneParameters), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
23 engineBuffers.lightBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
LightBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
24 engineBuffers.objectBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
ObjectBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
25 engineBuffers.shadowBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
ShadowBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
27 engineBuffers.animationBuffer = buffers->loadBuffer(
nullptr,
sizeof(
AnimationBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
29 buffers->annotate(engineBuffers.sceneBufferHandle,
"Engine:SceneParameters");
30 buffers->annotate(engineBuffers.lightBufferHandle,
"Engine:LightBuffer");
31 buffers->annotate(engineBuffers.objectBufferHandle,
"Engine:ObjectBuffer");
32 buffers->annotate(engineBuffers.shadowBufferHandle,
"Engine:ShadowBuffer");
33 buffers->annotate(engineBuffers.animationBuffer,
"Engine::AnimationBuffer");
35 if (capabilites && capabilites->getDeviceCapabilities().ConstantBufferRange) {
36 uint32_t alignment = capabilites->getDeviceCapabilities().ConstantBufferOffsetAlignment;
37 assert(alignment && ((alignment & (alignment - 1)) == 0) &&
"Constant buffer alignment is not a power of two");
39 engineBuffers.objectBatch.stride = uint32_t((
sizeof(
ObjectBuffer) + (alignment - 1))) & ~(alignment - 1);
40 engineBuffers.objectBatch.count = 128;
41 engineBuffers.objectBatch.bufferHandle = buffers->loadBuffer(
nullptr, engineBuffers.objectBatch.stride * engineBuffers.objectBatch.count, Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
42 buffers->annotate(engineBuffers.objectBatch.bufferHandle,
"Engine:ObjectBatchBuffer");
44 engineBuffers.objectBatch.count = 0;
56 if (passOptions.multiViews && viewportData->cameraArray) {
58 const CameraArrayData& camArrData = context->cameraArraySystem->getData(camArrComp);
61 assert(camArrData.viewBuffer.size() == passOptions.multiViews);
65 deviceContext->
updateBuffer(viewBufferHandle, camArrData.viewBuffer.data(),
sizeof(camArrData.viewBuffer[0]) * camArrData.viewBuffer.size());
76 auto& random = taskContext->context->
random;
78 updateViewBuffer(taskContext->context, viewBufferHandle, viewportData);
81 auto& sceneParameters = engineBuffers.sceneParameters;
83 static std::uniform_int_distribution<uint32_t> dist(0, 63);
84 glm::uvec4 offset(dist(random->mt), dist(random->mt), viewportData->blueNoiseOffset);
85 sceneParameters.blueNoiseOffset = offset;
87 sceneParameters.projectionMatrix = viewportData->projectionMatrix;
88 sceneParameters.viewMatrix = viewportData->viewMatrix;
89 sceneParameters.inverseViewMatrix = viewportData->inverseViewMatrix;
90 sceneParameters.worldToClipMatrix = sceneParameters.projectionMatrix * sceneParameters.viewMatrix;
91 sceneParameters.inverseProjectionMatrix = viewportData->inverseProjectionMatrix;
92 sceneParameters.viewFromViewportMatrix = viewportData->viewFromViewportMatrix;
93 sceneParameters.viewportOrigin = viewportData->viewportOrigin;
94 sceneParameters.viewportSize = viewportData->viewportSize;
95 sceneParameters.viewportSizeRcp = 1.0f / viewportData->viewportSize;
98 if (viewportData->cameraArray && !passOptions.multiViews) {
100 const CameraArrayData& camArrData = taskContext->context->cameraArraySystem->getData(camArrComp);
101 const ViewBufferEntry &entry = camArrData.viewBuffer[renderTarget->depthLayerIndex];
102 sceneParameters.projectionMatrix = entry.clipFromView;
103 sceneParameters.worldToClipMatrix = entry.clipFromWorld;
104 sceneParameters.viewMatrix = entry.viewFromWorld;
105 sceneParameters.inverseProjectionMatrix = entry.viewFromClip;
106 sceneParameters.inverseViewMatrix = entry.worldFromView;
109 const bool reverseDepth = taskContext->context->
variables->get(
"renderer.reverseDepth",
false);
110 float depthClamp = viewportData->depthClamp;
112 depthClamp = 1.0f - depthClamp;
115 sceneParameters.shadowDepthClamp = 2.f * depthClamp - 1.f;
118 sceneParameters.shadowDepthClamp = depthClamp;
121 sceneParameters.animationTime =
static_cast<float>(taskContext->context->
time->getAnimationTime());
122 sceneParameters.exposure = viewportData->exposure;
124 const float aspect = viewportData->viewportSize.y == 0 ? 1.0f : viewportData->viewportSize.x / viewportData->viewportSize.y;
125 sceneParameters.projectionParameters.y = 2.0f * viewportData->nearDistance * glm::tan(0.5f * viewportData->fieldOfView);
126 sceneParameters.projectionParameters.x = aspect * sceneParameters.projectionParameters.y;
127 sceneParameters.projectionParameters.z = aspect;
128 sceneParameters.projectionParameters.w = viewportData->fieldOfView;
130 unsigned sceneFlags = 0;
131 if ((renderTarget == taskContext->defaultRenderTarget && taskContext->renderer->
getSettings().defaultRenderTargetExpectsSRGB) || renderTarget->expectsSRGB) {
132 sceneFlags |= COGS_SCENEFLAGS_OUTPUT_SRGB;
135 sceneFlags |= COGS_SCENEFLAGS_SUBMERGED;
137 sceneParameters.sceneFlags = sceneFlags;
138 sceneParameters.clientFlags = viewportData->clientFlags;
139 if (taskContext->context->environmentSystem) {
140 auto* envComp = taskContext->context->environmentSystem->getGlobalEnvironment();
142 auto& envData = taskContext->context->environmentSystem->getData(envComp);
143 sceneParameters.numEnvironmentIrradianceMips =
static_cast<float>(envData.irradianceLods);
144 sceneParameters.numEnvironmentRadianceMips =
static_cast<float>(envData.radianceLods);
148 static const std::array<glm::vec4, 6> noClipEquations = {
149 glm::vec4(0.f, 0.f, 0.f, 1.f), glm::vec4(0.f, 0.f, 0.f, 1.f),
150 glm::vec4(0.f, 0.f, 0.f, 1.f), glm::vec4(0.f, 0.f, 0.f, 1.f),
151 glm::vec4(0.f, 0.f, 0.f, 1.f), glm::vec4(0.f, 0.f, 0.f, 1.f)
153 std::memcpy(&sceneParameters.clippingPlanes, clipEquations ? clipEquations : &noClipEquations,
sizeof(std::array<glm::vec4, 6>));
155 taskContext->cameraData = viewportData;
170 LightSystem& lightSystem = *taskContext->context->lightSystem;
171 LightBuffer& lightParameters = engineBuffers.lightParameters;
172 lightParameters = {};
173 lightParameters.eyePosition = viewportData->inverseViewMatrix[3];
175 size_t numActiveLights = activeLights.lights.size();
176 for (
size_t i = 0; i < numActiveLights; i++) {
178 const LightData& lightData = lightSystem.getData(light);
179 lightParameters.lightPositions[i] = lightData.lightPosition;
180 lightParameters.lightDirections[i] = lightData.lightDirection;
181 lightParameters.lightColorIntensity[i] = lightData.lightColor;
182 lightParameters.lightColorIntensity[i].a = (light->
lightingLayer & viewportData->lightingMask) == 0 ? 0.f : light->
intensity;
183 lightParameters.lightParameters[i].r = lightData.shadowIntensityOffset;
184 lightParameters.lightParameters[i].a = light->
range;
186 lightParameters.numLights[0] =
static_cast<uint32_t
>(numActiveLights);
187 lightParameters.ambientColor = taskContext->renderer->
getSettings().ambientColor;
188 lightParameters.ambientIntensity = taskContext->renderer->
getSettings().ambientIntensity;
190 const FogComponent* globalFog = taskContext->context->fogSystem->getGlobalFog();
191 if (globalFog && globalFog->
enabled) {
192 lightParameters.fogEnabled = 1;
193 lightParameters.fogColor = globalFog->
color;
194 lightParameters.fogDistance = globalFog->
distance;
195 lightParameters.fogAmount = globalFog->
amount;
198 lightParameters.fogEnabled = 0;
202 lightParameters.seaFlags = 0;
203 lightParameters.flags = 0;
204 lightParameters.environmentBrightness = 1.0f;
205 lightParameters.skyMultiplier = 1.0f;
206 if (environmentComponent) {
207 lightParameters.environmentBrightness = environmentComponent->brightness;
208 lightParameters.skyMultiplier = environmentComponent->skyMultiplier;
209 lightParameters.flags = ((
HandleIsValid(environmentComponent->skyDome) ? 1 : 0) |
212 (
HandleIsValid(environmentComponent->subseaRadiance) ? 8 : 0) |
213 (
HandleIsValid(environmentComponent->ambientIrradiance) ? 16 : 0) |
216 if (environmentComponent->subseaSupport) {
217 lightParameters.seaFlags = environmentComponent->isSubmerged(viewportData);
218 if (lightParameters.seaFlags) {
219 lightParameters.fogEnabled = 2 + 4;
220 lightParameters.fogColor = glm::vec4(1, 0, 0, 1);
221 lightParameters.fogDistance = environmentComponent->subseaTurbidityDistance;
222 lightParameters.fogAmount = environmentComponent->subseaTurbidityAmount;
228 const glm::vec4 softShadowJitter[] = {
229 { -2.5f, -2.5f, 0.0f, 0.0f },
230 { -2.5f, -1.5f, -1.5f, 0.0f },
231 { -2.5f, -0.5f, 0.0f, -1.5f },
232 { -2.5f, 0.5f, 0.0f, 1.5f },
233 { -2.5f, 1.5f, 1.5f, 0.0f },
234 { -2.5f, 2.5f, -1.5f, -1.5f },
235 { -1.5f, -2.5f, -1.5f, 1.5f },
236 { -1.5f, -1.5f, 1.5f, -1.5f },
237 { -1.5f, -0.5f, 1.5f, 1.5f },
238 { -1.5f, 0.5f, 0.0f, 0.0f },
239 { -1.5f, 1.5f, 0.0f, 0.0f },
240 { -1.5f, 2.5f, 0.0f, 0.0f },
241 { -0.5f, -2.5f, 0.0f, 0.0f },
242 { -0.5f, -1.5f, 0.0f, 0.0f },
243 { -0.5f, -0.5f, 0.0f, 0.0f },
244 { -0.5f, 0.5f, 0.0f, 0.0f },
245 { -0.5f, 1.5f, 0.0f, 0.0f },
246 { -0.5f, 2.5f, 0.0f, 0.0f },
247 { 0.5f, -2.5f, 0.0f, 0.0f },
248 { 0.5f, -1.5f, 0.0f, 0.0f },
249 { 0.5f, -0.5f, 0.0f, 0.0f },
250 { 0.5f, 0.5f, 0.0f, 0.0f },
251 { 0.5f, 1.5f, 0.0f, 0.0f },
252 { 0.5f, 2.5f, 0.0f, 0.0f },
253 { 1.5f, -2.5f, 0.0f, 0.0f },
254 { 1.5f, -1.5f, 0.0f, 0.0f },
255 { 1.5f, -0.5f, 0.0f, 0.0f },
256 { 1.5f, 0.5f, 0.0f, 0.0f },
257 { 1.5f, 1.5f, 0.0f, 0.0f },
258 { 1.5f, 2.5f, 0.0f, 0.0f },
259 { 2.5f, -2.5f, 0.0f, 0.0f },
260 { 2.5f, -1.5f, 0.0f, 0.0f },
261 { 2.5f, -0.5f, 0.0f, 0.0f },
262 { 2.5f, 0.5f, 0.0f, 0.0f },
263 { 2.5f, 1.5f, 0.0f, 0.0f },
264 { 2.5f, 2.5f, 0.0f, 0.0f }
271 LightSystem& lightSystem = *taskContext->context->lightSystem;
273 ShadowBuffer& shadowParameters = engineBuffers.shadowBuffer;
274 shadowParameters = {};
275 static_assert(
sizeof(softShadowJitter) ==
sizeof(ShadowBuffer::softShadowJitter));
276 std::memcpy(&shadowParameters.softShadowJitter, &softShadowJitter,
sizeof(ShadowBuffer::softShadowJitter));
277 const bool reverseDepth = taskContext->context->
variables->get(
"renderer.reverseDepth",
false);
278 glm::mat4 viewportTransform;
279 switch (taskContext->device->
getType())
286 viewportTransform = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
287 0.0f, 0.5f, 0.0f, 0.0f,
288 0.0f, 0.0f, 0.5f, 0.0f,
289 0.5f, 0.5f, 0.5f, 1.0f);
293 viewportTransform = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
294 0.0f, 0.5f, 0.0f, 0.0f,
295 0.0f, 0.0f, 1.0f, 0.0f,
296 0.5f, 0.5f, 0.0f, 1.0f);
302 viewportTransform = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
303 0.0f, -0.5f, 0.0f, 0.0f,
304 0.0f, 0.0f, 1.0f, 0.0f,
305 0.5f, 0.5f, 0.0f, 1.0f);
310 for (
size_t i = 0; i < activeLights.numDirectionalShadowLights; i++) {
312 const LightData& lightData = lightSystem.getData(light);
313 shadowParameters.cascadeOffsets[i].x = lightData.arrayOffset;
314 ShadowData& shadow = shadowParameters.shadowData[i];
315 shadow.shadowsEnabled = lightData.enabled && lightData.castShadows;
316 shadow.texelSize = 1.f / lightData.textureSize;
317 shadow.cascadeLine = lightData.cascadeLine;
318 shadow.nearSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.nearDepths);
319 shadow.farSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.farDepths);
321 shadow.numCascades = lightData.numViewports;
322 for (
size_t k = 0; k < lightData.numViewports; k++) {
323 shadow.lightMatrix[k] = viewportTransform * lightData.lightCameraData[k].viewProjection;
327 for (
size_t i = 0; i < activeLights.numPointShadowLights; i++) {
328 size_t o = activeLights.numDirectionalShadowLights + activeLights.numDirectionalLights + i;
330 const LightData& lightData = lightSystem.getData(light);
332 shadowParameters.cascadeOffsets[o].x = lightData.arrayOffset / 6;
334 ShadowData& shadow = shadowParameters.shadowData[o];
335 shadow.shadowsEnabled = lightData.enabled && lightData.castShadows;
336 shadow.texelSize = 1.f / lightData.textureSize;
337 shadow.cascadeLine = lightData.cascadeLine;
338 shadow.nearSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.nearDepths);
339 shadow.farSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.farDepths);
341 shadow.numCascades = lightData.numViewports;
342 for (
size_t k = 0; k < lightData.numViewports; k++) {
343 shadow.lightMatrix[k] = viewportTransform * lightData.lightCameraData[k].viewProjection;
352 auto device = taskContext->renderer->
getDevice();
357 if (!viewportData)
return;
359 updateViewportBuffer(taskContext, engineBuffers.sceneBufferHandle, engineBuffers.viewBufferHandle, renderTarget, viewportData, clipEquations);
361 updateLightBuffer(taskContext, viewportData);
363 deviceContext->
updateBuffer(engineBuffers.lightBufferHandle, &engineBuffers.lightParameters,
sizeof(
LightBuffer));
366 updateShadowBuffer(taskContext);
Multi-view: Render a set of related views into array texture layers.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
class IRenderer * renderer
Renderer.
std::unique_ptr< class Random > random
Random Number service instance.
std::unique_ptr< class Variables > variables
Variables service instance.
std::unique_ptr< class Time > time
Time service instance.
Contains data to describe fog.
glm::vec4 color
Fog color.
float amount
Amount of fog to blend in.
float distance
Distance at which the fog is at its most dense.
bool enabled
If the fog should be enabled or disabled.
virtual IGraphicsDevice * getDevice()=0
Get the graphics device used by the renderer.
Defines a single light source and its behavior.
float intensity
Intensity of the light source.
float shadowSampleBias
Constant term shadow map sampling bias.
LightingLayers lightingLayer
The lighting layer the light belongs to.
float range
Falloff range.
Holds all LightComponent instances in the system.
ActiveLights & getActiveLights() override
Get the reference to the ActiveLights structure.
EngineBuffers & getEngineBuffers() override
Get the reference to the EngineBuffers structure.
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
const RenderSettings & getSettings() const override
Get the settings of the renderer.
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual ICapabilities * getCapabilities()=0
Get a pointer to the capability management interface used to query the graphics device capability fla...
virtual IContext * getImmediateContext()=0
Get a pointer to the immediate context used to issue commands to the graphics device.
virtual GraphicsDeviceType getType() const
Get the type of the graphics device.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ OpenGL20
Graphics device using OpenGL, supporting at least OpenGL 2.0.
ComponentType * resolveComponent() const
Contains data describing a Camera instance and its derived data structured such as matrix data and vi...
Defines calculated light data.
bool DepthNegativeOneToOne
If true, min z depth=-1 otherwise it is min z depth = 0 (max z depth = 1).
virtual const GraphicsDeviceCapabilities & getDeviceCapabilities() const
Gets the device capabilities in a structure.
Represents a graphics device context which can receive rendering commands.
virtual void updateBuffer(BufferHandle bufferHandle, const void *data, size_t size)=0
Replace contents of buffer with new data.