Merge pull request #7509 from samcake/orange

Avoid the spot lights flickering in Home
This commit is contained in:
Brad Hefta-Gaub 2016-03-30 15:44:08 -07:00
commit e31546e172
26 changed files with 453 additions and 213 deletions

View file

@ -0,0 +1 @@
ConfigSlider 1.0 ConfigSlider.qml

View file

@ -0,0 +1,114 @@
//
// culling.qml
// examples/utilities/render
//
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import "configSlider"
Column {
id: root
spacing: 8
property var sceneOctree: Render.getConfig("DrawSceneOctree");
property var itemSelection: Render.getConfig("DrawItemSelection");
Component.onCompleted: {
sceneOctree.enabled = true;
itemSelection.enabled = true;
sceneOctree.showVisibleCells = false;
sceneOctree.showEmptyCells = false;
itemSelection.showInsideItems = false;
itemSelection.showInsideSubcellItems = false;
itemSelection.showPartialItems = false;
itemSelection.showPartialSubcellItems = false;
}
Component.onDestruction: {
sceneOctree.enabled = false;
itemSelection.enabled = false;
Render.getConfig("FetchSceneSelection").freezeFrustum = false;
Render.getConfig("CullSceneSelection").freezeFrustum = false;
}
GroupBox {
title: "Culling"
Row {
spacing: 8
Column {
spacing: 8
CheckBox {
text: "Freeze Culling Frustum"
checked: false
onCheckedChanged: {
Render.getConfig("FetchSceneSelection").freezeFrustum = checked;
Render.getConfig("CullSceneSelection").freezeFrustum = checked;
}
}
Label {
text: "Octree"
}
CheckBox {
text: "Visible Cells"
checked: root.sceneOctree.showVisibleCells
onCheckedChanged: { root.sceneOctree.showVisibleCells = checked }
}
CheckBox {
text: "Empty Cells"
checked: false
onCheckedChanged: { root.sceneOctree.showEmptyCells = checked }
}
}
Column {
spacing: 8
Label {
text: "Frustum Items"
}
CheckBox {
text: "Inside Items"
checked: false
onCheckedChanged: { root.itemSelection.showInsideItems = checked }
}
CheckBox {
text: "Inside Sub-cell Items"
checked: false
onCheckedChanged: { root.itemSelection.showInsideSubcellItems = checked }
}
CheckBox {
text: "Partial Items"
checked: false
onCheckedChanged: { root.itemSelection.showPartialItems = checked }
}
CheckBox {
text: "Partial Sub-cell Items"
checked: false
onCheckedChanged: { root.itemSelection.showPartialSubcellItems = checked }
}
}
}
}
GroupBox {
title: "Render Items"
Column{
Repeater {
model: [ "Opaque:DrawOpaqueDeferred", "Transparent:DrawTransparentDeferred", "Light:DrawLight",
"Opaque Overlays:DrawOverlay3DOpaque", "Transparent Overlays:DrawOverlay3DTransparent" ]
ConfigSlider {
label: qsTr(modelData.split(":")[0])
integral: true
config: Render.getConfig(modelData.split(":")[1])
property: "maxDrawn"
max: config.numDrawn
min: -1
}
}
}
}
}

View file

@ -0,0 +1,21 @@
//
// debugRender.js
// examples/utilities/render
//
// Sam Gateau, created on 3/22/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
//
// Set up the qml ui
var qml = Script.resolvePath('culling.qml');
var window = new OverlayWindow({
title: 'Render Draws',
source: qml,
width: 300,
height: 200
});
window.setPosition(200, 50);
window.closed.connect(function() { Script.stop(); });

View file

