|
@@ -476,7 +476,13 @@ namespace BansheeEngine
|
|
|
|
|
|
|
|
UINT32 numCameras = (UINT32)cameras.size();
|
|
UINT32 numCameras = (UINT32)cameras.size();
|
|
|
for (UINT32 i = 0; i < numCameras; i++)
|
|
for (UINT32 i = 0; i < numCameras; i++)
|
|
|
- render(renderTargetData, i, delta);
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ bool isOverlayCamera = ((UINT32)cameras[i]->getFlags() & (UINT32)CameraFlags::Overlay) != 0;
|
|
|
|
|
+ if (!isOverlayCamera)
|
|
|
|
|
+ render(renderTargetData, i, delta);
|
|
|
|
|
+ else
|
|
|
|
|
+ renderOverlay(renderTargetData, i, delta);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
RenderAPICore::instance().endFrame();
|
|
RenderAPICore::instance().endFrame();
|
|
|
RenderAPICore::instance().swapBuffers(target);
|
|
RenderAPICore::instance().swapBuffers(target);
|
|
@@ -495,25 +501,20 @@ namespace BansheeEngine
|
|
|
SPtr<ViewportCore> viewport = camera->getViewport();
|
|
SPtr<ViewportCore> viewport = camera->getViewport();
|
|
|
CameraShaderData cameraShaderData = getCameraShaderData(*camera);
|
|
CameraShaderData cameraShaderData = getCameraShaderData(*camera);
|
|
|
|
|
|
|
|
|
|
+ assert(((UINT32)camera->getFlags() & (UINT32)CameraFlags::Overlay) == 0);
|
|
|
|
|
+
|
|
|
mStaticHandler->updatePerCameraBuffers(cameraShaderData);
|
|
mStaticHandler->updatePerCameraBuffers(cameraShaderData);
|
|
|
|
|
|
|
|
// Render scene objects to g-buffer
|
|
// Render scene objects to g-buffer
|
|
|
- bool hasGBuffer = ((UINT32)camera->getFlags() & (UINT32)CameraFlags::Overlay) == 0;
|
|
|
|
|
|
|
+ bool createGBuffer = camData.target == nullptr ||
|
|
|
|
|
+ camData.target->getHDR() != mCoreOptions->hdr ||
|
|
|
|
|
+ camData.target->getNumSamples() != mCoreOptions->msaa;
|
|
|
|
|
|
|
|
- if (hasGBuffer)
|
|
|
|
|
- {
|
|
|
|
|
- bool createGBuffer = camData.target == nullptr ||
|
|
|
|
|
- camData.target->getHDR() != mCoreOptions->hdr ||
|
|
|
|
|
- camData.target->getNumSamples() != mCoreOptions->msaa;
|
|
|
|
|
|
|
+ if (createGBuffer)
|
|
|
|
|
+ camData.target = RenderTargets::create(viewport, mCoreOptions->hdr, mCoreOptions->msaa);
|
|
|
|
|
|
|
|
- if (createGBuffer)
|
|
|
|
|
- camData.target = RenderTargets::create(viewport, mCoreOptions->hdr, mCoreOptions->msaa);
|
|
|
|
|
-
|
|
|
|
|
- camData.target->allocate();
|
|
|
|
|
- camData.target->bindGBuffer();
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- camData.target = nullptr;
|
|
|
|
|
|
|
+ camData.target->allocate();
|
|
|
|
|
+ camData.target->bindGBuffer();
|
|
|
|
|
|
|
|
// Trigger pre-scene callbacks
|
|
// Trigger pre-scene callbacks
|
|
|
auto iterCameraCallbacks = mRenderCallbacks.find(camera);
|
|
auto iterCameraCallbacks = mRenderCallbacks.find(camera);
|
|
@@ -533,150 +534,119 @@ namespace BansheeEngine
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (hasGBuffer)
|
|
|
|
|
|
|
+ // Render base pass
|
|
|
|
|
+ const Vector<RenderQueueElement>& opaqueElements = camData.opaqueQueue->getSortedElements();
|
|
|
|
|
+ for (auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
|
|
|
{
|
|
{
|
|
|
- // Render base pass
|
|
|
|
|
- const Vector<RenderQueueElement>& opaqueElements = camData.opaqueQueue->getSortedElements();
|
|
|
|
|
- for (auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
|
|
|
|
|
- {
|
|
|
|
|
- BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
|
|
|
|
|
- SPtr<MaterialCore> material = renderElem->material;
|
|
|
|
|
-
|
|
|
|
|
- UINT32 rendererId = renderElem->renderableId;
|
|
|
|
|
- Matrix4 worldViewProjMatrix = cameraShaderData.viewProj * mRenderableShaderData[rendererId].worldTransform;
|
|
|
|
|
-
|
|
|
|
|
- mStaticHandler->updatePerObjectBuffers(*renderElem, mRenderableShaderData[rendererId], worldViewProjMatrix);
|
|
|
|
|
- mStaticHandler->bindGlobalBuffers(*renderElem); // Note: If I can keep global buffer slot indexes the same between shaders I could only bind these once
|
|
|
|
|
- mStaticHandler->bindPerObjectBuffers(*renderElem);
|
|
|
|
|
-
|
|
|
|
|
- if (iter->applyPass)
|
|
|
|
|
- {
|
|
|
|
|
- SPtr<PassCore> pass = material->getPass(iter->passIdx);
|
|
|
|
|
- setPass(pass);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
|
|
|
|
|
+ SPtr<MaterialCore> material = renderElem->material;
|
|
|
|
|
|
|
|
- SPtr<PassParametersCore> passParams = material->getPassParameters(iter->passIdx);
|
|
|
|
|
|
|
+ UINT32 rendererId = renderElem->renderableId;
|
|
|
|
|
+ Matrix4 worldViewProjMatrix = cameraShaderData.viewProj * mRenderableShaderData[rendererId].worldTransform;
|
|
|
|
|
|
|
|
- if (renderElem->samplerOverrides != nullptr)
|
|
|
|
|
- setPassParams(passParams, &renderElem->samplerOverrides->passes[iter->passIdx]);
|
|
|
|
|
- else
|
|
|
|
|
- setPassParams(passParams, nullptr);
|
|
|
|
|
|
|
+ mStaticHandler->updatePerObjectBuffers(*renderElem, mRenderableShaderData[rendererId], worldViewProjMatrix);
|
|
|
|
|
+ mStaticHandler->bindGlobalBuffers(*renderElem); // Note: If I can keep global buffer slot indexes the same between shaders I could only bind these once
|
|
|
|
|
+ mStaticHandler->bindPerObjectBuffers(*renderElem);
|
|
|
|
|
|
|
|
- gRendererUtility().draw(iter->renderElem->mesh, iter->renderElem->subMesh);
|
|
|
|
|
|
|
+ if (iter->applyPass)
|
|
|
|
|
+ {
|
|
|
|
|
+ SPtr<PassCore> pass = material->getPass(iter->passIdx);
|
|
|
|
|
+ setPass(pass);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- camData.target->bindSceneColor(true);
|
|
|
|
|
-
|
|
|
|
|
- // Render light pass
|
|
|
|
|
- SPtr<GpuParamBlockBufferCore> perCameraBuffer = mStaticHandler->getPerCameraParams().getBuffer();
|
|
|
|
|
|
|
+ SPtr<PassParametersCore> passParams = material->getPassParameters(iter->passIdx);
|
|
|
|
|
|
|
|
- SPtr<MaterialCore> dirMaterial = mDirLightMat->getMaterial();
|
|
|
|
|
- SPtr<PassCore> dirPass = dirMaterial->getPass(0);
|
|
|
|
|
|
|
+ if (renderElem->samplerOverrides != nullptr)
|
|
|
|
|
+ setPassParams(passParams, &renderElem->samplerOverrides->passes[iter->passIdx]);
|
|
|
|
|
+ else
|
|
|
|
|
+ setPassParams(passParams, nullptr);
|
|
|
|
|
|
|
|
- setPass(dirPass);
|
|
|
|
|
- mDirLightMat->setStaticParameters(camData.target, perCameraBuffer);
|
|
|
|
|
|
|
+ gRendererUtility().draw(iter->renderElem->mesh, iter->renderElem->subMesh);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- for (auto& light : mDirectionalLights)
|
|
|
|
|
- {
|
|
|
|
|
- if (!light.internal->getIsActive())
|
|
|
|
|
- continue;
|
|
|
|
|
|
|
+ camData.target->bindSceneColor(true);
|
|
|
|
|
|
|
|
- mDirLightMat->setParameters(light.internal);
|
|
|
|
|
|
|
+ // Render light pass
|
|
|
|
|
+ SPtr<GpuParamBlockBufferCore> perCameraBuffer = mStaticHandler->getPerCameraParams().getBuffer();
|
|
|
|
|
|
|
|
- // TODO - Bind parameters to the pipeline manually as I don't need to re-bind gbuffer textures for every light
|
|
|
|
|
- // - I can't think of a good way to do this automatically. Probably best to do it in setParameters()
|
|
|
|
|
- setPassParams(dirMaterial->getPassParameters(0), nullptr);
|
|
|
|
|
- gRendererUtility().drawScreenQuad();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ SPtr<MaterialCore> dirMaterial = mDirLightMat->getMaterial();
|
|
|
|
|
+ SPtr<PassCore> dirPass = dirMaterial->getPass(0);
|
|
|
|
|
|
|
|
- // Draw point lights which our camera is within
|
|
|
|
|
- SPtr<MaterialCore> pointInsideMaterial = mPointLightInMat->getMaterial();
|
|
|
|
|
- SPtr<PassCore> pointInsidePass = pointInsideMaterial->getPass(0);
|
|
|
|
|
|
|
+ setPass(dirPass);
|
|
|
|
|
+ mDirLightMat->setStaticParameters(camData.target, perCameraBuffer);
|
|
|
|
|
|
|
|
- // TODO - Possibly use instanced drawing here as only two meshes are drawn with various properties
|
|
|
|
|
- setPass(pointInsidePass);
|
|
|
|
|
- mPointLightInMat->setStaticParameters(camData.target, perCameraBuffer);
|
|
|
|
|
|
|
+ for (auto& light : mDirectionalLights)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!light.internal->getIsActive())
|
|
|
|
|
+ continue;
|
|
|
|
|
|
|
|
- // TODO - Cull lights based on visibility, right now I just iterate over all of them.
|
|
|
|
|
- for (auto& light : mPointLights)
|
|
|
|
|
- {
|
|
|
|
|
- if (!light.internal->getIsActive())
|
|
|
|
|
- continue;
|
|
|
|
|
|
|
+ mDirLightMat->setParameters(light.internal);
|
|
|
|
|
|
|
|
- float distToLight = (light.internal->getBounds().getCenter() - camera->getPosition()).squaredLength();
|
|
|
|
|
- float boundRadius = light.internal->getBounds().getRadius() * 1.05f + camera->getNearClipDistance() * 2.0f;
|
|
|
|
|
|
|
+ // TODO - Bind parameters to the pipeline manually as I don't need to re-bind gbuffer textures for every light
|
|
|
|
|
+ // - I can't think of a good way to do this automatically. Probably best to do it in setParameters()
|
|
|
|
|
+ setPassParams(dirMaterial->getPassParameters(0), nullptr);
|
|
|
|
|
+ gRendererUtility().drawScreenQuad();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- bool cameraInLightGeometry = distToLight < boundRadius * boundRadius;
|
|
|
|
|
- if (!cameraInLightGeometry)
|
|
|
|
|
- continue;
|
|
|
|
|
|
|
+ // Draw point lights which our camera is within
|
|
|
|
|
+ SPtr<MaterialCore> pointInsideMaterial = mPointLightInMat->getMaterial();
|
|
|
|
|
+ SPtr<PassCore> pointInsidePass = pointInsideMaterial->getPass(0);
|
|
|
|
|
|
|
|
- mPointLightInMat->setParameters(light.internal);
|
|
|
|
|
|
|
+ // TODO - Possibly use instanced drawing here as only two meshes are drawn with various properties
|
|
|
|
|
+ setPass(pointInsidePass);
|
|
|
|
|
+ mPointLightInMat->setStaticParameters(camData.target, perCameraBuffer);
|
|
|
|
|
|
|
|
- // TODO - Bind parameters to the pipeline manually as I don't need to re-bind gbuffer textures for every light
|
|
|
|
|
- // - I can't think of a good way to do this automatically. Probably best to do it in setParameters()
|
|
|
|
|
- setPassParams(pointInsideMaterial->getPassParameters(0), nullptr);
|
|
|
|
|
- SPtr<MeshCore> mesh = light.internal->getMesh();
|
|
|
|
|
- gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // TODO - Cull lights based on visibility, right now I just iterate over all of them.
|
|
|
|
|
+ for (auto& light : mPointLights)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!light.internal->getIsActive())
|
|
|
|
|
+ continue;
|
|
|
|
|
|
|
|
- // Draw other point lights
|
|
|
|
|
- SPtr<MaterialCore> pointOutsideMaterial = mPointLightOutMat->getMaterial();
|
|
|
|
|
- SPtr<PassCore> pointOutsidePass = pointOutsideMaterial->getPass(0);
|
|
|
|
|
|
|
+ float distToLight = (light.internal->getBounds().getCenter() - camera->getPosition()).squaredLength();
|
|
|
|
|
+ float boundRadius = light.internal->getBounds().getRadius() * 1.05f + camera->getNearClipDistance() * 2.0f;
|
|
|
|
|
|
|
|
- setPass(pointOutsidePass);
|
|
|
|
|
- mPointLightOutMat->setStaticParameters(camData.target, perCameraBuffer);
|
|
|
|
|
|
|
+ bool cameraInLightGeometry = distToLight < boundRadius * boundRadius;
|
|
|
|
|
+ if (!cameraInLightGeometry)
|
|
|
|
|
+ continue;
|
|
|
|
|
|
|
|
- for (auto& light : mPointLights)
|
|
|
|
|
- {
|
|
|
|
|
- if (!light.internal->getIsActive())
|
|
|
|
|
- continue;
|
|
|
|
|
|
|
+ mPointLightInMat->setParameters(light.internal);
|
|
|
|
|
|
|
|
- float distToLight = (light.internal->getBounds().getCenter() - camera->getPosition()).squaredLength();
|
|
|
|
|
- float boundRadius = light.internal->getBounds().getRadius() * 1.05f + camera->getNearClipDistance() * 2.0f;
|
|
|
|
|
|
|
+ // TODO - Bind parameters to the pipeline manually as I don't need to re-bind gbuffer textures for every light
|
|
|
|
|
+ // - I can't think of a good way to do this automatically. Probably best to do it in setParameters()
|
|
|
|
|
+ setPassParams(pointInsideMaterial->getPassParameters(0), nullptr);
|
|
|
|
|
+ SPtr<MeshCore> mesh = light.internal->getMesh();
|
|
|
|
|
+ gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- bool cameraInLightGeometry = distToLight < boundRadius * boundRadius;
|
|
|
|
|
- if (cameraInLightGeometry)
|
|
|
|
|
- continue;
|
|
|
|
|
|
|
+ // Draw other point lights
|
|
|
|
|
+ SPtr<MaterialCore> pointOutsideMaterial = mPointLightOutMat->getMaterial();
|
|
|
|
|
+ SPtr<PassCore> pointOutsidePass = pointOutsideMaterial->getPass(0);
|
|
|
|
|
|
|
|
- mPointLightOutMat->setParameters(light.internal);
|
|
|
|
|
|
|
+ setPass(pointOutsidePass);
|
|
|
|
|
+ mPointLightOutMat->setStaticParameters(camData.target, perCameraBuffer);
|
|
|
|
|
|
|
|
- // TODO - Bind parameters to the pipeline manually as I don't need to re-bind gbuffer textures for every light
|
|
|
|
|
- setPassParams(pointOutsideMaterial->getPassParameters(0), nullptr);
|
|
|
|
|
- SPtr<MeshCore> mesh = light.internal->getMesh();
|
|
|
|
|
- gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- camData.target->bindSceneColor(false);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
|
|
+ for (auto& light : mPointLights)
|
|
|
{
|
|
{
|
|
|
- // Prepare final render target
|
|
|
|
|
- SPtr<RenderTargetCore> target = rtData.target;
|
|
|
|
|
-
|
|
|
|
|
- RenderAPICore::instance().setRenderTarget(target);
|
|
|
|
|
- RenderAPICore::instance().setViewport(viewport->getNormArea());
|
|
|
|
|
|
|
+ if (!light.internal->getIsActive())
|
|
|
|
|
+ continue;
|
|
|
|
|
|
|
|
- // If first camera in render target, prepare the render target
|
|
|
|
|
- if (camIdx == 0)
|
|
|
|
|
- {
|
|
|
|
|
- UINT32 clearBuffers = 0;
|
|
|
|
|
- if (viewport->getRequiresColorClear())
|
|
|
|
|
- clearBuffers |= FBT_COLOR;
|
|
|
|
|
|
|
+ float distToLight = (light.internal->getBounds().getCenter() - camera->getPosition()).squaredLength();
|
|
|
|
|
+ float boundRadius = light.internal->getBounds().getRadius() * 1.05f + camera->getNearClipDistance() * 2.0f;
|
|
|
|
|
|
|
|
- if (viewport->getRequiresDepthClear())
|
|
|
|
|
- clearBuffers |= FBT_DEPTH;
|
|
|
|
|
|
|
+ bool cameraInLightGeometry = distToLight < boundRadius * boundRadius;
|
|
|
|
|
+ if (cameraInLightGeometry)
|
|
|
|
|
+ continue;
|
|
|
|
|
|
|
|
- if (viewport->getRequiresStencilClear())
|
|
|
|
|
- clearBuffers |= FBT_STENCIL;
|
|
|
|
|
|
|
+ mPointLightOutMat->setParameters(light.internal);
|
|
|
|
|
|
|
|
- if (clearBuffers != 0)
|
|
|
|
|
- {
|
|
|
|
|
- RenderAPICore::instance().clearViewport(clearBuffers, viewport->getClearColor(),
|
|
|
|
|
- viewport->getClearDepthValue(), viewport->getClearStencilValue());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // TODO - Bind parameters to the pipeline manually as I don't need to re-bind gbuffer textures for every light
|
|
|
|
|
+ setPassParams(pointOutsideMaterial->getPassParameters(0), nullptr);
|
|
|
|
|
+ SPtr<MeshCore> mesh = light.internal->getMesh();
|
|
|
|
|
+ gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ camData.target->bindSceneColor(false);
|
|
|
|
|
+
|
|
|
// Render transparent objects (TODO - No lighting yet)
|
|
// Render transparent objects (TODO - No lighting yet)
|
|
|
const Vector<RenderQueueElement>& transparentElements = camData.transparentQueue->getSortedElements();
|
|
const Vector<RenderQueueElement>& transparentElements = camData.transparentQueue->getSortedElements();
|
|
|
for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
|
|
for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
|
|
@@ -724,20 +694,70 @@ namespace BansheeEngine
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (hasGBuffer)
|
|
|
|
|
|
|
+ // TODO - If GBuffer has multiple samples, I should resolve them before post-processing
|
|
|
|
|
+ PostProcessing::instance().postProcess(camData.target->getSceneColorRT(),
|
|
|
|
|
+ viewport, camData.postProcessInfo, delta);
|
|
|
|
|
+
|
|
|
|
|
+ // Render overlay post-scene callbacks
|
|
|
|
|
+ if (iterCameraCallbacks != mRenderCallbacks.end())
|
|
|
{
|
|
{
|
|
|
- //PostProcessing::instance().postProcess(camData.target->getSceneColorRT(), camData.postProcessInfo, delta);
|
|
|
|
|
|
|
+ for (auto& callbackPair : iterCameraCallbacks->second)
|
|
|
|
|
+ {
|
|
|
|
|
+ const RenderCallbackData& callbackData = callbackPair.second;
|
|
|
|
|
+
|
|
|
|
|
+ if (!callbackData.overlay)
|
|
|
|
|
+ continue;
|
|
|
|
|
|
|
|
- // TODO - Instead of doing a separate resolve here I could potentially perform a resolve directly in some
|
|
|
|
|
- // post-processing pass (e.g. tone mapping). Right now it is just an unnecessary blit.
|
|
|
|
|
- camData.target->resolve();
|
|
|
|
|
|
|
+ callbackData.callback();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
|
|
+
|
|
|
|
|
+ camData.target->release();
|
|
|
|
|
+
|
|
|
|
|
+ gProfilerCPU().endSample("Render");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void RenderBeast::renderOverlay(RenderTargetData& rtData, UINT32 camIdx, float delta)
|
|
|
|
|
+ {
|
|
|
|
|
+ gProfilerCPU().beginSample("RenderOverlay");
|
|
|
|
|
+
|
|
|
|
|
+ const CameraCore* camera = rtData.cameras[camIdx];
|
|
|
|
|
+ CameraData& camData = mCameraData[camera];
|
|
|
|
|
+
|
|
|
|
|
+ assert(((UINT32)camera->getFlags() & (UINT32)CameraFlags::Overlay) != 0);
|
|
|
|
|
+
|
|
|
|
|
+ SPtr<ViewportCore> viewport = camera->getViewport();
|
|
|
|
|
+ CameraShaderData cameraShaderData = getCameraShaderData(*camera);
|
|
|
|
|
+
|
|
|
|
|
+ mStaticHandler->updatePerCameraBuffers(cameraShaderData);
|
|
|
|
|
+
|
|
|
|
|
+ SPtr<RenderTargetCore> target = rtData.target;
|
|
|
|
|
+
|
|
|
|
|
+ RenderAPICore::instance().setRenderTarget(target);
|
|
|
|
|
+ RenderAPICore::instance().setViewport(viewport->getNormArea());
|
|
|
|
|
+
|
|
|
|
|
+ // If first camera in render target, prepare the render target
|
|
|
|
|
+ if (camIdx == 0)
|
|
|
{
|
|
{
|
|
|
- // TODO - Post process without gbuffer
|
|
|
|
|
|
|
+ UINT32 clearBuffers = 0;
|
|
|
|
|
+ if (viewport->getRequiresColorClear())
|
|
|
|
|
+ clearBuffers |= FBT_COLOR;
|
|
|
|
|
+
|
|
|
|
|
+ if (viewport->getRequiresDepthClear())
|
|
|
|
|
+ clearBuffers |= FBT_DEPTH;
|
|
|
|
|
+
|
|
|
|
|
+ if (viewport->getRequiresStencilClear())
|
|
|
|
|
+ clearBuffers |= FBT_STENCIL;
|
|
|
|
|
+
|
|
|
|
|
+ if (clearBuffers != 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ RenderAPICore::instance().clearViewport(clearBuffers, viewport->getClearColor(),
|
|
|
|
|
+ viewport->getClearDepthValue(), viewport->getClearStencilValue());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Render overlay post-scene callbacks
|
|
// Render overlay post-scene callbacks
|
|
|
|
|
+ auto iterCameraCallbacks = mRenderCallbacks.find(camera);
|
|
|
if (iterCameraCallbacks != mRenderCallbacks.end())
|
|
if (iterCameraCallbacks != mRenderCallbacks.end())
|
|
|
{
|
|
{
|
|
|
for (auto& callbackPair : iterCameraCallbacks->second)
|
|
for (auto& callbackPair : iterCameraCallbacks->second)
|
|
@@ -751,14 +771,15 @@ namespace BansheeEngine
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (hasGBuffer)
|
|
|
|
|
- camData.target->release();
|
|
|
|
|
-
|
|
|
|
|
- gProfilerCPU().endSample("Render");
|
|
|
|
|
|
|
+ gProfilerCPU().endSample("RenderOverlay");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void RenderBeast::determineVisible(const CameraCore& camera)
|
|
void RenderBeast::determineVisible(const CameraCore& camera)
|
|
|
{
|
|
{
|
|
|
|
|
+ bool isOverlayCamera = ((UINT32)camera.getFlags() & (UINT32)CameraFlags::Overlay) != 0;
|
|
|
|
|
+ if (isOverlayCamera)
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
|
|
CameraData& cameraData = mCameraData[&camera];
|
|
CameraData& cameraData = mCameraData[&camera];
|
|
|
|
|
|
|
|
UINT64 cameraLayers = camera.getLayers();
|
|
UINT64 cameraLayers = camera.getLayers();
|