Merge pull request #9906 from samcake/red

Expose rendering in wireframe mode
This commit is contained in:
samcake 2017-03-17 17:09:44 -07:00 committed by GitHub
commit e1a0984fed
12 changed files with 91 additions and 26 deletions

View file

@ -54,6 +54,8 @@
#include "PhysicalEntitySimulation.h" #include "PhysicalEntitySimulation.h"
gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr; gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr;
gpu::PipelinePointer RenderablePolyVoxEntityItem::_wireframePipeline = nullptr;
const float MARCHING_CUBE_COLLISION_HULL_OFFSET = 0.5; const float MARCHING_CUBE_COLLISION_HULL_OFFSET = 0.5;
@ -716,6 +718,13 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setDepthTest(true, true, gpu::LESS_EQUAL);
_pipeline = gpu::Pipeline::create(program, state); _pipeline = gpu::Pipeline::create(program, state);
auto wireframeState = std::make_shared<gpu::State>();
wireframeState->setCullMode(gpu::State::CULL_BACK);
wireframeState->setDepthTest(true, true, gpu::LESS_EQUAL);
wireframeState->setFillMode(gpu::State::FILL_LINE);
_wireframePipeline = gpu::Pipeline::create(program, wireframeState);
} }
if (!_vertexFormat) { if (!_vertexFormat) {
@ -726,7 +735,11 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
} }
gpu::Batch& batch = *args->_batch; gpu::Batch& batch = *args->_batch;
batch.setPipeline(_pipeline);
// Pick correct Pipeline
bool wireframe = (render::ShapeKey(args->_globalShapeKey).isWireframe());
auto pipeline = (wireframe ? _wireframePipeline : _pipeline);
batch.setPipeline(pipeline);
Transform transform(voxelToWorldMatrix()); Transform transform(voxelToWorldMatrix());
batch.setModelTransform(transform); batch.setModelTransform(transform);
@ -763,7 +776,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
batch.setResourceTexture(2, DependencyManager::get<TextureCache>()->getWhiteTexture()); batch.setResourceTexture(2, DependencyManager::get<TextureCache>()->getWhiteTexture());
} }
int voxelVolumeSizeLocation = _pipeline->getProgram()->getUniforms().findLocation("voxelVolumeSize"); int voxelVolumeSizeLocation = pipeline->getProgram()->getUniforms().findLocation("voxelVolumeSize");
batch._glUniform3f(voxelVolumeSizeLocation, voxelVolumeSize.x, voxelVolumeSize.y, voxelVolumeSize.z); batch._glUniform3f(voxelVolumeSizeLocation, voxelVolumeSize.x, voxelVolumeSize.y, voxelVolumeSize.z);
batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)mesh->getNumIndices(), 0); batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)mesh->getNumIndices(), 0);

View file

@ -164,6 +164,7 @@ private:
const int MATERIAL_GPU_SLOT = 3; const int MATERIAL_GPU_SLOT = 3;
render::ItemID _myItem{ render::Item::INVALID_ITEM_ID }; render::ItemID _myItem{ render::Item::INVALID_ITEM_ID };
static gpu::PipelinePointer _pipeline; static gpu::PipelinePointer _pipeline;
static gpu::PipelinePointer _wireframePipeline;
ShapeInfo _shapeInfo; ShapeInfo _shapeInfo;

View file

@ -114,14 +114,23 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
auto outColor = _procedural->getColor(color); auto outColor = _procedural->getColor(color);
outColor.a *= _procedural->isFading() ? Interpolate::calculateFadeRatio(_procedural->getFadeStartTime()) : 1.0f; outColor.a *= _procedural->isFading() ? Interpolate::calculateFadeRatio(_procedural->getFadeStartTime()) : 1.0f;
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a); batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
DependencyManager::get<GeometryCache>()->renderWireShape(batch, MAPPING[_shape]);
} else {
DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]); DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);
}
} else { } else {
// FIXME, support instanced multi-shape rendering using multidraw indirect // FIXME, support instanced multi-shape rendering using multidraw indirect
color.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; color.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
auto geometryCache = DependencyManager::get<GeometryCache>(); auto geometryCache = DependencyManager::get<GeometryCache>();
auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline(); auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
geometryCache->renderWireShapeInstance(batch, MAPPING[_shape], color, pipeline);
} else {
geometryCache->renderSolidShapeInstance(batch, MAPPING[_shape], color, pipeline); geometryCache->renderSolidShapeInstance(batch, MAPPING[_shape], color, pipeline);
} }
}
static const auto triCount = DependencyManager::get<GeometryCache>()->getShapeTriangleCount(MAPPING[_shape]); static const auto triCount = DependencyManager::get<GeometryCache>()->getShapeTriangleCount(MAPPING[_shape]);
args->_details._trianglesRendered += (int)triCount; args->_details._trianglesRendered += (int)triCount;

