mirror of
https://github.com/overte-org/overte.git
synced 2025-07-10 21:38:40 +02:00
218 lines
8.5 KiB
C++
218 lines
8.5 KiB
C++
//
|
|
// ZoneRenderer.cpp
|
|
// render/src/render-utils
|
|
//
|
|
// Created by Sam Gateau on 4/4/2017.
|
|
// Copyright 2017 High Fidelity, Inc.
|
|
// Copyright 2024 Overte e.V.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
#include "ZoneRenderer.h"
|
|
|
|
#include <gpu/Context.h>
|
|
|
|
#include <render/FilterTask.h>
|
|
#include <render/DrawTask.h>
|
|
#include <shaders/Shaders.h>
|
|
#include <gpu/ShaderConstants.h>
|
|
#include <graphics/ShaderConstants.h>
|
|
|
|
#include "StencilMaskPass.h"
|
|
#include "DeferredLightingEffect.h"
|
|
|
|
#include "render-utils/ShaderConstants.h"
|
|
#include "StencilMaskPass.h"
|
|
#include "DeferredLightingEffect.h"
|
|
|
|
#include "BloomStage.h"
|
|
#include "TonemappingStage.h"
|
|
|
|
namespace ru {
|
|
using render_utils::slot::texture::Texture;
|
|
using render_utils::slot::buffer::Buffer;
|
|
}
|
|
|
|
namespace gr {
|
|
using graphics::slot::texture::Texture;
|
|
using graphics::slot::buffer::Buffer;
|
|
}
|
|
|
|
using namespace render;
|
|
|
|
const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" };
|
|
|
|
void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& output) {
|
|
// Filter out the sorted list of zones
|
|
// FIXME: the zones in the selection are already sorted, but we're doing another sort here to pick the selected items
|
|
// out of `input`, which means we're also looping over the inItems an extra time.
|
|
const auto zoneItems = task.addJob<render::SelectSortItems>("FilterZones", input, ZONES_SELECTION);
|
|
|
|
// just setup the current zone env
|
|
task.addJob<SetupZones>("SetupZones", zoneItems);
|
|
|
|
output = zoneItems;
|
|
}
|
|
|
|
void SetupZones::run(const RenderContextPointer& context, const Input& input) {
|
|
// Grab light, background, haze, and bloom stages and clear them
|
|
auto lightStage = context->_scene->getStage<LightStage>();
|
|
assert(lightStage);
|
|
lightStage->_currentFrame.clear();
|
|
|
|
auto backgroundStage = context->_scene->getStage<BackgroundStage>();
|
|
assert(backgroundStage);
|
|
backgroundStage->_currentFrame.clear();
|
|
|
|
auto hazeStage = context->_scene->getStage<HazeStage>();
|
|
assert(hazeStage);
|
|
hazeStage->_currentFrame.clear();
|
|
|
|
auto bloomStage = context->_scene->getStage<BloomStage>();
|
|
assert(bloomStage);
|
|
bloomStage->_currentFrame.clear();
|
|
|
|
auto tonemappingStage = context->_scene->getStage<TonemappingStage>();
|
|
assert(tonemappingStage);
|
|
tonemappingStage->_currentFrame.clear();
|
|
|
|
auto ambientOcclusionStage = context->_scene->getStage<AmbientOcclusionStage>();
|
|
assert(ambientOcclusionStage);
|
|
ambientOcclusionStage->_currentFrame.clear();
|
|
|
|
// call render over the zones to grab their components in the correct order first...
|
|
render::renderItems(context, input);
|
|
|
|
// Finally add the default lights and background:
|
|
lightStage->_currentFrame.pushSunLight(lightStage->getDefaultLight());
|
|
lightStage->_currentFrame.pushAmbientLight(lightStage->getDefaultLight());
|
|
backgroundStage->_currentFrame.pushElement(0);
|
|
hazeStage->_currentFrame.pushElement(0);
|
|
bloomStage->_currentFrame.pushElement(INVALID_INDEX);
|
|
tonemappingStage->_currentFrame.pushElement(0);
|
|
ambientOcclusionStage->_currentFrame.pushElement(INVALID_INDEX);
|
|
}
|
|
|
|
gpu::PipelinePointer DebugZoneLighting::_keyLightPipeline;
|
|
gpu::PipelinePointer DebugZoneLighting::_ambientPipeline;
|
|
gpu::PipelinePointer DebugZoneLighting::_backgroundPipeline;
|
|
|
|
const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() {
|
|
if (!_keyLightPipeline) {
|
|
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::zone_drawKeyLight);
|
|
gpu::StatePointer state = std::make_shared<gpu::State>();
|
|
|
|
PrepareStencil::testMaskResetNoAA(*state);
|
|
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
|
_keyLightPipeline = gpu::Pipeline::create(program, state);
|
|
}
|
|
return _keyLightPipeline;
|
|
}
|
|
|
|
const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() {
|
|
if (!_ambientPipeline) {
|
|
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::zone_drawAmbient);
|
|
gpu::StatePointer state = std::make_shared<gpu::State>();
|
|
|
|
PrepareStencil::testMaskResetNoAA(*state);
|
|
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
|
_ambientPipeline = gpu::Pipeline::create(program, state);
|
|
}
|
|
return _ambientPipeline;
|
|
}
|
|
|
|
const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() {
|
|
if (!_backgroundPipeline) {
|
|
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::zone_drawSkybox);
|
|
gpu::StatePointer state = std::make_shared<gpu::State>();
|
|
|
|
PrepareStencil::testMaskResetNoAA(*state);
|
|
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
|
_backgroundPipeline = gpu::Pipeline::create(program, state);
|
|
}
|
|
return _backgroundPipeline;
|
|
}
|
|
|
|
void DebugZoneLighting::run(const render::RenderContextPointer& context, const Inputs& inputs) {
|
|
RenderArgs* args = context->args;
|
|
|
|
auto deferredTransform = inputs.get0();
|
|
auto lightFrame = inputs.get1();
|
|
auto backgroundFrame = inputs.get2();
|
|
|
|
auto lightStage = context->_scene->getStage<LightStage>(LightStage::getName());
|
|
std::vector<graphics::LightPointer> keyLightStack;
|
|
if (lightStage && lightFrame->_sunLights.size()) {
|
|
for (auto index : lightFrame->_sunLights) {
|
|
keyLightStack.push_back(lightStage->getElement(index));
|
|
}
|
|
}
|
|
|
|
std::vector<graphics::LightPointer> ambientLightStack;
|
|
if (lightStage && lightFrame->_ambientLights.size()) {
|
|
for (auto index : lightFrame->_ambientLights) {
|
|
ambientLightStack.push_back(lightStage->getElement(index));
|
|
}
|
|
}
|
|
|
|
auto backgroundStage = context->_scene->getStage<BackgroundStage>(BackgroundStage::getName());
|
|
std::vector<graphics::SkyboxPointer> skyboxStack;
|
|
if (backgroundStage && backgroundFrame->_elements.size()) {
|
|
for (auto index : backgroundFrame->_elements) {
|
|
auto background = backgroundStage->getElement(index);
|
|
if (background) {
|
|
skyboxStack.push_back(background->getSkybox());
|
|
}
|
|
}
|
|
}
|
|
|
|
gpu::doInBatch("DebugZoneLighting::run", args->_context, [=](gpu::Batch& batch) {
|
|
|
|
batch.setViewportTransform(args->_viewport);
|
|
auto viewFrustum = args->getViewFrustum();
|
|
batch.setProjectionTransform(viewFrustum.getProjection());
|
|
batch.resetViewTransform();
|
|
|
|
Transform model;
|
|
|
|
batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, deferredTransform->getFrameTransformBuffer());
|
|
|
|
batch.setPipeline(getKeyLightPipeline());
|
|
auto numKeys = (int) keyLightStack.size();
|
|
for (int i = numKeys - 1; i >= 0; i--) {
|
|
model.setTranslation(glm::vec3(-4.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0)));
|
|
batch.setModelTransform(model);
|
|
if (keyLightStack[i]) {
|
|
batch.setUniformBuffer(gr::Buffer::KeyLight, keyLightStack[i]->getLightSchemaBuffer());
|
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
|
}
|
|
}
|
|
|
|
batch.setPipeline(getAmbientPipeline());
|
|
auto numAmbients = (int) ambientLightStack.size();
|
|
for (int i = numAmbients - 1; i >= 0; i--) {
|
|
model.setTranslation(glm::vec3(0.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0)));
|
|
batch.setModelTransform(model);
|
|
if (ambientLightStack[i]) {
|
|
batch.setUniformBuffer(gr::Buffer::AmbientLight, ambientLightStack[i]->getAmbientSchemaBuffer());
|
|
if (ambientLightStack[i]->getAmbientMap()) {
|
|
batch.setResourceTexture(ru::Texture::Skybox, ambientLightStack[i]->getAmbientMap());
|
|
}
|
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
|
}
|
|
}
|
|
|
|
batch.setPipeline(getBackgroundPipeline());
|
|
auto numBackgrounds = (int) skyboxStack.size();
|
|
for (int i = numBackgrounds - 1; i >= 0; i--) {
|
|
model.setTranslation(glm::vec3(4.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0)));
|
|
batch.setModelTransform(model);
|
|
if (skyboxStack[i]) {
|
|
batch.setResourceTexture(ru::Texture::Skybox, skyboxStack[i]->getCubemap());
|
|
batch.setUniformBuffer(ru::Buffer::DebugSkyboxParams, skyboxStack[i]->getSchemaBuffer());
|
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
|
}
|
|
}
|
|
});
|
|
}
|