1#include "ClipmapRenderer.h"
3#include "ClipmapLevel.h"
4#include "ClipmapGeometry.h"
5#include "ClipmapState.h"
6#include "ClipmapParameterCalculation.h"
8#include "RenderBlock.h"
9#include "RenderBlockCulling.h"
11#include "Rendering/IRenderTargets.h"
12#include "Rendering/IContext.h"
13#include "Rendering/ITextures.h"
14#include "Rendering/IEffects.h"
20 std::vector<Cogs::Vector3> colors = {
21 Cogs::Vector3(1, 0, 0),
22 Cogs::Vector3(0, 1, 0),
23 Cogs::Vector3(0, 0, 1),
24 Cogs::Vector3(1, 1, 0),
25 Cogs::Vector3(0, 1, 1),
26 Cogs::Vector3(1, 0, 1),
27 Cogs::Vector3(1, 0, 0),
28 Cogs::Vector3(0, 1, 0),
29 Cogs::Vector3(0, 0, 1),
30 Cogs::Vector3(1, 0, 0),
31 Cogs::Vector3(0, 1, 0),
32 Cogs::Vector3(0, 0, 1),
33 Cogs::Vector3(1, 0, 0),
34 Cogs::Vector3(0, 1, 0),
35 Cogs::Vector3(0, 0, 1),
36 Cogs::Vector3(1, 0, 0),
37 Cogs::Vector3(0, 1, 0),
38 Cogs::Vector3(0, 0, 1),
39 Cogs::Vector3(1, 0, 0),
40 Cogs::Vector3(0, 1, 0),
44void Cogs::DepthRenderData::initialize(IGraphicsDevice * device,
int width,
int height)
47 this->height = height;
48 auto textures = device->getTextures();
49 auto renderTargets = device->getRenderTargets();
53 depthRenderHandle = renderTargets->createRenderTarget(depthTextureHandle);
54 depthTargetHandle = renderTargets->createDepthStencilTarget(depthRenderHandle);
56 const size_t bufferSize = width * height *
sizeof(float);
60void Cogs::DepthRenderData::cleanup(IGraphicsDevice * device)
62 auto textures = device->getTextures();
63 auto renderTargets = device->getRenderTargets();
65 renderTargets->releaseDepthStencilTarget(depthTargetHandle);
66 renderTargets->releaseRenderTarget(depthRenderHandle);
68 textures->releaseTexture(depthTextureHandle);
70 device->getBuffers()->releaseBuffer(readbackBufferHandle);
73void Cogs::ClipmapRenderer::initializeTextures(ITextures * textures)
75 SamplerState pointSampler = {
80 SamplerState::ComparisonFunction::Never,
82 { 0.0f, 0.0f, 0.0f, 0.0f },
85 pointSamplerState = textures->loadSamplerState(pointSampler);
87 SamplerState linearSampler = {
92 SamplerState::ComparisonFunction::Never,
94 { 0.0f, 0.0f, 0.0f, 0.0f },
97 linearSamplerState = textures->loadSamplerState(linearSampler);
100 depthQueryTextureHandle = textures->loadTexture(
nullptr, depthQuerySize, depthQuerySize, TextureFormat::R32G32B32A32_FLOAT,
TextureFlags::RenderTarget);
103void Cogs::ClipmapRenderer::initializeEffects(IBuffers * buffers, IEffects * effects,
const size_t numImagery,
size_t permutation)
105 auto & permutationRendererData = getPermutationDependentClipmapRendererData(permutation);
106 if (!permutationRendererData.initialized) {
108 initializeConstantBuffers(buffers, permutationRendererData.effectVariables);
109 initializeConstantBuffers(buffers, permutationRendererData.depthEffectVariables);
112 initializeEffectVariables(effects, permutationRendererData.clipmapEffect, permutationRendererData.effectVariables, numImagery,
false);
113 initializeEffectVariables(effects, permutationRendererData.clipmapDepthEffect, permutationRendererData.depthEffectVariables, numImagery,
true);
115 initializeEffectBindings(effects, permutationRendererData.clipmapEffect, permutationRendererData.effectBindings, numImagery,
false);
116 initializeEffectBindings(effects, permutationRendererData.clipmapDepthEffect, permutationRendererData.depthEffectBindings, numImagery,
true);
119 VertexFormatHandle meshFormat = buffers->createVertexFormat(&element, 1);
120 inputLayout = buffers->loadInputLayout(&meshFormat, 1, permutationRendererData.clipmapEffect);
122 permutationRendererData.initialized =
true;
125void Cogs::ClipmapRenderer::initializeConstantBuffers(IBuffers * buffers, ClipmapEffectVariables & variables)
138void Cogs::ClipmapRenderer::initializeEffectVariables(IEffects * effects, EffectHandle effectHandle, ClipmapEffectVariables & variables,
const size_t ,
bool isDepth)
140 variables.globalBufferBinding = effects->getConstantBufferBinding(effectHandle,
"GlobalParameters");
141 variables.levelBufferBinding = effects->getConstantBufferBinding(effectHandle,
"LevelParameters");
143 variables.patchBufferBinding = effects->getConstantBufferBinding(effectHandle,
"PatchParameters");
144 variables.imageryBufferBinding = effects->getConstantBufferBinding(effectHandle,
"ImageryParameters");
148 variables.renderBufferBinding = effects->getConstantBufferBinding(effectHandle,
"RenderParameters");
149 variables.levelRenderBufferBinding = effects->getConstantBufferBinding(effectHandle,
"LevelRenderParameters");
152 variables.customParametersBufferBinding = effects->getConstantBufferBinding(effectHandle,
"CustomParameters");
157 const char * imagerySemantics[] = {
164 const char * coarseImagerySemantics[] = {
165 "coarseImageryTexture[0]",
166 "coarseImageryTexture[1]",
167 "coarseImageryTexture[2]",
168 "coarseImageryTexture[3]",
172void Cogs::ClipmapRenderer::initializeEffectBindings(IEffects * effects, EffectHandle effect, ClipmapTextureBindings & bindings,
const size_t numImagery,
bool isDepth)
176 bindings.heightMapBinding = effects->getTextureBinding(effect,
"heightTexture", unit);
177 bindings.heightMapSamplerBinding = effects->getSamplerStateBinding(effect,
"heightSampler", unit++);
179 bindings.coarseHeightMapBinding = effects->getTextureBinding(effect,
"coarseHeightTexture", unit);
180 bindings.coarseHeightMapSamplerBinding = effects->getSamplerStateBinding(effect,
"coarseHeightSampler", unit++);
182 if (!isDepth ||
true) {
183 bindings.normalMapBinding = effects->getTextureBinding(effect,
"normalTexture", unit);
184 bindings.normalMapSamplerBinding = effects->getSamplerStateBinding(effect,
"normalSampler", unit++);
186 bindings.coarseNormalMapBinding = effects->getTextureBinding(effect,
"coarseNormalTexture", unit);
187 bindings.coarseNormalMapSamplerBinding = effects->getSamplerStateBinding(effect,
"normalSampler", unit++);
189 if (numImagery > 1) {
190 for (
size_t i = 0; i < numImagery; ++i) {
191 auto & perImageBindings = bindings.getImageryBindingHandles(i);
192 perImageBindings.imageryBinding = effects->getTextureBinding(effect, imagerySemantics[i], unit);
193 perImageBindings.imagerySamplerBinding = effects->getSamplerStateBinding(effect,
"imagerySampler", unit++);
195 perImageBindings.coarseImageryBinding = effects->getTextureBinding(effect, coarseImagerySemantics[i], unit);
196 perImageBindings.coarseImagerySamplerBinding = effects->getSamplerStateBinding(effect,
"imagerySampler", unit++);
199 auto & perImageBindings = bindings.getImageryBindingHandles(0);
200 perImageBindings.imageryBinding = effects->getTextureBinding(effect,
"imageryTexture[0]", unit);
201 perImageBindings.imagerySamplerBinding = effects->getSamplerStateBinding(effect,
"imagerySampler", unit++);
203 perImageBindings.coarseImageryBinding = effects->getTextureBinding(effect,
"coarseImageryTexture[0]", unit);
204 perImageBindings.coarseImagerySamplerBinding = perImageBindings.imagerySamplerBinding;
209void Cogs::ClipmapRenderer::initializeRasterizerStates(IRenderTargets * renderTargets)
211 float offset = reverseDepth ? -1.0f : 1.0f;
216 solidRasterizerState = renderTargets->loadRasterizerState(solid);
219 solidNoDepthClip.noDepthClip =
true;
220 solidNoDepthClipRasterizerState = renderTargets->loadRasterizerState(solidNoDepthClip);
223 solidOffsetRasterizerState = renderTargets->loadRasterizerState(solidOffset);
226 wireframeRasterizerState = renderTargets->loadRasterizerState(wireFrame);
228 DepthStencilState solidDepth = {
true,
true, cmp };
229 solidDepthState = renderTargets->loadDepthStencilState(solidDepth);
231 DepthStencilState wireDepth = {
true,
true, cmpOrEqual };
232 wireframeDepthState = renderTargets->loadDepthStencilState(wireDepth);
234 DepthStencilState transparentDepth = {
true,
false, cmp };
235 transparentDepthState = renderTargets->loadDepthStencilState(transparentDepth);
237 DepthStencilState transparentWireDepth = {
true,
false, cmpOrEqual };
238 transparentWireframeDepthState = renderTargets->loadDepthStencilState(transparentWireDepth);
241void Cogs::ClipmapRenderer::initializeRenderTargets(IRenderTargets * renderTargets)
243 depthQueryRenderHandle = renderTargets->createRenderTarget(depthQueryTextureHandle);
244 depthQueryTargetHandle = renderTargets->createDepthStencilTarget(depthQueryRenderHandle);
249 template<
typename Parameters>
250 void applyParameters(IContext * context,
const Parameters & parameters, BufferHandle bufferHandle)
255 ::memcpy(out, ¶meters,
sizeof(Parameters));
260void Cogs::ClipmapRenderer::updateGlobalParameters(
const RenderContext & renderContext,
const RenderOptions & renderOptions,
const ClipmapState & ,
const GlobalParameters & globalParameters)
262 IContext * context = renderContext.context;
264 const auto & permutationRendererData = getPermutationDependentClipmapRendererData(renderContext.permutation);
265 const auto & variables = this->depthPass ? permutationRendererData.depthEffectVariables : permutationRendererData.effectVariables;
267 if (!this->depthPass) {
268 RenderParameters renderParameters;
269 renderParameters.blendRegionColor = renderOptions.blendRegionColor;
270 renderParameters.showBlendRegions = renderOptions.showBlendRegions;
271 renderParameters.showImagery = renderOptions.showImagery;
272 renderParameters.showLevelColors = renderOptions.showLevelColors;
274 applyParameters(context, renderParameters, variables.renderBuffer);
277 applyParameters(context, globalParameters, variables.globalBuffer);
280void Cogs::ClipmapRenderer::updateLevelParameters(IContext * context,
const RenderOptions & options,
const LevelParameters & parameters,
const ImageryParameters & imageryParameters,
size_t permutation)
282 const auto & permutationRendererData = getPermutationDependentClipmapRendererData(permutation);
283 const auto & variables = this->depthPass ? permutationRendererData.depthEffectVariables : permutationRendererData.effectVariables;
285 applyParameters(context, parameters, variables.levelBuffer);
286 applyParameters(context, imageryParameters, variables.imageryBuffer);
288 if (options.showLevelColors && !this->depthPass) {
289 Vector4 diffuseColor = pad3to4(colors[parameters.levelIndex & colors.size()]);
290 applyParameters(context, diffuseColor, variables.levelRenderBuffer);
291 }
else if (!this->depthPass) {
292 applyParameters(context, options.diffuseColor, variables.levelRenderBuffer);
296void Cogs::ClipmapRenderer::updateLevelTextures(IContext * context,
297 const RenderLevel * renderLevel,
300 auto & permutationRendererData = getPermutationDependentClipmapRendererData(permutation);
301 auto & bindings = this->depthPass ? permutationRendererData.depthEffectBindings : permutationRendererData.effectBindings;
303 context->setTexture(bindings.heightMapBinding, renderLevel->terrainLevel->renderTexture.handle);
304 context->setSamplerState(bindings.heightMapSamplerBinding, pointSamplerState);
306 context->setTexture(bindings.coarseHeightMapBinding, renderLevel->coarserTerrainLevel->renderTexture.handle);
307 context->setSamplerState(bindings.coarseHeightMapSamplerBinding, linearSamplerState);
309 if (!this->depthPass ||
true) {
310 if (renderLevel->normalLevel) {
311 context->setTexture(bindings.normalMapBinding, renderLevel->normalLevel->renderTexture.handle);
312 context->setSamplerState(bindings.normalMapSamplerBinding, linearSamplerState);
314 context->setTexture(bindings.coarseNormalMapBinding, renderLevel->coarserNormalLevel->renderTexture.handle);
315 context->setSamplerState(bindings.coarseNormalMapSamplerBinding, linearSamplerState);
318 const size_t levelIndex = renderLevel->terrainLevel->index;
320 for (
size_t i = 0; i < renderLevel->imagery->size(); ++i) {
321 const ClipmapLevel & imageryLevel = (*renderLevel->imagery)[i][levelIndex];
322 const auto & perImageBindings = bindings.getImageryBindingHandles(i);
324 context->setTexture(perImageBindings.imageryBinding, imageryLevel.renderTexture.handle);
325 context->setSamplerState(perImageBindings.imagerySamplerBinding, linearSamplerState);
327 context->setTexture(perImageBindings.coarseImageryBinding, imageryLevel.coarserLevel->renderTexture.handle);
328 context->setSamplerState(perImageBindings.coarseImagerySamplerBinding, linearSamplerState);
333void Cogs::ClipmapRenderer::initLevels()
338bool Cogs::ClipmapRenderer::createRenderLevel(ClipmapGeometry & geometry,
339 ClipmapState & clipmapState,
340 ClipmapLevel & terrainLevel,
341 std::vector<std::vector<ClipmapLevel>> & imagery,
342 ClipmapLevel * normalLevel,
343 const GlobalParameters & globalParameters,
344 const LevelParameters & parameters,
345 const ImageryParameters & imageryParameters,
349 this->geometry = &geometry;
351 const int west = terrainLevel.currentExtent.west;
352 const int south = terrainLevel.currentExtent.south;
353 const int east = terrainLevel.currentExtent.east;
354 const int north = terrainLevel.currentExtent.north;
356 const int fillPatchSegments =
static_cast<int>(clipmapState.fillPatchSegments);
357 const int fillPatchPosts =
static_cast<int>(clipmapState.fillPatchPosts);
359 RenderLevel & renderLevel = levels[levelIndex++];
361 renderLevel.globalParameters = &globalParameters;
362 renderLevel.levelParameters = ¶meters;
363 renderLevel.imageryParameters = &imageryParameters;
365 renderLevel.terrainLevel = &terrainLevel;
366 renderLevel.coarserTerrainLevel = terrainLevel.coarserLevel;
368 renderLevel.imagery = &imagery;
370 renderLevel.normalLevel = normalLevel;
371 renderLevel.coarserNormalLevel = normalLevel ? normalLevel->coarserLevel :
nullptr;
373 renderLevel.blockCount = 0;
375 createBlock(geometry.fieldBlockMesh, west, south, west, south, renderLevel, select);
377 createBlock(geometry.fieldBlockMesh, west, south, west + fillPatchSegments, south, renderLevel, select);
378 createBlock(geometry.fieldBlockMesh, west, south, east - 2 * fillPatchSegments, south, renderLevel, select);
379 createBlock(geometry.fieldBlockMesh, west, south, east - fillPatchSegments, south, renderLevel, select);
381 createBlock(geometry.fieldBlockMesh, west, south, west, south + fillPatchSegments, renderLevel, select);
382 createBlock(geometry.fieldBlockMesh, west, south, east - fillPatchSegments, south + fillPatchSegments, renderLevel, select);
384 createBlock(geometry.fieldBlockMesh, west, south, west, north - 2 * fillPatchSegments, renderLevel, select);
385 createBlock(geometry.fieldBlockMesh, west, south, east - fillPatchSegments, north - 2 * fillPatchSegments, renderLevel, select);
387 createBlock(geometry.fieldBlockMesh, west, south, west, north - fillPatchSegments, renderLevel, select);
388 createBlock(geometry.fieldBlockMesh, west, south, west + fillPatchSegments, north - fillPatchSegments, renderLevel, select);
389 createBlock(geometry.fieldBlockMesh, west, south, east - 2 * fillPatchSegments, north - fillPatchSegments, renderLevel, select);
390 createBlock(geometry.fieldBlockMesh, west, south, east - fillPatchSegments, north - fillPatchSegments, renderLevel, select);
392 createBlock(geometry.ringFixupHorizontalMesh, west, south, west, south + 2 * fillPatchSegments, renderLevel);
393 createBlock(geometry.ringFixupHorizontalMesh, west, south, east - fillPatchSegments, south + 2 * fillPatchSegments, renderLevel);
395 createBlock(geometry.ringFixupVerticalMesh, west, south, west + 2 * fillPatchSegments, south, renderLevel);
396 createBlock(geometry.ringFixupVerticalMesh, west, south, west + 2 * fillPatchSegments, north - fillPatchSegments, renderLevel);
398 createBlock(geometry.degenerateTriangleMesh, west, south, west, south, renderLevel);
402 createBlock(geometry.fieldBlockMesh, west, south, west + fillPatchSegments, south + fillPatchSegments, renderLevel);
403 createBlock(geometry.fieldBlockMesh, west, south, west + 2 * fillPatchPosts, south + fillPatchSegments, renderLevel);
404 createBlock(geometry.fieldBlockMesh, west, south, west + fillPatchSegments, south + 2 * fillPatchPosts, renderLevel);
405 createBlock(geometry.fieldBlockMesh, west, south, west + 2 * fillPatchPosts, south + 2 * fillPatchPosts, renderLevel);
407 createBlock(geometry.ringFixupHorizontalMesh, west, south, west + fillPatchSegments, south + 2 * fillPatchSegments, renderLevel);
408 createBlock(geometry.ringFixupHorizontalMesh, west, south, west + 2 * fillPatchPosts, south + 2 * fillPatchSegments, renderLevel);
410 createBlock(geometry.ringFixupVerticalMesh, west, south, west + 2 * fillPatchSegments, south + fillPatchSegments, renderLevel);
411 createBlock(geometry.ringFixupVerticalMesh, west, south, west + 2 * fillPatchSegments, south + 2 * fillPatchPosts, renderLevel);
413 createBlock(geometry.centerMesh, west, south, west + 2 * fillPatchSegments, south + 2 * fillPatchSegments, renderLevel);
415 int offset = terrainLevel.offsetStripOnNorth ? north - fillPatchPosts : south + fillPatchSegments;
417 createBlock(geometry.offsetStripHorizontalMesh, west, south, west + fillPatchSegments, offset, renderLevel);
419 int southOffset = terrainLevel.offsetStripOnNorth ? 0 : 1;
420 offset = terrainLevel.offsetStripOnEast ? east - fillPatchPosts : west + fillPatchSegments;
422 createBlock(geometry.offsetStripVerticalMesh, west, south, offset, south + fillPatchSegments + southOffset, renderLevel);
428bool Cogs::ClipmapRenderer::createBackgroundRenderLevel(ClipmapGeometry & geometry,
430 ClipmapLevel & terrainLevel,
431 std::vector<std::vector<ClipmapLevel>> & imagery,
432 ClipmapLevel * normalLevel,
433 const GlobalParameters & globalParameters,
434 const LevelParameters & levelParameters,
435 const ImageryParameters & imageryParameters,
436 bool useSimplifiedMesh)
438 const int west = terrainLevel.currentExtent.west;
439 const int south = terrainLevel.currentExtent.south;
441 RenderLevel & renderLevel = levels[levelIndex++];
443 renderLevel.globalParameters = &globalParameters;
444 renderLevel.levelParameters = &levelParameters;
445 renderLevel.imageryParameters = &imageryParameters;
447 renderLevel.terrainLevel = &terrainLevel;
448 renderLevel.coarserTerrainLevel = terrainLevel.coarserLevel;
450 renderLevel.imagery = &imagery;
452 renderLevel.normalLevel = normalLevel;
453 renderLevel.coarserNormalLevel = normalLevel ? normalLevel->coarserLevel :
nullptr;
455 renderLevel.blockCount = 0;
457 const int width = terrainLevel.renderTexture.width;
458 const int height = terrainLevel.renderTexture.height;
460 const int blockSize = 64;
462 const int numDivisionsX = (width + blockSize - 1) / blockSize;
463 const int numDivisionsY = (height + blockSize - 1) / blockSize;
465 const int widthIncrement = blockSize * terrainLevel.currentExtent.getWidth() / terrainLevel.renderTexture.width;
466 const int heightIncrement = blockSize * terrainLevel.currentExtent.getHeight() / terrainLevel.renderTexture.height;
469 geometry.worldMesh = createMesh(geometry.buffers, 0, 0, widthIncrement, heightIncrement, blockSize, blockSize, geometry.meshFormat);
470 geometry.simpleWorldMesh = createMesh(geometry.buffers, 0, 0, widthIncrement, heightIncrement, 1, 1, geometry.meshFormat);
473 for (
int x = 0; x < numDivisionsX; ++x) {
474 for (
int y = 0; y < numDivisionsY; ++y) {
475 assert(renderLevel.blockCount < kMaxNumBlocks - 1 &&
"Number of blocks too large.");
476 createBlock(geometry.worldMesh, west, south, west + widthIncrement * x, south + heightIncrement * y, renderLevel, useSimplifiedMesh);
483void Cogs::ClipmapRenderer::setupDepthPass(RenderContext & renderContext,
size_t depthDataIndex)
487 auto context = renderContext.context;
488 const auto & permutationRendererData = getPermutationDependentClipmapRendererData(renderContext.permutation);
489 auto & variables = permutationRendererData.depthEffectVariables;
491 auto & depthData = raypickDepthData[depthDataIndex];
493 context->setRenderTarget(depthData.depthRenderHandle, depthData.depthTargetHandle);
495 context->setRasterizerState(solidRasterizerState);
496 context->setDepthStencilState(solidDepthState);
498 float color[] = { 1.0f, 0.0f, 0.0f, 1.0f };
499 if(reverseDepth) color[0] = 0.0f;
501 context->clearRenderTarget(color);
503 context->clearDepth(0.0f);
505 context->clearDepth();
506 depthData.depthRenderInitialized =
true;
508 context->setViewport(0, 0,
static_cast<float>(depthData.width),
static_cast<float>(depthData.height));
510 context->setEffect(permutationRendererData.clipmapDepthEffect);
511 context->setInputLayout(inputLayout);
513 renderContext.callback(permutationRendererData.clipmapDepthEffect);
515 context->setConstantBuffer(variables.globalBufferBinding, variables.globalBuffer);
516 context->setConstantBuffer(variables.levelBufferBinding, variables.levelBuffer);
517 context->setConstantBuffer(variables.imageryBufferBinding, variables.imageryBuffer);
518 context->setConstantBuffer(variables.patchBufferBinding, variables.patchBuffer);
520 if (customParameters.size()) {
521 auto buffers = renderContext.device->getBuffers();
524 buffers->releaseBuffer(customParametersBuffer);
529 customParameters.clear();
533 context->setConstantBuffer(variables.customParametersBufferBinding, customParametersBuffer);
537void Cogs::ClipmapRenderer::setupDepthQueryPass(RenderContext & renderContext)
541 auto context = renderContext.context;
542 const auto & permutationRendererData = getPermutationDependentClipmapRendererData(renderContext.permutation);
543 auto & variables = permutationRendererData.depthEffectVariables;
545 context->setRenderTarget(depthQueryRenderHandle, depthQueryTargetHandle);
547 context->setRasterizerState(solidNoDepthClipRasterizerState);
548 context->setDepthStencilState(solidDepthState);
550 float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
557 context->clearRenderTarget(color);
559 context->clearDepth(0.0f);
561 context->clearDepth();
562 depthQueryRenderInitialized =
true;
564 context->setViewport(0, 0,
static_cast<float>(depthQuerySize),
static_cast<float>(depthQuerySize));
566 context->setEffect(permutationRendererData.clipmapDepthEffect);
567 context->setInputLayout(inputLayout);
569 renderContext.callback(permutationRendererData.clipmapDepthEffect);
571 context->setConstantBuffer(variables.globalBufferBinding, variables.globalBuffer);
572 context->setConstantBuffer(variables.levelBufferBinding, variables.levelBuffer);
573 context->setConstantBuffer(variables.imageryBufferBinding, variables.imageryBuffer);
574 context->setConstantBuffer(variables.patchBufferBinding, variables.patchBuffer);
577void Cogs::ClipmapRenderer::setupRegularPass(RenderContext & renderContext)
581 const auto & permutationRendererData = getPermutationDependentClipmapRendererData(renderContext.permutation);
582 auto context = renderContext.context;
583 auto & variables = permutationRendererData.effectVariables;
585 context->setRenderTarget(renderContext.renderTarget, renderContext.depthStencilTarget);
586 context->setViewport(renderContext.viewportX, renderContext.viewportY, renderContext.width, renderContext.height);
588 context->setEffect(permutationRendererData.clipmapEffect);
589 context->setInputLayout(inputLayout);
591 renderContext.callback(permutationRendererData.clipmapEffect);
593 if (renderContext.wireframe) {
594 context->setRasterizerState(wireframeRasterizerState);
596 context->setRasterizerState(renderContext.offsetEnabled ? solidOffsetRasterizerState : solidRasterizerState);
599 context->setDepthStencilState(renderContext.wireframe ? wireframeDepthState : solidDepthState);
601 context->setConstantBuffer(variables.globalBufferBinding, variables.globalBuffer);
602 context->setConstantBuffer(variables.levelBufferBinding, variables.levelBuffer);
603 context->setConstantBuffer(variables.imageryBufferBinding, variables.imageryBuffer);
605 context->setConstantBuffer(variables.patchBufferBinding, variables.patchBuffer);
608 context->setConstantBuffer(variables.renderBufferBinding, variables.renderBuffer);
612 context->setConstantBuffer(variables.levelRenderBufferBinding, variables.levelRenderBuffer);
616 context->setConstantBuffer(variables.customParametersBufferBinding, customParametersBuffer);
620void Cogs::ClipmapRenderer::render(RenderContext & renderContext,
const RenderOptions & renderOptions,
const WorldOptions & worldOptions,
bool usePreviousCullingResults)
622 if (!usePreviousCullingResults) {
623 for (
size_t i = 0; i < levelIndex; ++i) {
624 const RenderLevel & renderLevel = levels[i];
626 updateLevelTextures(renderContext.context, &renderLevel, renderContext.permutation);
628 updateLevelParameters(renderContext.context, renderOptions, *renderLevel.levelParameters, *renderLevel.imageryParameters, renderContext.permutation);
630 cullRenderBlocks(renderLevel.renderBlocks,
631 visibleBlocks + i * kMaxNumBlocks,
632 renderLevel.blockCount,
634 renderContext.cullVolume,
635 renderContext.center - renderContext.cullOrigin + renderContext.offset,
636 worldOptions.heightExaggeration,
637 static_cast<float>(worldOptions.worldScale.x),
638 static_cast<float>(worldOptions.worldScale.y));
640 for (
size_t j = 0; j < renderLevel.blockCount; ++j) {
641 bool draw = visibleBlocks[j + i * kMaxNumBlocks] || !renderOptions.enableCulling;
644 drawBlock(renderLevel.renderBlocks[j], renderContext);
649 for (
size_t i = 0; i < levelIndex; ++i) {
650 const RenderLevel & renderLevel = levels[i];
652 updateLevelTextures(renderContext.context, &renderLevel, renderContext.permutation);
654 updateLevelParameters(renderContext.context, renderOptions, *renderLevel.levelParameters, *renderLevel.imageryParameters, renderContext.permutation);
656 for (
size_t j = 0; j < renderLevel.blockCount; ++j) {
657 if (visibleBlocks[j + i * kMaxNumBlocks] || !renderOptions.enableCulling) {
658 drawBlock(renderLevel.renderBlocks[j], renderContext);
665void Cogs::ClipmapRenderer::createBlock(ClipmapMesh & mesh,
int overallWest,
int overallSouth,
int blockWest,
int blockSouth, RenderLevel & renderLevel,
bool useSimplifiedMesh)
667 auto & renderBlock = renderLevel.renderBlocks[renderLevel.blockCount++];
669 renderBlock.mesh = &mesh;
671 const int textureWest = blockWest - overallWest;
672 const int textureSouth = blockSouth - overallSouth;
674 renderBlock.patchOriginInClippedLevel = Vector2(
static_cast<float>(textureWest),
static_cast<float>(textureSouth));
677 const auto levelOffset = renderLevel.levelParameters->levelOffsetFromClipmapCenter;
678 const auto scaleFactor = renderLevel.levelParameters->levelScaleFactor * renderLevel.globalParameters->levelZeroWorldScaleFactor;
680 renderBlock.min = Vector2(renderBlock.patchOriginInClippedLevel + levelOffset) * scaleFactor;
681 renderBlock.max = Vector2(renderBlock.patchOriginInClippedLevel + levelOffset + Vector2(mesh.width, mesh.height)) * scaleFactor;
683 if (useSimplifiedMesh && renderBlock.mesh == &geometry->fieldBlockMesh) {
684 renderBlock.mesh = &geometry->simpleMesh;
685 }
else if (useSimplifiedMesh && renderBlock.mesh == &geometry->worldMesh) {
686 renderBlock.mesh = &geometry->simpleWorldMesh;
690void Cogs::ClipmapRenderer::drawBlock(
const RenderBlock & renderBlock, RenderContext & renderContext)
692 IContext * context = renderContext.context;
694 auto & permutationRendererData = getPermutationDependentClipmapRendererData(renderContext.permutation);
695 const auto & effectVariables = this->depthPass ? permutationRendererData.depthEffectVariables : permutationRendererData.effectVariables;
697 applyParameters(context, renderBlock.patchOriginInClippedLevel, effectVariables.patchBuffer);
699 context->setVertexBuffers(&renderBlock.mesh->vertexBuffer, 1, &renderBlock.mesh->stride,
nullptr);
700 context->setIndexBuffer(renderBlock.mesh->indexBuffer,
sizeof(
unsigned short), 0);
705void Cogs::ClipmapRenderer::setCustomParameters(
const unsigned char * data,
int count)
707 customParameters.assign(data, data + count);
710void Cogs::ClipmapRenderer::cleanup(IGraphicsDevice * device)
713 device->getRenderTargets()->releaseRenderTarget(depthQueryRenderHandle);
717 device->getRenderTargets()->releaseDepthStencilTarget(depthQueryTargetHandle);
721 device->getTextures()->releaseTexture(depthQueryTextureHandle);
724 for (
auto & data : raypickDepthData)
726 data.cleanup(device);
730Cogs::RenderTexture Cogs::createClipmapTexture(IGraphicsDevice * device,
int width,
int height, TextureFormat textureFormat,
bool mipmap, glm::vec4 clearColor)
733 TextureHandle textureHandle = device->getTextures()->loadTexture(
nullptr, width, height, textureFormat, flags);
734 RenderTargetHandle renderTarget = device->getRenderTargets()->createRenderTarget(textureHandle);
736 RenderTexture texture = {
738 Cogs::getTextureSize(width, height, textureFormat),
745 assert(
HandleIsValid(texture.handle) &&
"Texture handle not valid.");
746 assert(
HandleIsValid(texture.renderTarget) &&
"Render target handle not valid.");
748 clearClipmapTexture(device, texture);
753void Cogs::releaseClipmapTexture(IGraphicsDevice * device, RenderTexture & texture)
756 device->getRenderTargets()->releaseRenderTarget(texture.renderTarget);
759 device->getTextures()->releaseTexture(texture.handle);
762void Cogs::clearClipmapTexture(IGraphicsDevice * device, RenderTexture & texture)
764 auto context = device->getImmediateContext();
768 context->clearRenderTarget(
reinterpret_cast<float *
>(&texture.clearColor));
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
Contains all Cogs related functionality.
@ VertexData
Per vertex data.
@ Position
Position semantic.
@ Read
The buffer can be mapped and read from by the CPU after creation.
@ Write
The buffer can be mapped and written to by the CPU after creation.
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
DepthFunction
Depth functions to apply when determining object visibility based on its depth test.
@ GreaterOrEqual
Greater or equal depth.
@ LessOrEqual
Less or equal depth.
static const Handle_t NoHandle
Represents a handle to nothing.
static const Handle_t InvalidHandle
Represents an invalid handle.
@ WriteDiscard
Write access. When unmapping the graphics system will discard the old contents of the resource.
@ TriangleList
List of triangles.
@ None
Do not perform any face culling.
@ Wrap
Texture coordinates automatically wrap around to [0, 1] range.
@ MinMagMipPoint
Point sampling for both minification and magnification.
@ MinMagMipLinear
Linear sampling for both minification and magnification.
@ RenderTarget
The texture can be used as a render target and drawn into.
@ GenerateMipMaps
The texture supports automatic mipmap generation performed by the graphics device.
@ Dynamic
Buffer will be loaded and modified with some frequency.