mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 12:13:28 +02:00
Merge pull request #9207 from zzmp/feat/render-forward-empty
Forward render task (empty and only used with RENDER_FORWARD set)
This commit is contained in:
commit
7a29dbe7d4
4 changed files with 229 additions and 18 deletions
interface/src
libraries/render-utils/src
|
@ -98,6 +98,7 @@
|
|||
#include <RenderableWebEntityItem.h>
|
||||
#include <RenderShadowTask.h>
|
||||
#include <RenderDeferredTask.h>
|
||||
#include <RenderForwardTask.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <SandboxUtils.h>
|
||||
#include <SceneScriptingInterface.h>
|
||||
|
@ -1745,10 +1746,14 @@ void Application::initializeGL() {
|
|||
// Set up the render engine
|
||||
render::CullFunctor cullFunctor = LODManager::shouldRender;
|
||||
_renderEngine->addJob<RenderShadowTask>("RenderShadowTask", cullFunctor);
|
||||
_renderEngine->addJob<RenderDeferredTask>("RenderDeferredTask", cullFunctor);
|
||||
static const QString RENDER_FORWARD = "RENDER_FORWARD";
|
||||
if (QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD)) {
|
||||
_renderEngine->addJob<RenderForwardTask>("RenderForwardTask", cullFunctor);
|
||||
} else {
|
||||
_renderEngine->addJob<RenderDeferredTask>("RenderDeferredTask", cullFunctor);
|
||||
}
|
||||
_renderEngine->load();
|
||||
_renderEngine->registerScene(_main3DScene);
|
||||
// TODO: Load a cached config file
|
||||
|
||||
// The UI can't be created until the primary OpenGL
|
||||
// context is created, because it needs to share
|
||||
|
|
|
@ -292,23 +292,24 @@ void setupPreferences() {
|
|||
{
|
||||
static const QString RENDER("Graphics");
|
||||
auto renderConfig = qApp->getRenderEngine()->getConfiguration();
|
||||
if (renderConfig) {
|
||||
auto ambientOcclusionConfig = renderConfig->getConfig<AmbientOcclusionEffect>();
|
||||
if (ambientOcclusionConfig) {
|
||||
auto getter = [ambientOcclusionConfig]()->QString { return ambientOcclusionConfig->getPreset(); };
|
||||
auto setter = [ambientOcclusionConfig](QString preset) { ambientOcclusionConfig->setPreset(preset); };
|
||||
auto preference = new ComboBoxPreference(RENDER, "Ambient occlusion", getter, setter);
|
||||
preference->setItems(ambientOcclusionConfig->getPresetList());
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
|
||||
auto ambientOcclusionConfig = renderConfig->getConfig<AmbientOcclusionEffect>();
|
||||
{
|
||||
auto getter = [ambientOcclusionConfig]()->QString { return ambientOcclusionConfig->getPreset(); };
|
||||
auto setter = [ambientOcclusionConfig](QString preset) { ambientOcclusionConfig->setPreset(preset); };
|
||||
auto preference = new ComboBoxPreference(RENDER, "Ambient occlusion", getter, setter);
|
||||
preference->setItems(ambientOcclusionConfig->getPresetList());
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
|
||||
auto shadowConfig = renderConfig->getConfig<RenderShadowTask>();
|
||||
{
|
||||
auto getter = [shadowConfig]()->QString { return shadowConfig->getPreset(); };
|
||||
auto setter = [shadowConfig](QString preset) { shadowConfig->setPreset(preset); };
|
||||
auto preference = new ComboBoxPreference(RENDER, "Shadows", getter, setter);
|
||||
preference->setItems(shadowConfig->getPresetList());
|
||||
preferences->addPreference(preference);
|
||||
auto shadowConfig = renderConfig->getConfig<RenderShadowTask>();
|
||||
if (shadowConfig) {
|
||||
auto getter = [shadowConfig]()->QString { return shadowConfig->getPreset(); };
|
||||
auto setter = [shadowConfig](QString preset) { shadowConfig->setPreset(preset); };
|
||||
auto preference = new ComboBoxPreference(RENDER, "Shadows", getter, setter);
|
||||
preference->setItems(shadowConfig->getPresetList());
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
|
|
163
libraries/render-utils/src/RenderForwardTask.cpp
Executable file
163
libraries/render-utils/src/RenderForwardTask.cpp
Executable file
|
@ -0,0 +1,163 @@
|
|||
|
||||
//
|
||||
// RenderForwardTask.cpp
|
||||
// render-utils/src/
|
||||
//
|
||||
// Created by Zach Pomerantz on 12/13/2016.
|
||||
// Copyright 2016 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 "RenderForwardTask.h"
|
||||
#include "RenderDeferredTask.h"
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <PathUtils.h>
|
||||
#include <RenderArgs.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
#include <render/CullTask.h>
|
||||
#include <render/SortTask.h>
|
||||
#include <render/DrawTask.h>
|
||||
#include <render/DrawStatus.h>
|
||||
#include <render/DrawSceneOctree.h>
|
||||
#include <render/BlurTask.h>
|
||||
|
||||
#include "LightingModel.h"
|
||||
#include "DebugDeferredBuffer.h"
|
||||
#include "DeferredFramebuffer.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
#include "SurfaceGeometryPass.h"
|
||||
#include "FramebufferCache.h"
|
||||
#include "HitEffect.h"
|
||||
#include "TextureCache.h"
|
||||
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
#include "AntialiasingEffect.h"
|
||||
#include "ToneMappingEffect.h"
|
||||
#include "SubsurfaceScattering.h"
|
||||
|
||||
#include <gpu/StandardShaderLib.h>
|
||||
|
||||
#include "drawOpaqueStencil_frag.h"
|
||||
|
||||
|
||||
using namespace render;
|
||||
extern void initOverlay3DPipelines(render::ShapePlumber& plumber);
|
||||
extern void initDeferredPipelines(render::ShapePlumber& plumber);
|
||||
|
||||
RenderForwardTask::RenderForwardTask(CullFunctor cullFunctor) {
|
||||
// Prepare the ShapePipelines
|
||||
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
||||
initDeferredPipelines(*shapePlumber);
|
||||
|
||||
// CPU jobs:
|
||||
// Fetch and cull the items from the scene
|
||||
const auto spatialSelection = addJob<FetchSpatialTree>("FetchSceneSelection");
|
||||
|
||||
cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; };
|
||||
auto spatialFilter = ItemFilter::Builder::visibleWorldItems().withoutLayered();
|
||||
const auto culledSpatialSelection = addJob<CullSpatialSelection>("CullSceneSelection", spatialSelection, cullFunctor, RenderDetails::ITEM, spatialFilter);
|
||||
|
||||
// Overlays are not culled
|
||||
const auto nonspatialSelection = addJob<FetchNonspatialItems>("FetchOverlaySelection");
|
||||
|
||||
// Multi filter visible items into different buckets
|
||||
const int NUM_FILTERS = 3;
|
||||
const int OPAQUE_SHAPE_BUCKET = 0;
|
||||
const int TRANSPARENT_SHAPE_BUCKET = 1;
|
||||
const int LIGHT_BUCKET = 2;
|
||||
const int BACKGROUND_BUCKET = 2;
|
||||
MultiFilterItem<NUM_FILTERS>::ItemFilterArray spatialFilters = { {
|
||||
ItemFilter::Builder::opaqueShape(),
|
||||
ItemFilter::Builder::transparentShape(),
|
||||
ItemFilter::Builder::light()
|
||||
} };
|
||||
MultiFilterItem<NUM_FILTERS>::ItemFilterArray nonspatialFilters = { {
|
||||
ItemFilter::Builder::opaqueShape(),
|
||||
ItemFilter::Builder::transparentShape(),
|
||||
ItemFilter::Builder::background()
|
||||
} };
|
||||
const auto filteredSpatialBuckets = addJob<MultiFilterItem<NUM_FILTERS>>("FilterSceneSelection", culledSpatialSelection, spatialFilters).get<MultiFilterItem<NUM_FILTERS>::ItemBoundsArray>();
|
||||
const auto filteredNonspatialBuckets = addJob<MultiFilterItem<NUM_FILTERS>>("FilterOverlaySelection", nonspatialSelection, nonspatialFilters).get<MultiFilterItem<NUM_FILTERS>::ItemBoundsArray>();
|
||||
|
||||
// Extract / Sort opaques / Transparents / Lights / Overlays
|
||||
const auto opaques = addJob<DepthSortItems>("DepthSortOpaque", filteredSpatialBuckets[OPAQUE_SHAPE_BUCKET]);
|
||||
const auto transparents = addJob<DepthSortItems>("DepthSortTransparent", filteredSpatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false));
|
||||
const auto lights = filteredSpatialBuckets[LIGHT_BUCKET];
|
||||
|
||||
const auto overlayOpaques = addJob<DepthSortItems>("DepthSortOverlayOpaque", filteredNonspatialBuckets[OPAQUE_SHAPE_BUCKET]);
|
||||
const auto overlayTransparents = addJob<DepthSortItems>("DepthSortOverlayTransparent", filteredNonspatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false));
|
||||
const auto background = filteredNonspatialBuckets[BACKGROUND_BUCKET];
|
||||
|
||||
const auto framebuffer = addJob<PrepareFramebuffer>("PrepareFramebuffer");
|
||||
|
||||
// Blit!
|
||||
addJob<Blit>("Blit", framebuffer);
|
||||
}
|
||||
|
||||
void RenderForwardTask::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
// sanity checks
|
||||
assert(sceneContext);
|
||||
if (!sceneContext->_scene) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Is it possible that we render without a viewFrustum ?
|
||||
if (!(renderContext->args && renderContext->args->hasViewFrustum())) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||
|
||||
for (auto job : _jobs) {
|
||||
job.run(sceneContext, renderContext);
|
||||
}
|
||||
}
|
||||
|
||||
void PrepareFramebuffer::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer) {
|
||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
auto framebufferSize = framebufferCache->getFrameBufferSize();
|
||||
glm::uvec2 frameSize(framebufferSize.width(), framebufferSize.height());
|
||||
|
||||
// Resizing framebuffers instead of re-building them seems to cause issues with threaded rendering
|
||||
if (_framebuffer && _framebuffer->getSize() != frameSize) {
|
||||
_framebuffer.reset();
|
||||
}
|
||||
|
||||
if (!_framebuffer) {
|
||||
_framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("forward"));
|
||||
|
||||
auto colorFormat = gpu::Element::COLOR_SRGBA_32;
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
|
||||
auto colorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, frameSize.x, frameSize.y, defaultSampler));
|
||||
_framebuffer->setRenderBuffer(0, colorTexture);
|
||||
|
||||
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
|
||||
auto depthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, frameSize.x, frameSize.y, defaultSampler));
|
||||
_framebuffer->setDepthStencilBuffer(depthTexture, depthFormat);
|
||||
}
|
||||
|
||||
auto args = renderContext->args;
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setStateScissorRect(args->_viewport);
|
||||
|
||||
batch.setFramebuffer(_framebuffer);
|
||||
batch.clearFramebuffer(
|
||||
gpu::Framebuffer::BUFFER_COLOR0 |
|
||||
gpu::Framebuffer::BUFFER_COLOR1 |
|
||||
gpu::Framebuffer::BUFFER_COLOR2 |
|
||||
gpu::Framebuffer::BUFFER_COLOR3 |
|
||||
gpu::Framebuffer::BUFFER_DEPTH |
|
||||
gpu::Framebuffer::BUFFER_STENCIL,
|
||||
vec4(vec3(0), 0), 1.0, 0.0, true);
|
||||
});
|
||||
|
||||
framebuffer = _framebuffer;
|
||||
}
|
42
libraries/render-utils/src/RenderForwardTask.h
Executable file
42
libraries/render-utils/src/RenderForwardTask.h
Executable file
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// RenderForwardTask.h
|
||||
// render-utils/src/
|
||||
//
|
||||
// Created by Zach Pomerantz on 12/13/2016.
|
||||
// Copyright 2016 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_RenderForwardTask_h
|
||||
#define hifi_RenderForwardTask_h
|
||||
|
||||
#include <gpu/Pipeline.h>
|
||||
#include <render/CullTask.h>
|
||||
#include "LightingModel.h"
|
||||
|
||||
using RenderForwardTaskConfig = render::GPUTaskConfig;
|
||||
|
||||
class RenderForwardTask : public render::Task {
|
||||
public:
|
||||
using Config = RenderForwardTaskConfig;
|
||||
RenderForwardTask(render::CullFunctor cullFunctor);
|
||||
|
||||
void configure(const Config& config) {}
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
using JobModel = Model<RenderForwardTask, Config>;
|
||||
};
|
||||
|
||||
class PrepareFramebuffer {
|
||||
public:
|
||||
using JobModel = render::Job::ModelO<PrepareFramebuffer, gpu::FramebufferPointer>;
|
||||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer);
|
||||
|
||||
private:
|
||||
gpu::FramebufferPointer _framebuffer;
|
||||
};
|
||||
|
||||
#endif // hifi_RenderForwardTask_h
|
Loading…
Reference in a new issue