View file

@ -133,6 +133,7 @@ void LightingModel::setSpotLight(bool enable) {
bool LightingModel::isSpotLightEnabled() const { bool LightingModel::isSpotLightEnabled() const {
return (bool)_parametersBuffer.get<Parameters>().enableSpotLight; return (bool)_parametersBuffer.get<Parameters>().enableSpotLight;
} }
void LightingModel::setShowLightContour(bool enable) { void LightingModel::setShowLightContour(bool enable) {
if (enable != isShowLightContourEnabled()) { if (enable != isShowLightContourEnabled()) {
_parametersBuffer.edit<Parameters>().showLightContour = (float)enable; _parametersBuffer.edit<Parameters>().showLightContour = (float)enable;
@ -142,6 +143,14 @@ bool LightingModel::isShowLightContourEnabled() const {
return (bool)_parametersBuffer.get<Parameters>().showLightContour; return (bool)_parametersBuffer.get<Parameters>().showLightContour;
} }
void LightingModel::setWireframe(bool enable) {
if (enable != isWireframeEnabled()) {
_parametersBuffer.edit<Parameters>().enableWireframe = (float)enable;
}
}
bool LightingModel::isWireframeEnabled() const {
return (bool)_parametersBuffer.get<Parameters>().enableWireframe;
}
MakeLightingModel::MakeLightingModel() { MakeLightingModel::MakeLightingModel() {
_lightingModel = std::make_shared<LightingModel>(); _lightingModel = std::make_shared<LightingModel>();
} }
@ -167,6 +176,7 @@ void MakeLightingModel::configure(const Config& config) {
_lightingModel->setSpotLight(config.enableSpotLight); _lightingModel->setSpotLight(config.enableSpotLight);
_lightingModel->setShowLightContour(config.showLightContour); _lightingModel->setShowLightContour(config.showLightContour);
_lightingModel->setWireframe(config.enableWireframe);
} }
void MakeLightingModel::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, LightingModelPointer& lightingModel) { void MakeLightingModel::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, LightingModelPointer& lightingModel) {

View file

@ -64,6 +64,9 @@ public:
void setShowLightContour(bool enable); void setShowLightContour(bool enable);
bool isShowLightContourEnabled() const; bool isShowLightContourEnabled() const;
void setWireframe(bool enable);
bool isWireframeEnabled() const;
UniformBufferView getParametersBuffer() const { return _parametersBuffer; } UniformBufferView getParametersBuffer() const { return _parametersBuffer; }
protected: protected:
@ -94,8 +97,7 @@ protected:
float enableObscurance{ 1.0f }; float enableObscurance{ 1.0f };
float enableMaterialTexturing { 1.0f }; float enableMaterialTexturing { 1.0f };
float enableWireframe { 0.0f }; // false by default
float spares{ 0.0f };
Parameters() {} Parameters() {}
}; };
@ -129,6 +131,7 @@ class MakeLightingModelConfig : public render::Job::Config {
Q_PROPERTY(bool enablePointLight MEMBER enablePointLight NOTIFY dirty) Q_PROPERTY(bool enablePointLight MEMBER enablePointLight NOTIFY dirty)
Q_PROPERTY(bool enableSpotLight MEMBER enableSpotLight NOTIFY dirty) Q_PROPERTY(bool enableSpotLight MEMBER enableSpotLight NOTIFY dirty)
Q_PROPERTY(bool enableWireframe MEMBER enableWireframe NOTIFY dirty)
Q_PROPERTY(bool showLightContour MEMBER showLightContour NOTIFY dirty) Q_PROPERTY(bool showLightContour MEMBER showLightContour NOTIFY dirty)
public: public:
@ -152,9 +155,10 @@ public:
bool enablePointLight{ true }; bool enablePointLight{ true };
bool enableSpotLight{ true }; bool enableSpotLight{ true };
bool showLightContour { false }; // false by default bool showLightContour { false }; // false by default
bool enableWireframe { false }; // false by default
signals: signals:
void dirty(); void dirty();
}; };

View file

