mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 12:04:18 +02:00
Merge pull request #10913 from samcake/orange
Introducing the Stages to the render::Scene, Better scene update phase and getting away from the singleton model
This commit is contained in:
commit
96b88dccd7
45 changed files with 539 additions and 254 deletions
|
@ -112,10 +112,7 @@
|
|||
#include <plugins/InputConfiguration.h>
|
||||
#include <RecordingScriptingInterface.h>
|
||||
#include <RenderableWebEntityItem.h>
|
||||
#include <RenderShadowTask.h>
|
||||
#include <render/RenderFetchCullSortTask.h>
|
||||
#include <RenderDeferredTask.h>
|
||||
#include <RenderForwardTask.h>
|
||||
#include <UpdateSceneTask.h>
|
||||
#include <RenderViewTask.h>
|
||||
#include <SecondaryCamera.h>
|
||||
#include <ResourceCache.h>
|
||||
|
@ -1973,6 +1970,7 @@ void Application::initializeGL() {
|
|||
render::CullFunctor cullFunctor = LODManager::shouldRender;
|
||||
static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
|
||||
bool isDeferred = !QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD);
|
||||
_renderEngine->addJob<UpdateSceneTask>("UpdateScene");
|
||||
_renderEngine->addJob<SecondaryCameraRenderTask>("SecondaryCameraFrame", cullFunctor);
|
||||
_renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, isDeferred);
|
||||
_renderEngine->load();
|
||||
|
@ -5312,7 +5310,7 @@ namespace render {
|
|||
|
||||
auto& batch = *args->_batch;
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch);
|
||||
renderWorldBox(batch);
|
||||
renderWorldBox(args, batch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5375,10 +5373,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("SceneProcessTransaction");
|
||||
_main3DScene->enqueueTransaction(transaction);
|
||||
|
||||
_main3DScene->processTransactionQueue();
|
||||
}
|
||||
|
||||
// For now every frame pass the renderContext
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
void renderWorldBox(gpu::Batch& batch) {
|
||||
void renderWorldBox(RenderArgs* args, gpu::Batch& batch) {
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
|
||||
// Show center of world
|
||||
|
@ -115,7 +115,7 @@ void renderWorldBox(gpu::Batch& batch) {
|
|||
geometryIds[17]);
|
||||
|
||||
|
||||
geometryCache->renderWireCubeInstance(batch, GREY4);
|
||||
geometryCache->renderWireCubeInstance(args, batch, GREY4);
|
||||
|
||||
// Draw meter markers along the 3 axis to help with measuring things
|
||||
const float MARKER_DISTANCE = 1.0f;
|
||||
|
@ -123,23 +123,23 @@ void renderWorldBox(gpu::Batch& batch) {
|
|||
|
||||
transform = Transform().setScale(MARKER_RADIUS);
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderSolidSphereInstance(batch, RED);
|
||||
geometryCache->renderSolidSphereInstance(args, batch, RED);
|
||||
|
||||
transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS);
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderSolidSphereInstance(batch, RED);
|
||||
geometryCache->renderSolidSphereInstance(args, batch, RED);
|
||||
|
||||
transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS);
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderSolidSphereInstance(batch, GREEN);
|
||||
geometryCache->renderSolidSphereInstance(args, batch, GREEN);
|
||||
|
||||
transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS);
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderSolidSphereInstance(batch, BLUE);
|
||||
geometryCache->renderSolidSphereInstance(args, batch, BLUE);
|
||||
|
||||
transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS);
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderSolidSphereInstance(batch, GREY);
|
||||
geometryCache->renderSolidSphereInstance(args, batch, GREY);
|
||||
}
|
||||
|
||||
// Do some basic timing tests and report the results
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
#include <render/Forward.h>
|
||||
|
||||
void renderWorldBox(gpu::Batch& batch);
|
||||
void renderWorldBox(RenderArgs* args, gpu::Batch& batch);
|
||||
|
||||
void runTimingTests();
|
||||
void runUnitTests();
|
||||
|
|
|
@ -80,8 +80,8 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
Q_ASSERT(args->_batch);
|
||||
auto& batch = *args->_batch;
|
||||
if (args->_pipeline) {
|
||||
batch.setPipeline(args->_pipeline->pipeline);
|
||||
if (args->_shapePipeline) {
|
||||
batch.setPipeline(args->_shapePipeline->pipeline);
|
||||
}
|
||||
|
||||
// FIXME: THe line width of _lineWidth is not supported anymore, we ll need a workaround
|
||||
|
|
|
@ -65,15 +65,15 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
transform.setTranslation(position);
|
||||
transform.setRotation(rotation);
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto pipeline = args->_pipeline;
|
||||
if (!pipeline) {
|
||||
pipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||
auto shapePipeline = args->_shapePipeline;
|
||||
if (!shapePipeline) {
|
||||
shapePipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||
}
|
||||
|
||||
if (_isSolid) {
|
||||
transform.setScale(dimensions);
|
||||
batch->setModelTransform(transform);
|
||||
geometryCache->renderSolidCubeInstance(*batch, cubeColor, pipeline);
|
||||
geometryCache->renderSolidCubeInstance(args, *batch, cubeColor, shapePipeline);
|
||||
} else {
|
||||
geometryCache->bindSimpleProgram(*batch, false, false, false, true, true);
|
||||
if (getIsDashedLine()) {
|
||||
|
@ -109,7 +109,7 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
} else {
|
||||
transform.setScale(dimensions);
|
||||
batch->setModelTransform(transform);
|
||||
geometryCache->renderWireCubeInstance(*batch, cubeColor, pipeline);
|
||||
geometryCache->renderWireCubeInstance(args, *batch, cubeColor, shapePipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,17 +45,17 @@ void Shape3DOverlay::render(RenderArgs* args) {
|
|||
transform.setTranslation(position);
|
||||
transform.setRotation(rotation);
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto pipeline = args->_pipeline;
|
||||
if (!pipeline) {
|
||||
pipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||
auto shapePipeline = args->_shapePipeline;
|
||||
if (!shapePipeline) {
|
||||
shapePipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||
}
|
||||
|
||||
transform.setScale(dimensions);
|
||||
batch->setModelTransform(transform);
|
||||
if (_isSolid) {
|
||||
geometryCache->renderSolidShapeInstance(*batch, _shape, cubeColor, pipeline);
|
||||
geometryCache->renderSolidShapeInstance(args, *batch, _shape, cubeColor, shapePipeline);
|
||||
} else {
|
||||
geometryCache->renderWireShapeInstance(*batch, _shape, cubeColor, pipeline);
|
||||
geometryCache->renderWireShapeInstance(args, *batch, _shape, cubeColor, shapePipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,15 +44,15 @@ void Sphere3DOverlay::render(RenderArgs* args) {
|
|||
batch->setModelTransform(transform);
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto pipeline = args->_pipeline;
|
||||
if (!pipeline) {
|
||||
pipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||
auto shapePipeline = args->_shapePipeline;
|
||||
if (!shapePipeline) {
|
||||
shapePipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||
}
|
||||
|
||||
if (_isSolid) {
|
||||
geometryCache->renderSolidSphereInstance(*batch, sphereColor, pipeline);
|
||||
geometryCache->renderSolidSphereInstance(args, *batch, sphereColor, shapePipeline);
|
||||
} else {
|
||||
geometryCache->renderWireSphereInstance(*batch, sphereColor, pipeline);
|
||||
geometryCache->renderWireSphereInstance(args, *batch, sphereColor, shapePipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,8 +137,8 @@ void Text3DOverlay::render(RenderArgs* args) {
|
|||
// Text renderer sets its own pipeline,
|
||||
_textRenderer->draw(batch, 0, 0, getText(), textColor, glm::vec2(-1.0f), getDrawInFront());
|
||||
// so before we continue, we must reset the pipeline
|
||||
batch.setPipeline(args->_pipeline->pipeline);
|
||||
args->_pipeline->prepare(batch);
|
||||
batch.setPipeline(args->_shapePipeline->pipeline);
|
||||
args->_shapePipeline->prepare(batch, args);
|
||||
}
|
||||
|
||||
const render::ShapeKey Text3DOverlay::getShapeKey() {
|
||||
|
|
|
@ -610,7 +610,7 @@ void Avatar::render(RenderArgs* renderArgs) {
|
|||
if (showCollisionShapes && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) {
|
||||
PROFILE_RANGE_BATCH(batch, __FUNCTION__":skeletonBoundingCollisionShapes");
|
||||
const float BOUNDING_SHAPE_ALPHA = 0.7f;
|
||||
_skeletonModel->renderBoundingCollisionShapes(*renderArgs->_batch, getUniformScale(), BOUNDING_SHAPE_ALPHA);
|
||||
_skeletonModel->renderBoundingCollisionShapes(renderArgs, *renderArgs->_batch, getUniformScale(), BOUNDING_SHAPE_ALPHA);
|
||||
}
|
||||
|
||||
if (showReceiveStats || showNamesAboveHeads) {
|
||||
|
|
|
@ -322,20 +322,20 @@ void SkeletonModel::computeBoundingShape() {
|
|||
_boundingCapsuleLocalOffset = invScale * offset;
|
||||
}
|
||||
|
||||
void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float scale, float alpha) {
|
||||
void SkeletonModel::renderBoundingCollisionShapes(RenderArgs* args, gpu::Batch& batch, float scale, float alpha) {
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
// draw a blue sphere at the capsule top point
|
||||
glm::vec3 topPoint = _translation + getRotation() * (scale * (_boundingCapsuleLocalOffset + (0.5f * _boundingCapsuleHeight) * Vectors::UNIT_Y));
|
||||
|
||||
batch.setModelTransform(Transform().setTranslation(topPoint).postScale(scale * _boundingCapsuleRadius));
|
||||
geometryCache->renderSolidSphereInstance(batch, glm::vec4(0.6f, 0.6f, 0.8f, alpha));
|
||||
geometryCache->renderSolidSphereInstance(args, batch, glm::vec4(0.6f, 0.6f, 0.8f, alpha));
|
||||
|
||||
// draw a yellow sphere at the capsule bottom point
|
||||
glm::vec3 bottomPoint = topPoint - glm::vec3(0.0f, scale * _boundingCapsuleHeight, 0.0f);
|
||||
glm::vec3 axis = topPoint - bottomPoint;
|
||||
|
||||
batch.setModelTransform(Transform().setTranslation(bottomPoint).postScale(scale * _boundingCapsuleRadius));
|
||||
geometryCache->renderSolidSphereInstance(batch, glm::vec4(0.8f, 0.8f, 0.6f, alpha));
|
||||
geometryCache->renderSolidSphereInstance(args, batch, glm::vec4(0.8f, 0.8f, 0.6f, alpha));
|
||||
|
||||
// draw a green cylinder between the two points
|
||||
glm::vec3 origin(0.0f);
|
||||
|
|
|
@ -96,7 +96,7 @@ public:
|
|||
/// \return whether or not the head was found.
|
||||
glm::vec3 getDefaultEyeModelPosition() const;
|
||||
|
||||
void renderBoundingCollisionShapes(gpu::Batch& batch, float scale, float alpha);
|
||||
void renderBoundingCollisionShapes(RenderArgs* args, gpu::Batch& batch, float scale, float alpha);
|
||||
float getBoundingCapsuleRadius() const { return _boundingCapsuleRadius; }
|
||||
float getBoundingCapsuleHeight() const { return _boundingCapsuleHeight; }
|
||||
const glm::vec3 getBoundingCapsuleOffset() const { return _boundingCapsuleLocalOffset; }
|
||||
|
|
|
@ -378,7 +378,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
auto shapeTransform = getTransformToCenter(success);
|
||||
if (success) {
|
||||
batch.setModelTransform(shapeTransform); // we want to include the scale as well
|
||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(batch, greenColor);
|
||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(args, batch, greenColor);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -128,9 +128,9 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
|
|||
auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
||||
|
||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
|
||||
geometryCache->renderWireShapeInstance(batch, MAPPING[_shape], color, pipeline);
|
||||
geometryCache->renderWireShapeInstance(args, batch, MAPPING[_shape], color, pipeline);
|
||||
} else {
|
||||
geometryCache->renderSolidShapeInstance(batch, MAPPING[_shape], color, pipeline);
|
||||
geometryCache->renderSolidShapeInstance(args, batch, MAPPING[_shape], color, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -221,10 +221,10 @@ void RenderableZoneEntityItem::render(RenderArgs* args) {
|
|||
if (getShapeType() == SHAPE_TYPE_SPHERE) {
|
||||
shapeTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||
batch.setModelTransform(shapeTransform);
|
||||
geometryCache->renderWireSphereInstance(batch, DEFAULT_COLOR);
|
||||
geometryCache->renderWireSphereInstance(args, batch, DEFAULT_COLOR);
|
||||
} else {
|
||||
batch.setModelTransform(shapeTransform);
|
||||
geometryCache->renderWireCubeInstance(batch, DEFAULT_COLOR);
|
||||
geometryCache->renderWireCubeInstance(args, batch, DEFAULT_COLOR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -554,11 +554,13 @@ void RenderableZoneEntityItemMeta::setProceduralUserData(QString userData) {
|
|||
|
||||
void RenderableZoneEntityItemMeta::render(RenderArgs* args) {
|
||||
if (!_stage) {
|
||||
_stage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
_stage = args->_scene->getStage<LightStage>();
|
||||
assert(_stage);
|
||||
}
|
||||
|
||||
if (!_backgroundStage) {
|
||||
_backgroundStage = DependencyManager::get<DeferredLightingEffect>()->getBackgroundStage();
|
||||
_backgroundStage = args->_scene->getStage<BackgroundStage>();
|
||||
assert(_backgroundStage);
|
||||
}
|
||||
|
||||
{ // Sun
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include <gpu/Context.h>
|
||||
|
||||
std::string BackgroundStage::_stageName { "BACKGROUND_STAGE"};
|
||||
|
||||
BackgroundStage::Index BackgroundStage::findBackground(const BackgroundPointer& background) const {
|
||||
auto found = _backgroundMap.find(background);
|
||||
if (found != _backgroundMap.end()) {
|
||||
|
@ -52,15 +54,15 @@ BackgroundStage::BackgroundPointer BackgroundStage::removeBackground(Index index
|
|||
|
||||
|
||||
void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||
|
||||
const auto& lightingModel = inputs;
|
||||
if (!lightingModel->isBackgroundEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Background rendering decision
|
||||
auto backgroundStage = DependencyManager::get<DeferredLightingEffect>()->getBackgroundStage();
|
||||
auto backgroundStage = renderContext->_scene->getStage<BackgroundStage>();
|
||||
assert(backgroundStage);
|
||||
|
||||
model::SunSkyStagePointer background;
|
||||
model::SkyboxPointer skybox;
|
||||
if (backgroundStage->_currentFrame._backgrounds.size()) {
|
||||
|
@ -68,11 +70,8 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext,
|
|||
auto background = backgroundStage->getBackground(backgroundId);
|
||||
if (background) {
|
||||
skybox = background->getSkybox();
|
||||
}
|
||||
} else {
|
||||
skybox = DependencyManager::get<DeferredLightingEffect>()->getDefaultSkybox();
|
||||
}
|
||||
}
|
||||
|
||||
/* auto backgroundMode = skyStage->getBackgroundMode();
|
||||
|
||||
switch (backgroundMode) {
|
||||
|
@ -137,4 +136,15 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext,
|
|||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BackgroundStageSetup::BackgroundStageSetup() {
|
||||
}
|
||||
|
||||
void BackgroundStageSetup::run(const render::RenderContextPointer& renderContext) {
|
||||
auto stage = renderContext->_scene->getStage(BackgroundStage::getName());
|
||||
if (!stage) {
|
||||
renderContext->_scene->resetStage(BackgroundStage::getName(), std::make_shared<BackgroundStage>());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,13 +15,17 @@
|
|||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <render/IndexedContainer.h>
|
||||
#include <render/Stage.h>
|
||||
|
||||
#include "LightingModel.h"
|
||||
|
||||
|
||||
// Background stage to set up background-related rendering tasks
|
||||
class BackgroundStage {
|
||||
class BackgroundStage : public render::Stage {
|
||||
public:
|
||||
static std::string _stageName;
|
||||
static const std::string& getName() { return _stageName; }
|
||||
|
||||
using Index = render::indexed_container::Index;
|
||||
static const Index INVALID_INDEX { render::indexed_container::INVALID_INDEX };
|
||||
static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; }
|
||||
|
@ -66,6 +70,15 @@ public:
|
|||
};
|
||||
using BackgroundStagePointer = std::shared_ptr<BackgroundStage>;
|
||||
|
||||
class BackgroundStageSetup {
|
||||
public:
|
||||
using JobModel = render::Job::Model<BackgroundStageSetup>;
|
||||
|
||||
BackgroundStageSetup();
|
||||
void run(const render::RenderContextPointer& renderContext);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
class DrawBackgroundStage {
|
||||
public:
|
||||
|
|
|
@ -432,9 +432,10 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I
|
|||
batch.setResourceTexture(Lighting, deferredFramebuffer->getLightingTexture());
|
||||
}
|
||||
|
||||
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
||||
assert(deferredLightingEffect->getLightStage()->getNumLights() > 0);
|
||||
auto lightAndShadow = deferredLightingEffect->getLightStage()->getLightAndShadow(0);
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
assert(lightStage->getNumLights() > 0);
|
||||
auto lightAndShadow = lightStage->getLightAndShadow(0);
|
||||
const auto& globalShadow = lightAndShadow.second;
|
||||
if (globalShadow) {
|
||||
batch.setResourceTexture(Shadow, globalShadow->map);
|
||||
|
|
|
@ -99,75 +99,35 @@ void DeferredLightingEffect::init() {
|
|||
|
||||
loadLightProgram(deferred_light_vert, local_lights_shading_frag, true, _localLight, _localLightLocations);
|
||||
loadLightProgram(deferred_light_vert, local_lights_drawOutline_frag, true, _localLightOutline, _localLightOutlineLocations);
|
||||
|
||||
// Light Stage and clusters
|
||||
_lightStage = std::make_shared<LightStage>();
|
||||
|
||||
// Allocate a global light representing the Global Directional light casting shadow (the sun) and the ambient light
|
||||
_allocatedLights.push_back(std::make_shared<model::Light>());
|
||||
model::LightPointer lp = _allocatedLights[0];
|
||||
lp->setType(model::Light::SUN);
|
||||
lp->setDirection(glm::vec3(-1.0f));
|
||||
lp->setColor(glm::vec3(1.0f));
|
||||
lp->setIntensity(1.0f);
|
||||
lp->setType(model::Light::SUN);
|
||||
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset::OLD_TOWN_SQUARE);
|
||||
|
||||
// Add the global light to the light stage (for later shadow rendering)
|
||||
_globalLights.push_back(_lightStage->addLight(lp));
|
||||
_lightStage->addShadow(_globalLights[0]);
|
||||
|
||||
|
||||
_backgroundStage = std::make_shared<BackgroundStage>();
|
||||
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "Process Default Skybox");
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
|
||||
auto skyboxUrl = PathUtils::resourcesPath().toStdString() + "images/Default-Sky-9-cubemap.ktx";
|
||||
|
||||
_defaultSkyboxTexture = gpu::Texture::unserialize(skyboxUrl);
|
||||
_defaultSkyboxAmbientTexture = _defaultSkyboxTexture;
|
||||
|
||||
_defaultSkybox->setCubemap(_defaultSkyboxTexture);
|
||||
}
|
||||
|
||||
|
||||
lp->setAmbientIntensity(0.5f);
|
||||
lp->setAmbientMap(_defaultSkyboxAmbientTexture);
|
||||
auto irradianceSH = _defaultSkyboxAmbientTexture->getIrradiance();
|
||||
if (irradianceSH) {
|
||||
lp->setAmbientSphere((*irradianceSH));
|
||||
}
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) {
|
||||
void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) {
|
||||
PerformanceTimer perfTimer("DLE->setupBatch()");
|
||||
model::LightPointer keySunLight;
|
||||
if (_lightStage && _lightStage->_currentFrame._sunLights.size()) {
|
||||
keySunLight = _lightStage->getLight(_lightStage->_currentFrame._sunLights.front());
|
||||
} else {
|
||||
keySunLight = _allocatedLights[_globalLights.front()];
|
||||
auto lightStage = args->_scene->getStage<LightStage>();
|
||||
if (lightStage && lightStage->_currentFrame._sunLights.size()) {
|
||||
keySunLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front());
|
||||
}
|
||||
|
||||
model::LightPointer keyAmbiLight;
|
||||
if (_lightStage && _lightStage->_currentFrame._ambientLights.size()) {
|
||||
keyAmbiLight = _lightStage->getLight(_lightStage->_currentFrame._ambientLights.front());
|
||||
} else {
|
||||
keyAmbiLight = _allocatedLights[_globalLights.front()];
|
||||
if (lightStage && lightStage->_currentFrame._ambientLights.size()) {
|
||||
keyAmbiLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front());
|
||||
}
|
||||
|
||||
if (lightBufferUnit >= 0) {
|
||||
batch.setUniformBuffer(lightBufferUnit, keySunLight->getLightSchemaBuffer());
|
||||
}
|
||||
if (ambientBufferUnit >= 0) {
|
||||
batch.setUniformBuffer(ambientBufferUnit, keyAmbiLight->getAmbientSchemaBuffer());
|
||||
if (keySunLight) {
|
||||
if (lightBufferUnit >= 0) {
|
||||
batch.setUniformBuffer(lightBufferUnit, keySunLight->getLightSchemaBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
if (keyAmbiLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) {
|
||||
batch.setResourceTexture(skyboxCubemapUnit, keyAmbiLight->getAmbientMap());
|
||||
if (keyAmbiLight) {
|
||||
if (ambientBufferUnit >= 0) {
|
||||
batch.setUniformBuffer(ambientBufferUnit, keyAmbiLight->getAmbientSchemaBuffer());
|
||||
}
|
||||
|
||||
if (keyAmbiLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) {
|
||||
batch.setResourceTexture(skyboxCubemapUnit, keyAmbiLight->getAmbientMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,21 +226,6 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
|
|||
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) {
|
||||
/* auto globalLight = _allocatedLights.front();
|
||||
globalLight->setDirection(light->getDirection());
|
||||
globalLight->setColor(light->getColor());
|
||||
globalLight->setIntensity(light->getIntensity());
|
||||
globalLight->setAmbientIntensity(light->getAmbientIntensity());
|
||||
globalLight->setAmbientSphere(light->getAmbientSphere());
|
||||
globalLight->setAmbientMap(light->getAmbientMap());*/
|
||||
}
|
||||
|
||||
const model::LightPointer& DeferredLightingEffect::getGlobalLight() const {
|
||||
return _allocatedLights.front();
|
||||
}
|
||||
|
||||
|
||||
#include <shared/Shapes.h>
|
||||
|
||||
model::MeshPointer DeferredLightingEffect::getPointLightMesh() {
|
||||
|
@ -483,8 +428,9 @@ void PrepareDeferred::run(const RenderContextPointer& renderContext, const Input
|
|||
|
||||
|
||||
// Prepare a fresh Light Frame
|
||||
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
||||
deferredLightingEffect->getLightStage()->_currentFrame.clear();
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
lightStage->_currentFrame.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -547,8 +493,10 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
|
||||
// Global directional light and ambient pass
|
||||
|
||||
assert(deferredLightingEffect->getLightStage()->getNumLights() > 0);
|
||||
auto lightAndShadow = deferredLightingEffect->getLightStage()->getLightAndShadow(0);
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
assert(lightStage->getNumLights() > 0);
|
||||
auto lightAndShadow = lightStage->getLightAndShadow(0);
|
||||
const auto& globalShadow = lightAndShadow.second;
|
||||
|
||||
// Bind the shadow buffer
|
||||
|
@ -558,7 +506,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
|
||||
auto& program = deferredLightingEffect->_directionalSkyboxLight;
|
||||
LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations;
|
||||
const auto& keyLight = deferredLightingEffect->_allocatedLights[deferredLightingEffect->_globalLights.front()];
|
||||
|
||||
auto keyLight = lightStage->getLight(0);
|
||||
|
||||
// Setup the global directional pass pipeline
|
||||
{
|
||||
|
@ -597,7 +546,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
batch._glUniform4fv(locations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
|
||||
|
||||
// Setup the global lighting
|
||||
deferredLightingEffect->setupKeyLightBatch(batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
|
||||
deferredLightingEffect->setupKeyLightBatch(args, batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
|
||||
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
|
@ -749,3 +698,66 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
|
|||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||
config->setGPUBatchRunTime(_gpuTimer->getGPUAverage(), _gpuTimer->getBatchAverage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DefaultLightingSetup::run(const RenderContextPointer& renderContext) {
|
||||
|
||||
if (!_defaultLight || !_defaultBackground) {
|
||||
if (!_defaultSkyboxTexture) {
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
{
|
||||
PROFILE_RANGE(render, "Process Default Skybox");
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
|
||||
auto skyboxUrl = PathUtils::resourcesPath().toStdString() + "images/Default-Sky-9-cubemap.ktx";
|
||||
|
||||
_defaultSkyboxTexture = gpu::Texture::unserialize(skyboxUrl);
|
||||
_defaultSkyboxAmbientTexture = _defaultSkyboxTexture;
|
||||
|
||||
_defaultSkybox->setCubemap(_defaultSkyboxTexture);
|
||||
}
|
||||
}
|
||||
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
if (lightStage) {
|
||||
|
||||
// Allocate a default global light directional and ambient
|
||||
auto lp = std::make_shared<model::Light>();
|
||||
lp->setType(model::Light::SUN);
|
||||
lp->setDirection(glm::vec3(-1.0f));
|
||||
lp->setColor(glm::vec3(1.0f));
|
||||
lp->setIntensity(1.0f);
|
||||
lp->setType(model::Light::SUN);
|
||||
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset::OLD_TOWN_SQUARE);
|
||||
|
||||
lp->setAmbientIntensity(0.5f);
|
||||
lp->setAmbientMap(_defaultSkyboxAmbientTexture);
|
||||
auto irradianceSH = _defaultSkyboxAmbientTexture->getIrradiance();
|
||||
if (irradianceSH) {
|
||||
lp->setAmbientSphere((*irradianceSH));
|
||||
}
|
||||
|
||||
// capture default light
|
||||
_defaultLight = lp;
|
||||
|
||||
// Add the global light to the light stage (for later shadow rendering)
|
||||
_defaultLightID = lightStage->addLight(lp);
|
||||
lightStage->addShadow(_defaultLightID);
|
||||
}
|
||||
|
||||
auto backgroundStage = renderContext->_scene->getStage<BackgroundStage>();
|
||||
if (backgroundStage) {
|
||||
|
||||
auto background = std::make_shared<model::SunSkyStage>();
|
||||
background->setSkybox(_defaultSkybox);
|
||||
|
||||
// capture deault background
|
||||
_defaultBackground = background;
|
||||
|
||||
// Add the global light to the light stage (for later shadow rendering)
|
||||
_defaultBackgroundID = backgroundStage->addBackground(_defaultBackground);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,30 +47,16 @@ class DeferredLightingEffect : public Dependency {
|
|||
public:
|
||||
void init();
|
||||
|
||||
void setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit);
|
||||
void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit);
|
||||
void unsetKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit);
|
||||
|
||||
// update global lighting
|
||||
void setGlobalLight(const model::LightPointer& light);
|
||||
const model::LightPointer& getGlobalLight() const;
|
||||
|
||||
const LightStagePointer& getLightStage() { return _lightStage; }
|
||||
const BackgroundStagePointer& getBackgroundStage() { return _backgroundStage; }
|
||||
|
||||
void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
|
||||
void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
|
||||
bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; }
|
||||
|
||||
model::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; }
|
||||
gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; }
|
||||
gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; }
|
||||
|
||||
private:
|
||||
DeferredLightingEffect() = default;
|
||||
|
||||
LightStagePointer _lightStage;
|
||||
BackgroundStagePointer _backgroundStage;
|
||||
|
||||
bool _shadowMapEnabled{ false };
|
||||
bool _ambientOcclusionEnabled{ false };
|
||||
|
||||
|
@ -97,15 +83,6 @@ private:
|
|||
LightLocationsPtr _localLightLocations;
|
||||
LightLocationsPtr _localLightOutlineLocations;
|
||||
|
||||
using Lights = std::vector<model::LightPointer>;
|
||||
|
||||
Lights _allocatedLights;
|
||||
std::vector<int> _globalLights;
|
||||
|
||||
model::SkyboxPointer _defaultSkybox { new ProceduralSkybox() };
|
||||
gpu::TexturePointer _defaultSkyboxTexture;
|
||||
gpu::TexturePointer _defaultSkyboxAmbientTexture;
|
||||
|
||||
friend class LightClusteringPass;
|
||||
friend class RenderDeferredSetup;
|
||||
friend class RenderDeferredLocals;
|
||||
|
@ -195,6 +172,20 @@ protected:
|
|||
gpu::RangeTimerPointer _gpuTimer;
|
||||
};
|
||||
|
||||
class DefaultLightingSetup {
|
||||
public:
|
||||
using JobModel = render::Job::Model<DefaultLightingSetup>;
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext);
|
||||
|
||||
protected:
|
||||
model::LightPointer _defaultLight;
|
||||
LightStage::Index _defaultLightID{ LightStage::INVALID_INDEX };
|
||||
model::SunSkyStagePointer _defaultBackground;
|
||||
BackgroundStage::Index _defaultBackgroundID{ BackgroundStage::INVALID_INDEX };
|
||||
model::SkyboxPointer _defaultSkybox { new ProceduralSkybox() };
|
||||
gpu::TexturePointer _defaultSkyboxTexture;
|
||||
gpu::TexturePointer _defaultSkyboxAmbientTexture;
|
||||
};
|
||||
|
||||
#endif // hifi_DeferredLightingEffect_h
|
||||
|
|
|
@ -455,7 +455,7 @@ _nextID(0) {
|
|||
buildShapes();
|
||||
GeometryCache::_simpleOpaquePipeline =
|
||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, false, true, false), nullptr,
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch, RenderArgs* args) {
|
||||
// Set the defaults needed for a simple program
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
|
@ -463,7 +463,7 @@ _nextID(0) {
|
|||
);
|
||||
GeometryCache::_simpleTransparentPipeline =
|
||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, true, true, false), nullptr,
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch, RenderArgs* args) {
|
||||
// Set the defaults needed for a simple program
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
|
@ -471,7 +471,7 @@ _nextID(0) {
|
|||
);
|
||||
GeometryCache::_simpleWirePipeline =
|
||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, false, true, true), nullptr,
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch) {});
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch, RenderArgs* args) {});
|
||||
}
|
||||
|
||||
GeometryCache::~GeometryCache() {
|
||||
|
@ -1938,7 +1938,7 @@ uint32_t toCompactColor(const glm::vec4& color) {
|
|||
|
||||
static const size_t INSTANCE_COLOR_BUFFER = 0;
|
||||
|
||||
void renderInstances(gpu::Batch& batch, const glm::vec4& color, bool isWire,
|
||||
void renderInstances(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color, bool isWire,
|
||||
const render::ShapePipelinePointer& pipeline, GeometryCache::Shape shape) {
|
||||
// Add pipeline to name
|
||||
std::string instanceName = (isWire ? "wire_shapes_" : "solid_shapes_") + std::to_string(shape) + "_" + std::to_string(std::hash<render::ShapePipelinePointer>()(pipeline));
|
||||
|
@ -1951,9 +1951,9 @@ void renderInstances(gpu::Batch& batch, const glm::vec4& color, bool isWire,
|
|||
}
|
||||
|
||||
// Add call to named buffer
|
||||
batch.setupNamedCalls(instanceName, [isWire, pipeline, shape](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
batch.setupNamedCalls(instanceName, [args, isWire, pipeline, shape](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
batch.setPipeline(pipeline->pipeline);
|
||||
pipeline->prepare(batch);
|
||||
pipeline->prepare(batch, args);
|
||||
|
||||
if (isWire) {
|
||||
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, shape, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||
|
@ -1963,28 +1963,28 @@ void renderInstances(gpu::Batch& batch, const glm::vec4& color, bool isWire,
|
|||
});
|
||||
}
|
||||
|
||||
void GeometryCache::renderSolidShapeInstance(gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
renderInstances(batch, color, false, pipeline, shape);
|
||||
void GeometryCache::renderSolidShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
renderInstances(args, batch, color, false, pipeline, shape);
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireShapeInstance(gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
renderInstances(batch, color, true, pipeline, shape);
|
||||
void GeometryCache::renderWireShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
renderInstances(args, batch, color, true, pipeline, shape);
|
||||
}
|
||||
|
||||
|
||||
void GeometryCache::renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
renderInstances(batch, color, false, pipeline, GeometryCache::Sphere);
|
||||
void GeometryCache::renderSolidSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
renderInstances(args, batch, color, false, pipeline, GeometryCache::Sphere);
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
renderInstances(batch, color, true, pipeline, GeometryCache::Sphere);
|
||||
void GeometryCache::renderWireSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
renderInstances(args, batch, color, true, pipeline, GeometryCache::Sphere);
|
||||
}
|
||||
|
||||
// Enable this in a debug build to cause 'box' entities to iterate through all the
|
||||
// available shape types, both solid and wireframes
|
||||
//#define DEBUG_SHAPES
|
||||
|
||||
void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
void GeometryCache::renderSolidCubeInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
#ifdef DEBUG_SHAPES
|
||||
static auto startTime = usecTimestampNow();
|
||||
renderInstances(INSTANCE_NAME, batch, color, pipeline, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
|
@ -2018,11 +2018,11 @@ void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4&
|
|||
}
|
||||
});
|
||||
#else
|
||||
renderInstances(batch, color, false, pipeline, GeometryCache::Cube);
|
||||
renderInstances(args, batch, color, false, pipeline, GeometryCache::Cube);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
void GeometryCache::renderWireCubeInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||
renderInstances(batch, color, true, pipeline, GeometryCache::Cube);
|
||||
renderInstances(args, batch, color, true, pipeline, GeometryCache::Cube);
|
||||
}
|
||||
|
|
|
@ -172,46 +172,46 @@ public:
|
|||
void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||
|
||||
void renderSolidShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec4& color = glm::vec4(1),
|
||||
void renderSolidShapeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, const glm::vec4& color = glm::vec4(1),
|
||||
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
|
||||
void renderSolidShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec3& color,
|
||||
void renderSolidShapeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline) {
|
||||
renderSolidShapeInstance(batch, shape, glm::vec4(color, 1.0f), pipeline);
|
||||
renderSolidShapeInstance(args, batch, shape, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
void renderWireShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec4& color = glm::vec4(1),
|
||||
void renderWireShapeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, const glm::vec4& color = glm::vec4(1),
|
||||
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
|
||||
void renderWireShapeInstance(gpu::Batch& batch, Shape shape, const glm::vec3& color,
|
||||
void renderWireShapeInstance(RenderArgs* args, gpu::Batch& batch, Shape shape, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline) {
|
||||
renderWireShapeInstance(batch, shape, glm::vec4(color, 1.0f), pipeline);
|
||||
renderWireShapeInstance(args, batch, shape, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||
void renderSolidSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
|
||||
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||
void renderSolidSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline) {
|
||||
renderSolidSphereInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||
renderSolidSphereInstance(args, batch, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||
void renderWireSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline);
|
||||
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||
void renderWireSphereInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline) {
|
||||
renderWireSphereInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||
renderWireSphereInstance(args, batch, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||
void renderSolidCubeInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline);
|
||||
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||
void renderSolidCubeInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleOpaquePipeline) {
|
||||
renderSolidCubeInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||
renderSolidCubeInstance(args, batch, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||
void renderWireCubeInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec4& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline);
|
||||
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||
void renderWireCubeInstance(RenderArgs* args, gpu::Batch& batch, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simpleWirePipeline) {
|
||||
renderWireCubeInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||
renderWireCubeInstance(args, batch, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
// Dynamic geometry
|
||||
|
|
|
@ -574,8 +574,8 @@ void LightClusteringPass::run(const render::RenderContextPointer& renderContext,
|
|||
}
|
||||
|
||||
// From the LightStage and the current frame, update the light cluster Grid
|
||||
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
||||
auto lightStage = deferredLightingEffect->getLightStage();
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
_lightClusters->updateLightStage(lightStage);
|
||||
_lightClusters->updateLightFrame(lightStage->_currentFrame, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled());
|
||||
|
||||
|
|
|
@ -55,7 +55,8 @@ LightPayload::~LightPayload() {
|
|||
|
||||
void LightPayload::render(RenderArgs* args) {
|
||||
if (!_stage) {
|
||||
_stage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
_stage = args->_scene->getStage<LightStage>();
|
||||
assert(_stage);
|
||||
}
|
||||
// Do we need to allocate the light in the stage ?
|
||||
if (LightStage::isIndexInvalid(_index)) {
|
||||
|
@ -123,7 +124,8 @@ KeyLightPayload::~KeyLightPayload() {
|
|||
|
||||
void KeyLightPayload::render(RenderArgs* args) {
|
||||
if (!_stage) {
|
||||
_stage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
_stage = args->_scene->getStage<LightStage>();
|
||||
assert(_stage);
|
||||
}
|
||||
// Do we need to allocate the light in the stage ?
|
||||
if (LightStage::isIndexInvalid(_index)) {
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
|
||||
#include "LightStage.h"
|
||||
|
||||
std::string LightStage::_stageName { "LIGHT_STAGE"};
|
||||
|
||||
LightStage::LightStage() {
|
||||
}
|
||||
|
||||
LightStage::Shadow::Shadow(model::LightPointer light) : _light{ light}, _frustum{ std::make_shared<ViewFrustum>() } {
|
||||
framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(MAP_SIZE));
|
||||
map = framebuffer->getDepthStencilBuffer();
|
||||
|
@ -165,3 +170,14 @@ void LightStage::updateLightArrayBuffer(Index lightId) {
|
|||
}
|
||||
}
|
||||
|
||||
LightStageSetup::LightStageSetup() {
|
||||
}
|
||||
|
||||
void LightStageSetup::run(const render::RenderContextPointer& renderContext) {
|
||||
auto stage = renderContext->_scene->getStage(LightStage::getName());
|
||||
if (!stage) {
|
||||
stage = std::make_shared<LightStage>();
|
||||
renderContext->_scene->resetStage(LightStage::getName(), stage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,17 +14,23 @@
|
|||
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <gpu/Framebuffer.h>
|
||||
|
||||
#include <model/Light.h>
|
||||
|
||||
#include <render/IndexedContainer.h>
|
||||
|
||||
#include "gpu/Framebuffer.h"
|
||||
|
||||
#include "model/Light.h"
|
||||
#include <render/Stage.h>
|
||||
#include <render/Engine.h>
|
||||
|
||||
class ViewFrustum;
|
||||
|
||||
// Light stage to set up light-related rendering tasks
|
||||
class LightStage {
|
||||
class LightStage : public render::Stage {
|
||||
public:
|
||||
static std::string _stageName;
|
||||
static const std::string& getName() { return _stageName; }
|
||||
|
||||
using Index = render::indexed_container::Index;
|
||||
static const Index INVALID_INDEX { render::indexed_container::INVALID_INDEX };
|
||||
static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; }
|
||||
|
@ -93,6 +99,7 @@ public:
|
|||
LightPointer getLight(Index lightId) const {
|
||||
return _lights.get(lightId);
|
||||
}
|
||||
|
||||
Index getShadowId(Index lightId) const {
|
||||
if (checkLightId(lightId)) {
|
||||
return _descs[lightId].shadowId;
|
||||
|
@ -109,6 +116,7 @@ public:
|
|||
return LightAndShadow(getLight(lightId), getShadow(lightId));
|
||||
}
|
||||
|
||||
LightStage();
|
||||
Lights _lights;
|
||||
LightMap _lightMap;
|
||||
Descs _descs;
|
||||
|
@ -149,5 +157,15 @@ using LightStagePointer = std::shared_ptr<LightStage>;
|
|||
|
||||
|
||||
|
||||
class LightStageSetup {
|
||||
public:
|
||||
using JobModel = render::Job::Model<LightStageSetup>;
|
||||
|
||||
LightStageSetup();
|
||||
void run(const render::RenderContextPointer& renderContext);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -259,7 +259,7 @@ void MeshPartPayload::render(RenderArgs* args) {
|
|||
|
||||
gpu::Batch& batch = *(args->_batch);
|
||||
|
||||
auto locations = args->_pipeline->locations;
|
||||
auto locations = args->_shapePipeline->locations;
|
||||
assert(locations);
|
||||
|
||||
// Bind the model transform and the skinCLusterMatrices if needed
|
||||
|
@ -583,7 +583,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
gpu::Batch& batch = *(args->_batch);
|
||||
auto locations = args->_pipeline->locations;
|
||||
auto locations = args->_shapePipeline->locations;
|
||||
assert(locations);
|
||||
|
||||
bindTransform(batch, locations, args->_renderMode);
|
||||
|
|
|
@ -76,8 +76,8 @@ void initForwardPipelines(ShapePlumber& plumber);
|
|||
void addPlumberPipeline(ShapePlumber& plumber,
|
||||
const ShapeKey& key, const gpu::ShaderPointer& vertex, const gpu::ShaderPointer& pixel);
|
||||
|
||||
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch);
|
||||
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch);
|
||||
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* args);
|
||||
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* args);
|
||||
|
||||
void initOverlay3DPipelines(ShapePlumber& plumber) {
|
||||
auto vertex = gpu::Shader::createVertex(std::string(overlay3D_vert));
|
||||
|
@ -359,7 +359,7 @@ void addPlumberPipeline(ShapePlumber& plumber,
|
|||
}
|
||||
}
|
||||
|
||||
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* args) {
|
||||
// Set a default albedo map
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
|
@ -382,13 +382,13 @@ void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
|||
}
|
||||
}
|
||||
|
||||
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* args) {
|
||||
// Set the batch
|
||||
batchSetter(pipeline, batch);
|
||||
batchSetter(pipeline, batch, args);
|
||||
|
||||
// Set the light
|
||||
if (pipeline.locations->lightBufferUnit >= 0) {
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(batch,
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(args, batch,
|
||||
pipeline.locations->lightBufferUnit,
|
||||
pipeline.locations->lightAmbientBufferUnit,
|
||||
pipeline.locations->lightAmbientMapUnit);
|
||||
|
|
|
@ -35,8 +35,8 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext,
|
|||
assert(renderContext->args);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
auto lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
LightStage::Index globalLightIndex { 0 };
|
||||
|
||||
const auto globalLight = lightStage->getLight(globalLightIndex);
|
||||
|
@ -68,7 +68,7 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext,
|
|||
std::vector<ShapeKey> skinnedShapeKeys{};
|
||||
|
||||
// Iterate through all inShapes and render the unskinned
|
||||
args->_pipeline = shadowPipeline;
|
||||
args->_shapePipeline = shadowPipeline;
|
||||
batch.setPipeline(shadowPipeline->pipeline);
|
||||
for (auto items : inShapes) {
|
||||
if (items.first.isSkinned()) {
|
||||
|
@ -79,13 +79,13 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext,
|
|||
}
|
||||
|
||||
// Reiterate to render the skinned
|
||||
args->_pipeline = shadowSkinnedPipeline;
|
||||
args->_shapePipeline = shadowSkinnedPipeline;
|
||||
batch.setPipeline(shadowSkinnedPipeline->pipeline);
|
||||
for (const auto& key : skinnedShapeKeys) {
|
||||
renderItems(renderContext, inShapes.at(key));
|
||||
}
|
||||
|
||||
args->_pipeline = nullptr;
|
||||
args->_shapePipeline = nullptr;
|
||||
args->_batch = nullptr;
|
||||
});
|
||||
}
|
||||
|
@ -140,7 +140,8 @@ void RenderShadowTask::configure(const Config& configuration) {
|
|||
}
|
||||
|
||||
void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Output& output) {
|
||||
auto lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
const auto globalShadow = lightStage->getShadow(0);
|
||||
|
||||
// Cache old render args
|
||||
|
|
|
@ -532,9 +532,11 @@ void DebugSubsurfaceScattering::run(const render::RenderContextPointer& renderCo
|
|||
|
||||
|
||||
|
||||
|
||||
const auto light = DependencyManager::get<DeferredLightingEffect>()->getLightStage()->getLight(0);
|
||||
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
// const auto light = DependencyManager::get<DeferredLightingEffect>()->getLightStage()->getLight(0);
|
||||
const auto light = lightStage->getLight(0);
|
||||
|
||||
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
||||
|
|
26
libraries/render-utils/src/UpdateSceneTask.cpp
Normal file
26
libraries/render-utils/src/UpdateSceneTask.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// UpdateSceneTask.cpp
|
||||
// render-utils/src/
|
||||
//
|
||||
// Created by Sam Gateau on 6/21/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "UpdateSceneTask.h"
|
||||
|
||||
#include <render/SceneTask.h>
|
||||
#include "LightStage.h"
|
||||
#include "BackgroundStage.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
void UpdateSceneTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
|
||||
task.addJob<LightStageSetup>("LightStageSetup");
|
||||
task.addJob<BackgroundStageSetup>("BackgroundStageSetup");
|
||||
|
||||
task.addJob<DefaultLightingSetup>("DefaultLightingSetup");
|
||||
|
||||
task.addJob<render::PerformSceneTransaction>("PerformSceneTransaction");
|
||||
}
|
||||
|
30
libraries/render-utils/src/UpdateSceneTask.h
Normal file
30
libraries/render-utils/src/UpdateSceneTask.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// UpdateSceneTask.h
|
||||
// render-utils/src/
|
||||
//
|
||||
// Created by Sam Gateau on 6/21/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#pragma once
|
||||
#ifndef hifi_UpdateSceneTask_h
|
||||
#define hifi_UpdateSceneTask_h
|
||||
|
||||
#include <render/Engine.h>
|
||||
#include <render/RenderFetchCullSortTask.h>
|
||||
|
||||
|
||||
class UpdateSceneTask {
|
||||
public:
|
||||
using JobModel = render::Task::Model<UpdateSceneTask>;
|
||||
|
||||
UpdateSceneTask() {}
|
||||
|
||||
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // hifi_UpdateSceneTask_h
|
|
@ -52,13 +52,21 @@ void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& oupu
|
|||
}
|
||||
|
||||
void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) {
|
||||
|
||||
auto backgroundStage = DependencyManager::get<DeferredLightingEffect>()->getBackgroundStage();
|
||||
auto backgroundStage = context->_scene->getStage<BackgroundStage>();
|
||||
assert(backgroundStage);
|
||||
backgroundStage->_currentFrame.clear();
|
||||
|
||||
// call render in the correct order first...
|
||||
render::renderItems(context, inputs);
|
||||
|
||||
// Finally add the default lights and background:
|
||||
auto lightStage = context->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
|
||||
lightStage->_currentFrame.pushSunLight(0);
|
||||
lightStage->_currentFrame.pushAmbientLight(0);
|
||||
|
||||
backgroundStage->_currentFrame.pushBackground(0);
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() {
|
||||
|
@ -130,14 +138,13 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I
|
|||
|
||||
auto deferredTransform = inputs;
|
||||
|
||||
auto lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
auto lightStage = context->_scene->getStage<LightStage>(LightStage::getName());
|
||||
std::vector<model::LightPointer> keyLightStack;
|
||||
if (lightStage && lightStage->_currentFrame._sunLights.size()) {
|
||||
for (auto index : lightStage->_currentFrame._sunLights) {
|
||||
keyLightStack.push_back(lightStage->getLight(index));
|
||||
}
|
||||
}
|
||||
keyLightStack.push_back(DependencyManager::get<DeferredLightingEffect>()->getGlobalLight());
|
||||
|
||||
std::vector<model::LightPointer> ambientLightStack;
|
||||
if (lightStage && lightStage->_currentFrame._ambientLights.size()) {
|
||||
|
@ -145,10 +152,8 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I
|
|||
ambientLightStack.push_back(lightStage->getLight(index));
|
||||
}
|
||||
}
|
||||
ambientLightStack.push_back(DependencyManager::get<DeferredLightingEffect>()->getGlobalLight());
|
||||
|
||||
|
||||
auto backgroundStage = DependencyManager::get<DeferredLightingEffect>()->getBackgroundStage();
|
||||
auto backgroundStage = context->_scene->getStage<BackgroundStage>(BackgroundStage::getName());
|
||||
std::vector<model::SkyboxPointer> skyboxStack;
|
||||
if (backgroundStage && backgroundStage->_currentFrame._backgrounds.size()) {
|
||||
for (auto index : backgroundStage->_currentFrame._backgrounds) {
|
||||
|
@ -157,8 +162,7 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I
|
|||
skyboxStack.push_back(background->getSkybox());
|
||||
}
|
||||
}
|
||||
}
|
||||
skyboxStack.push_back(DependencyManager::get<DeferredLightingEffect>()->getDefaultSkybox());
|
||||
}
|
||||
|
||||
|
||||
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||
|
|
|
@ -103,7 +103,7 @@ namespace render {
|
|||
|
||||
std::shared_ptr<gpu::Context> _context;
|
||||
std::shared_ptr<gpu::Framebuffer> _blitFramebuffer;
|
||||
std::shared_ptr<render::ShapePipeline> _pipeline;
|
||||
std::shared_ptr<render::ShapePipeline> _shapePipeline;
|
||||
QSharedPointer<QObject> _renderData;
|
||||
std::stack<ViewFrustum> _viewFrustums;
|
||||
glm::ivec4 _viewport { 0.0f, 0.0f, 1.0f, 1.0f };
|
||||
|
|
|
@ -43,11 +43,11 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons
|
|||
assert(item.getKey().isShape());
|
||||
auto key = item.getShapeKey() | globalKey;
|
||||
if (key.isValid() && !key.hasOwnPipeline()) {
|
||||
args->_pipeline = shapeContext->pickPipeline(args, key);
|
||||
if (args->_pipeline) {
|
||||
args->_shapePipeline = shapeContext->pickPipeline(args, key);
|
||||
if (args->_shapePipeline) {
|
||||
item.render(args);
|
||||
}
|
||||
args->_pipeline = nullptr;
|
||||
args->_shapePipeline = nullptr;
|
||||
} else if (key.hasOwnPipeline()) {
|
||||
item.render(args);
|
||||
} else {
|
||||
|
@ -109,15 +109,15 @@ void render::renderStateSortShapes(const RenderContextPointer& renderContext,
|
|||
// Then render
|
||||
for (auto& pipelineKey : sortedPipelines) {
|
||||
auto& bucket = sortedShapes[pipelineKey];
|
||||
args->_pipeline = shapeContext->pickPipeline(args, pipelineKey);
|
||||
if (!args->_pipeline) {
|
||||
args->_shapePipeline = shapeContext->pickPipeline(args, pipelineKey);
|
||||
if (!args->_shapePipeline) {
|
||||
continue;
|
||||
}
|
||||
for (auto& item : bucket) {
|
||||
item.render(args);
|
||||
}
|
||||
}
|
||||
args->_pipeline = nullptr;
|
||||
args->_shapePipeline = nullptr;
|
||||
for (auto& item : ownPipelineBucket) {
|
||||
item.render(args);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <gpu/Context.h>
|
||||
|
||||
#include "EngineStats.h"
|
||||
#include "SceneTask.h"
|
||||
|
||||
#include "Logging.h"
|
||||
|
||||
using namespace render;
|
||||
|
|
|
@ -237,3 +237,26 @@ void Scene::resetSelections(const Selections& selections) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Access a particular Stage (empty if doesn't exist)
|
||||
// Thread safe
|
||||
StagePointer Scene::getStage(const Stage::Name& name) const {
|
||||
std::unique_lock<std::mutex> lock(_stagesMutex);
|
||||
auto found = _stages.find(name);
|
||||
if (found == _stages.end()) {
|
||||
return StagePointer();
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Scene::resetStage(const Stage::Name& name, const StagePointer& stage) {
|
||||
std::unique_lock<std::mutex> lock(_stagesMutex);
|
||||
auto found = _stages.find(name);
|
||||
if (found == _stages.end()) {
|
||||
_stages.insert(StageMap::value_type(name, stage));
|
||||
} else {
|
||||
(*found).second = stage;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "Item.h"
|
||||
#include "SpatialTree.h"
|
||||
#include "Stage.h"
|
||||
#include "Selection.h"
|
||||
|
||||
namespace render {
|
||||
|
@ -110,6 +111,19 @@ public:
|
|||
// Access non-spatialized items (overlays, backgrounds)
|
||||
const ItemIDSet& getNonspatialSet() const { return _masterNonspatialSet; }
|
||||
|
||||
|
||||
|
||||
// Access a particular Stage (empty if doesn't exist)
|
||||
// Thread safe
|
||||
StagePointer getStage(const Stage::Name& name) const;
|
||||
template <class T>
|
||||
std::shared_ptr<T> getStage(const Stage::Name& name = T::getName()) const {
|
||||
auto stage = getStage(name);
|
||||
return (stage ? std::static_pointer_cast<T>(stage) : std::shared_ptr<T>());
|
||||
}
|
||||
void resetStage(const Stage::Name& name, const StagePointer& stage);
|
||||
|
||||
|
||||
protected:
|
||||
// Thread safe elements that can be accessed from anywhere
|
||||
std::atomic<unsigned int> _IDAllocator{ 1 }; // first valid itemID will be One
|
||||
|
@ -128,7 +142,6 @@ protected:
|
|||
void removeItems(const ItemIDs& ids);
|
||||
void updateItems(const ItemIDs& ids, UpdateFunctors& functors);
|
||||
|
||||
|
||||
// The Selection map
|
||||
mutable std::mutex _selectionsMutex; // mutable so it can be used in the thread safe getSelection const method
|
||||
SelectionMap _selections;
|
||||
|
@ -139,6 +152,11 @@ protected:
|
|||
// void appendToSelection(const Selection& selection);
|
||||
// void mergeWithSelection(const Selection& selection);
|
||||
|
||||
// The Stage map
|
||||
mutable std::mutex _stagesMutex; // mutable so it can be used in the thread safe getStage const method
|
||||
StageMap _stages;
|
||||
|
||||
|
||||
friend class Engine;
|
||||
};
|
||||
|
||||
|
|
21
libraries/render/src/render/SceneTask.cpp
Normal file
21
libraries/render/src/render/SceneTask.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// SceneTask.cpp
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Sam Gateau on 6/14/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "SceneTask.h"
|
||||
|
||||
|
||||
using namespace render;
|
||||
|
||||
void PerformSceneTransaction::configure(const Config& config) {
|
||||
}
|
||||
|
||||
void PerformSceneTransaction::run(const RenderContextPointer& renderContext) {
|
||||
renderContext->_scene->processTransactionQueue();
|
||||
}
|
41
libraries/render/src/render/SceneTask.h
Normal file
41
libraries/render/src/render/SceneTask.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// SceneTask.h
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Sam Gateau on 6/14/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_render_SceneTask_h
|
||||
#define hifi_render_SceneTask_h
|
||||
|
||||
#include "Engine.h"
|
||||
|
||||
namespace render {
|
||||
|
||||
class PerformSceneTransactionConfig : public Job::Config {
|
||||
Q_OBJECT
|
||||
public:
|
||||
signals:
|
||||
void dirty();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
class PerformSceneTransaction {
|
||||
public:
|
||||
using Config = PerformSceneTransactionConfig;
|
||||
using JobModel = Job::Model<PerformSceneTransaction, Config>;
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const RenderContextPointer& renderContext);
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_render_SceneTask_h
|
|
@ -17,9 +17,9 @@
|
|||
|
||||
using namespace render;
|
||||
|
||||
void ShapePipeline::prepare(gpu::Batch& batch) {
|
||||
void ShapePipeline::prepare(gpu::Batch& batch, RenderArgs* args) {
|
||||
if (batchSetter) {
|
||||
batchSetter(*this, batch);
|
||||
batchSetter(*this, batch, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Ke
|
|||
|
||||
// Run the pipeline's BatchSetter on the passed in batch
|
||||
if (shapePipeline->batchSetter) {
|
||||
shapePipeline->batchSetter(*shapePipeline, *batch);
|
||||
shapePipeline->batchSetter(*shapePipeline, *batch, args);
|
||||
}
|
||||
|
||||
return shapePipeline;
|
||||
|
|
|
@ -240,14 +240,14 @@ public:
|
|||
};
|
||||
using LocationsPointer = std::shared_ptr<Locations>;
|
||||
|
||||
using BatchSetter = std::function<void(const ShapePipeline&, gpu::Batch&)>;
|
||||
using BatchSetter = std::function<void(const ShapePipeline&, gpu::Batch&, RenderArgs* args)>;
|
||||
|
||||
ShapePipeline(gpu::PipelinePointer pipeline, LocationsPointer locations, BatchSetter batchSetter) :
|
||||
pipeline(pipeline), locations(locations), batchSetter(batchSetter) {}
|
||||
|
||||
// Normally, a pipeline is accessed thorugh pickPipeline. If it needs to be set manually,
|
||||
// after calling setPipeline this method should be called to prepare the pipeline with default buffers.
|
||||
void prepare(gpu::Batch& batch);
|
||||
void prepare(gpu::Batch& batch, RenderArgs* args);
|
||||
|
||||
gpu::PipelinePointer pipeline;
|
||||
std::shared_ptr<Locations> locations;
|
||||
|
|
26
libraries/render/src/render/Stage.cpp
Normal file
26
libraries/render/src/render/Stage.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Stage.cpp
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Sam Gateau on 6/14/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "Stage.h"
|
||||
|
||||
|
||||
using namespace render;
|
||||
|
||||
|
||||
|
||||
Stage::~Stage() {
|
||||
|
||||
}
|
||||
|
||||
Stage::Stage() :
|
||||
_name()
|
||||
{
|
||||
}
|
||||
|
38
libraries/render/src/render/Stage.h
Normal file
38
libraries/render/src/render/Stage.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// Stage.h
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Sam Gateau on 6/14/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_render_Stage_h
|
||||
#define hifi_render_Stage_h
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace render {
|
||||
|
||||
class Stage {
|
||||
public:
|
||||
using Name = std::string;
|
||||
|
||||
Stage();
|
||||
virtual ~Stage();
|
||||
|
||||
protected:
|
||||
Name _name;
|
||||
};
|
||||
|
||||
using StagePointer = std::shared_ptr<Stage>;
|
||||
|
||||
using StageMap = std::map<const Stage::Name, StagePointer>;
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_render_Stage_h
|
|
@ -77,7 +77,6 @@ void TestWindow::initGl() {
|
|||
#ifdef DEFERRED_LIGHTING
|
||||
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
||||
deferredLightingEffect->init();
|
||||
deferredLightingEffect->setGlobalLight(_light);
|
||||
initDeferredPipelines(*_shapePlumber);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -889,11 +889,6 @@ private:
|
|||
BackgroundRenderData::_item = _main3DScene->allocateID();
|
||||
transaction.resetItem(BackgroundRenderData::_item, backgroundRenderPayload);
|
||||
}
|
||||
// Setup the current Zone Entity lighting
|
||||
{
|
||||
auto stage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(stage->getSunLight());
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("SceneProcessTransaction");
|
||||
|
@ -914,8 +909,6 @@ private:
|
|||
PerformanceTimer perfTimer("draw");
|
||||
// The pending changes collecting the changes here
|
||||
render::Transaction transaction;
|
||||
// Setup the current Zone Entity lighting
|
||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(_sunSkyStage.getSunLight());
|
||||
{
|
||||
PerformanceTimer perfTimer("SceneProcessTransaction");
|
||||
_main3DScene->enqueueTransaction(transaction);
|
||||
|
|
Loading…
Reference in a new issue