Moved draw frustum job to render DrawTask and made generic. A couple of fixes as requested by @samcake

This commit is contained in:
Olivier Prat 2017-11-15 09:42:57 +01:00
parent bf46ccefaf
commit f47a3e7d2c
7 changed files with 165 additions and 118 deletions

View file

@ -44,8 +44,6 @@
#include "DrawHaze.h"
#include "HighlightEffect.h"
#include <gpu/StandardShaderLib.h>
#include <sstream>
using namespace render;
@ -193,14 +191,18 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
task.addJob<EndGPURangeTimer>("HighlightRangeTimer", outlineRangeTimer);
{ // DEbug the bounds of the rendered items, still look at the zbuffer
{ // Debug the bounds of the rendered items, still look at the zbuffer
task.addJob<DrawBounds>("DrawMetaBounds", metas);
task.addJob<DrawBounds>("DrawOpaqueBounds", opaques);
task.addJob<DrawBounds>("DrawTransparentBounds", transparents);
task.addJob<DrawBounds>("DrawLightBounds", lights);
task.addJob<DrawBounds>("DrawZones", zones);
task.addJob<DrawFrustums>("DrawFrustums");
const auto frustums = task.addJob<ExtractFrustums>("ExtractFrustums");
const auto viewFrustum = frustums.getN<ExtractFrustums::Output>(ExtractFrustums::VIEW_FRUSTUM);
const auto shadowFrustum = frustums.getN<ExtractFrustums::Output>(ExtractFrustums::SHADOW_FRUSTUM);
task.addJob<DrawFrustum>("DrawViewFrustum", viewFrustum, glm::vec3(1.0f, 1.0f, 0.0f));
task.addJob<DrawFrustum>("DrawShadowFrustum", shadowFrustum, glm::vec3(0.0f, 0.0f, 1.0f));
// Render.getConfig("RenderMainView.DrawSelectionBounds").enabled = true
task.addJob<DrawBounds>("DrawSelectionBounds", selectedItems);
@ -533,88 +535,32 @@ void Blit::run(const RenderContextPointer& renderContext, const gpu::Framebuffer
});
}
void DrawFrustums::configure(const Config& configuration) {
_updateFrustums = !configuration.isFrozen;
}
void DrawFrustums::run(const render::RenderContextPointer& renderContext) {
void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Output& output) {
assert(renderContext->args);
assert(renderContext->args->_context);
RenderArgs* args = renderContext->args;
static uint8_t indexData[] = { 0, 1, 2, 3, 0, 4, 5, 6, 7, 4, 5, 1, 2, 6, 7, 3 };
if (!_frustumMeshIndices._buffer) {
auto indices = std::make_shared<gpu::Buffer>(sizeof(indexData), indexData);
_frustumMeshIndices = gpu::BufferView(indices, gpu::Element(gpu::SCALAR, gpu::UINT8, gpu::INDEX));
_viewFrustumMeshVertices = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(glm::vec3) * 8, nullptr), gpu::Element::VEC3F_XYZ);
_viewFrustumMeshStream.addBuffer(_viewFrustumMeshVertices._buffer, _viewFrustumMeshVertices._offset, _viewFrustumMeshVertices._stride);
_shadowFrustumMeshVertices = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(glm::vec3) * 8, nullptr), gpu::Element::VEC3F_XYZ);
_shadowFrustumMeshStream.addBuffer(_shadowFrustumMeshVertices._buffer, _shadowFrustumMeshVertices._offset, _shadowFrustumMeshVertices._stride);
// Return view frustum
auto& viewFrustum = output[VIEW_FRUSTUM].edit<ViewFrustumPointer>();
if (!viewFrustum) {
viewFrustum = std::make_shared<ViewFrustum>(args->getViewFrustum());
} else {
*viewFrustum = args->getViewFrustum();
}
if (_updateFrustums) {
updateFrustum(args->getViewFrustum(), _viewFrustumMeshVertices);
// Return shadow frustum
auto& shadowFrustum = output[SHADOW_FRUSTUM].edit<ViewFrustumPointer>();
auto lightStage = args->_scene->getStage<LightStage>(LightStage::getName());
if (lightStage) {
auto globalShadow = lightStage->getCurrentKeyShadow();
auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage);
const auto globalShadow = lightStage->getCurrentKeyShadow();
if (globalShadow) {
updateFrustum(*globalShadow->getFrustum(), _shadowFrustumMeshVertices);
shadowFrustum = globalShadow->getFrustum();
} else {
shadowFrustum.reset();
}
} else {
shadowFrustum.reset();
}
if (!_pipeline) {
auto vs = gpu::StandardShaderLib::getDrawTransformVertexPositionVS();
auto ps = gpu::StandardShaderLib::getDrawColorPS();
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding("color", 0));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(true, false));
_pipeline = gpu::Pipeline::create(program, state);
}
// Render the frustums in wireframe
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
args->_batch = &batch;
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
glm::mat4 projMat;
Transform viewMat;
args->getViewFrustum().evalProjectionMatrix(projMat);
args->getViewFrustum().evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setPipeline(_pipeline);
batch.setIndexBuffer(_frustumMeshIndices);
batch._glUniform4f(0, 1.0f, 1.0f, 0.0f, 1.0f);
batch.setInputStream(0, _viewFrustumMeshStream);
batch.drawIndexed(gpu::LINE_STRIP, sizeof(indexData) / sizeof(indexData[0]), 0U);
batch._glUniform4f(0, 1.0f, 0.0f, 0.0f, 1.0f);
batch.setInputStream(0, _shadowFrustumMeshStream);
batch.drawIndexed(gpu::LINE_STRIP, sizeof(indexData) / sizeof(indexData[0]), 0U);
args->_batch = nullptr;
});
}
void DrawFrustums::updateFrustum(const ViewFrustum& frustum, gpu::BufferView& vertexBuffer) {
auto& vertices = vertexBuffer.edit<std::array<glm::vec3, 8U> >();
vertices[0] = frustum.getNearTopLeft();
vertices[1] = frustum.getNearTopRight();
vertices[2] = frustum.getNearBottomRight();
vertices[3] = frustum.getNearBottomLeft();
vertices[4] = frustum.getFarTopLeft();
vertices[5] = frustum.getFarTopRight();
vertices[6] = frustum.getFarBottomRight();
vertices[7] = frustum.getFarBottomLeft();
}