@ -17,7 +17,7 @@ struct LightingModel {
vec4 _UnlitEmissiveLightmapBackground; vec4 _UnlitEmissiveLightmapBackground;
vec4 _ScatteringDiffuseSpecularAlbedo; vec4 _ScatteringDiffuseSpecularAlbedo;
vec4 _AmbientDirectionalPointSpot; vec4 _AmbientDirectionalPointSpot;
vec4 _ShowContourObscuranceSpare2; vec4 _ShowContourObscuranceWireframe;
}; };
uniform lightingModelBuffer{ uniform lightingModelBuffer{
@ -37,7 +37,7 @@ float isBackgroundEnabled() {
return lightingModel._UnlitEmissiveLightmapBackground.w; return lightingModel._UnlitEmissiveLightmapBackground.w;
} }
float isObscuranceEnabled() { float isObscuranceEnabled() {
return lightingModel._ShowContourObscuranceSpare2.y; return lightingModel._ShowContourObscuranceWireframe.y;
} }
float isScatteringEnabled() { float isScatteringEnabled() {
@ -67,9 +67,12 @@ float isSpotEnabled() {
} }
float isShowLightContour() { float isShowLightContour() {
return lightingModel._ShowContourObscuranceSpare2.x; return lightingModel._ShowContourObscuranceWireframe.x;
} }
float isWireframeEnabled() {
return lightingModel._ShowContourObscuranceWireframe.z;
}
<@endfunc@> <@endfunc@>
<$declareLightingModel()$> <$declareLightingModel()$>

View file

@ -259,8 +259,18 @@ void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderCont
// Setup lighting model for all items; // Setup lighting model for all items;
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn); // From the lighting model define a global shapKey ORED with individiual keys
ShapeKey::Builder keyBuilder;
if (lightingModel->isWireframeEnabled()) {
keyBuilder.withWireframe();
}
ShapeKey globalKey = keyBuilder.build();
args->_globalShapeKey = globalKey._flags.to_ulong();
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn, globalKey);
args->_batch = nullptr; args->_batch = nullptr;
args->_globalShapeKey = 0;
}); });
config->setNumDrawn((int)inItems.size()); config->setNumDrawn((int)inItems.size());
@ -295,12 +305,21 @@ void DrawStateSortDeferred::run(const SceneContextPointer& sceneContext, const R
// Setup lighting model for all items; // Setup lighting model for all items;
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
// From the lighting model define a global shapKey ORED with individiual keys
ShapeKey::Builder keyBuilder;
if (lightingModel->isWireframeEnabled()) {
keyBuilder.withWireframe();
}
ShapeKey globalKey = keyBuilder.build();
args->_globalShapeKey = globalKey._flags.to_ulong();
if (_stateSort) { if (_stateSort) {
renderStateSortShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn); renderStateSortShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn, globalKey);
} else { } else {
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn); renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn, globalKey);
} }
args->_batch = nullptr; args->_batch = nullptr;
args->_globalShapeKey = 0;
}); });
config->setNumDrawn((int)inItems.size()); config->setNumDrawn((int)inItems.size());

View file

