mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 20:16:16 +02:00
Merge branch 'team-teaching' of https://github.com/highfidelity/hifi into team-teaching-scene-api
This commit is contained in:
commit
c9c434bc8c
23 changed files with 602 additions and 171 deletions
|
@ -134,7 +134,7 @@ Slider = function(x,y,width,thumbSize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Checkbox class
|
// The Checkbox class
|
||||||
Checkbox = function(x,y,width,thumbSize) {
|
Checkbox = function(x,y,thumbSize) {
|
||||||
|
|
||||||
this.thumb = Overlays.addOverlay("text", {
|
this.thumb = Overlays.addOverlay("text", {
|
||||||
backgroundColor: { red: 255, green: 255, blue: 255 },
|
backgroundColor: { red: 255, green: 255, blue: 255 },
|
||||||
|
@ -150,7 +150,7 @@ Checkbox = function(x,y,width,thumbSize) {
|
||||||
backgroundColor: { red: 125, green: 125, blue: 255 },
|
backgroundColor: { red: 125, green: 125, blue: 255 },
|
||||||
x: x,
|
x: x,
|
||||||
y: y,
|
y: y,
|
||||||
width: width,
|
width: thumbSize * 2,
|
||||||
height: thumbSize,
|
height: thumbSize,
|
||||||
alpha: 1.0,
|
alpha: 1.0,
|
||||||
backgroundAlpha: 0.5,
|
backgroundAlpha: 0.5,
|
||||||
|
@ -161,7 +161,7 @@ Checkbox = function(x,y,width,thumbSize) {
|
||||||
this.thumbHalfSize = 0.5 * thumbSize;
|
this.thumbHalfSize = 0.5 * thumbSize;
|
||||||
|
|
||||||
this.minThumbX = x + this.thumbHalfSize;
|
this.minThumbX = x + this.thumbHalfSize;
|
||||||
this.maxThumbX = x + width - this.thumbHalfSize;
|
this.maxThumbX = x + thumbSize * 2 - this.thumbHalfSize;
|
||||||
this.thumbX = this.minThumbX;
|
this.thumbX = this.minThumbX;
|
||||||
|
|
||||||
this.minValue = 0.0;
|
this.minValue = 0.0;
|
||||||
|
@ -553,7 +553,7 @@ Panel = function(x, y) {
|
||||||
|
|
||||||
var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight);
|
var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight);
|
||||||
|
|
||||||
var checkbox = new Checkbox(this.widgetX, this.nextY, widgetWidth, rawHeight);
|
var checkbox = new Checkbox(this.widgetX, this.nextY, rawHeight);
|
||||||
|
|
||||||
item.widget = checkbox;
|
item.widget = checkbox;
|
||||||
item.widget.onValueChanged = function(value) { item.setterFromWidget(value); };
|
item.widget.onValueChanged = function(value) { item.setterFromWidget(value); };
|
||||||
|
|
92
examples/utilities/tools/renderEngineDebug.js
Executable file
92
examples/utilities/tools/renderEngineDebug.js
Executable file
|
@ -0,0 +1,92 @@
|
||||||
|
//
|
||||||
|
// SunLightExample.js
|
||||||
|
// examples
|
||||||
|
// Sam Gateau
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
|
||||||
|
Script.include("cookies.js");
|
||||||
|
|
||||||
|
var panel = new Panel(10, 400);
|
||||||
|
|
||||||
|
panel.newCheckbox("Enable Cull Opaque",
|
||||||
|
function(value) { Scene.setEngineCullOpaque((value != 0)); },
|
||||||
|
function() { return Scene.doEngineCullOpaque(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
panel.newCheckbox("Enable Sort Opaque",
|
||||||
|
function(value) { Scene.setEngineSortOpaque((value != 0)); },
|
||||||
|
function() { return Scene.doEngineSortOpaque(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
panel.newCheckbox("Enable Render Opaque",
|
||||||
|
function(value) { Scene.setEngineRenderOpaque((value != 0)); },
|
||||||
|
function() { return Scene.doEngineRenderOpaque(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
panel.newSlider("Num Feed Opaques", 0, 1000,
|
||||||
|
function(value) { },
|
||||||
|
function() { return Scene.getEngineNumFeedOpaqueItems(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
panel.newSlider("Num Drawn Opaques", 0, 1000,
|
||||||
|
function(value) { },
|
||||||
|
function() { return Scene.getEngineNumDrawnOpaqueItems(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
panel.newCheckbox("Enable Cull Transparent",
|
||||||
|
function(value) { Scene.setEngineCullTransparent((value != 0)); },
|
||||||
|
function() { return Scene.doEngineCullTransparent(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
panel.newCheckbox("Enable Sort Transparent",
|
||||||
|
function(value) { Scene.setEngineSortTransparent((value != 0)); },
|
||||||
|
function() { return Scene.doEngineSortTransparent(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
panel.newCheckbox("Enable Render Transparent",
|
||||||
|
function(value) { Scene.setEngineRenderTransparent((value != 0)); },
|
||||||
|
function() { return Scene.doEngineRenderTransparent(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
panel.newSlider("Num Feed Transparents", 0, 1000,
|
||||||
|
function(value) { },
|
||||||
|
function() { return Scene.getEngineNumFeedTransparentItems(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
panel.newSlider("Num Drawn Transparents", 0, 1000,
|
||||||
|
function(value) { },
|
||||||
|
function() { return Scene.getEngineNumDrawnTransparentItems(); },
|
||||||
|
function(value) { return (value); }
|
||||||
|
);
|
||||||
|
|
||||||
|
var tickTackPeriod = 500;
|
||||||
|
|
||||||
|
function updateCounters() {
|
||||||
|
panel.set("Num Feed Opaques", panel.get("Num Feed Opaques"));
|
||||||
|
panel.set("Num Drawn Opaques", panel.get("Num Drawn Opaques"));
|
||||||
|
panel.set("Num Feed Transparents", panel.get("Num Feed Transparents"));
|
||||||
|
panel.set("Num Drawn Transparents", panel.get("Num Drawn Transparents"));
|
||||||
|
}
|
||||||
|
Script.setInterval(updateCounters, tickTackPeriod);
|
||||||
|
|
||||||
|
Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) { return panel.mouseMoveEvent(event); });
|
||||||
|
Controller.mousePressEvent.connect( function panelMousePressEvent(event) { return panel.mousePressEvent(event); });
|
||||||
|
Controller.mouseReleaseEvent.connect(function(event) { return panel.mouseReleaseEvent(event); });
|
||||||
|
|
||||||
|
function scriptEnding() {
|
||||||
|
panel.destroy();
|
||||||
|
}
|
||||||
|
Script.scriptEnding.connect(scriptEnding);
|
|
@ -3200,6 +3200,113 @@ namespace render {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Background Render Data & rendering functions
|
||||||
|
class BackgroundRenderData {
|
||||||
|
public:
|
||||||
|
typedef render::Payload<BackgroundRenderData> Payload;
|
||||||
|
typedef Payload::DataPointer Pointer;
|
||||||
|
|
||||||
|
Stars _stars;
|
||||||
|
Environment* _environment;
|
||||||
|
|
||||||
|
BackgroundRenderData(Environment* environment) : _environment(environment) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static render::ItemID _item; // unique WorldBoxRenderData
|
||||||
|
};
|
||||||
|
|
||||||
|
render::ItemID BackgroundRenderData::_item = 0;
|
||||||
|
|
||||||
|
namespace render {
|
||||||
|
template <> const ItemKey payloadGetKey(const BackgroundRenderData::Pointer& stuff) { return ItemKey::Builder::background(); }
|
||||||
|
template <> const Item::Bound payloadGetBound(const BackgroundRenderData::Pointer& stuff) { return Item::Bound(); }
|
||||||
|
template <> void payloadRender(const BackgroundRenderData::Pointer& background, RenderArgs* args) {
|
||||||
|
|
||||||
|
// Background rendering decision
|
||||||
|
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||||
|
auto skybox = model::SkyboxPointer();
|
||||||
|
if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) {
|
||||||
|
} else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) {
|
||||||
|
if (/*!selfAvatarOnly &&*/ Menu::getInstance()->isOptionChecked(MenuOption::Stars)) {
|
||||||
|
PerformanceTimer perfTimer("stars");
|
||||||
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
|
"Application::payloadRender<BackgroundRenderData>() ... stars...");
|
||||||
|
if (!background->_stars.isStarsLoaded()) {
|
||||||
|
background->_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED);
|
||||||
|
}
|
||||||
|
// should be the first rendering pass - w/o depth buffer / lighting
|
||||||
|
|
||||||
|
// compute starfield alpha based on distance from atmosphere
|
||||||
|
float alpha = 1.0f;
|
||||||
|
bool hasStars = true;
|
||||||
|
|
||||||
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||||
|
// TODO: handle this correctly for zones
|
||||||
|
const EnvironmentData& closestData = background->_environment->getClosestData(args->_viewFrustum->getPosition()); // was theCamera instead of _viewFrustum
|
||||||
|
|
||||||
|
if (closestData.getHasStars()) {
|
||||||
|
const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
|
||||||
|
const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f;
|
||||||
|
|
||||||
|
glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation())
|
||||||
|
/ closestData.getAtmosphereOuterRadius();
|
||||||
|
float height = glm::distance(args->_viewFrustum->getPosition()/*theCamera.getPosition()*/, closestData.getAtmosphereCenter());
|
||||||
|
if (height < closestData.getAtmosphereInnerRadius()) {
|
||||||
|
// If we're inside the atmosphere, then determine if our keyLight is below the horizon
|
||||||
|
alpha = 0.0f;
|
||||||
|
|
||||||
|
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
||||||
|
float directionY = glm::clamp(sunDirection.y,
|
||||||
|
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||||
|
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
||||||
|
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else if (height < closestData.getAtmosphereOuterRadius()) {
|
||||||
|
alpha = (height - closestData.getAtmosphereInnerRadius()) /
|
||||||
|
(closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
|
||||||
|
|
||||||
|
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
||||||
|
float directionY = glm::clamp(sunDirection.y,
|
||||||
|
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||||
|
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
||||||
|
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasStars = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally render the starfield
|
||||||
|
if (hasStars) {
|
||||||
|
background->_stars.render(args->_viewFrustum->getFieldOfView(), args->_viewFrustum->getAspectRatio(), args->_viewFrustum->getNearClip(), alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the sky dome
|
||||||
|
if (/*!selfAvatarOnly &&*/ Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||||
|
PerformanceTimer perfTimer("atmosphere");
|
||||||
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
|
"Application::displaySide() ... atmosphere...");
|
||||||
|
background->_environment->renderAtmospheres(*(args->_viewFrustum));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
|
||||||
|
PerformanceTimer perfTimer("skybox");
|
||||||
|
|
||||||
|
skybox = skyStage->getSkybox();
|
||||||
|
if (skybox) {
|
||||||
|
gpu::Batch batch;
|
||||||
|
model::Skybox::render(batch, *(args->_viewFrustum), *skybox);
|
||||||
|
|
||||||
|
gpu::GLBackend::renderBatch(batch, true);
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly, bool billboard) {
|
void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly, bool billboard) {
|
||||||
|
@ -3272,86 +3379,19 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][2]);
|
glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// THe pending changes collecting the changes here
|
||||||
|
render::PendingChanges pendingChanges;
|
||||||
|
|
||||||
// Background rendering decision
|
// Background rendering decision
|
||||||
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
if (BackgroundRenderData::_item == 0) {
|
||||||
auto skybox = model::SkyboxPointer();
|
auto backgroundRenderData = BackgroundRenderData::Pointer(new BackgroundRenderData(&_environment));
|
||||||
if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) {
|
auto backgroundRenderPayload = render::PayloadPointer(new BackgroundRenderData::Payload(backgroundRenderData));
|
||||||
} else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) {
|
|
||||||
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) {
|
|
||||||
PerformanceTimer perfTimer("stars");
|
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
|
||||||
"Application::displaySide() ... stars...");
|
|
||||||
if (!_stars.isStarsLoaded()) {
|
|
||||||
_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED);
|
|
||||||
}
|
|
||||||
// should be the first rendering pass - w/o depth buffer / lighting
|
|
||||||
|
|
||||||
// compute starfield alpha based on distance from atmosphere
|
BackgroundRenderData::_item = _main3DScene->allocateID();
|
||||||
float alpha = 1.0f;
|
|
||||||
bool hasStars = true;
|
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
pendingChanges.resetItem(WorldBoxRenderData::_item, backgroundRenderPayload);
|
||||||
// TODO: handle this correctly for zones
|
} else {
|
||||||
const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition());
|
|
||||||
|
|
||||||
if (closestData.getHasStars()) {
|
|
||||||
const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
|
|
||||||
const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f;
|
|
||||||
|
|
||||||
glm::vec3 sunDirection = (getAvatarPosition() - closestData.getSunLocation())
|
|
||||||
/ closestData.getAtmosphereOuterRadius();
|
|
||||||
float height = glm::distance(theCamera.getPosition(), closestData.getAtmosphereCenter());
|
|
||||||
if (height < closestData.getAtmosphereInnerRadius()) {
|
|
||||||
// If we're inside the atmosphere, then determine if our keyLight is below the horizon
|
|
||||||
alpha = 0.0f;
|
|
||||||
|
|
||||||
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
|
||||||
float directionY = glm::clamp(sunDirection.y,
|
|
||||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
|
||||||
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
|
||||||
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else if (height < closestData.getAtmosphereOuterRadius()) {
|
|
||||||
alpha = (height - closestData.getAtmosphereInnerRadius()) /
|
|
||||||
(closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
|
|
||||||
|
|
||||||
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
|
||||||
float directionY = glm::clamp(sunDirection.y,
|
|
||||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
|
||||||
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
|
||||||
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hasStars = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally render the starfield
|
|
||||||
if (hasStars) {
|
|
||||||
_stars.render(_displayViewFrustum.getFieldOfView(), _displayViewFrustum.getAspectRatio(), _displayViewFrustum.getNearClip(), alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the sky dome
|
|
||||||
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
|
||||||
PerformanceTimer perfTimer("atmosphere");
|
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
|
||||||
"Application::displaySide() ... atmosphere...");
|
|
||||||
_environment.renderAtmospheres(theCamera);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
|
|
||||||
skybox = skyStage->getSkybox();
|
|
||||||
if (skybox) {
|
|
||||||
gpu::Batch batch;
|
|
||||||
model::Skybox::render(batch, _viewFrustum, *skybox);
|
|
||||||
|
|
||||||
gpu::GLBackend::renderBatch(batch, true);
|
|
||||||
glUseProgram(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
||||||
|
@ -3361,7 +3401,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->prepare();
|
// Assuming nothing get's rendered through that
|
||||||
|
// DependencyManager::get<DeferredLightingEffect>()->prepare();
|
||||||
|
|
||||||
if (!selfAvatarOnly) {
|
if (!selfAvatarOnly) {
|
||||||
|
|
||||||
|
@ -3388,10 +3429,11 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
renderArgs->_debugFlags = renderDebugFlags;
|
renderArgs->_debugFlags = renderDebugFlags;
|
||||||
_entities.render(renderArgs);
|
_entities.render(renderArgs);
|
||||||
|
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
// This shouldn't matter anymore
|
||||||
|
/* if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
||||||
// Restaure polygon mode
|
// Restaure polygon mode
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// render the ambient occlusion effect if enabled
|
// render the ambient occlusion effect if enabled
|
||||||
|
@ -3403,7 +3445,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render::PendingChanges pendingChanges;
|
|
||||||
|
|
||||||
// Make sure the WorldBox is in the scene
|
// Make sure the WorldBox is in the scene
|
||||||
if (WorldBoxRenderData::_item == 0) {
|
if (WorldBoxRenderData::_item == 0) {
|
||||||
|
@ -3423,6 +3464,26 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!billboard) {
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->setAmbientLightMode(getRenderAmbientLight());
|
||||||
|
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity());
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->setGlobalAtmosphere(skyStage->getAtmosphere());
|
||||||
|
|
||||||
|
auto skybox = model::SkyboxPointer();
|
||||||
|
if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
|
||||||
|
skybox = skyStage->getSkybox();
|
||||||
|
}
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->setGlobalSkybox(skybox);
|
||||||
|
|
||||||
|
// Not needed anymore here, taken care off by the Engine
|
||||||
|
/*
|
||||||
|
PROFILE_RANGE("DeferredLighting");
|
||||||
|
PerformanceTimer perfTimer("lighting");
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->render();*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("SceneProcessPendingChanges");
|
PerformanceTimer perfTimer("SceneProcessPendingChanges");
|
||||||
_main3DScene->enqueuePendingChanges(pendingChanges);
|
_main3DScene->enqueuePendingChanges(pendingChanges);
|
||||||
|
@ -3434,8 +3495,20 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("EngineRun");
|
PerformanceTimer perfTimer("EngineRun");
|
||||||
render::RenderContext renderContext;
|
render::RenderContext renderContext;
|
||||||
|
|
||||||
|
auto sceneInterface = DependencyManager::get<SceneScriptingInterface>();
|
||||||
|
|
||||||
|
renderContext._cullOpaque = sceneInterface->doEngineCullOpaque();
|
||||||
|
renderContext._sortOpaque = sceneInterface->doEngineSortOpaque();
|
||||||
|
renderContext._renderOpaque = sceneInterface->doEngineRenderOpaque();
|
||||||
|
renderContext._cullTransparent = sceneInterface->doEngineCullTransparent();
|
||||||
|
renderContext._sortTransparent = sceneInterface->doEngineSortTransparent();
|
||||||
|
renderContext._renderTransparent = sceneInterface->doEngineRenderTransparent();
|
||||||
|
|
||||||
renderArgs->_shouldRender = LODManager::shouldRender;
|
renderArgs->_shouldRender = LODManager::shouldRender;
|
||||||
|
|
||||||
renderContext.args = renderArgs;
|
renderContext.args = renderArgs;
|
||||||
|
renderArgs->_viewFrustum = getDisplayViewFrustum();
|
||||||
_renderEngine->setRenderContext(renderContext);
|
_renderEngine->setRenderContext(renderContext);
|
||||||
|
|
||||||
// Before the deferred pass, let's try to use the render engine
|
// Before the deferred pass, let's try to use the render engine
|
||||||
|
@ -3446,20 +3519,15 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
qDebug() << "renderArgs._trianglesRendered:" << renderArgs->_trianglesRendered;
|
qDebug() << "renderArgs._trianglesRendered:" << renderArgs->_trianglesRendered;
|
||||||
qDebug() << "renderArgs._quadsRendered:" << renderArgs->_quadsRendered;
|
qDebug() << "renderArgs._quadsRendered:" << renderArgs->_quadsRendered;
|
||||||
*/
|
*/
|
||||||
|
auto engineRC = _renderEngine->getRenderContext();
|
||||||
|
sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems);
|
||||||
|
sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems);
|
||||||
|
|
||||||
|
sceneInterface->setEngineFeedTransparentItems(engineRC->_numFeedTransparentItems);
|
||||||
|
sceneInterface->setEngineDrawnTransparentItems(engineRC->_numDrawnTransparentItems);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!billboard) {
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->setAmbientLightMode(getRenderAmbientLight());
|
|
||||||
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity());
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalAtmosphere(skyStage->getAtmosphere());
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalSkybox(skybox);
|
|
||||||
|
|
||||||
PROFILE_RANGE("DeferredLighting");
|
|
||||||
PerformanceTimer perfTimer("lighting");
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Render the sixense lasers
|
//Render the sixense lasers
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
|
||||||
|
@ -3709,7 +3777,7 @@ void Application::updateWindowTitle(){
|
||||||
void Application::clearDomainOctreeDetails() {
|
void Application::clearDomainOctreeDetails() {
|
||||||
qCDebug(interfaceapp) << "Clearing domain octree details...";
|
qCDebug(interfaceapp) << "Clearing domain octree details...";
|
||||||
// reset the environment so that we don't erroneously end up with multiple
|
// reset the environment so that we don't erroneously end up with multiple
|
||||||
_environment.resetToDefault();
|
// _environment.resetToDefault();
|
||||||
|
|
||||||
// reset our node to stats and node to jurisdiction maps... since these must be changing...
|
// reset our node to stats and node to jurisdiction maps... since these must be changing...
|
||||||
_entityServerJurisdictions.lockForWrite();
|
_entityServerJurisdictions.lockForWrite();
|
||||||
|
|
|
@ -210,7 +210,7 @@ public:
|
||||||
ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; }
|
ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; }
|
||||||
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
||||||
EntityTreeRenderer* getEntities() { return &_entities; }
|
EntityTreeRenderer* getEntities() { return &_entities; }
|
||||||
Environment* getEnvironment() { return &_environment; }
|
// Environment* getEnvironment() { return &_environment; }
|
||||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||||
MainWindow* getWindow() { return _window; }
|
MainWindow* getWindow() { return _window; }
|
||||||
OctreeQuery& getOctreeQuery() { return _octreeQuery; }
|
OctreeQuery& getOctreeQuery() { return _octreeQuery; }
|
||||||
|
@ -535,7 +535,7 @@ private:
|
||||||
QElapsedTimer _timerStart;
|
QElapsedTimer _timerStart;
|
||||||
QElapsedTimer _lastTimeUpdated;
|
QElapsedTimer _lastTimeUpdated;
|
||||||
bool _justStarted;
|
bool _justStarted;
|
||||||
Stars _stars;
|
// Stars _stars;
|
||||||
|
|
||||||
ShapeManager _shapeManager;
|
ShapeManager _shapeManager;
|
||||||
PhysicalEntitySimulation _entitySimulation;
|
PhysicalEntitySimulation _entitySimulation;
|
||||||
|
|
|
@ -68,7 +68,7 @@ void Environment::resetToDefault() {
|
||||||
_data[HifiSockAddr()][0];
|
_data[HifiSockAddr()][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::renderAtmospheres(Camera& camera) {
|
void Environment::renderAtmospheres(ViewFrustum& camera) {
|
||||||
// get the lock for the duration of the call
|
// get the lock for the duration of the call
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) {
|
void Environment::renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data) {
|
||||||
glm::vec3 center = data.getAtmosphereCenter();
|
glm::vec3 center = data.getAtmosphereCenter();
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include "EnvironmentData.h"
|
#include "EnvironmentData.h"
|
||||||
|
|
||||||
class Camera;
|
class ViewFrustum;
|
||||||
class ProgramObject;
|
class ProgramObject;
|
||||||
|
|
||||||
class Environment {
|
class Environment {
|
||||||
|
@ -29,7 +29,7 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void resetToDefault();
|
void resetToDefault();
|
||||||
void renderAtmospheres(Camera& camera);
|
void renderAtmospheres(ViewFrustum& camera);
|
||||||
|
|
||||||
void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; }
|
void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; }
|
||||||
void endOverride() { _environmentIsOverridden = false; }
|
void endOverride() { _environmentIsOverridden = false; }
|
||||||
|
@ -46,7 +46,7 @@ private:
|
||||||
|
|
||||||
ProgramObject* createSkyProgram(const char* from, int* locations);
|
ProgramObject* createSkyProgram(const char* from, int* locations);
|
||||||
|
|
||||||
void renderAtmosphere(Camera& camera, const EnvironmentData& data);
|
void renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data);
|
||||||
|
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
ProgramObject* _skyFromAtmosphereProgram;
|
ProgramObject* _skyFromAtmosphereProgram;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void renderWorldBox() {
|
void renderWorldBox() {
|
||||||
|
return;
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
|
||||||
// Show edge of world
|
// Show edge of world
|
||||||
|
|
|
@ -45,6 +45,9 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
|
|
||||||
|
#include "gpu/GLBackend.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f);
|
const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f);
|
||||||
|
@ -1485,7 +1488,8 @@ void MyAvatar::maybeUpdateBillboard() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RenderArgs renderArgs;
|
gpu::Context context(new gpu::GLBackend());
|
||||||
|
RenderArgs renderArgs(&context);
|
||||||
QImage image = Application::getInstance()->renderAvatarBillboard(&renderArgs);
|
QImage image = Application::getInstance()->renderAvatarBillboard(&renderArgs);
|
||||||
_billboard.clear();
|
_billboard.clear();
|
||||||
QBuffer buffer(&_billboard);
|
QBuffer buffer(&_billboard);
|
||||||
|
|
|
@ -525,9 +525,9 @@ void EntityTreeRenderer::render(RenderArgs* renderArgs) {
|
||||||
Model::endScene(renderArgs);
|
Model::endScene(renderArgs);
|
||||||
_tree->unlock();
|
_tree->unlock();
|
||||||
|
|
||||||
glPushMatrix();
|
// glPushMatrix();
|
||||||
renderArgs->_context->render(batch);
|
// renderArgs->_context->render(batch);
|
||||||
glPopMatrix();
|
// glPopMatrix();
|
||||||
|
|
||||||
renderArgs->_batch = nullptr;
|
renderArgs->_batch = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -34,5 +34,8 @@ bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings) {
|
||||||
|
|
||||||
void Context::render(Batch& batch) {
|
void Context::render(Batch& batch) {
|
||||||
_backend->render(batch);
|
_backend->render(batch);
|
||||||
// GLBackend::renderBatch(batch, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::syncCache() {
|
||||||
|
_backend->syncCache();
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ public:
|
||||||
|
|
||||||
virtual~ Backend() {};
|
virtual~ Backend() {};
|
||||||
virtual void render(Batch& batch) = 0;
|
virtual void render(Batch& batch) = 0;
|
||||||
|
virtual void syncCache() = 0;
|
||||||
|
|
||||||
class TransformObject {
|
class TransformObject {
|
||||||
public:
|
public:
|
||||||
|
@ -115,6 +116,7 @@ public:
|
||||||
|
|
||||||
void render(Batch& batch);
|
void render(Batch& batch);
|
||||||
|
|
||||||
|
void syncCache();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Context(const Context& context);
|
Context(const Context& context);
|
||||||
|
|
|
@ -30,6 +30,12 @@ public:
|
||||||
|
|
||||||
virtual void render(Batch& batch);
|
virtual void render(Batch& batch);
|
||||||
|
|
||||||
|
// This call synchronize the Full Backend cache with the current GLState
|
||||||
|
// THis is only intended to be used when mixing raw gl calls with the gpu api usage in order to sync
|
||||||
|
// the gpu::Backend state with the true gl state which has probably been messed up by these ugly naked gl calls
|
||||||
|
// Let's try to avoid to do that as much as possible!
|
||||||
|
virtual void syncCache();
|
||||||
|
|
||||||
// Render Batch create a local Context and execute the batch with it
|
// Render Batch create a local Context and execute the batch with it
|
||||||
// WARNING:
|
// WARNING:
|
||||||
// if syncCache is true, then the gpu::GLBackend will synchornize
|
// if syncCache is true, then the gpu::GLBackend will synchornize
|
||||||
|
@ -195,12 +201,6 @@ public:
|
||||||
|
|
||||||
void do_setStateColorWriteMask(uint32 mask);
|
void do_setStateColorWriteMask(uint32 mask);
|
||||||
|
|
||||||
// This call synchronize the Full Backend cache with the current GLState
|
|
||||||
// THis is only intended to be used when mixing raw gl calls with the gpu api usage in order to sync
|
|
||||||
// the gpu::Backend state with the true gl state which has probably been messed up by these ugly naked gl calls
|
|
||||||
// Let's try to avoid to do that as much as possible!
|
|
||||||
void syncCache();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Draw Stage
|
// Draw Stage
|
||||||
|
|
|
@ -865,6 +865,9 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
|
||||||
}
|
}
|
||||||
|
|
||||||
bool somethingAdded = false;
|
bool somethingAdded = false;
|
||||||
|
|
||||||
|
qDebug() << "Model::addToScene : " << this->getURL().toString();
|
||||||
|
|
||||||
// allow the attachments to add to scene
|
// allow the attachments to add to scene
|
||||||
foreach (Model* attachment, _attachments) {
|
foreach (Model* attachment, _attachments) {
|
||||||
bool attachementSomethingAdded = attachment->addToScene(scene, pendingChanges);
|
bool attachementSomethingAdded = attachment->addToScene(scene, pendingChanges);
|
||||||
|
@ -904,6 +907,7 @@ void Model::removeFromScene(std::shared_ptr<render::Scene> scene, render::Pendin
|
||||||
}
|
}
|
||||||
_renderItems.clear();
|
_renderItems.clear();
|
||||||
_readyWhenAdded = false;
|
_readyWhenAdded = false;
|
||||||
|
qDebug() << "Model::removeFromScene : " << this->getURL().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::render(RenderArgs* renderArgs, float alpha) {
|
bool Model::render(RenderArgs* renderArgs, float alpha) {
|
||||||
|
@ -922,6 +926,8 @@ bool Model::render(RenderArgs* renderArgs, float alpha) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::renderCore(RenderArgs* args, float alpha) {
|
bool Model::renderCore(RenderArgs* args, float alpha) {
|
||||||
|
return true;
|
||||||
|
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
if (!_viewState) {
|
if (!_viewState) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2247,14 +2253,19 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
|
||||||
_transforms.push_back(Transform());
|
_transforms.push_back(Transform());
|
||||||
}
|
}
|
||||||
|
|
||||||
_transforms[0] = _viewState->getViewTransform();
|
// _transforms[0] = _viewState->getViewTransform();
|
||||||
// apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space)
|
// args->_viewFrustum->evalViewTransform(_transforms[0]);
|
||||||
_transforms[0].preTranslate(-_translation);
|
|
||||||
batch.setViewTransform(_transforms[0]);
|
|
||||||
|
|
||||||
const float OPAQUE_ALPHA_THRESHOLD = 0.5f;
|
// apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space)
|
||||||
const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
|
// _transforms[0].setTranslation(_translation);
|
||||||
auto alphaThreshold = translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME
|
|
||||||
|
// batch.setViewTransform(_transforms[0]);
|
||||||
|
|
||||||
|
|
||||||
|
// const float OPAQUE_ALPHA_THRESHOLD = 0.5f;
|
||||||
|
// const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
|
||||||
|
// auto alphaThreshold = translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME
|
||||||
|
auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
|
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
|
||||||
|
|
||||||
|
@ -2305,10 +2316,17 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
|
||||||
if (state.clusterMatrices.size() > 1) {
|
if (state.clusterMatrices.size() > 1) {
|
||||||
GLBATCH(glUniformMatrix4fv)(locations->clusterMatrices, state.clusterMatrices.size(), false,
|
GLBATCH(glUniformMatrix4fv)(locations->clusterMatrices, state.clusterMatrices.size(), false,
|
||||||
(const float*)state.clusterMatrices.constData());
|
(const float*)state.clusterMatrices.constData());
|
||||||
batch.setModelTransform(Transform());
|
// batch.setModelTransform(Transform());
|
||||||
|
_transforms[0].setTranslation(_translation);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
batch.setModelTransform(Transform(state.clusterMatrices[0]));
|
_transforms[0] = Transform(state.clusterMatrices[0]);
|
||||||
|
_transforms[0].preTranslate(_translation);
|
||||||
|
|
||||||
|
//batch.setModelTransform(Transform(state.clusterMatrices[0]));
|
||||||
}
|
}
|
||||||
|
batch.setModelTransform(_transforms[0]);
|
||||||
|
|
||||||
|
|
||||||
if (mesh.blendshapes.isEmpty()) {
|
if (mesh.blendshapes.isEmpty()) {
|
||||||
batch.setInputFormat(networkMesh._vertexFormat);
|
batch.setInputFormat(networkMesh._vertexFormat);
|
||||||
|
@ -2331,7 +2349,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
|
||||||
model::MaterialPointer material = part._material;
|
model::MaterialPointer material = part._material;
|
||||||
|
|
||||||
if (material == nullptr) {
|
if (material == nullptr) {
|
||||||
qCDebug(renderutils) << "WARNING: material == nullptr!!!";
|
// qCDebug(renderutils) << "WARNING: material == nullptr!!!";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material != nullptr) {
|
if (material != nullptr) {
|
||||||
|
|
|
@ -10,12 +10,34 @@
|
||||||
//
|
//
|
||||||
#include "RenderDeferredTask.h"
|
#include "RenderDeferredTask.h"
|
||||||
|
|
||||||
|
#include "gpu/Context.h"
|
||||||
|
|
||||||
|
#include <PerfStat.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
|
|
||||||
|
template <> void render::jobRun(const PrepareDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
PerformanceTimer perfTimer("PrepareDeferred");
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
PerformanceTimer perfTimer("ResolveDeferred");
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RenderDeferredTask::RenderDeferredTask() : Task() {
|
RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||||
|
_jobs.push_back(Job(PrepareDeferred()));
|
||||||
|
_jobs.push_back(Job(DrawBackground()));
|
||||||
_jobs.push_back(Job(DrawOpaque()));
|
_jobs.push_back(Job(DrawOpaque()));
|
||||||
_jobs.push_back(Job(DrawLight()));
|
_jobs.push_back(Job(DrawLight()));
|
||||||
_jobs.push_back(Job(DrawTransparent()));
|
_jobs.push_back(Job(DrawTransparent()));
|
||||||
|
_jobs.push_back(Job(ResetGLState()));
|
||||||
|
_jobs.push_back(Job(ResolveDeferred()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderDeferredTask::~RenderDeferredTask() {
|
RenderDeferredTask::~RenderDeferredTask() {
|
||||||
|
@ -34,6 +56,8 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderContext->args->_context->syncCache();
|
||||||
|
|
||||||
for (auto job : _jobs) {
|
for (auto job : _jobs) {
|
||||||
job.run(sceneContext, renderContext);
|
job.run(sceneContext, renderContext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,21 @@
|
||||||
|
|
||||||
#include "render/DrawTask.h"
|
#include "render/DrawTask.h"
|
||||||
|
|
||||||
|
#include "DeferredLightingEffect.h"
|
||||||
|
|
||||||
|
class PrepareDeferred {
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
namespace render {
|
||||||
|
template <> void jobRun(const PrepareDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ResolveDeferred {
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
namespace render {
|
||||||
|
template <> void jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||||
|
}
|
||||||
|
|
||||||
class RenderDeferredTask : public render::Task {
|
class RenderDeferredTask : public render::Task {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -29,6 +29,7 @@ DrawSceneTask::DrawSceneTask() : Task() {
|
||||||
_jobs.push_back(Job(DrawOpaque()));
|
_jobs.push_back(Job(DrawOpaque()));
|
||||||
_jobs.push_back(Job(DrawLight()));
|
_jobs.push_back(Job(DrawLight()));
|
||||||
_jobs.push_back(Job(DrawTransparent()));
|
_jobs.push_back(Job(DrawTransparent()));
|
||||||
|
_jobs.push_back(Job(ResetGLState()));
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawSceneTask::~DrawSceneTask() {
|
DrawSceneTask::~DrawSceneTask() {
|
||||||
|
@ -56,6 +57,7 @@ Job::~Job() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemIDs& outItems) {
|
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemIDs& outItems) {
|
||||||
|
PerformanceTimer perfTimer("cullItems");
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
|
@ -114,6 +116,7 @@ struct BackToFrontSort {
|
||||||
};
|
};
|
||||||
|
|
||||||
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDs& inItems, ItemIDs& outItems) {
|
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDs& inItems, ItemIDs& outItems) {
|
||||||
|
PerformanceTimer perfTimer("depthSortItems");
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
|
@ -152,6 +155,7 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende
|
||||||
}
|
}
|
||||||
|
|
||||||
void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems) {
|
void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems) {
|
||||||
|
PerformanceTimer perfTimer("renderItems");
|
||||||
auto& scene = sceneContext->_scene;
|
auto& scene = sceneContext->_scene;
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
// render
|
// render
|
||||||
|
@ -195,8 +199,16 @@ void addClearStateCommands(gpu::Batch& batch) {
|
||||||
batch._glUseProgram(0);
|
batch._glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> void render::jobRun(const ResetGLState& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
|
||||||
|
gpu::Batch theBatch;
|
||||||
|
addClearStateCommands(theBatch);
|
||||||
|
assert(renderContext->args);
|
||||||
|
renderContext->args->_context->render(theBatch);
|
||||||
|
}
|
||||||
|
|
||||||
template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
PerformanceTimer perfTimer("DrawOpaque");
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
|
@ -209,40 +221,57 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer
|
||||||
for (auto id : items) {
|
for (auto id : items) {
|
||||||
inItems.push_back(id);
|
inItems.push_back(id);
|
||||||
}
|
}
|
||||||
|
ItemIDs& renderedItems = inItems;
|
||||||
|
|
||||||
|
renderContext->_numFeedOpaqueItems = renderedItems.size();
|
||||||
|
|
||||||
ItemIDs culledItems;
|
ItemIDs culledItems;
|
||||||
cullItems(sceneContext, renderContext, inItems, culledItems);
|
if (renderContext->_cullOpaque) {
|
||||||
|
cullItems(sceneContext, renderContext, renderedItems, culledItems);
|
||||||
ItemIDs sortedItems;
|
renderedItems = culledItems;
|
||||||
depthSortItems(sceneContext, renderContext, true, culledItems, sortedItems); // Sort Front to back opaque items!
|
|
||||||
|
|
||||||
RenderArgs* args = renderContext->args;
|
|
||||||
gpu::Batch theBatch;
|
|
||||||
args->_batch = &theBatch;
|
|
||||||
|
|
||||||
glm::mat4 proj;
|
|
||||||
args->_viewFrustum->evalProjectionMatrix(proj);
|
|
||||||
theBatch.setProjectionTransform(proj);
|
|
||||||
|
|
||||||
renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE;
|
|
||||||
{
|
|
||||||
GLenum buffers[3];
|
|
||||||
int bufferCount = 0;
|
|
||||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
|
|
||||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
|
|
||||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
|
|
||||||
theBatch._glDrawBuffers(bufferCount, buffers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderItems(sceneContext, renderContext, sortedItems);
|
renderContext->_numDrawnOpaqueItems = renderedItems.size();
|
||||||
|
|
||||||
addClearStateCommands((*args->_batch));
|
|
||||||
args->_context->render((*args->_batch));
|
ItemIDs sortedItems;
|
||||||
args->_batch = nullptr;
|
if (renderContext->_sortOpaque) {
|
||||||
|
depthSortItems(sceneContext, renderContext, true, renderedItems, sortedItems); // Sort Front to back opaque items!
|
||||||
|
renderedItems = sortedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderContext->_renderOpaque) {
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
gpu::Batch batch;
|
||||||
|
args->_batch = &batch;
|
||||||
|
|
||||||
|
glm::mat4 projMat;
|
||||||
|
Transform viewMat;
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewMat);
|
||||||
|
|
||||||
|
renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE;
|
||||||
|
{
|
||||||
|
GLenum buffers[3];
|
||||||
|
int bufferCount = 0;
|
||||||
|
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
|
||||||
|
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
|
||||||
|
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
|
||||||
|
batch._glDrawBuffers(bufferCount, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderItems(sceneContext, renderContext, renderedItems);
|
||||||
|
|
||||||
|
args->_context->render((*args->_batch));
|
||||||
|
args->_batch = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <> void render::jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
template <> void render::jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
PerformanceTimer perfTimer("DrawTransparent");
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
|
@ -255,33 +284,71 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo
|
||||||
for (auto id : items) {
|
for (auto id : items) {
|
||||||
inItems.push_back(id);
|
inItems.push_back(id);
|
||||||
}
|
}
|
||||||
|
ItemIDs& renderedItems = inItems;
|
||||||
|
|
||||||
|
renderContext->_numFeedTransparentItems = renderedItems.size();
|
||||||
|
|
||||||
ItemIDs culledItems;
|
ItemIDs culledItems;
|
||||||
cullItems(sceneContext, renderContext, inItems, culledItems);
|
if (renderContext->_cullTransparent) {
|
||||||
|
cullItems(sceneContext, renderContext, inItems, culledItems);
|
||||||
ItemIDs sortedItems;
|
renderedItems = culledItems;
|
||||||
depthSortItems(sceneContext, renderContext, false, culledItems, sortedItems); // Sort Back to front transparent items!
|
|
||||||
|
|
||||||
RenderArgs* args = renderContext->args;
|
|
||||||
gpu::Batch theBatch;
|
|
||||||
args->_batch = &theBatch;
|
|
||||||
|
|
||||||
renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE;
|
|
||||||
{
|
|
||||||
GLenum buffers[3];
|
|
||||||
int bufferCount = 0;
|
|
||||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
|
|
||||||
theBatch._glDrawBuffers(bufferCount, buffers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderItems(sceneContext, renderContext, sortedItems);
|
renderContext->_numDrawnTransparentItems = renderedItems.size();
|
||||||
|
|
||||||
addClearStateCommands((*args->_batch));
|
ItemIDs sortedItems;
|
||||||
args->_context->render((*args->_batch));
|
if (renderContext->_sortTransparent) {
|
||||||
args->_batch = nullptr;
|
depthSortItems(sceneContext, renderContext, false, renderedItems, sortedItems); // Sort Back to front transparent items!
|
||||||
|
renderedItems = sortedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderContext->_renderTransparent) {
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
gpu::Batch batch;
|
||||||
|
args->_batch = &batch;
|
||||||
|
|
||||||
|
glm::mat4 projMat;
|
||||||
|
Transform viewMat;
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewMat);
|
||||||
|
|
||||||
|
args->_renderMode = RenderArgs::NORMAL_RENDER_MODE;
|
||||||
|
|
||||||
|
const float MOSTLY_OPAQUE_THRESHOLD = 0.75f;
|
||||||
|
const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
|
||||||
|
|
||||||
|
// render translucent meshes afterwards
|
||||||
|
{
|
||||||
|
GLenum buffers[2];
|
||||||
|
int bufferCount = 0;
|
||||||
|
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
|
||||||
|
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
|
||||||
|
batch._glDrawBuffers(bufferCount, buffers);
|
||||||
|
args->_alphaThreshold = MOSTLY_OPAQUE_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderItems(sceneContext, renderContext, renderedItems);
|
||||||
|
|
||||||
|
{
|
||||||
|
GLenum buffers[3];
|
||||||
|
int bufferCount = 0;
|
||||||
|
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
|
||||||
|
batch._glDrawBuffers(bufferCount, buffers);
|
||||||
|
args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
renderItems(sceneContext, renderContext, renderedItems);
|
||||||
|
|
||||||
|
args->_context->render((*args->_batch));
|
||||||
|
args->_batch = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
PerformanceTimer perfTimer("DrawLight");
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
|
@ -306,3 +373,37 @@ template <> void render::jobRun(const DrawLight& job, const SceneContextPointer&
|
||||||
args->_context->render((*args->_batch));
|
args->_context->render((*args->_batch));
|
||||||
args->_batch = nullptr;
|
args->_batch = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> void render::jobRun(const DrawBackground& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
PerformanceTimer perfTimer("DrawBackground");
|
||||||
|
assert(renderContext->args);
|
||||||
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
|
// render backgrounds
|
||||||
|
auto& scene = sceneContext->_scene;
|
||||||
|
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::background());
|
||||||
|
|
||||||
|
|
||||||
|
ItemIDs inItems;
|
||||||
|
inItems.reserve(items.size());
|
||||||
|
for (auto id : items) {
|
||||||
|
inItems.push_back(id);
|
||||||
|
}
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
gpu::Batch batch;
|
||||||
|
args->_batch = &batch;
|
||||||
|
|
||||||
|
glm::mat4 projMat;
|
||||||
|
Transform viewMat;
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewMat);
|
||||||
|
|
||||||
|
renderItems(sceneContext, renderContext, inItems);
|
||||||
|
args->_context->render((*args->_batch));
|
||||||
|
args->_batch = nullptr;
|
||||||
|
|
||||||
|
// Force the context sync
|
||||||
|
args->_context->syncCache();
|
||||||
|
}
|
||||||
|
|
|
@ -78,6 +78,16 @@ public:
|
||||||
};
|
};
|
||||||
template <> void jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
template <> void jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||||
|
|
||||||
|
class DrawBackground {
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
template <> void jobRun(const DrawBackground& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||||
|
|
||||||
|
class ResetGLState {
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
template <> void jobRun(const ResetGLState& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||||
|
|
||||||
|
|
||||||
class DrawSceneTask : public Task {
|
class DrawSceneTask : public Task {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -30,6 +30,19 @@ class RenderContext {
|
||||||
public:
|
public:
|
||||||
RenderArgs* args;
|
RenderArgs* args;
|
||||||
|
|
||||||
|
bool _cullOpaque = true;
|
||||||
|
bool _sortOpaque = true;
|
||||||
|
bool _renderOpaque = true;
|
||||||
|
bool _cullTransparent = true;
|
||||||
|
bool _sortTransparent = true;
|
||||||
|
bool _renderTransparent = true;
|
||||||
|
|
||||||
|
int _numFeedOpaqueItems = 0;
|
||||||
|
int _numDrawnOpaqueItems = 0;
|
||||||
|
|
||||||
|
int _numFeedTransparentItems = 0;
|
||||||
|
int _numDrawnTransparentItems = 0;
|
||||||
|
|
||||||
RenderContext() {}
|
RenderContext() {}
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr<RenderContext> RenderContextPointer;
|
typedef std::shared_ptr<RenderContext> RenderContextPointer;
|
||||||
|
@ -60,6 +73,7 @@ public:
|
||||||
|
|
||||||
// Push a RenderContext
|
// Push a RenderContext
|
||||||
void setRenderContext(const RenderContext& renderContext);
|
void setRenderContext(const RenderContext& renderContext);
|
||||||
|
RenderContextPointer getRenderContext() const { return _renderContext; }
|
||||||
|
|
||||||
void addTask(const TaskPointer& task);
|
void addTask(const TaskPointer& task);
|
||||||
const Tasks& getTasks() const { return _tasks; }
|
const Tasks& getTasks() const { return _tasks; }
|
||||||
|
|
|
@ -47,8 +47,8 @@ void ItemBucketMap::reset(const ItemID& id, const ItemKey& oldKey, const ItemKey
|
||||||
void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() {
|
void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() {
|
||||||
(*this)[ItemFilter::Builder::opaqueShape()];
|
(*this)[ItemFilter::Builder::opaqueShape()];
|
||||||
(*this)[ItemFilter::Builder::transparentShape()];
|
(*this)[ItemFilter::Builder::transparentShape()];
|
||||||
auto lightFilter = ItemFilter::Builder().withTypeLight().build();
|
(*this)[ItemFilter::Builder::light()];
|
||||||
(*this)[lightFilter];
|
(*this)[ItemFilter::Builder::background()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
enum FlagBit {
|
enum FlagBit {
|
||||||
TYPE_SHAPE = 0, // Item is a Shape
|
TYPE_SHAPE = 0, // Item is a Shape
|
||||||
TYPE_LIGHT, // Item is a Light
|
TYPE_LIGHT, // Item is a Light
|
||||||
|
TYPE_BACKGROUND, // Item is a Background
|
||||||
TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work...
|
TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work...
|
||||||
VIEW_SPACE, // Transformed in view space, and not in world space
|
VIEW_SPACE, // Transformed in view space, and not in world space
|
||||||
DYNAMIC, // Dynamic and bound will change unlike static item
|
DYNAMIC, // Dynamic and bound will change unlike static item
|
||||||
|
@ -62,6 +63,7 @@ public:
|
||||||
|
|
||||||
Builder& withTypeShape() { _flags.set(TYPE_SHAPE); return (*this); }
|
Builder& withTypeShape() { _flags.set(TYPE_SHAPE); return (*this); }
|
||||||
Builder& withTypeLight() { _flags.set(TYPE_LIGHT); return (*this); }
|
Builder& withTypeLight() { _flags.set(TYPE_LIGHT); return (*this); }
|
||||||
|
Builder& withTypeBackground() { _flags.set(TYPE_BACKGROUND); return (*this); }
|
||||||
Builder& withTransparent() { _flags.set(TRANSLUCENT); return (*this); }
|
Builder& withTransparent() { _flags.set(TRANSLUCENT); return (*this); }
|
||||||
Builder& withViewSpace() { _flags.set(VIEW_SPACE); return (*this); }
|
Builder& withViewSpace() { _flags.set(VIEW_SPACE); return (*this); }
|
||||||
Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); }
|
Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); }
|
||||||
|
@ -75,6 +77,7 @@ public:
|
||||||
static ItemKey opaqueShape() { return Builder().withTypeShape().build(); }
|
static ItemKey opaqueShape() { return Builder().withTypeShape().build(); }
|
||||||
static ItemKey transparentShape() { return Builder().withTypeShape().withTransparent().build(); }
|
static ItemKey transparentShape() { return Builder().withTypeShape().withTransparent().build(); }
|
||||||
static ItemKey light() { return Builder().withTypeLight().build(); }
|
static ItemKey light() { return Builder().withTypeLight().build(); }
|
||||||
|
static ItemKey background() { return Builder().withTypeBackground().build(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isOpaque() const { return !_flags[TRANSLUCENT]; }
|
bool isOpaque() const { return !_flags[TRANSLUCENT]; }
|
||||||
|
@ -126,6 +129,7 @@ public:
|
||||||
|
|
||||||
Builder& withTypeShape() { _value.set(ItemKey::TYPE_SHAPE); _mask.set(ItemKey::TYPE_SHAPE); return (*this); }
|
Builder& withTypeShape() { _value.set(ItemKey::TYPE_SHAPE); _mask.set(ItemKey::TYPE_SHAPE); return (*this); }
|
||||||
Builder& withTypeLight() { _value.set(ItemKey::TYPE_LIGHT); _mask.set(ItemKey::TYPE_LIGHT); return (*this); }
|
Builder& withTypeLight() { _value.set(ItemKey::TYPE_LIGHT); _mask.set(ItemKey::TYPE_LIGHT); return (*this); }
|
||||||
|
Builder& withTypeBackground() { _value.set(ItemKey::TYPE_BACKGROUND); _mask.set(ItemKey::TYPE_BACKGROUND); return (*this); }
|
||||||
|
|
||||||
Builder& withOpaque() { _value.reset(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); }
|
Builder& withOpaque() { _value.reset(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); }
|
||||||
Builder& withTransparent() { _value.set(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); }
|
Builder& withTransparent() { _value.set(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); }
|
||||||
|
@ -154,6 +158,7 @@ public:
|
||||||
static ItemFilter opaqueShape() { return Builder().withTypeShape().withOpaque().withWorldSpace().build(); }
|
static ItemFilter opaqueShape() { return Builder().withTypeShape().withOpaque().withWorldSpace().build(); }
|
||||||
static ItemFilter transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace().build(); }
|
static ItemFilter transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace().build(); }
|
||||||
static ItemFilter light() { return Builder().withTypeLight().build(); }
|
static ItemFilter light() { return Builder().withTypeLight().build(); }
|
||||||
|
static ItemFilter background() { return Builder().withTypeBackground().build(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Item Filter operator testing if a key pass the filter
|
// Item Filter operator testing if a key pass the filter
|
||||||
|
|
|
@ -128,4 +128,35 @@ void SceneScriptingInterface::setShouldRenderEntities(bool shouldRenderEntities)
|
||||||
_shouldRenderEntities = shouldRenderEntities;
|
_shouldRenderEntities = shouldRenderEntities;
|
||||||
emit shouldRenderEntitiesChanged(_shouldRenderEntities);
|
emit shouldRenderEntitiesChanged(_shouldRenderEntities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneScriptingInterface::setEngineRenderOpaque(bool renderOpaque) {
|
||||||
|
_engineRenderOpaque = renderOpaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneScriptingInterface::setEngineRenderTransparent(bool renderTransparent) {
|
||||||
|
_engineRenderTransparent = renderTransparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneScriptingInterface::setEngineCullOpaque(bool cullOpaque) {
|
||||||
|
_engineCullOpaque = cullOpaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneScriptingInterface::setEngineCullTransparent(bool cullTransparent) {
|
||||||
|
_engineCullTransparent = cullTransparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneScriptingInterface::setEngineSortOpaque(bool sortOpaque) {
|
||||||
|
_engineSortOpaque = sortOpaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneScriptingInterface::setEngineSortTransparent(bool sortTransparent) {
|
||||||
|
_engineSortOpaque = sortTransparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneScriptingInterface::clearEngineCounters() {
|
||||||
|
_numFeedOpaqueItems = 0;
|
||||||
|
_numDrawnOpaqueItems = 0;
|
||||||
|
_numFeedTransparentItems = 0;
|
||||||
|
_numDrawnTransparentItems = 0;
|
||||||
|
}
|
||||||
|
|
|
@ -67,7 +67,36 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void setShouldRenderEntities(bool shouldRenderEntities);
|
Q_INVOKABLE void setShouldRenderEntities(bool shouldRenderEntities);
|
||||||
Q_INVOKABLE bool shouldRenderEntities() const { return _shouldRenderEntities; }
|
Q_INVOKABLE bool shouldRenderEntities() const { return _shouldRenderEntities; }
|
||||||
|
|
||||||
|
|
||||||
|
// Controlling the rendering engine
|
||||||
|
Q_INVOKABLE void setEngineRenderOpaque(bool renderOpaque);
|
||||||
|
Q_INVOKABLE bool doEngineRenderOpaque() const { return _engineRenderOpaque; }
|
||||||
|
Q_INVOKABLE void setEngineRenderTransparent(bool renderTransparent);
|
||||||
|
Q_INVOKABLE bool doEngineRenderTransparent() const { return _engineRenderTransparent; }
|
||||||
|
|
||||||
|
Q_INVOKABLE void setEngineCullOpaque(bool cullOpaque);
|
||||||
|
Q_INVOKABLE bool doEngineCullOpaque() const { return _engineCullOpaque; }
|
||||||
|
Q_INVOKABLE void setEngineCullTransparent(bool cullTransparent);
|
||||||
|
Q_INVOKABLE bool doEngineCullTransparent() const { return _engineCullTransparent; }
|
||||||
|
|
||||||
|
Q_INVOKABLE void setEngineSortOpaque(bool sortOpaque);
|
||||||
|
Q_INVOKABLE bool doEngineSortOpaque() const { return _engineSortOpaque; }
|
||||||
|
Q_INVOKABLE void setEngineSortTransparent(bool sortTransparent);
|
||||||
|
Q_INVOKABLE bool doEngineSortTransparent() const { return _engineSortTransparent; }
|
||||||
|
|
||||||
|
void clearEngineCounters();
|
||||||
|
void setEngineDrawnOpaqueItems(int count) { _numDrawnOpaqueItems = count; }
|
||||||
|
Q_INVOKABLE int getEngineNumDrawnOpaqueItems() { return _numDrawnOpaqueItems; }
|
||||||
|
void setEngineDrawnTransparentItems(int count) { _numDrawnTransparentItems = count; }
|
||||||
|
Q_INVOKABLE int getEngineNumDrawnTransparentItems() { return _numDrawnTransparentItems; }
|
||||||
|
|
||||||
|
void setEngineFeedOpaqueItems(int count) { _numFeedOpaqueItems = count; }
|
||||||
|
Q_INVOKABLE int getEngineNumFeedOpaqueItems() { return _numFeedOpaqueItems; }
|
||||||
|
void setEngineFeedTransparentItems(int count) { _numFeedTransparentItems = count; }
|
||||||
|
Q_INVOKABLE int getEngineNumFeedTransparentItems() { return _numFeedTransparentItems; }
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void shouldRenderAvatarsChanged(bool shouldRenderAvatars);
|
void shouldRenderAvatarsChanged(bool shouldRenderAvatars);
|
||||||
void shouldRenderEntitiesChanged(bool shouldRenderEntities);
|
void shouldRenderEntitiesChanged(bool shouldRenderEntities);
|
||||||
|
@ -79,6 +108,18 @@ protected:
|
||||||
|
|
||||||
bool _shouldRenderAvatars = true;
|
bool _shouldRenderAvatars = true;
|
||||||
bool _shouldRenderEntities = true;
|
bool _shouldRenderEntities = true;
|
||||||
|
|
||||||
|
bool _engineRenderOpaque = true;
|
||||||
|
bool _engineRenderTransparent = true;
|
||||||
|
bool _engineCullOpaque = true;
|
||||||
|
bool _engineCullTransparent = true;
|
||||||
|
bool _engineSortOpaque = true;
|
||||||
|
bool _engineSortTransparent = true;
|
||||||
|
|
||||||
|
int _numFeedOpaqueItems = 0;
|
||||||
|
int _numDrawnOpaqueItems = 0;
|
||||||
|
int _numFeedTransparentItems = 0;
|
||||||
|
int _numDrawnTransparentItems = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_SceneScriptingInterface_h
|
#endif // hifi_SceneScriptingInterface_h
|
||||||
|
|
|
@ -119,6 +119,8 @@ public:
|
||||||
|
|
||||||
int _translucentMeshPartsRendered;
|
int _translucentMeshPartsRendered;
|
||||||
int _opaqueMeshPartsRendered;
|
int _opaqueMeshPartsRendered;
|
||||||
|
|
||||||
|
float _alphaThreshold = 0.5f;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_RenderArgs_h
|
#endif // hifi_RenderArgs_h
|
||||||
|
|
Loading…
Reference in a new issue