View file

@ -170,38 +170,20 @@ public:
void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer);
};
class DrawFrustumsConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(bool isFrozen MEMBER isFrozen NOTIFY dirty)
class ExtractFrustums {
public:
DrawFrustumsConfig(bool enabled = false) : JobConfig(enabled) {}
enum Frustum {
VIEW_FRUSTUM,
SHADOW_FRUSTUM,
bool isFrozen{ false };
signals:
void dirty();
FRUSTUM_COUNT
};
};
using Output = render::VaryingArray<ViewFrustumPointer, FRUSTUM_COUNT>;
using JobModel = render::Job::ModelO<ExtractFrustums, Output>;
class DrawFrustums {
public:
using Config = DrawFrustumsConfig;
using JobModel = render::Job::Model<DrawFrustums, Config>;
void configure(const Config& configuration);
void run(const render::RenderContextPointer& renderContext);
private:
bool _updateFrustums{ true };
gpu::PipelinePointer _pipeline;
gpu::BufferView _frustumMeshIndices;
gpu::BufferView _viewFrustumMeshVertices;
gpu::BufferView _shadowFrustumMeshVertices;
gpu::BufferStream _viewFrustumMeshStream;
gpu::BufferStream _shadowFrustumMeshStream;
static void updateFrustum(const ViewFrustum& frustum, gpu::BufferView& vertexBuffer);
void run(const render::RenderContextPointer& renderContext, Output& output);
};
class RenderDeferredTaskConfig : public render::Task::Config {

View file

@ -20,7 +20,7 @@
#include <PerfStat.h>
#include <ViewFrustum.h>
#include <gpu/Context.h>
#include <gpu/StandardShaderLib.h>
#include <drawItemBounds_vert.h>
#include <drawItemBounds_frag.h>
@ -215,3 +215,85 @@ void DrawBounds::run(const RenderContextPointer& renderContext,
});
}
gpu::PipelinePointer DrawFrustum::_pipeline;
gpu::BufferView DrawFrustum::_frustumMeshIndices;
DrawFrustum::DrawFrustum(const glm::vec3& color) :
_color{ color } {
_frustumMeshVertices = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(glm::vec3) * 8, nullptr), gpu::Element::VEC3F_XYZ);
_frustumMeshStream.addBuffer(_frustumMeshVertices._buffer, _frustumMeshVertices._offset, _frustumMeshVertices._stride);
}
void DrawFrustum::configure(const Config& configuration) {
_updateFrustum = !configuration.isFrozen;
}
void DrawFrustum::run(const render::RenderContextPointer& renderContext, const Input& input) {
assert(renderContext->args);
assert(renderContext->args->_context);
RenderArgs* args = renderContext->args;
if (input) {
const auto& frustum = *input;
static uint8_t indexData[] = { 0, 1, 2, 3, 0, 4, 5, 6, 7, 4, 5, 1, 2, 6, 7, 3 };
if (!_frustumMeshIndices._buffer) {
auto indices = std::make_shared<gpu::Buffer>(sizeof(indexData), indexData);
_frustumMeshIndices = gpu::BufferView(indices, gpu::Element(gpu::SCALAR, gpu::UINT8, gpu::INDEX));
}
if (!_pipeline) {
auto vs = gpu::StandardShaderLib::getDrawTransformVertexPositionVS();
auto ps = gpu::StandardShaderLib::getDrawColorPS();
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding("color", 0));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(true, false));
_pipeline = gpu::Pipeline::create(program, state);
}
if (_updateFrustum) {
updateFrustum(frustum);
}
// Render the frustums in wireframe
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
args->_batch = &batch;
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
glm::mat4 projMat;
Transform viewMat;
args->getViewFrustum().evalProjectionMatrix(projMat);
args->getViewFrustum().evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setPipeline(_pipeline);
batch.setIndexBuffer(_frustumMeshIndices);
batch._glUniform4f(0, _color.x, _color.y, _color.z, 1.0f);
batch.setInputStream(0, _frustumMeshStream);
batch.drawIndexed(gpu::LINE_STRIP, sizeof(indexData) / sizeof(indexData[0]), 0U);
args->_batch = nullptr;
});
}
}
void DrawFrustum::updateFrustum(const ViewFrustum& frustum) {
auto& vertices = _frustumMeshVertices.edit<std::array<glm::vec3, 8U> >();
vertices[0] = frustum.getNearTopLeft();
vertices[1] = frustum.getNearTopRight();
vertices[2] = frustum.getNearBottomRight();
vertices[3] = frustum.getNearBottomLeft();
vertices[4] = frustum.getFarTopLeft();
vertices[5] = frustum.getFarTopRight();
vertices[6] = frustum.getFarBottomRight();
vertices[7] = frustum.getFarBottomLeft();
}

