Adding the pipeline to render the view spheres

This commit is contained in:
samcake 2018-03-01 17:57:44 -08:00
parent fef3552851
commit 5b8e18f15d
6 changed files with 225 additions and 28 deletions

View file

@ -16,11 +16,13 @@
#include <GeometryCache.h>
#include "render-utils/drawWorkloadProxy_vert.h"
#include "render-utils/drawWorkloadView_vert.h"
#include "render-utils/drawWorkloadProxy_frag.h"
void GameSpaceToRender::configure(const Config& config) {
_showAllProxies = config.showAllProxies;
_showAllProxies = config.showProxies;
_showAllViews = config.showViews;
}
void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext, Outputs& outputs) {
@ -33,7 +35,10 @@ void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext,
return;
}
auto visible = _showAllProxies;
auto visible = _showAllProxies || _showAllViews;
auto showProxies = _showAllProxies;
auto showViews = _showAllViews;
render::Transaction transaction;
auto scene = gameWorkloadContext->_scene;
@ -51,22 +56,26 @@ void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext,
std::vector<workload::Space::Proxy> proxies(space->getNumAllocatedProxies());
space->copyProxyValues(proxies.data(), (uint32_t)proxies.size());
std::vector<workload::Space::View> views(space->getNumViews());
space->copyViews(views);
// Valid space, let's display its content
if (!render::Item::isValidID(_spaceRenderItemID)) {
_spaceRenderItemID = scene->allocateID();
auto renderItem = std::make_shared<GameWorkloadRenderItem>();
renderItem->editBound().setBox(glm::vec3(-100.0f), 200.0f);
renderItem->setVisible(visible);
renderItem->setAllProxies(proxies);
transaction.resetItem(_spaceRenderItemID, std::make_shared<GameWorkloadRenderItem::Payload>(renderItem));
} else {
transaction.updateItem<GameWorkloadRenderItem>(_spaceRenderItemID, [visible, proxies](GameWorkloadRenderItem& item) {
item.setVisible(visible);
item.setAllProxies(proxies);
});
}
transaction.updateItem<GameWorkloadRenderItem>(_spaceRenderItemID, [visible, showProxies, proxies, showViews, views](GameWorkloadRenderItem& item) {
item.setVisible(visible);
item.showProxies(showProxies);
item.setAllProxies(proxies);
item.showViews(showViews);
item.setAllViews(views);
});
scene->enqueueTransaction(transaction);
}
@ -109,6 +118,15 @@ void GameWorkloadRenderItem::setVisible(bool isVisible) {
}
}
void GameWorkloadRenderItem::showProxies(bool show) {
_showProxies = show;
}
void GameWorkloadRenderItem::showViews(bool show) {
_showViews = show;
}
void GameWorkloadRenderItem::setAllProxies(const std::vector<workload::Space::Proxy>& proxies) {
_myOwnProxies = proxies;
static const uint32_t sizeOfProxy = sizeof(workload::Space::Proxy);
@ -120,7 +138,18 @@ void GameWorkloadRenderItem::setAllProxies(const std::vector<workload::Space::Pr
_numAllProxies = (uint32_t) proxies.size();
}
const gpu::PipelinePointer GameWorkloadRenderItem::getPipeline() {
void GameWorkloadRenderItem::setAllViews(const std::vector<workload::Space::View>& views) {
_myOwnViews = views;
static const uint32_t sizeOfView = sizeof(workload::Space::View);
if (!_allViewsBuffer) {
_allViewsBuffer = std::make_shared<gpu::Buffer>(sizeOfView);
}
_allViewsBuffer->setData(views.size() * sizeOfView, (const gpu::Byte*) views.data());
_numAllViews = (uint32_t)views.size();
}
const gpu::PipelinePointer GameWorkloadRenderItem::getProxiesPipeline() {
if (!_drawAllProxiesPipeline) {
auto vs = drawWorkloadProxy_vert::getShader();
auto ps = drawWorkloadProxy_frag::getShader();
@ -143,6 +172,29 @@ const gpu::PipelinePointer GameWorkloadRenderItem::getPipeline() {
return _drawAllProxiesPipeline;
}
const gpu::PipelinePointer GameWorkloadRenderItem::getViewsPipeline() {
if (!_drawAllViewsPipeline) {
auto vs = drawWorkloadView_vert::getShader();
auto ps = drawWorkloadProxy_frag::getShader();
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding("workloadViewsBuffer", 1));
gpu::Shader::makeProgram(*program, slotBindings);
auto state = std::make_shared<gpu::State>();
state->setDepthTest(true, true, gpu::LESS_EQUAL);
/* state->setBlendFunction(true,
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::DEST_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ZERO);*/
PrepareStencil::testMaskDrawShape(*state);
state->setCullMode(gpu::State::CULL_NONE);
_drawAllViewsPipeline = gpu::Pipeline::create(program, state);
}
return _drawAllViewsPipeline;
}
void GameWorkloadRenderItem::render(RenderArgs* args) {
gpu::Batch& batch = *(args->_batch);
@ -155,15 +207,28 @@ void GameWorkloadRenderItem::render(RenderArgs* args) {
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
// Bind program
batch.setPipeline(getPipeline());
batch.setResourceBuffer(0, _allProxiesBuffer);
batch.setResourceBuffer(1, _allViewsBuffer);
static const int NUM_VERTICES_PER_QUAD = 3;
batch.draw(gpu::TRIANGLES, NUM_VERTICES_PER_QUAD * _numAllProxies, 0);
// Show Proxies
if (_showProxies) {
batch.setPipeline(getProxiesPipeline());
static const int NUM_VERTICES_PER_QUAD = 3;
batch.draw(gpu::TRIANGLES, NUM_VERTICES_PER_QUAD * _numAllProxies, 0);
}
// Show Views
if (_showViews) {
batch.setPipeline(getViewsPipeline());
static const int NUM_VERTICES_PER_QUAD = 3;
batch.draw(gpu::TRIANGLES, NUM_VERTICES_PER_QUAD * 3 * _numAllViews, 0);
}
batch.setResourceBuffer(0, nullptr);
batch.setResourceBuffer(1, nullptr);
batch.setResourceBuffer(11, nullptr);
}

View file

@ -14,10 +14,12 @@
class GameSpaceToRenderConfig : public workload::Job::Config {
Q_OBJECT
Q_PROPERTY(bool showAllProxies MEMBER showAllProxies NOTIFY dirty)
Q_PROPERTY(bool showProxies MEMBER showProxies NOTIFY dirty)
Q_PROPERTY(bool showViews MEMBER showViews NOTIFY dirty)
public:
bool showAllProxies{ false };
bool showProxies{ false };
bool showViews{ false };
signals:
void dirty();
@ -38,6 +40,7 @@ public:
protected:
render::ItemID _spaceRenderItemID{ render::Item::INVALID_ITEM_ID };
bool _showAllProxies{ false };
bool _showAllViews{ false };
};
@ -50,12 +53,15 @@ public:
~GameWorkloadRenderItem() {}
void render(RenderArgs* args);
render::Item::Bound& editBound() { _needUpdate = true; return _bound; }
render::Item::Bound& editBound() { return _bound; }
const render::Item::Bound& getBound() { return _bound; }
void setVisible(bool visible);
void showProxies(bool show);
void showViews(bool show);
void setAllProxies(const std::vector<workload::Space::Proxy>& proxies);
void setAllViews(const std::vector<workload::Space::View>& views);
render::ItemKey getKey() const;
@ -66,12 +72,19 @@ protected:
gpu::BufferPointer _allProxiesBuffer;
uint32_t _numAllProxies{ 0 };
std::vector<workload::Space::View> _myOwnViews;
gpu::BufferPointer _allViewsBuffer;
uint32_t _numAllViews{ 0 };
gpu::PipelinePointer _drawAllProxiesPipeline;
const gpu::PipelinePointer getPipeline();
const gpu::PipelinePointer getProxiesPipeline();
gpu::PipelinePointer _drawAllViewsPipeline;
const gpu::PipelinePointer getViewsPipeline();
render::ItemKey _key;
bool _needUpdate{ true };
bool _isVisible{ true };
bool _showProxies{ true };
bool _showViews{ true };
};
namespace render {

View file

@ -0,0 +1,94 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// drawItemBounds.slv
// vertex shader
//
// Created by Sam Gateau on 6/29/2015.
// Copyright 2015 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 gpu/Transform.slh@>
<$declareStandardTransform()$>
<@include gpu/Color.slh@>
<$declareColorWheel()$>
uniform vec4 inColor;
struct WorkloadView {
vec4 origin;
vec4 radiuses;
};
#if defined(GPU_GL410)
uniform samplerBuffer workloadViewsBuffer;
WorkloadView getWorkloadView(int i) {
int offset = 2 * i;
WorkloadView view;
view.origin = texelFetch(workloadViewsBuffer, offset);
view.radiuses = texelFetch(workloadViewsBuffer, offset + 1);
return view;
}
#else
layout(std140) buffer workloadViewsBuffer {
WorkloadView _views[];
};
WorkloadView getWorkloadView(int i) {
WorkloadView view = _views[i];
return view;
}
#endif
out vec4 varColor;
out vec2 varTexcoord;
void main(void) {
const vec4 UNIT_SPRITE[3] = vec4[3](
vec4(-1.0, -1.0, 0.0, 1.0),
vec4(3.0, -1.0, 0.0, 1.0),
vec4(-1.0, 3.0, 0.0, 1.0)
);
const int UNIT_SPRITE_INDICES[3] = int[3](
0, 1, 2
);
int viewID = gl_VertexID / 9;
int reminder = gl_VertexID - viewID * 9;
int regionID = reminder / 3;
reminder = reminder - regionID * 3;
int vertexID = reminder;
vec4 spriteVert = UNIT_SPRITE[UNIT_SPRITE_INDICES[vertexID]];
WorkloadView view = getWorkloadView(viewID);
vec4 proxyPosWorld = vec4(view.origin.xyz, 1.0);
// standard transform, bring proxy in view space
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
vec4 proxyPosEye;
<$transformModelToEyePos(cam, obj, proxyPosWorld, proxyPosEye)$>
// Define the billboarded space
vec3 dirZ = -normalize(proxyPosEye.xyz);
vec3 dirX = normalize(cross(vec3(0.0, 1.0, 0.0), dirZ));
vec3 dirY = vec3(0.0, 1.0, 0.0);
// vec3 dirY = normalize(cross(dirZ, vec3(1.0, 0.0, 0.0)));
float regionRadius = view.radiuses[regionID];
vec4 pos = vec4(proxyPosEye.xyz + regionRadius * ( dirX * spriteVert.x + dirY * spriteVert.y /* + dirZ * spriteVert.z*/), 1.0);
varTexcoord = spriteVert.xy;
<$transformEyeToClipPos(cam, pos, gl_Position)$>
// Convert region to color
varColor = vec4(colorWheel(float(regionID) / 4.0), regionRadius);
}

View file

@ -58,6 +58,10 @@ void Space::setViews(const std::vector<Space::View>& views) {
_views = views;
}
void Space::copyViews(std::vector<View>& copy) const {
copy = _views;
}
// TODO?: move this to an algorithm/job?
void Space::categorizeAndGetChanges(std::vector<Space::Change>& changes) {
uint32_t numProxies = (uint32_t)_proxies.size();
@ -106,7 +110,7 @@ void Space::deleteProxy(int32_t proxyId) {
}
}
uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) {
uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const {
auto numCopied = std::min(numDestProxies, (uint32_t)_proxies.size());
memcpy(proxies, _proxies.data(), numCopied * sizeof(Proxy));

View file

@ -51,13 +51,16 @@ public:
class View {
public:
View() = default;
View(const glm::vec3& pos, float nearRadius, float midRadius, float farRadius) : center(pos) {
radiuses[REGION_NEAR] = nearRadius;
radiuses[REGION_MIDDLE] = midRadius;
radiuses[REGION_FAR] = farRadius;
}
glm::vec3 center;
glm::vec3 center;
float _padding0;
float radiuses[NUM_CLASSIFICATIONS - 1];
float _padding1;
};
class Change {
@ -76,11 +79,15 @@ public:
void updateProxies(const std::vector<ProxyUpdate>& changedProxies);
void setViews(const std::vector<View>& views);
uint32_t getNumViews() const { return (uint32_t)(_views.size()); }
void copyViews(std::vector<View>& copy) const;
uint32_t getNumObjects() const { return (uint32_t)(_proxies.size() - _freeIndices.size()); }
uint32_t getNumAllocatedProxies() const { return (uint32_t)(_proxies.size()); }
void categorizeAndGetChanges(std::vector<Change>& changes);
uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies);
uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const;
private:
void deleteProxy(int32_t proxyId);

View file

@ -30,11 +30,25 @@ Rectangle {
anchors.margins: hifi.dimensions.contentMargin.x
//padding: hifi.dimensions.contentMargin.x
HifiControls.Label {
text: "Workload"
}
Separator {}
HifiControls.Label {
text: "Display"
}
HifiControls.CheckBox {
boxSize: 20
text: "Show All Proxies"
checked: workload.spaceToRender["showAllProxies"]
onCheckedChanged: { workload.spaceToRender["showAllProxies"] = checked }
text: "Show Proxies"
checked: workload.spaceToRender["showProxies"]
onCheckedChanged: { workload.spaceToRender["showProxies"] = checked }
}
HifiControls.CheckBox {
boxSize: 20
text: "Show Views"
checked: workload.spaceToRender["showViews"]
onCheckedChanged: { workload.spaceToRender["showViews"] = checked }
}
Separator {}
}
}