Merge pull request from zzmp/feat/render-forward-empty

Forward render task (empty and only used with RENDER_FORWARD set)
This commit is contained in:
samcake 2016-12-15 09:57:18 -08:00 committed by GitHub
commit 7a29dbe7d4
4 changed files with 229 additions and 18 deletions

View file

@ -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

View file

@ -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);
}
}
}
{

View 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;
}

View 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