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.sceneBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
SceneBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
22 engineBuffers.viewBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
ViewBufferEntry) * 2, Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
23 engineBuffers.objectBufferHandle = buffers->loadBuffer(
nullptr,
sizeof(
ObjectBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
24 engineBuffers.animationBuffer = buffers->loadBuffer(
nullptr,
sizeof(
AnimationBuffer), Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
26 buffers->annotate(engineBuffers.sceneBufferHandle,
"Engine:SceneBuffer");
27 buffers->annotate(engineBuffers.objectBufferHandle,
"Engine:ObjectBuffer");
28 buffers->annotate(engineBuffers.animationBuffer,
"Engine::AnimationBuffer");
30 if (capabilites && capabilites->getDeviceCapabilities().ConstantBufferRange) {
31 uint32_t alignment = capabilites->getDeviceCapabilities().ConstantBufferOffsetAlignment;
32 assert(alignment && ((alignment & (alignment - 1)) == 0) &&
"Constant buffer alignment is not a power of two");
34 engineBuffers.objectBatch.stride = uint32_t((
sizeof(
ObjectBuffer) + (alignment - 1))) & ~(alignment - 1);
35 engineBuffers.objectBatch.count = 128;
36 engineBuffers.objectBatch.bufferHandle = buffers->loadBuffer(
nullptr, engineBuffers.objectBatch.stride * engineBuffers.objectBatch.count, Usage::Dynamic, AccessMode::Write, BindFlags::ConstantBuffer);
37 buffers->annotate(engineBuffers.objectBatch.bufferHandle,
"Engine:ObjectBatchBuffer");
39 engineBuffers.objectBatch.count = 0;
51 if (passOptions.multiViews && viewportData->cameraArray) {
53 const CameraArrayData& camArrData = context->cameraArraySystem->getData(camArrComp);
56 assert(camArrData.viewBuffer.size() == passOptions.multiViews);
60 deviceContext->
updateBuffer(viewBufferHandle, camArrData.viewBuffer.data(),
sizeof(camArrData.viewBuffer[0]) * camArrData.viewBuffer.size());
69 LightSystem& lightSystem = *taskContext->context->lightSystem;
70 LightBuffer& lightParameters = engineBuffers.lightParameters;
72 lightParameters.eyePosition = viewportData->inverseViewMatrix[3];
74 size_t numActiveLights = activeLights.lights.size();
75 for (
size_t i = 0; i < numActiveLights; i++) {
77 const LightData& lightData = lightSystem.getData(light);
78 lightParameters.lightPositions[i] = lightData.lightPosition;
79 lightParameters.lightDirections[i] = lightData.lightDirection;
80 lightParameters.lightColorIntensity[i] = lightData.lightColor;
81 lightParameters.lightColorIntensity[i].a = (light->
lightingLayer & viewportData->lightingMask) == 0 ? 0.f : light->
intensity;
82 lightParameters.lightParameters[i].r = lightData.shadowIntensityOffset;
83 lightParameters.lightParameters[i].a = light->
range;
85 lightParameters.numLights[0] =
static_cast<uint32_t
>(numActiveLights);
86 lightParameters.ambientColor = taskContext->renderer->
getSettings().ambientColor;
87 lightParameters.ambientIntensity = taskContext->renderer->
getSettings().ambientIntensity;
89 const FogComponent* globalFog = taskContext->context->fogSystem->getGlobalFog();
90 if (globalFog && globalFog->
enabled) {
91 lightParameters.fogEnabled = 1;
92 lightParameters.fogColor = globalFog->
color;
93 lightParameters.fogDistance = globalFog->
distance;
94 lightParameters.fogAmount = globalFog->
amount;
97 lightParameters.fogEnabled = 0;
101 lightParameters.seaFlags = 0;
102 lightParameters.flags = 0;
103 lightParameters.environmentBrightness = 1.0f;
104 lightParameters.skyMultiplier = 1.0f;
105 if (environmentComponent) {
106 lightParameters.environmentBrightness = environmentComponent->brightness;
107 lightParameters.skyMultiplier = environmentComponent->skyMultiplier;
108 lightParameters.flags = ((
HandleIsValid(environmentComponent->skyDome) ? 1 : 0) |
111 (
HandleIsValid(environmentComponent->subseaRadiance) ? 8 : 0) |
112 (
HandleIsValid(environmentComponent->ambientIrradiance) ? 16 : 0) |
115 if (environmentComponent->subseaSupport) {
116 lightParameters.seaFlags = environmentComponent->isSubmerged(viewportData);
117 if (lightParameters.seaFlags) {
118 lightParameters.fogEnabled = 2 + 4;
119 lightParameters.fogColor = glm::vec4(1, 0, 0, 1);
120 lightParameters.fogDistance = environmentComponent->subseaTurbidityDistance;
121 lightParameters.fogAmount = environmentComponent->subseaTurbidityAmount;
127 const glm::vec4 softShadowJitter[] = {
128 { -2.5f, -2.5f, 0.0f, 0.0f },
129 { -2.5f, -1.5f, -1.5f, 0.0f },
130 { -2.5f, -0.5f, 0.0f, -1.5f },
131 { -2.5f, 0.5f, 0.0f, 1.5f },
132 { -2.5f, 1.5f, 1.5f, 0.0f },
133 { -2.5f, 2.5f, -1.5f, -1.5f },
134 { -1.5f, -2.5f, -1.5f, 1.5f },
135 { -1.5f, -1.5f, 1.5f, -1.5f },
136 { -1.5f, -0.5f, 1.5f, 1.5f },
137 { -1.5f, 0.5f, 0.0f, 0.0f },
138 { -1.5f, 1.5f, 0.0f, 0.0f },
139 { -1.5f, 2.5f, 0.0f, 0.0f },
140 { -0.5f, -2.5f, 0.0f, 0.0f },
141 { -0.5f, -1.5f, 0.0f, 0.0f },
142 { -0.5f, -0.5f, 0.0f, 0.0f },
143 { -0.5f, 0.5f, 0.0f, 0.0f },
144 { -0.5f, 1.5f, 0.0f, 0.0f },
145 { -0.5f, 2.5f, 0.0f, 0.0f },
146 { 0.5f, -2.5f, 0.0f, 0.0f },
147 { 0.5f, -1.5f, 0.0f, 0.0f },
148 { 0.5f, -0.5f, 0.0f, 0.0f },
149 { 0.5f, 0.5f, 0.0f, 0.0f },
150 { 0.5f, 1.5f, 0.0f, 0.0f },
151 { 0.5f, 2.5f, 0.0f, 0.0f },
152 { 1.5f, -2.5f, 0.0f, 0.0f },
153 { 1.5f, -1.5f, 0.0f, 0.0f },
154 { 1.5f, -0.5f, 0.0f, 0.0f },
155 { 1.5f, 0.5f, 0.0f, 0.0f },
156 { 1.5f, 1.5f, 0.0f, 0.0f },
157 { 1.5f, 2.5f, 0.0f, 0.0f },
158 { 2.5f, -2.5f, 0.0f, 0.0f },
159 { 2.5f, -1.5f, 0.0f, 0.0f },
160 { 2.5f, -0.5f, 0.0f, 0.0f },
161 { 2.5f, 0.5f, 0.0f, 0.0f },
162 { 2.5f, 1.5f, 0.0f, 0.0f },
163 { 2.5f, 2.5f, 0.0f, 0.0f }
170 LightSystem& lightSystem = *taskContext->context->lightSystem;
172 ShadowBuffer& shadowParameters = engineBuffers.shadowBuffer;
173 shadowParameters = {};
174 static_assert(
sizeof(softShadowJitter) ==
sizeof(ShadowBuffer::softShadowJitter));
175 std::memcpy(&shadowParameters.softShadowJitter, &softShadowJitter,
sizeof(ShadowBuffer::softShadowJitter));
176 const bool reverseDepth = taskContext->context->
variables->get(
"renderer.reverseDepth",
false);
177 glm::mat4 viewportTransform;
178 switch (taskContext->device->
getType())
185 viewportTransform = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
186 0.0f, 0.5f, 0.0f, 0.0f,
187 0.0f, 0.0f, 0.5f, 0.0f,
188 0.5f, 0.5f, 0.5f, 1.0f);
192 viewportTransform = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
193 0.0f, 0.5f, 0.0f, 0.0f,
194 0.0f, 0.0f, 1.0f, 0.0f,
195 0.5f, 0.5f, 0.0f, 1.0f);
201 viewportTransform = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
202 0.0f, -0.5f, 0.0f, 0.0f,
203 0.0f, 0.0f, 1.0f, 0.0f,
204 0.5f, 0.5f, 0.0f, 1.0f);
209 for (
size_t i = 0; i < activeLights.numDirectionalShadowLights; i++) {
211 const LightData& lightData = lightSystem.getData(light);
212 shadowParameters.cascadeOffsets[i].x = lightData.arrayOffset;
213 ShadowData& shadow = shadowParameters.shadowData[i];
214 shadow.shadowsEnabled = lightData.enabled && lightData.castShadows;
215 shadow.texelSize = 1.f / lightData.textureSize;
216 shadow.cascadeLine = lightData.cascadeLine;
217 shadow.nearSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.nearDepths);
218 shadow.farSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.farDepths);
220 shadow.numCascades = lightData.numViewports;
221 for (
size_t k = 0; k < lightData.numViewports; k++) {
222 shadow.lightMatrix[k] = viewportTransform * lightData.lightCameraData[k].viewProjection;
226 for (
size_t i = 0; i < activeLights.numPointShadowLights; i++) {
227 size_t o = activeLights.numDirectionalShadowLights + activeLights.numDirectionalLights + i;
229 const LightData& lightData = lightSystem.getData(light);
231 shadowParameters.cascadeOffsets[o].x = lightData.arrayOffset / 6;
233 ShadowData& shadow = shadowParameters.shadowData[o];
234 shadow.shadowsEnabled = lightData.enabled && lightData.castShadows;
235 shadow.texelSize = 1.f / lightData.textureSize;
236 shadow.cascadeLine = lightData.cascadeLine;
237 shadow.nearSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.nearDepths);
238 shadow.farSplits = *
reinterpret_cast<const glm::vec4*
>(lightData.farDepths);
240 shadow.numCascades = lightData.numViewports;
241 for (
size_t k = 0; k < lightData.numViewports; k++) {
242 shadow.lightMatrix[k] = viewportTransform * lightData.lightCameraData[k].viewProjection;
253 auto& random = taskContext->context->
random;
255 updateViewBuffer(taskContext->context, viewBufferHandle, viewportData);
258 auto& sceneParameters = engineBuffers.sceneParameters;
260 static std::uniform_int_distribution<uint32_t> dist(0, 63);
261 glm::uvec4 offset(dist(random->mt), dist(random->mt), viewportData->blueNoiseOffset);
262 sceneParameters.blueNoiseOffset = offset;
264 sceneParameters.projectionMatrix = viewportData->projectionMatrix;
265 sceneParameters.viewMatrix = viewportData->viewMatrix;
266 sceneParameters.inverseViewMatrix = viewportData->inverseViewMatrix;
267 sceneParameters.worldToClipMatrix = sceneParameters.projectionMatrix * sceneParameters.viewMatrix;
268 sceneParameters.inverseProjectionMatrix = viewportData->inverseProjectionMatrix;
269 sceneParameters.viewFromViewportMatrix = viewportData->viewFromViewportMatrix;
270 sceneParameters.viewportFromViewMatrix = viewportData->viewportFromViewMatrix;
271 sceneParameters.viewportOrigin = viewportData->viewportOrigin;
272 sceneParameters.viewportSize = viewportData->viewportSize;
273 sceneParameters.viewportSizeRcp = 1.0f / viewportData->viewportSize;
276 if (viewportData->cameraArray && !passOptions.multiViews) {
278 const CameraArrayData& camArrData = taskContext->context->cameraArraySystem->getData(camArrComp);
279 const ViewBufferEntry &entry = camArrData.viewBuffer[renderTarget->depthLayerIndex];
280 sceneParameters.projectionMatrix = entry.clipFromView;
281 sceneParameters.worldToClipMatrix = entry.clipFromWorld;
282 sceneParameters.viewMatrix = entry.viewFromWorld;
283 sceneParameters.inverseProjectionMatrix = entry.viewFromClip;
284 sceneParameters.inverseViewMatrix = entry.worldFromView;
287 glm::dvec3 origin = taskContext->context->transformSystem->
getOrigin();
288 glm::vec3 originHigh = glm::vec3(origin);
289 glm::vec3 originLow = glm::vec3(origin - glm::dvec3(originHigh));
290 sceneParameters.originHigh = glm::vec4(originHigh, 0.f);
291 sceneParameters.originLow = glm::vec4(originLow, 0.f);
294 const bool reverseDepth = taskContext->context->
variables->get(
"renderer.reverseDepth",
false);
295 float depthClamp = viewportData->depthClamp;
297 depthClamp = 1.0f - depthClamp;
300 sceneParameters.shadowDepthClamp = 2.f * depthClamp - 1.f;
303 sceneParameters.shadowDepthClamp = depthClamp;
306 sceneParameters.animationTime =
static_cast<float>(taskContext->context->
time->getAnimationTime());
307 sceneParameters.exposure = viewportData->exposure;
309 const float aspect = viewportData->viewportSize.y == 0 ? 1.0f : viewportData->viewportSize.x / viewportData->viewportSize.y;
310 sceneParameters.projectionParameters.y = 2.0f * viewportData->nearDistance * glm::tan(0.5f * viewportData->fieldOfView);
311 sceneParameters.projectionParameters.x = aspect * sceneParameters.projectionParameters.y;
312 sceneParameters.projectionParameters.z = aspect;
313 sceneParameters.projectionParameters.w = viewportData->fieldOfView;
315 unsigned sceneFlags = 0;
316 if ((renderTarget == taskContext->defaultRenderTarget && taskContext->renderer->
getSettings().defaultRenderTargetExpectsSRGB) || renderTarget->expectsSRGB) {
317 sceneFlags |= COGS_SCENEFLAGS_OUTPUT_SRGB;
320 sceneFlags |= COGS_SCENEFLAGS_SUBMERGED;
322 sceneParameters.sceneFlags = sceneFlags;
323 sceneParameters.clientFlags = viewportData->clientFlags;
324 if (taskContext->context->environmentSystem) {
325 auto* envComp = taskContext->context->environmentSystem->getGlobalEnvironment();
327 auto& envData = taskContext->context->environmentSystem->getData(envComp);
328 sceneParameters.numEnvironmentIrradianceMips =
static_cast<float>(envData.irradianceLods);
329 sceneParameters.numEnvironmentRadianceMips =
static_cast<float>(envData.radianceLods);
333 static const std::array<glm::vec4, 6> noClipEquations = {
334 glm::vec4(0.f, 0.f, 0.f, 1.f), glm::vec4(0.f, 0.f, 0.f, 1.f),
335 glm::vec4(0.f, 0.f, 0.f, 1.f), glm::vec4(0.f, 0.f, 0.f, 1.f),
336 glm::vec4(0.f, 0.f, 0.f, 1.f), glm::vec4(0.f, 0.f, 0.f, 1.f)
338 std::memcpy(&sceneParameters.clippingPlanes, clipEquations ? clipEquations : &noClipEquations,
sizeof(std::array<glm::vec4, 6>));
340 taskContext->cameraData = viewportData;
343 updateLightBuffer(taskContext, viewportData);
344 updateShadowBuffer(taskContext);
347 engineBuffers.sceneBuffer.scene = engineBuffers.sceneParameters;
348 engineBuffers.sceneBuffer.light = engineBuffers.lightParameters;
349 engineBuffers.sceneBuffer.shadow = engineBuffers.shadowBuffer;
359 if (!viewportData)
return;
362 updateViewportBuffer(taskContext, engineBuffers.sceneBufferHandle, engineBuffers.viewBufferHandle, renderTarget, viewportData, clipEquations);
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.