View file

@ -70,6 +70,43 @@ private:
int _colorLocation { -1 };
};
class DrawFrustumConfig : public render::JobConfig {
Q_OBJECT
Q_PROPERTY(bool isFrozen MEMBER isFrozen NOTIFY dirty)
public:
DrawFrustumConfig(bool enabled = false) : JobConfig(enabled) {}
bool isFrozen{ false };
signals:
void dirty();
};
class DrawFrustum {
public:
using Config = DrawFrustumConfig;
using Input = ViewFrustumPointer;
using JobModel = render::Job::ModelI<DrawFrustum, Input, Config>;
DrawFrustum(const glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f));
void configure(const Config& configuration);
void run(const render::RenderContextPointer& renderContext, const Input& input);
private:
static gpu::PipelinePointer _pipeline;
static gpu::BufferView _frustumMeshIndices;
bool _updateFrustum{ true };
gpu::BufferView _frustumMeshVertices;
gpu::BufferStream _frustumMeshStream;
glm::vec3 _color;
void updateFrustum(const ViewFrustum& frustum);
};
}
#endif // hifi_render_DrawTask_h

View file

@ -151,11 +151,7 @@ void DepthSortShapesAndComputeBounds::run(const RenderContextPointer& renderCont
AABox bounds;
depthSortItems(renderContext, _frontToBack, inItems, outItems->second, &bounds);
if (!outBounds.isNull()) {
outBounds += bounds;
} else {
outBounds = bounds;
}
outBounds += bounds;
}
}

View file

@ -149,7 +149,7 @@ public:
Vec4 transform(const Vec4& pos) const;
Vec3 transform(const Vec3& pos) const;
Vec3 transformDirection(const Vec3& pos) const;
Vec3 transformDirection(const Vec3& dir) const;
bool containsNaN() const { return isNaN(_rotation) || isNaN(glm::dot(_scale, _translation)); }
@ -542,10 +542,10 @@ inline Transform::Vec3 Transform::transform(const Vec3& pos) const {
return Vec3(result.x / result.w, result.y / result.w, result.z / result.w);
}
inline Transform::Vec3 Transform::transformDirection(const Vec3& pos) const {
inline Transform::Vec3 Transform::transformDirection(const Vec3& dir) const {
Mat4 m;
getMatrix(m);
Vec4 result = m * Vec4(pos, 0.0f);
Vec4 result = m * Vec4(dir, 0.0f);
return Vec3(result.x, result.y, result.z);
}

View file

@ -14,20 +14,24 @@ import QtQuick.Controls 1.4
Column {
id: root
spacing: 8
property var config: Render.getConfig("RenderMainView.DrawFrustums");
property var viewConfig: Render.getConfig("RenderMainView.DrawViewFrustum");
property var shadowConfig: Render.getConfig("RenderMainView.DrawShadowFrustum");
Component.onCompleted: {
config.enabled = true;
viewConfig.enabled = true;
shadowConfig.enabled = true;
}
Component.onDestruction: {
config.enabled = false;
viewConfig.enabled = false;
shadowConfig.enabled = false;
}
CheckBox {
text: "Freeze Frustums"
checked: false
onCheckedChanged: {
config.isFrozen = checked;
viewConfig.isFrozen = checked;
shadowConfig.isFrozen = checked;
}
}
Row {
@ -39,7 +43,7 @@ Column {
}
Label {
text: "Shadow"
color: "red"
color: "blue"
font.italic: true
}
}