@ -10,6 +10,7 @@
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import "configSlider"
Column {
id: root

View file

@ -1,6 +1,6 @@
//
// PlotPerf.qml
// examples/utilities/tools/render
// examples/utilities/render/plotperf
//
// Created by Sam Gateau on 3//2016
// Copyright 2016 High Fidelity, Inc.
@ -15,40 +15,64 @@ Item {
id: root
width: parent.width
height: 100
// The title of the graph
property string title
property var config
property string parameters
// THis is my hack to get the name of the first property and assign it to a trigger var in order to get
// THe object used as the default source object for the prop plots
property var object
// THis is my hack to get a property and assign it to a trigger var in order to get
// a signal called whenever the value changed
property var trigger: config[parameters.split(":")[3].split("-")[0]]
property var trigger
// Plots is an array of plot descriptor
// a default plot descriptor expects the following object:
// prop: [ {
// object: {} // Optional: this is the object from which the prop will be fetched,
// if nothing than the object from root is used
// prop:"bufferCPUCount", // Needed the name of the property from the object to feed the plot
// label: "CPU", // Optional: Label as displayed on the plot
// color: "#00B4EF" // Optional: Color of the curve
// unit: "km/h" // Optional: Unit added to the value displayed, if nothing then the default unit is used
// scale: 1 // Optional: Extra scaling used to represent the value, this scale is combined with the global scale.
// },
property var plots
// Default value scale used to define the max value of the chart
property var valueScale: 1
// Default value unit appended to the value displayed
property var valueUnit: ""
// Default number of digits displayed
property var valueNumDigits: 0
property var inputs: parameters.split(":")
property var valueScale: +inputs[0]
property var valueUnit: inputs[1]
property var valueNumDigits: inputs[2]
property var input_VALUE_OFFSET: 3
property var valueMax : 1
property var _values : new Array()
property var tick : 0
function createValues() {
if (inputs.length > input_VALUE_OFFSET) {
for (var i = input_VALUE_OFFSET; i < inputs.length; i++) {
var varProps = inputs[i].split("-")
_values.push( {
value: varProps[0],
valueMax: 1,
numSamplesConstantMax: 0,
valueHistory: new Array(),
label: varProps[1],
color: varProps[2],
scale: (varProps.length > 3 ? varProps[3] : 1),
unit: (varProps.length > 4 ? varProps[4] : valueUnit)
})
}
}
print("trigger is: " + JSON.stringify(trigger))
if (Array.isArray(plots)) {
for (var i =0; i < plots.length; i++) {
var plot = plots[i];
print(" a pnew Plot:" + JSON.stringify(plot));
_values.push( {
object: (plot["object"] !== undefined ? plot["object"] : root.object),
value: plot["prop"],
valueMax: 1,
numSamplesConstantMax: 0,
valueHistory: new Array(),
label: (plot["label"] !== undefined ? plot["label"] : ""),
color: (plot["color"] !== undefined ? plot["color"] : "white"),
scale: (plot["scale"] !== undefined ? plot["scale"] : 1),
unit: (plot["unit"] !== undefined ? plot["unit"] : valueUnit)
})
}
}
print("in creator" + JSON.stringify(_values));
}
@ -69,7 +93,8 @@ Item {
var currentValueMax = 0
for (var i = 0; i < _values.length; i++) {
var currentVal = config[_values[i].value] * _values[i].scale;
var currentVal = _values[i].object[_values[i].value] * _values[i].scale;
_values[i].valueHistory.push(currentVal)
_values[i].numSamplesConstantMax++;

View file

@ -0,0 +1,195 @@
//
// stats.qml
// examples/utilities/render
//
// Created by Zach Pomerantz on 2/8/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import "plotperf"
Item {
id: statsUI
anchors.fill:parent
Column {
id: stats
spacing: 8
anchors.fill:parent
property var config: Render.getConfig("Stats")
function evalEvenHeight() {
// Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ?
return (height - spacing * (children.length - 1)) / children.length
}
PlotPerf {
title: "Num Buffers"
height: parent.evalEvenHeight()
object: stats.config
trigger: stats.config["bufferCPUCount"]
plots: [
{
prop: "bufferCPUCount",
label: "CPU",
color: "#00B4EF"
},
{
prop: "bufferGPUCount",
label: "GPU",
color: "#1AC567"
}
]
}
PlotPerf {
title: "gpu::Buffer Memory"
height: parent.evalEvenHeight()
object: stats.config
trigger: stats.config["bufferCPUMemoryUsage"]
valueScale: 1048576
valueUnit: "Mb"
valueNumDigits: "1"
plots: [
{
prop: "bufferCPUMemoryUsage",
label: "CPU",
color: "#00B4EF"
},
{
prop: "bufferGPUMemoryUsage",
label: "GPU",
color: "#1AC567"
}
]
}
PlotPerf {
title: "Num Textures"
height: parent.evalEvenHeight()
object: stats.config
trigger: stats.config["textureCPUCount"]
plots: [
{
prop: "textureCPUCount",
label: "CPU",
color: "#00B4EF"
},
{
prop: "textureGPUCount",
label: "GPU",
color: "#1AC567"
},
{
prop: "frameTextureCount",
label: "Frame",
color: "#E2334D"
}
]
}
PlotPerf {
title: "gpu::Texture Memory"
height: parent.evalEvenHeight()
object: stats.config
trigger: stats.config["textureCPUMemoryUsage"]
valueScale: 1048576
valueUnit: "Mb"
valueNumDigits: "1"
plots: [
{
prop: "textureCPUMemoryUsage",
label: "CPU",
color: "#00B4EF"
},
{
prop: "textureGPUMemoryUsage",
label: "GPU",
color: "#1AC567"
}
]
}
PlotPerf {
title: "Triangles"
height: parent.evalEvenHeight()
object: stats.config
trigger: stats.config["frameTriangleCount"]
valueScale: 1000
valueUnit: "K"
plots: [
{
prop: "frameTriangleCount",
label: "Triangles",
color: "#1AC567"
},
{
prop: "frameTriangleRate",
label: "rate",
color: "#E2334D",
scale: 0.001,
unit: "MT/s"
}
]
}
PlotPerf {
title: "Drawcalls"
height: parent.evalEvenHeight()
object: stats.config
trigger: stats.config["frameDrawcallCount"]
plots: [
{
prop: "frameAPIDrawcallCount",
label: "API Drawcalls",
color: "#00B4EF"
},
{
prop: "frameDrawcallCount",
label: "GPU Drawcalls",
color: "#1AC567"
},
{
prop: "frameDrawcallRate",
label: "rate",
color: "#E2334D",
scale: 0.001,
unit: "K/s"
}
]
}
property var drawOpaqueConfig: Render.getConfig("DrawOpaqueDeferred")
property var drawTransparentConfig: Render.getConfig("DrawTransparentDeferred")
property var drawLightConfig: Render.getConfig("DrawLight")
PlotPerf {
title: "Items"
height: parent.evalEvenHeight()
object: parent.drawOpaqueConfig
trigger: Render.getConfig("DrawOpaqueDeferred")["numDrawn"]
plots: [
{
object: Render.getConfig("DrawOpaqueDeferred"),
prop: "numDrawn",
label: "Opaques",
color: "#1AC567"
},
{
object: Render.getConfig("DrawTransparentDeferred"),
prop: "numDrawn",
label: "Translucents",
color: "#00B4EF"
},
{
object: Render.getConfig("DrawLight"),
prop: "numDrawn",
label: "Lights",
color: "#E2334D"
}
]
}
}
}

View file

@ -1,99 +0,0 @@
//
// debugRenderOctree.js
// examples/utilities/tools
//
// Sam Gateau
// 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
//
Script.include("cookies.js");
var panel = new Panel(10, 300);
var drawOctree = Render.RenderDeferredTask.DrawSceneOctree;
Render.RenderDeferredTask.DrawSceneOctree.enabled = true;
Render.RenderDeferredTask.DrawItemSelection.enabled = true;
panel.newCheckbox("Show Octree Cells",
function(value) { Render.RenderDeferredTask.DrawSceneOctree.showVisibleCells = value; },
function() { return (Render.RenderDeferredTask.DrawSceneOctree.showVisibleCells); },
function(value) { return (value); }
);
panel.newCheckbox("Show Empty Cells",
function(value) { Render.RenderDeferredTask.DrawSceneOctree.showEmptyCells = value; },
function() { return (Render.RenderDeferredTask.DrawSceneOctree.showEmptyCells); },
function(value) { return (value); }
);
panel.newCheckbox("Freeze Frustum",
function(value) { Render.RenderDeferredTask.FetchSceneSelection.freezeFrustum = value; Render.RenderDeferredTask.CullSceneSelection.freezeFrustum = value; },
function() { return (Render.RenderDeferredTask.FetchSceneSelection.freezeFrustum); },
function(value) { return (value); }
);
panel.newCheckbox("Show Inside Items",
function(value) { Render.RenderDeferredTask.DrawItemSelection.showInsideItems = value; },
function() { return (Render.RenderDeferredTask.DrawItemSelection.showInsideItems); },
function(value) { return (value); }
);
panel.newCheckbox("Show Inside Subcell Items",
function(value) { Render.RenderDeferredTask.DrawItemSelection.showInsideSubcellItems = value; },
function() { return (Render.RenderDeferredTask.DrawItemSelection.showInsideSubcellItems); },
function(value) { return (value); }
);
panel.newCheckbox("Show Partial Items",
function(value) { Render.RenderDeferredTask.DrawItemSelection.showPartialItems = value; },
function() { return (Render.RenderDeferredTask.DrawItemSelection.showPartialItems); },
function(value) { return (value); }
);
panel.newCheckbox("Show Partial Subcell Items",
function(value) { Render.RenderDeferredTask.DrawItemSelection.showPartialSubcellItems = value; },
function() { return (Render.RenderDeferredTask.DrawItemSelection.showPartialSubcellItems); },
function(value) { return (value); }
);
/*
panel.newSlider('Cells Free / Allocated', -1, 1,
function(value) { value; }, // setter
function() { return Render.RenderDeferredTask.DrawSceneOctree.numFreeCells; }, // getter
function(value) { return value; });
this.update = function () {
var numFree = Render.RenderDeferredTask.DrawSceneOctree.numFreeCells;
var numAlloc = Render.RenderDeferredTask.DrawSceneOctree.numAllocatedCells;
var title = [
' ' + name,
numFree + ' / ' + numAlloc
].join('\t');
widget.editTitle({ text: title });
slider.setMaxValue(numAlloc);
};
*/
function mouseMoveEvent(event) {
panel.mouseMoveEvent(event);
}
function mousePressEvent(event) {
panel.mousePressEvent(event);
}
function mouseReleaseEvent(event) {
panel.mouseReleaseEvent(event);
}
Controller.mouseMoveEvent.connect(mouseMoveEvent);
Controller.mousePressEvent.connect(mousePressEvent);
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
function scriptEnding() {
panel.destroy();
Render.RenderDeferredTask.DrawSceneOctree.enabled = false;
Render.RenderDeferredTask.DrawItemSelection.enabled = false;
}
Script.scriptEnding.connect(scriptEnding);

View file

@ -1,69 +0,0 @@
//
// stats.qml
// examples/utilities/tools/render
//
// Created by Zach Pomerantz on 2/8/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import "plotperf"
Item {
id: statsUI
anchors.fill:parent
Column {
id: stats
spacing: 8
anchors.fill:parent
property var config: Render.getConfig("Stats")
function evalEvenHeight() {
// Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ?
return (height - spacing * (children.length - 1)) / children.length
}
PlotPerf {
title: "Num Buffers"
config: stats.config
height: parent.evalEvenHeight()
parameters: "1::0:bufferCPUCount-CPU-#00B4EF:bufferGPUCount-GPU-#1AC567"
}
PlotPerf {
title: "gpu::Buffer Memory"
config: stats.config
height: parent.evalEvenHeight()
parameters: "1048576:Mb:1:bufferCPUMemoryUsage-CPU-#00B4EF:bufferGPUMemoryUsage-GPU-#1AC567"
}
PlotPerf {
title: "Num Textures"
config: stats.config
height: parent.evalEvenHeight()
parameters: "1::0:textureCPUCount-CPU-#00B4EF:textureGPUCount-GPU-#1AC567:frameTextureCount-Frame-#E2334D"
}
PlotPerf {
title: "gpu::Texture Memory"
config: stats.config
height: parent.evalEvenHeight()
parameters: "1048576:Mb:1:textureCPUMemoryUsage-CPU-#00B4EF:textureGPUMemoryUsage-GPU-#1AC567"
}
PlotPerf {
title: "Drawcalls"
config: stats.config
height: parent.evalEvenHeight()
parameters: "1::0:frameDrawcallCount-frame-#E2334D:frameDrawcallRate-rate-#1AC567-0.001-K/s"
}
PlotPerf {
title: "Triangles"
config: stats.config
height: parent.evalEvenHeight()
parameters: "1000:K:0:frameTriangleCount-frame-#E2334D:frameTriangleRate-rate-#1AC567-0.001-MT/s"
}
}
}

View file

@ -35,6 +35,7 @@ public:
int _RSNumTextureBounded = 0;
int _DSNumAPIDrawcalls = 0;
int _DSNumDrawcalls = 0;
int _DSNumTriangles = 0;

View file

@ -326,6 +326,7 @@ void GLBackend::do_draw(Batch& batch, size_t paramOffset) {
glDrawArrays(mode, startVertex, numVertices);
_stats._DSNumTriangles += numVertices / 3;
_stats._DSNumDrawcalls++;
_stats._DSNumAPIDrawcalls++;
(void)CHECK_GL_ERROR();
}
@ -344,6 +345,7 @@ void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) {
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
_stats._DSNumTriangles += numIndices / 3;
_stats._DSNumDrawcalls++;
_stats._DSNumAPIDrawcalls++;
(void) CHECK_GL_ERROR();
}
@ -358,6 +360,7 @@ void GLBackend::do_drawInstanced(Batch& batch, size_t paramOffset) {
glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances);
_stats._DSNumTriangles += (numInstances * numVertices) / 3;
_stats._DSNumDrawcalls += numInstances;
_stats._DSNumAPIDrawcalls++;
(void) CHECK_GL_ERROR();
}
@ -383,6 +386,7 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) {
#endif
_stats._DSNumTriangles += (numInstances * numIndices) / 3;
_stats._DSNumDrawcalls += numInstances;
_stats._DSNumAPIDrawcalls++;
(void)CHECK_GL_ERROR();
}
@ -395,6 +399,8 @@ void GLBackend::do_multiDrawIndirect(Batch& batch, size_t paramOffset) {
glMultiDrawArraysIndirect(mode, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride);
_stats._DSNumDrawcalls += commandCount;
_stats._DSNumAPIDrawcalls++;
#else
// FIXME implement the slow path
#endif
@ -410,7 +416,7 @@ void GLBackend::do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) {
glMultiDrawElementsIndirect(mode, indexType, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride);
_stats._DSNumDrawcalls += commandCount;
_stats._DSNumAPIDrawcalls++;
#else
// FIXME implement the slow path
#endif

View file

@ -435,8 +435,9 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
const float OVER_CONSERVATIVE_SCALE = 1.1f;
if ((eyeHalfPlaneDistance > -nearRadius) &&
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) {
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < (expandedRadius * OVER_CONSERVATIVE_SCALE) + nearRadius)) {
coneParam.w = 0.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
@ -452,6 +453,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
batch.setProjectionTransform( projMats[side]);
batch.setViewTransform(viewTransforms[side]);
} else {
light->setShowContour(false);
coneParam.w = 1.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));