@ -39,9 +39,9 @@ void render::renderItems(const SceneContextPointer& sceneContext, const RenderCo
} }
} }
void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, const Item& item) { void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, const Item& item, const ShapeKey& globalKey) {
assert(item.getKey().isShape()); assert(item.getKey().isShape());
const auto& key = item.getShapeKey(); auto key = item.getShapeKey() | globalKey;
if (key.isValid() && !key.hasOwnPipeline()) { if (key.isValid() && !key.hasOwnPipeline()) {
args->_pipeline = shapeContext->pickPipeline(args, key); args->_pipeline = shapeContext->pickPipeline(args, key);
if (args->_pipeline) { if (args->_pipeline) {
@ -56,7 +56,7 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons
} }
void render::renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, void render::renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems) { const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems, const ShapeKey& globalKey) {
auto& scene = sceneContext->_scene; auto& scene = sceneContext->_scene;
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
@ -66,12 +66,12 @@ void render::renderShapes(const SceneContextPointer& sceneContext, const RenderC
} }
for (auto i = 0; i < numItemsToDraw; ++i) { for (auto i = 0; i < numItemsToDraw; ++i) {
auto& item = scene->getItem(inItems[i].id); auto& item = scene->getItem(inItems[i].id);
renderShape(args, shapeContext, item); renderShape(args, shapeContext, item, globalKey);
} }
} }
void render::renderStateSortShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, void render::renderStateSortShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems) { const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems, const ShapeKey& globalKey) {
auto& scene = sceneContext->_scene; auto& scene = sceneContext->_scene;
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
@ -91,7 +91,7 @@ void render::renderStateSortShapes(const SceneContextPointer& sceneContext, cons
{ {
assert(item.getKey().isShape()); assert(item.getKey().isShape());
const auto key = item.getShapeKey(); auto key = item.getShapeKey() | globalKey;
if (key.isValid() && !key.hasOwnPipeline()) { if (key.isValid() && !key.hasOwnPipeline()) {
auto& bucket = sortedShapes[key]; auto& bucket = sortedShapes[key];
if (bucket.empty()) { if (bucket.empty()) {

View file

@ -17,8 +17,8 @@
namespace render { namespace render {
void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, int maxDrawnItems = -1); void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, int maxDrawnItems = -1);
void renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems = -1); void renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems = -1, const ShapeKey& globalKey = ShapeKey());
void renderStateSortShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems = -1); void renderStateSortShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems = -1, const ShapeKey& globalKey = ShapeKey());
class DrawLightConfig : public Job::Config { class DrawLightConfig : public Job::Config {
Q_OBJECT Q_OBJECT

View file

@ -46,6 +46,10 @@ public:
ShapeKey() : _flags{ 0 } {} ShapeKey() : _flags{ 0 } {}
ShapeKey(const Flags& flags) : _flags{flags} {} ShapeKey(const Flags& flags) : _flags{flags} {}
friend ShapeKey operator&(const ShapeKey& _Left, const ShapeKey& _Right) { return ShapeKey(_Left._flags & _Right._flags); }
friend ShapeKey operator|(const ShapeKey& _Left, const ShapeKey& _Right) { return ShapeKey(_Left._flags | _Right._flags); }
friend ShapeKey operator^(const ShapeKey& _Left, const ShapeKey& _Right) { return ShapeKey(_Left._flags ^ _Right._flags); }
class Builder { class Builder {
public: public:
Builder() {} Builder() {}
@ -144,7 +148,7 @@ public:
bool isSkinned() const { return _flags[SKINNED]; } bool isSkinned() const { return _flags[SKINNED]; }
bool isDepthOnly() const { return _flags[DEPTH_ONLY]; } bool isDepthOnly() const { return _flags[DEPTH_ONLY]; }
bool isDepthBiased() const { return _flags[DEPTH_BIAS]; } bool isDepthBiased() const { return _flags[DEPTH_BIAS]; }
bool isWireFrame() const { return _flags[WIREFRAME]; } bool isWireframe() const { return _flags[WIREFRAME]; }
bool isCullFace() const { return !_flags[NO_CULL_FACE]; } bool isCullFace() const { return !_flags[NO_CULL_FACE]; }
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; } bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
@ -180,7 +184,7 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& key) {
<< "isSkinned:" << key.isSkinned() << "isSkinned:" << key.isSkinned()
<< "isDepthOnly:" << key.isDepthOnly() << "isDepthOnly:" << key.isDepthOnly()
<< "isDepthBiased:" << key.isDepthBiased() << "isDepthBiased:" << key.isDepthBiased()
<< "isWireFrame:" << key.isWireFrame() << "isWireframe:" << key.isWireframe()
<< "isCullFace:" << key.isCullFace() << "isCullFace:" << key.isCullFace()
<< "]"; << "]";
} }

View file

@ -122,6 +122,7 @@ public:
gpu::Batch* _batch = nullptr; gpu::Batch* _batch = nullptr;
std::shared_ptr<gpu::Texture> _whiteTexture; std::shared_ptr<gpu::Texture> _whiteTexture;
uint32_t _globalShapeKey { 0 };
bool _enableTexturing { true }; bool _enableTexturing { true };
RenderDetails _details; RenderDetails _details;

View file

@ -25,7 +25,7 @@ Column {
"Lightmap:LightingModel:enableLightmap", "Lightmap:LightingModel:enableLightmap",
"Background:LightingModel:enableBackground", "Background:LightingModel:enableBackground",
"ssao:AmbientOcclusion:enabled", "ssao:AmbientOcclusion:enabled",
"Textures:LightingModel:enableMaterialTexturing", "Textures:LightingModel:enableMaterialTexturing"
] ]
CheckBox { CheckBox {
text: modelData.split(":")[0] text: modelData.split(":")[0]
@ -45,6 +45,7 @@ Column {
"Diffuse:LightingModel:enableDiffuse", "Diffuse:LightingModel:enableDiffuse",
"Specular:LightingModel:enableSpecular", "Specular:LightingModel:enableSpecular",
"Albedo:LightingModel:enableAlbedo", "Albedo:LightingModel:enableAlbedo",
"Wireframe:LightingModel:enableWireframe"
] ]
CheckBox { CheckBox {
text: modelData.split(":")[0] text: modelData.split(":")[0]