View file

@ -32,9 +32,10 @@ public:
class RenderDeferred {
public:
using JobModel = render::Job::Model<RenderDeferred>;
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Job::Model<RenderDeferred>;
};
class DrawConfig : public render::Job::Config {

View file

@ -25,6 +25,7 @@ in vec4 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
// Grab the fragment data from the uv

View file

@ -20,17 +20,14 @@ namespace render {
class DrawSceneOctreeConfig : public Job::Config {
Q_OBJECT
Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty())
Q_PROPERTY(bool showVisibleCells MEMBER showVisibleCells WRITE setShowVisibleCells)
Q_PROPERTY(bool showEmptyCells MEMBER showEmptyCells WRITE setShowEmptyCells)
Q_PROPERTY(bool showVisibleCells READ getShowVisibleCells WRITE setShowVisibleCells NOTIFY dirty())
Q_PROPERTY(bool showEmptyCells READ getShowEmptyCells WRITE setShowEmptyCells NOTIFY dirty())
Q_PROPERTY(int numAllocatedCells READ getNumAllocatedCells)
Q_PROPERTY(int numFreeCells READ getNumFreeCells)
public:
DrawSceneOctreeConfig() : Job::Config(false) {}
bool showVisibleCells{ true };
bool showEmptyCells{ false };
int numAllocatedCells{ 0 };
int numFreeCells{ 0 };
@ -38,6 +35,12 @@ namespace render {
int getNumAllocatedCells() const { return numAllocatedCells; }
int getNumFreeCells() const { return numFreeCells; }
bool showVisibleCells{ true };
bool showEmptyCells{ false };
bool getShowVisibleCells() { return showVisibleCells; }
bool getShowEmptyCells() { return showEmptyCells; }
public slots:
void setShowVisibleCells(bool show) { showVisibleCells = show; emit dirty(); }
void setShowEmptyCells(bool show) { showEmptyCells = show; emit dirty(); }
@ -79,10 +82,10 @@ namespace render {
class DrawItemSelectionConfig : public Job::Config {
Q_OBJECT
Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty())
Q_PROPERTY(bool showInsideItems MEMBER showInsideItems WRITE setShowInsideItems)
Q_PROPERTY(bool showInsideSubcellItems MEMBER showInsideSubcellItems WRITE setShowInsideSubcellItems)
Q_PROPERTY(bool showPartialItems MEMBER showPartialItems WRITE setShowPartialItems)
Q_PROPERTY(bool showPartialSubcellItems MEMBER showPartialSubcellItems WRITE setShowPartialSubcellItems)
Q_PROPERTY(bool showInsideItems READ getShowInsideItems WRITE setShowInsideItems NOTIFY dirty())
Q_PROPERTY(bool showInsideSubcellItems READ getShowInsideSubcellItems WRITE setShowInsideSubcellItems NOTIFY dirty())
Q_PROPERTY(bool showPartialItems READ getShowPartialItems WRITE setShowPartialItems NOTIFY dirty())
Q_PROPERTY(bool showPartialSubcellItems READ getShowPartialSubcellItems WRITE setShowPartialSubcellItems NOTIFY dirty())
public:
DrawItemSelectionConfig() : Job::Config(false) {}
@ -92,7 +95,12 @@ namespace render {
bool showPartialItems{ true };
bool showPartialSubcellItems{ true };
public slots:
bool getShowInsideItems() const { return showInsideItems; };
bool getShowInsideSubcellItems() const { return showInsideSubcellItems; };
bool getShowPartialItems() const { return showPartialItems; };
bool getShowPartialSubcellItems() const { return showPartialSubcellItems; };
public slots:
void setShowInsideItems(bool show) { showInsideItems = show; emit dirty(); }
void setShowInsideSubcellItems(bool show) { showInsideSubcellItems = show; emit dirty(); }
void setShowPartialItems(bool show) { showPartialItems = show; emit dirty(); }

View file

@ -20,12 +20,16 @@
using namespace render;
void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems) {
void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, int maxDrawnItems) {
auto& scene = sceneContext->_scene;
RenderArgs* args = renderContext->args;
for (const auto& itemDetails : inItems) {
auto& item = scene->getItem(itemDetails.id);
int numItemsToDraw = (int)inItems.size();
if (maxDrawnItems != -1) {
numItemsToDraw = glm::min(numItemsToDraw, maxDrawnItems);
}
for (auto i = 0; i < numItemsToDraw; ++i) {
auto& item = scene->getItem(inItems[i].id);
item.render(args);
}
}
@ -69,7 +73,10 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext
// render lights
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
args->_batch = &batch;
renderItems(sceneContext, renderContext, inLights);
renderItems(sceneContext, renderContext, inLights, _maxDrawn);
args->_batch = nullptr;
});
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->setNumDrawn((int)inLights.size());
}

View file

@ -16,15 +16,37 @@
namespace render {
void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems);
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);
class DrawLightConfig : public Job::Config {
Q_OBJECT
Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
public:
int getNumDrawn() { return numDrawn; }
void setNumDrawn(int num) { numDrawn = num; emit numDrawnChanged(); }
int maxDrawn{ -1 };
signals:
void numDrawnChanged();
void dirty();
protected:
int numDrawn{ 0 };
};
class DrawLight {
public:
using JobModel = Job::ModelI<DrawLight, ItemBounds>;
using Config = DrawLightConfig;
using JobModel = Job::ModelI<DrawLight, ItemBounds, Config>;
void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inLights);
protected:
int _maxDrawn; // initialized by Config
};
}

View file

@ -36,6 +36,7 @@ void EngineStats::run(const SceneContextPointer& sceneContext, const RenderConte
gpu::ContextStats gpuStats(_gpuStats);
renderContext->args->_context->getStats(_gpuStats);
config->frameAPIDrawcallCount = _gpuStats._DSNumAPIDrawcalls - gpuStats._DSNumAPIDrawcalls;
config->frameDrawcallCount = _gpuStats._DSNumDrawcalls - gpuStats._DSNumDrawcalls;
config->frameDrawcallRate = config->frameDrawcallCount * frequency;

View file

@ -34,6 +34,7 @@ namespace render {
Q_PROPERTY(qint64 textureCPUMemoryUsage MEMBER textureCPUMemoryUsage NOTIFY dirty)
Q_PROPERTY(qint64 textureGPUMemoryUsage MEMBER textureGPUMemoryUsage NOTIFY dirty)
Q_PROPERTY(quint32 frameAPIDrawcallCount MEMBER frameAPIDrawcallCount NOTIFY dirty)
Q_PROPERTY(quint32 frameDrawcallCount MEMBER frameDrawcallCount NOTIFY dirty)
Q_PROPERTY(quint32 frameDrawcallRate MEMBER frameDrawcallRate NOTIFY dirty)
@ -57,6 +58,7 @@ namespace render {
qint64 textureCPUMemoryUsage{ 0 };
qint64 textureGPUMemoryUsage{ 0 };
quint32 frameAPIDrawcallCount{ 0 };
quint32 frameDrawcallCount{ 0 };
quint32 frameDrawcallRate{ 0 };