mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 00:04:43 +02:00
Merging with master
This commit is contained in:
commit
38e9d2281d
43 changed files with 761 additions and 675 deletions
|
@ -11,6 +11,7 @@
|
|||
Script.load("away.js");
|
||||
Script.load("progress.js");
|
||||
Script.load("edit.js");
|
||||
Script.load("marketplace.js");
|
||||
Script.load("selectAudioDevice.js");
|
||||
Script.load("inspect.js");
|
||||
Script.load("notifications.js");
|
||||
|
|
|
@ -9,89 +9,118 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
Script.include("libraries/globals.js");
|
||||
Script.include([
|
||||
"libraries/toolBars.js",
|
||||
]);
|
||||
|
||||
var directory = (function () {
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/";
|
||||
|
||||
var DIRECTORY_URL = "https://metaverse.highfidelity.com/directory",
|
||||
directoryWindow,
|
||||
DIRECTORY_BUTTON_URL = HIFI_PUBLIC_BUCKET + "images/tools/directory.svg",
|
||||
BUTTON_WIDTH = 50,
|
||||
BUTTON_HEIGHT = 50,
|
||||
BUTTON_ALPHA = 0.9,
|
||||
BUTTON_MARGIN = 8,
|
||||
directoryButton,
|
||||
EDIT_TOOLBAR_BUTTONS = 10, // Number of buttons in edit.js toolbar
|
||||
viewport;
|
||||
var DIRECTORY_WINDOW_URL = "https://metaverse.highfidelity.com/directory";
|
||||
var directoryWindow = new OverlayWebWindow({
|
||||
title: 'directory',
|
||||
source: "about:blank",
|
||||
width: 900,
|
||||
height: 700,
|
||||
visible: false
|
||||
});
|
||||
|
||||
function updateButtonPosition() {
|
||||
Overlays.editOverlay(directoryButton, {
|
||||
x: viewport.x - BUTTON_WIDTH - BUTTON_MARGIN,
|
||||
y: (viewport.y - (EDIT_TOOLBAR_BUTTONS + 1) * (BUTTON_HEIGHT + BUTTON_MARGIN) - BUTTON_MARGIN) / 2 - 1
|
||||
var toolHeight = 50;
|
||||
var toolWidth = 50;
|
||||
|
||||
|
||||
function showDirectory() {
|
||||
directoryWindow.setURL(DIRECTORY_WINDOW_URL);
|
||||
directoryWindow.setVisible(true);
|
||||
}
|
||||
|
||||
function hideDirectory() {
|
||||
directoryWindow.setVisible(false);
|
||||
directoryWindow.setURL("about:blank");
|
||||
}
|
||||
|
||||
function toggleDirectory() {
|
||||
if (directoryWindow.visible) {
|
||||
hideDirectory();
|
||||
} else {
|
||||
showDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
var toolBar = (function() {
|
||||
var that = {},
|
||||
toolBar,
|
||||
browseDirectoryButton;
|
||||
|
||||
function initialize() {
|
||||
ToolBar.SPACING = 16;
|
||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.directory.toolbar", function(windowDimensions, toolbar) {
|
||||
return {
|
||||
x: windowDimensions.x - 8 - toolbar.width,
|
||||
y: 50
|
||||
};
|
||||
});
|
||||
browseDirectoryButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "directory.svg",
|
||||
width: toolWidth,
|
||||
height: toolHeight,
|
||||
alpha: 0.9,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
toolBar.showTool(browseDirectoryButton, true);
|
||||
}
|
||||
|
||||
function onMousePressEvent(event) {
|
||||
var clickedOverlay;
|
||||
var browseDirectoryButtonDown = false;
|
||||
that.mousePressEvent = function(event) {
|
||||
var clickedOverlay,
|
||||
url,
|
||||
file;
|
||||
|
||||
clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y });
|
||||
|
||||
if (clickedOverlay === directoryButton) {
|
||||
if (directoryWindow.url !== DIRECTORY_URL) {
|
||||
directoryWindow.setURL(DIRECTORY_URL);
|
||||
}
|
||||
directoryWindow.setVisible(true);
|
||||
directoryWindow.raise();
|
||||
if (!event.isLeftButton) {
|
||||
// if another mouse button than left is pressed ignore it
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function onDomainChanged() {
|
||||
directoryWindow.setVisible(false);
|
||||
}
|
||||
clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
|
||||
function onScriptUpdate() {
|
||||
var oldViewport = viewport;
|
||||
|
||||
viewport = Controller.getViewportDimensions();
|
||||
|
||||
if (viewport.x !== oldViewport.x || viewport.y !== oldViewport.y) {
|
||||
updateButtonPosition();
|
||||
if (browseDirectoryButton === toolBar.clicked(clickedOverlay)) {
|
||||
toggleDirectory();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
that.mouseReleaseEvent = function(event) {
|
||||
var handled = false;
|
||||
|
||||
|
||||
if (browseDirectoryButtonDown) {
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
}
|
||||
|
||||
newModelButtonDown = false;
|
||||
browseDirectoryButtonDown = false;
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
viewport = Controller.getViewportDimensions();
|
||||
that.cleanup = function() {
|
||||
toolBar.cleanup();
|
||||
};
|
||||
|
||||
directoryWindow = new OverlayWebWindow({
|
||||
title: 'Directory',
|
||||
source: DIRECTORY_URL,
|
||||
width: 900,
|
||||
height: 700,
|
||||
visible: false
|
||||
});
|
||||
initialize();
|
||||
return that;
|
||||
}());
|
||||
|
||||
directoryButton = Overlays.addOverlay("image", {
|
||||
imageURL: DIRECTORY_BUTTON_URL,
|
||||
width: BUTTON_WIDTH,
|
||||
height: BUTTON_HEIGHT,
|
||||
x: viewport.x - BUTTON_WIDTH - BUTTON_MARGIN,
|
||||
y: BUTTON_MARGIN,
|
||||
alpha: BUTTON_ALPHA,
|
||||
visible: true
|
||||
});
|
||||
|
||||
updateButtonPosition();
|
||||
|
||||
Controller.mousePressEvent.connect(onMousePressEvent);
|
||||
Window.domainChanged.connect(onDomainChanged);
|
||||
|
||||
Script.update.connect(onScriptUpdate);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
Overlays.deleteOverlay(directoryButton);
|
||||
}
|
||||
|
||||
setUp();
|
||||
Script.scriptEnding.connect(tearDown);
|
||||
}());
|
||||
Controller.mousePressEvent.connect(toolBar.mousePressEvent)
|
||||
Script.scriptEnding.connect(toolBar.cleanup);
|
||||
|
|
|
@ -183,8 +183,7 @@ var toolBar = (function() {
|
|||
newTextButton,
|
||||
newWebButton,
|
||||
newZoneButton,
|
||||
newPolyVoxButton,
|
||||
browseMarketplaceButton;
|
||||
newPolyVoxButton;
|
||||
|
||||
function initialize() {
|
||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.edit.toolbar", function(windowDimensions, toolbar) {
|
||||
|
@ -194,13 +193,7 @@ var toolBar = (function() {
|
|||
};
|
||||
});
|
||||
|
||||
browseMarketplaceButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "marketplace.svg",
|
||||
width: toolWidth,
|
||||
height: toolHeight,
|
||||
alpha: 0.9,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
|
||||
activeButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "edit-status.svg",
|
||||
|
@ -415,7 +408,6 @@ var toolBar = (function() {
|
|||
}
|
||||
|
||||
var newModelButtonDown = false;
|
||||
var browseMarketplaceButtonDown = false;
|
||||
that.mousePressEvent = function(event) {
|
||||
var clickedOverlay,
|
||||
url,
|
||||
|
@ -443,11 +435,7 @@ var toolBar = (function() {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) {
|
||||
toggleMarketplace();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (newCubeButton === toolBar.clicked(clickedOverlay)) {
|
||||
createNewEntity({
|
||||
type: "Box",
|
||||
|
@ -652,22 +640,10 @@ var toolBar = (function() {
|
|||
}
|
||||
handled = true;
|
||||
}
|
||||
} else if (browseMarketplaceButtonDown) {
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) {
|
||||
url = Window.s3Browse(".*(fbx|FBX|obj|OBJ)");
|
||||
if (url !== null && url !== "") {
|
||||
addModel(url);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
newModelButtonDown = false;
|
||||
browseMarketplaceButtonDown = false;
|
||||
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
|
131
examples/marketplace.js
Normal file
131
examples/marketplace.js
Normal file
|
@ -0,0 +1,131 @@
|
|||
//
|
||||
// marketplace.js
|
||||
// examples
|
||||
//
|
||||
// Created by Eric Levin on 8 Jan 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
|
||||
//
|
||||
|
||||
Script.include([
|
||||
"libraries/toolBars.js",
|
||||
]);
|
||||
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/";
|
||||
|
||||
var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace";
|
||||
var marketplaceWindow = new OverlayWebWindow({
|
||||
title: 'Marketplace',
|
||||
source: "about:blank",
|
||||
width: 900,
|
||||
height: 700,
|
||||
visible: false
|
||||
});
|
||||
|
||||
var toolHeight = 50;
|
||||
var toolWidth = 50;
|
||||
|
||||
|
||||
function showMarketplace(marketplaceID) {
|
||||
var url = MARKETPLACE_URL;
|
||||
if (marketplaceID) {
|
||||
url = url + "/items/" + marketplaceID;
|
||||
}
|
||||
print("setting marketplace URL to " + url);
|
||||
marketplaceWindow.setURL(url);
|
||||
marketplaceWindow.setVisible(true);
|
||||
}
|
||||
|
||||
function hideMarketplace() {
|
||||
marketplaceWindow.setVisible(false);
|
||||
marketplaceWindow.setURL("about:blank");
|
||||
}
|
||||
|
||||
function toggleMarketplace() {
|
||||
if (marketplaceWindow.visible) {
|
||||
hideMarketplace();
|
||||
} else {
|
||||
showMarketplace();
|
||||
}
|
||||
}
|
||||
|
||||
var toolBar = (function() {
|
||||
var that = {},
|
||||
toolBar,
|
||||
browseMarketplaceButton;
|
||||
|
||||
function initialize() {
|
||||
ToolBar.SPACING = 16;
|
||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.marketplace.toolbar", function(windowDimensions, toolbar) {
|
||||
return {
|
||||
x: windowDimensions.x - 8 - toolbar.width,
|
||||
y: 135
|
||||
};
|
||||
});
|
||||
browseMarketplaceButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "marketplace.svg",
|
||||
width: toolWidth,
|
||||
height: toolHeight,
|
||||
alpha: 0.9,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
toolBar.showTool(browseMarketplaceButton, true);
|
||||
}
|
||||
|
||||
var browseMarketplaceButtonDown = false;
|
||||
that.mousePressEvent = function(event) {
|
||||
var clickedOverlay,
|
||||
url,
|
||||
file;
|
||||
|
||||
if (!event.isLeftButton) {
|
||||
// if another mouse button than left is pressed ignore it
|
||||
return false;
|
||||
}
|
||||
|
||||
clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) {
|
||||
toggleMarketplace();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
that.mouseReleaseEvent = function(event) {
|
||||
var handled = false;
|
||||
|
||||
|
||||
if (browseMarketplaceButtonDown) {
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
}
|
||||
|
||||
newModelButtonDown = false;
|
||||
browseMarketplaceButtonDown = false;
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
that.cleanup = function() {
|
||||
toolBar.cleanup();
|
||||
};
|
||||
|
||||
initialize();
|
||||
return that;
|
||||
}());
|
||||
|
||||
Controller.mousePressEvent.connect(toolBar.mousePressEvent)
|
||||
Script.scriptEnding.connect(toolBar.cleanup);
|
|
@ -1,4 +1,4 @@
|
|||
<!-- Copyright 2015 High Fidelity, Inc. -->
|
||||
<!-- Copyright 2015 High Fidelity, Inc. -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
body {
|
||||
background: white;
|
||||
width: 839px;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@
|
|||
function overrideBodyWidth() {
|
||||
document.body.style.width = "100%";
|
||||
<!-- Force reset layout after body resized-->
|
||||
container.style.width = "0";
|
||||
<!-- container.style.width = "0"; -->
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
|
|
|
@ -51,6 +51,16 @@ Hifi.VrMenu {
|
|||
VrMenuView {
|
||||
property int menuDepth: root.models.length - 1
|
||||
model: root.models[menuDepth]
|
||||
|
||||
function fit(position, size, maxposition) {
|
||||
var padding = 8;
|
||||
if (position < padding) {
|
||||
position = padding;
|
||||
} else if (position + size + padding > maxposition) {
|
||||
position = maxposition - (size + padding);
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (menuDepth === 0) {
|
||||
|
@ -61,6 +71,8 @@ Hifi.VrMenu {
|
|||
x = lastColumn.x + 64;
|
||||
y = lastMousePosition.y - height / 2;
|
||||
}
|
||||
x = fit(x, width, parent.width);
|
||||
y = fit(y, height, parent.height);
|
||||
}
|
||||
|
||||
onSelected: {
|
||||
|
|
|
@ -5062,8 +5062,23 @@ const DisplayPlugin* Application::getActiveDisplayPlugin() const {
|
|||
static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) {
|
||||
auto menu = Menu::getInstance();
|
||||
QString name = displayPlugin->getName();
|
||||
auto grouping = displayPlugin->getGrouping();
|
||||
QString groupingMenu { "" };
|
||||
Q_ASSERT(!menu->menuItemExists(MenuOption::OutputMenu, name));
|
||||
|
||||
// assign the meny grouping based on plugin grouping
|
||||
switch (grouping) {
|
||||
case Plugin::ADVANCED:
|
||||
groupingMenu = "Advanced";
|
||||
break;
|
||||
case Plugin::DEVELOPER:
|
||||
groupingMenu = "Developer";
|
||||
break;
|
||||
default:
|
||||
groupingMenu = "Standard";
|
||||
break;
|
||||
}
|
||||
|
||||
static QActionGroup* displayPluginGroup = nullptr;
|
||||
if (!displayPluginGroup) {
|
||||
displayPluginGroup = new QActionGroup(menu);
|
||||
|
@ -5072,7 +5087,9 @@ static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool acti
|
|||
auto parent = menu->getMenu(MenuOption::OutputMenu);
|
||||
auto action = menu->addActionToQMenuAndActionHash(parent,
|
||||
name, 0, qApp,
|
||||
SLOT(updateDisplayMode()));
|
||||
SLOT(updateDisplayMode()),
|
||||
QAction::NoRole, UNSPECIFIED_POSITION, groupingMenu);
|
||||
|
||||
action->setCheckable(true);
|
||||
action->setChecked(active);
|
||||
displayPluginGroup->addAction(action);
|
||||
|
@ -5086,7 +5103,31 @@ void Application::updateDisplayMode() {
|
|||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
bool first = true;
|
||||
|
||||
// first sort the plugins into groupings: standard, advanced, developer
|
||||
DisplayPluginList standard;
|
||||
DisplayPluginList advanced;
|
||||
DisplayPluginList developer;
|
||||
foreach(auto displayPlugin, displayPlugins) {
|
||||
auto grouping = displayPlugin->getGrouping();
|
||||
switch (grouping) {
|
||||
case Plugin::ADVANCED:
|
||||
advanced.push_back(displayPlugin);
|
||||
break;
|
||||
case Plugin::DEVELOPER:
|
||||
developer.push_back(displayPlugin);
|
||||
break;
|
||||
default:
|
||||
standard.push_back(displayPlugin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// concactonate the groupings into a single list in the order: standard, advanced, developer
|
||||
standard.insert(std::end(standard), std::begin(advanced), std::end(advanced));
|
||||
standard.insert(std::end(standard), std::begin(developer), std::end(developer));
|
||||
|
||||
foreach(auto displayPlugin, standard) {
|
||||
addDisplayPluginToMenu(displayPlugin, first);
|
||||
// This must be a queued connection to avoid a deadlock
|
||||
QObject::connect(displayPlugin.get(), &DisplayPlugin::requestRender,
|
||||
|
@ -5098,6 +5139,11 @@ void Application::updateDisplayMode() {
|
|||
|
||||
first = false;
|
||||
}
|
||||
|
||||
// after all plugins have been added to the menu, add a seperator to the menu
|
||||
auto menu = Menu::getInstance();
|
||||
auto parent = menu->getMenu(MenuOption::OutputMenu);
|
||||
parent->addSeparator();
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ namespace MenuOption {
|
|||
const QString OctreeStats = "Entity Statistics";
|
||||
const QString OnePointCalibration = "1 Point Calibration";
|
||||
const QString OnlyDisplayTopTen = "Only Display Top Ten";
|
||||
const QString OutputMenu = "Display>Mode";
|
||||
const QString OutputMenu = "Display";
|
||||
const QString PackageModel = "Package Model...";
|
||||
const QString Pair = "Pair";
|
||||
const QString PhysicsShowOwned = "Highlight Simulation Ownership";
|
||||
|
|
|
@ -15,14 +15,10 @@
|
|||
|
||||
#include <plugins/PluginContainer.h>
|
||||
|
||||
const QString Basic2DWindowOpenGLDisplayPlugin::NAME("2D Display");
|
||||
const QString Basic2DWindowOpenGLDisplayPlugin::NAME("Desktop");
|
||||
|
||||
static const QString FULLSCREEN = "Fullscreen";
|
||||
|
||||
const QString& Basic2DWindowOpenGLDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
void Basic2DWindowOpenGLDisplayPlugin::activate() {
|
||||
WindowOpenGLDisplayPlugin::activate();
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class Basic2DWindowOpenGLDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual const QString & getName() const override;
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
|
||||
virtual float getTargetFrameRate() override { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; }
|
||||
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
|
||||
const QString NullDisplayPlugin::NAME("NullDisplayPlugin");
|
||||
|
||||
const QString & NullDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
glm::uvec2 NullDisplayPlugin::getRecommendedRenderSize() const {
|
||||
return glm::uvec2(100, 100);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@ class NullDisplayPlugin : public DisplayPlugin {
|
|||
public:
|
||||
|
||||
virtual ~NullDisplayPlugin() final {}
|
||||
virtual const QString & getName() const override;
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual grouping getGrouping() const override { return DEVELOPER; }
|
||||
|
||||
void stop() override;
|
||||
|
||||
|
|
|
@ -44,11 +44,7 @@ void main() {
|
|||
|
||||
)FS";
|
||||
|
||||
const QString InterleavedStereoDisplayPlugin::NAME("Interleaved Stereo Display");
|
||||
|
||||
const QString & InterleavedStereoDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
const QString InterleavedStereoDisplayPlugin::NAME("3D TV - Interleaved");
|
||||
|
||||
InterleavedStereoDisplayPlugin::InterleavedStereoDisplayPlugin() {
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ class InterleavedStereoDisplayPlugin : public StereoDisplayPlugin {
|
|||
Q_OBJECT
|
||||
public:
|
||||
InterleavedStereoDisplayPlugin();
|
||||
virtual const QString & getName() const override;
|
||||
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual grouping getGrouping() const override { return ADVANCED; }
|
||||
|
||||
// initialize OpenGL context settings needed by the plugin
|
||||
virtual void customizeContext() override;
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
|
||||
const QString SideBySideStereoDisplayPlugin::NAME("3D TV - Side by Side Stereo");
|
||||
|
||||
const QString & SideBySideStereoDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
SideBySideStereoDisplayPlugin::SideBySideStereoDisplayPlugin() {
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@ class SideBySideStereoDisplayPlugin : public StereoDisplayPlugin {
|
|||
Q_OBJECT
|
||||
public:
|
||||
SideBySideStereoDisplayPlugin();
|
||||
virtual const QString& getName() const override;
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual grouping getGrouping() const override { return ADVANCED; }
|
||||
virtual glm::uvec2 getRecommendedRenderSize() const override;
|
||||
private:
|
||||
static const QString NAME;
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
// Plugin functions
|
||||
virtual bool isSupported() const override { return true; }
|
||||
virtual bool isJointController() const override { return false; }
|
||||
const QString& getName() const override { return NAME; }
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
|
||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override;
|
||||
|
|
|
@ -19,6 +19,11 @@ public:
|
|||
/// \return human-readable name
|
||||
virtual const QString& getName() const = 0;
|
||||
|
||||
typedef enum { STANDARD, ADVANCED, DEVELOPER } grouping;
|
||||
|
||||
/// \return human-readable grouping for the plugin, STANDARD, ADVANCED, or DEVELOPER
|
||||
virtual grouping getGrouping() const { return STANDARD; }
|
||||
|
||||
/// \return string ID (not necessarily human-readable)
|
||||
virtual const QString& getID() const { assert(false); return UNKNOWN_PLUGIN_ID; }
|
||||
|
||||
|
|
|
@ -22,15 +22,16 @@ public:
|
|||
AmbientOcclusionEffect();
|
||||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
typedef render::Job::Model<AmbientOcclusionEffect> JobModel;
|
||||
|
||||
|
||||
void setRadius(float radius);
|
||||
float getRadius() const { return _parametersBuffer.get<Parameters>()._radiusInfo.x; }
|
||||
|
||||
// Obscurance level which intensify or dim down the obscurance effect
|
||||
void setLevel(float level);
|
||||
float getLevel() const { return _parametersBuffer.get<Parameters>()._radiusInfo.w; }
|
||||
|
||||
|
||||
using JobModel = render::Task::Job::Model<AmbientOcclusionEffect>;
|
||||
|
||||
private:
|
||||
|
||||
void setDepthInfo(float nearZ, float farZ);
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
Antialiasing();
|
||||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
typedef render::Job::Model<Antialiasing> JobModel;
|
||||
using JobModel = render::Task::Job::Model<Antialiasing>;
|
||||
|
||||
const gpu::PipelinePointer& getAntialiasingPipeline();
|
||||
const gpu::PipelinePointer& getBlendPipeline();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
class DebugDeferredBuffer {
|
||||
public:
|
||||
using JobModel = render::Job::Model<DebugDeferredBuffer>;
|
||||
using JobModel = render::Task::Job::Model<DebugDeferredBuffer>;
|
||||
|
||||
DebugDeferredBuffer();
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ public:
|
|||
HitEffect();
|
||||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
typedef render::Job::Model<HitEffect> JobModel;
|
||||
using JobModel = render::Task::Job::Model<HitEffect>;
|
||||
|
||||
const gpu::PipelinePointer& getHitEffectPipeline();
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "HitEffect.h"
|
||||
#include "TextureCache.h"
|
||||
|
||||
#include "render/DrawTask.h"
|
||||
#include "render/DrawStatus.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
#include "AntialiasingEffect.h"
|
||||
|
@ -51,63 +52,61 @@ void ToneMappingDeferred::run(const SceneContextPointer& sceneContext, const Ren
|
|||
|
||||
RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||
// CPU only, create the list of renderedOpaques items
|
||||
_jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque",
|
||||
FetchItems([](const RenderContextPointer& context, int count) {
|
||||
context->getItemsConfig().opaque.numFeed = count;
|
||||
})
|
||||
)));
|
||||
_jobs.push_back(Job(new CullItemsOpaque::JobModel("CullOpaque", _jobs.back().getOutput())));
|
||||
_jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortOpaque", _jobs.back().getOutput())));
|
||||
addJob<FetchItems>("FetchOpaque", FetchItems([](const RenderContextPointer& context, int count) {
|
||||
context->getItemsConfig().opaque.numFeed = count;
|
||||
}));
|
||||
addJob<CullItemsOpaque>("CullOpaque", _jobs.back().getOutput());
|
||||
addJob<DepthSortItems>("DepthSortOpaque", _jobs.back().getOutput());
|
||||
auto& renderedOpaques = _jobs.back().getOutput();
|
||||
|
||||
// CPU only, create the list of renderedTransparents items
|
||||
_jobs.push_back(Job(new FetchItems::JobModel("FetchTransparent",
|
||||
FetchItems(ItemFilter::Builder::transparentShape().withoutLayered(),
|
||||
[](const RenderContextPointer& context, int count) {
|
||||
context->getItemsConfig().transparent.numFeed = count;
|
||||
})
|
||||
)));
|
||||
_jobs.push_back(Job(new CullItemsTransparent::JobModel("CullTransparent", _jobs.back().getOutput())));
|
||||
_jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortTransparent", _jobs.back().getOutput(), DepthSortItems(false))));
|
||||
addJob<FetchItems>("FetchTransparent", FetchItems(
|
||||
ItemFilter::Builder::transparentShape().withoutLayered(),
|
||||
[](const RenderContextPointer& context, int count) {
|
||||
context->getItemsConfig().transparent.numFeed = count;
|
||||
}
|
||||
));
|
||||
addJob<CullItemsTransparent>("CullTransparent", _jobs.back().getOutput());
|
||||
addJob<DepthSortItems>("DepthSortTransparent", _jobs.back().getOutput(), DepthSortItems(false));
|
||||
auto& renderedTransparents = _jobs.back().getOutput();
|
||||
|
||||
// GPU Jobs: Start preparing the deferred and lighting buffer
|
||||
_jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred")));
|
||||
addJob<PrepareDeferred>("PrepareDeferred");
|
||||
|
||||
// Render opaque objects in DeferredBuffer
|
||||
_jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", renderedOpaques)));
|
||||
addJob<DrawOpaqueDeferred>("DrawOpaqueDeferred", renderedOpaques);
|
||||
|
||||
// Once opaque is all rendered create stencil background
|
||||
_jobs.push_back(Job(new DrawStencilDeferred::JobModel("DrawOpaqueStencil")));
|
||||
addJob<DrawStencilDeferred>("DrawOpaqueStencil");
|
||||
|
||||
// Use Stencil and start drawing background in Lighting buffer
|
||||
_jobs.push_back(Job(new DrawBackgroundDeferred::JobModel("DrawBackgroundDeferred")));
|
||||
addJob<DrawBackgroundDeferred>("DrawBackgroundDeferred");
|
||||
|
||||
// AO job, to be revisited
|
||||
_jobs.push_back(Job(new AmbientOcclusionEffect::JobModel("AmbientOcclusion")));
|
||||
// AO job
|
||||
addJob<AmbientOcclusionEffect>("AmbientOcclusion");
|
||||
_jobs.back().setEnabled(false);
|
||||
_occlusionJobIndex = (int)_jobs.size() - 1;
|
||||
|
||||
// Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now.
|
||||
_jobs.push_back(Job(new DrawLight::JobModel("DrawLight")));
|
||||
addJob<DrawLight>("DrawLight");
|
||||
|
||||
// DeferredBuffer is complete, now let's shade it into the LightingBuffer
|
||||
_jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred")));
|
||||
addJob<RenderDeferred>("RenderDeferred");
|
||||
|
||||
// AA job to be revisited
|
||||
_jobs.push_back(Job(new Antialiasing::JobModel("Antialiasing")));
|
||||
addJob<Antialiasing>("Antialiasing");
|
||||
_jobs.back().setEnabled(false);
|
||||
_antialiasingJobIndex = (int)_jobs.size() - 1;
|
||||
|
||||
// Render transparent objects forward in LigthingBuffer
|
||||
_jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", renderedTransparents)));
|
||||
addJob<DrawTransparentDeferred>("TransparentDeferred", renderedTransparents);
|
||||
|
||||
// Lighting Buffer ready for tone mapping
|
||||
_jobs.push_back(Job(new ToneMappingDeferred::JobModel("ToneMapping")));
|
||||
addJob<ToneMappingDeferred>("ToneMapping");
|
||||
_toneMappingJobIndex = (int)_jobs.size() - 1;
|
||||
|
||||
// Debugging Deferred buffer job
|
||||
_jobs.push_back(Job(new DebugDeferredBuffer::JobModel("DebugDeferredBuffer")));
|
||||
addJob<DebugDeferredBuffer>("DebugDeferredBuffer");
|
||||
_jobs.back().setEnabled(false);
|
||||
_drawDebugDeferredBufferIndex = (int)_jobs.size() - 1;
|
||||
|
||||
|
@ -116,21 +115,18 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
// Grab a texture map representing the different status icons and assign that to the drawStatsuJob
|
||||
auto iconMapPath = PathUtils::resourcesPath() + "icons/statusIconAtlas.svg";
|
||||
auto statusIconMap = DependencyManager::get<TextureCache>()->getImageTexture(iconMapPath);
|
||||
_jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques, DrawStatus(statusIconMap))));
|
||||
addJob<DrawStatus>("DrawStatus", renderedOpaques, DrawStatus(statusIconMap));
|
||||
_jobs.back().setEnabled(false);
|
||||
_drawStatusJobIndex = (int)_jobs.size() - 1;
|
||||
}
|
||||
|
||||
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
|
||||
addJob<DrawOverlay3D>("DrawOverlay3D");
|
||||
|
||||
_jobs.push_back(Job(new HitEffect::JobModel("HitEffect")));
|
||||
addJob<HitEffect>("HitEffect");
|
||||
_jobs.back().setEnabled(false);
|
||||
_drawHitEffectJobIndex = (int)_jobs.size() -1;
|
||||
|
||||
_jobs.push_back(Job(new Blit::JobModel("Blit")));
|
||||
}
|
||||
|
||||
RenderDeferredTask::~RenderDeferredTask() {
|
||||
addJob<Blit>("Blit");
|
||||
}
|
||||
|
||||
void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#ifndef hifi_RenderDeferredTask_h
|
||||
#define hifi_RenderDeferredTask_h
|
||||
|
||||
#include "render/DrawTask.h"
|
||||
#include "render/Engine.h"
|
||||
|
||||
#include "gpu/Pipeline.h"
|
||||
|
||||
|
@ -22,14 +22,14 @@ class SetupDeferred {
|
|||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
typedef render::Job::Model<SetupDeferred> JobModel;
|
||||
using JobModel = render::Task::Job::Model<SetupDeferred>;
|
||||
};
|
||||
|
||||
class PrepareDeferred {
|
||||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
typedef render::Job::Model<PrepareDeferred> JobModel;
|
||||
using JobModel = render::Task::Job::Model<PrepareDeferred>;
|
||||
};
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@ class RenderDeferred {
|
|||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
typedef render::Job::Model<RenderDeferred> JobModel;
|
||||
using JobModel = render::Task::Job::Model<RenderDeferred>;
|
||||
};
|
||||
|
||||
class ToneMappingDeferred {
|
||||
|
@ -46,21 +46,21 @@ public:
|
|||
|
||||
ToneMappingEffect _toneMappingEffect;
|
||||
|
||||
typedef render::Job::Model<ToneMappingDeferred> JobModel;
|
||||
using JobModel = render::Task::Job::Model<ToneMappingDeferred>;
|
||||
};
|
||||
|
||||
class DrawOpaqueDeferred {
|
||||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems);
|
||||
|
||||
typedef render::Job::ModelI<DrawOpaqueDeferred, render::ItemIDsBounds> JobModel;
|
||||
using JobModel = render::Task::Job::ModelI<DrawOpaqueDeferred, render::ItemIDsBounds>;
|
||||
};
|
||||
|
||||
class DrawTransparentDeferred {
|
||||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems);
|
||||
|
||||
typedef render::Job::ModelI<DrawTransparentDeferred, render::ItemIDsBounds> JobModel;
|
||||
using JobModel = render::Task::Job::ModelI<DrawTransparentDeferred, render::ItemIDsBounds>;
|
||||
};
|
||||
|
||||
class DrawStencilDeferred {
|
||||
|
@ -70,14 +70,14 @@ public:
|
|||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
typedef render::Job::Model<DrawStencilDeferred> JobModel;
|
||||
using JobModel = render::Task::Job::Model<DrawStencilDeferred>;
|
||||
};
|
||||
|
||||
class DrawBackgroundDeferred {
|
||||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
typedef render::Job::Model<DrawBackgroundDeferred> JobModel;
|
||||
using JobModel = render::Task::Job::Model<DrawBackgroundDeferred>;
|
||||
};
|
||||
|
||||
class DrawOverlay3D {
|
||||
|
@ -86,25 +86,22 @@ public:
|
|||
static const gpu::PipelinePointer& getOpaquePipeline();
|
||||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
typedef render::Job::Model<DrawOverlay3D> JobModel;
|
||||
|
||||
using JobModel = render::Task::Job::Model<DrawOverlay3D>;
|
||||
};
|
||||
|
||||
class Blit {
|
||||
public:
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
typedef render::Job::Model<Blit> JobModel;
|
||||
using JobModel = render::Task::Job::Model<Blit>;
|
||||
};
|
||||
|
||||
class RenderDeferredTask : public render::Task {
|
||||
public:
|
||||
|
||||
RenderDeferredTask();
|
||||
~RenderDeferredTask();
|
||||
|
||||
render::Jobs _jobs;
|
||||
|
||||
int _drawDebugDeferredBufferIndex = -1;
|
||||
int _drawStatusJobIndex = -1;
|
||||
int _drawHitEffectJobIndex = -1;
|
||||
|
|
30
libraries/render/src/render/Context.cpp
Normal file
30
libraries/render/src/render/Context.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// Context.cpp
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Zach Pomerantz on 1/6/2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Context.h"
|
||||
|
||||
using namespace render;
|
||||
|
||||
RenderContext::RenderContext(ItemsConfig items, Tone tone, AmbientOcclusion ao, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode)
|
||||
: _deferredDebugMode{ deferredDebugMode }, _deferredDebugSize{ deferredDebugSize },
|
||||
_args{ nullptr },
|
||||
_drawStatus{ drawStatus }, _drawHitEffect{ drawHitEffect },
|
||||
_items{ items }, _tone{ tone }, _ambientOcclusion{ ao } {}
|
||||
|
||||
void RenderContext::setOptions(bool occlusion, bool fxaa, bool showOwned) {
|
||||
_occlusionStatus = occlusion;
|
||||
_fxaaStatus = fxaa;
|
||||
|
||||
if (showOwned) {
|
||||
_drawStatus |= render::showNetworkStatusFlag;
|
||||
}
|
||||
};
|
||||
|
117
libraries/render/src/render/Context.h
Normal file
117
libraries/render/src/render/Context.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
//
|
||||
// Context.h
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Zach Pomerantz on 1/6/2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_render_Context_h
|
||||
#define hifi_render_Context_h
|
||||
|
||||
#include "Scene.h"
|
||||
|
||||
namespace render {
|
||||
|
||||
class SceneContext {
|
||||
public:
|
||||
ScenePointer _scene;
|
||||
|
||||
SceneContext() {}
|
||||
};
|
||||
using SceneContextPointer = std::shared_ptr<SceneContext>;
|
||||
|
||||
// see examples/utilities/tools/renderEngineDebug.js
|
||||
const int showDisplayStatusFlag = 1;
|
||||
const int showNetworkStatusFlag = 2;
|
||||
|
||||
class RenderContext {
|
||||
public:
|
||||
class ItemsConfig {
|
||||
public:
|
||||
class Counter {
|
||||
public:
|
||||
Counter() {}
|
||||
Counter(const Counter& counter) : maxDrawn { counter.maxDrawn } {}
|
||||
|
||||
void setCounts(const Counter& counter) {
|
||||
numFeed = counter.numFeed;
|
||||
numDrawn = counter.numDrawn;
|
||||
};
|
||||
|
||||
int numFeed { 0 };
|
||||
int numDrawn { 0 };
|
||||
int maxDrawn { -1 };
|
||||
};
|
||||
|
||||
class State : public Counter {
|
||||
public:
|
||||
bool render { true };
|
||||
bool cull { true };
|
||||
bool sort { true };
|
||||
|
||||
Counter counter{};
|
||||
};
|
||||
|
||||
ItemsConfig(State opaqueState, State transparentState, Counter overlay3DCounter)
|
||||
: opaque{ opaqueState }, transparent{ transparentState }, overlay3D{ overlay3DCounter } {}
|
||||
ItemsConfig() : ItemsConfig{ {}, {}, {} } {}
|
||||
|
||||
// TODO: If member count increases, store counters in a map instead of multiple members
|
||||
State opaque{};
|
||||
State transparent{};
|
||||
Counter overlay3D{};
|
||||
};
|
||||
|
||||
class Tone {
|
||||
public:
|
||||
int toneCurve = 1; // Means just Gamma 2.2 correction
|
||||
float exposure = 0.0;
|
||||
};
|
||||
|
||||
class AmbientOcclusion {
|
||||
public:
|
||||
float radius = 0.5f; // radius in meters of the AO effect
|
||||
float level = 0.5f; // Level of the obscrance value
|
||||
};
|
||||
|
||||
RenderContext(ItemsConfig items, Tone tone, AmbientOcclusion ao, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode);
|
||||
RenderContext() {};
|
||||
|
||||
void setArgs(RenderArgs* args) { _args = args; }
|
||||
RenderArgs* getArgs() { return _args; }
|
||||
ItemsConfig& getItemsConfig() { return _items; }
|
||||
Tone& getTone() { return _tone; }
|
||||
AmbientOcclusion& getAmbientOcclusion() { return _ambientOcclusion; }
|
||||
int getDrawStatus() { return _drawStatus; }
|
||||
bool getDrawHitEffect() { return _drawHitEffect; }
|
||||
bool getOcclusionStatus() { return _occlusionStatus; }
|
||||
bool getFxaaStatus() { return _fxaaStatus; }
|
||||
void setOptions(bool occlusion, bool fxaa, bool showOwned);
|
||||
|
||||
// Debugging
|
||||
int _deferredDebugMode;
|
||||
glm::vec4 _deferredDebugSize;
|
||||
|
||||
protected:
|
||||
RenderArgs* _args;
|
||||
|
||||
// Options
|
||||
int _drawStatus; // bitflag
|
||||
bool _drawHitEffect;
|
||||
bool _occlusionStatus { false };
|
||||
bool _fxaaStatus = { false };
|
||||
|
||||
ItemsConfig _items;
|
||||
Tone _tone;
|
||||
AmbientOcclusion _ambientOcclusion;
|
||||
};
|
||||
typedef std::shared_ptr<RenderContext> RenderContextPointer;
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_render_Context_h
|
||||
|
|
@ -38,7 +38,7 @@ namespace render {
|
|||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems);
|
||||
|
||||
typedef Job::ModelI<DrawStatus, ItemIDsBounds> JobModel;
|
||||
using JobModel = Task::Job::ModelI<DrawStatus, ItemIDsBounds>;
|
||||
|
||||
const gpu::PipelinePointer getDrawItemBoundsPipeline();
|
||||
const gpu::PipelinePointer getDrawItemStatusPipeline();
|
||||
|
|
|
@ -15,44 +15,12 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <RenderArgs.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
|
||||
using namespace render;
|
||||
|
||||
DrawSceneTask::DrawSceneTask() : Task() {
|
||||
}
|
||||
|
||||
DrawSceneTask::~DrawSceneTask() {
|
||||
}
|
||||
|
||||
void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
// sanity checks
|
||||
assert(sceneContext);
|
||||
if (!sceneContext->_scene) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Is it possible that we render without a viewFrustum ?
|
||||
if (!(renderContext->getArgs() && renderContext->getArgs()->_viewFrustum)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto job : _jobs) {
|
||||
job.run(sceneContext, renderContext);
|
||||
}
|
||||
};
|
||||
|
||||
Job::~Job() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) {
|
||||
assert(renderContext->getArgs());
|
||||
assert(renderContext->getArgs()->_viewFrustum);
|
||||
|
@ -263,50 +231,3 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext
|
|||
});
|
||||
args->_batch = nullptr;
|
||||
}
|
||||
|
||||
void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
assert(renderContext->getArgs());
|
||||
assert(renderContext->getArgs()->_viewFrustum);
|
||||
|
||||
// render backgrounds
|
||||
auto& scene = sceneContext->_scene;
|
||||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::background());
|
||||
|
||||
|
||||
ItemIDsBounds inItems;
|
||||
inItems.reserve(items.size());
|
||||
for (auto id : items) {
|
||||
inItems.emplace_back(id);
|
||||
}
|
||||
RenderArgs* args = renderContext->getArgs();
|
||||
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||
args->_batch = &batch;
|
||||
batch.enableSkybox(true);
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setStateScissorRect(args->_viewport);
|
||||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
||||
renderItems(sceneContext, renderContext, inItems);
|
||||
});
|
||||
args->_batch = nullptr;
|
||||
}
|
||||
|
||||
void ItemMaterialBucketMap::insert(const ItemID& id, const model::MaterialKey& key) {
|
||||
// Insert the itemID in every bucket where it filters true
|
||||
for (auto& bucket : (*this)) {
|
||||
if (bucket.first.test(key)) {
|
||||
bucket.second.push_back(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ItemMaterialBucketMap::allocateStandardMaterialBuckets() {
|
||||
(*this)[model::MaterialFilter::Builder::opaqueDiffuse()];
|
||||
}
|
||||
|
|
|
@ -9,217 +9,15 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_render_Task_h
|
||||
#define hifi_render_Task_h
|
||||
#ifndef hifi_render_DrawTask_h
|
||||
#define hifi_render_DrawTask_h
|
||||
|
||||
#include "Engine.h"
|
||||
#include "gpu/Batch.h"
|
||||
#include <PerfStat.h>
|
||||
|
||||
|
||||
namespace render {
|
||||
|
||||
template <class T> void jobRun(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
jobModel.run(sceneContext, renderContext);
|
||||
}
|
||||
template <class T, class I> void jobRunI(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) {
|
||||
jobModel.run(sceneContext, renderContext, input);
|
||||
}
|
||||
template <class T, class O> void jobRunO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) {
|
||||
jobModel.run(sceneContext, renderContext, output);
|
||||
}
|
||||
template <class T, class I, class O> void jobRunIO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) {
|
||||
jobModel.run(sceneContext, renderContext, input, output);
|
||||
}
|
||||
|
||||
class Job {
|
||||
public:
|
||||
|
||||
// Varying represent a varying piece of data
|
||||
class Varying {
|
||||
public:
|
||||
|
||||
Varying(const Varying& var): _concept(var._concept) {}
|
||||
|
||||
Varying() {}
|
||||
template <class T>
|
||||
Varying(const T& data) : _concept(std::make_shared<Job::Varying::Model<T>>(data)) {}
|
||||
|
||||
// Access the _data contained win the concept explicitely
|
||||
template <class T> T& edit() { return std::static_pointer_cast<Model<T>>(_concept)->_data; }
|
||||
template <class T> const T& get() const { return std::static_pointer_cast<const Model<T>>(_concept)->_data; }
|
||||
|
||||
protected:
|
||||
friend class Job;
|
||||
|
||||
std::vector<std::weak_ptr<Job>> _consumerJobs;
|
||||
|
||||
void addJobConsumer(const std::shared_ptr<Job>& job) {
|
||||
_consumerJobs.push_back(job);
|
||||
}
|
||||
|
||||
class Concept {
|
||||
public:
|
||||
virtual ~Concept() = default;
|
||||
};
|
||||
template <class T> class Model : public Concept {
|
||||
public:
|
||||
typedef T Data;
|
||||
Data _data;
|
||||
Model(const Model& source): _data(source.data) {}
|
||||
Model(const Data& data): _data(data) {}
|
||||
virtual ~Model() {}
|
||||
};
|
||||
|
||||
std::shared_ptr<Concept> _concept;
|
||||
};
|
||||
|
||||
Job(const Job& other) : _concept(other._concept) {}
|
||||
~Job();
|
||||
|
||||
bool isEnabled() const { return _concept->isEnabled(); }
|
||||
void setEnabled(bool isEnabled) { _concept->setEnabled(isEnabled); }
|
||||
|
||||
const std::string& getName() const { return _concept->getName(); }
|
||||
const Varying getInput() const { return _concept->getInput(); }
|
||||
const Varying getOutput() const { return _concept->getOutput(); }
|
||||
|
||||
template <class T> T& edit() {
|
||||
auto theConcept = std::dynamic_pointer_cast<typename T::JobModel>(_concept);
|
||||
assert(theConcept);
|
||||
return theConcept->_data;
|
||||
}
|
||||
template <class T> const T& get() const {
|
||||
auto theConcept = std::dynamic_pointer_cast<typename T::JobModel>(_concept);
|
||||
assert(theConcept);
|
||||
return theConcept->_data;
|
||||
}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
PerformanceTimer perfTimer(getName().c_str());
|
||||
PROFILE_RANGE(getName().c_str());
|
||||
_concept->run(sceneContext, renderContext);
|
||||
}
|
||||
|
||||
protected:
|
||||
public:
|
||||
|
||||
class Concept {
|
||||
std::string _name;
|
||||
bool _isEnabled = true;
|
||||
public:
|
||||
Concept() : _name() {}
|
||||
Concept(const std::string& name) : _name(name) {}
|
||||
virtual ~Concept() = default;
|
||||
|
||||
void setName(const std::string& name) { _name = name; }
|
||||
const std::string& getName() const { return _name; }
|
||||
|
||||
bool isEnabled() const { return _isEnabled; }
|
||||
void setEnabled(bool isEnabled) { _isEnabled = isEnabled; }
|
||||
|
||||
virtual const Varying getInput() const { return Varying(); }
|
||||
virtual const Varying getOutput() const { return Varying(); }
|
||||
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0;
|
||||
};
|
||||
|
||||
Job(Concept* concept) : _concept(concept) {}
|
||||
|
||||
public:
|
||||
template <class T> class Model : public Concept {
|
||||
public:
|
||||
typedef T Data;
|
||||
|
||||
Data _data;
|
||||
|
||||
Model() {}
|
||||
Model(const std::string& name): Concept(name) {}
|
||||
Model(Data data): _data(data) {}
|
||||
Model(Data data, const std::string& name): Concept(name), _data(data) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
if (isEnabled()) {
|
||||
jobRun(_data, sceneContext, renderContext);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class I> class ModelI : public Concept {
|
||||
public:
|
||||
typedef T Data;
|
||||
typedef I Input;
|
||||
|
||||
Data _data;
|
||||
Varying _input;
|
||||
|
||||
const Varying getInput() const { return _input; }
|
||||
|
||||
ModelI(const std::string& name, const Varying& input, Data data = Data()) : Concept(name), _data(data), _input(input) {}
|
||||
ModelI(const std::string& name, Data data): Concept(name), _data(data) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
if (isEnabled()) {
|
||||
jobRunI(_data, sceneContext, renderContext, _input.get<I>());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class O> class ModelO : public Concept {
|
||||
public:
|
||||
typedef T Data;
|
||||
typedef O Output;
|
||||
|
||||
Data _data;
|
||||
Varying _output;
|
||||
|
||||
const Varying getOutput() const { return _output; }
|
||||
|
||||
ModelO(const std::string& name): Concept(name), _output(Output()) {
|
||||
|
||||
}
|
||||
|
||||
ModelO(const std::string& name, Data data): Concept(name), _data(data), _output(Output()) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
if (isEnabled()) {
|
||||
jobRunO(_data, sceneContext, renderContext, _output.edit<O>());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class I, class O> class ModelIO : public Concept {
|
||||
public:
|
||||
typedef T Data;
|
||||
typedef I Input;
|
||||
typedef O Output;
|
||||
|
||||
Data _data;
|
||||
Varying _input;
|
||||
Varying _output;
|
||||
|
||||
const Varying getInput() const { return _input; }
|
||||
const Varying getOutput() const { return _output; }
|
||||
|
||||
ModelIO(const std::string& name, const Varying& input, Data data = Data()): Concept(name), _data(data), _input(input), _output(Output()) {}
|
||||
ModelIO(const std::string& name, Data data, Output output): Concept(name), _data(data), _output(output) {}
|
||||
|
||||
void setInput(const Varying& input) { _input = input; }
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
if (isEnabled()) {
|
||||
jobRunIO(_data, sceneContext, renderContext, _input.get<I>(), _output.edit<O>());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<Concept> _concept;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
typedef std::vector<Job> Jobs;
|
||||
|
||||
void cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
|
||||
void depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
|
||||
void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, int maxDrawnItems = -1);
|
||||
|
@ -236,25 +34,25 @@ public:
|
|||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemIDsBounds& outItems);
|
||||
|
||||
typedef Job::ModelO<FetchItems, ItemIDsBounds> JobModel;
|
||||
using JobModel = Task::Job::ModelO<FetchItems, ItemIDsBounds>;
|
||||
};
|
||||
|
||||
class CullItems {
|
||||
public:
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
|
||||
typedef Job::ModelIO<CullItems, ItemIDsBounds, ItemIDsBounds> JobModel;
|
||||
using JobModel = Task::Job::ModelIO<CullItems, ItemIDsBounds, ItemIDsBounds>;
|
||||
};
|
||||
|
||||
class CullItemsOpaque {
|
||||
public:
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
|
||||
typedef Job::ModelIO<CullItemsOpaque, ItemIDsBounds, ItemIDsBounds> JobModel;
|
||||
using JobModel = Task::Job::ModelIO<CullItemsOpaque, ItemIDsBounds, ItemIDsBounds>;
|
||||
};
|
||||
|
||||
class CullItemsTransparent {
|
||||
public:
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
|
||||
typedef Job::ModelIO<CullItemsTransparent, ItemIDsBounds, ItemIDsBounds> JobModel;
|
||||
using JobModel = Task::Job::ModelIO<CullItemsTransparent, ItemIDsBounds, ItemIDsBounds>;
|
||||
};
|
||||
|
||||
class DepthSortItems {
|
||||
|
@ -265,52 +63,16 @@ public:
|
|||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
|
||||
|
||||
typedef Job::ModelIO<DepthSortItems, ItemIDsBounds, ItemIDsBounds> JobModel;
|
||||
using JobModel = Task::Job::ModelIO<DepthSortItems, ItemIDsBounds, ItemIDsBounds>;
|
||||
};
|
||||
|
||||
class DrawLight {
|
||||
public:
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||
|
||||
typedef Job::Model<DrawLight> JobModel;
|
||||
using JobModel = Task::Job::Model<DrawLight>;
|
||||
};
|
||||
|
||||
class DrawBackground {
|
||||
public:
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||
|
||||
|
||||
typedef Job::Model<DrawBackground> JobModel;
|
||||
};
|
||||
|
||||
|
||||
class DrawSceneTask : public Task {
|
||||
public:
|
||||
|
||||
DrawSceneTask();
|
||||
~DrawSceneTask();
|
||||
|
||||
Jobs _jobs;
|
||||
|
||||
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||
|
||||
};
|
||||
|
||||
|
||||
// A map of ItemIDs allowing to create bucket lists of SHAPE type items which are filtered by their
|
||||
// Material
|
||||
class ItemMaterialBucketMap : public std::map<model::MaterialFilter, ItemIDs, model::MaterialFilter::Less> {
|
||||
public:
|
||||
|
||||
ItemMaterialBucketMap() {}
|
||||
|
||||
void insert(const ItemID& id, const model::MaterialKey& key);
|
||||
|
||||
// standard builders allocating the main buckets
|
||||
void allocateStandardMaterialBuckets();
|
||||
};
|
||||
void materialSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_render_Task_h
|
||||
#endif // hifi_render_DrawTask_h
|
||||
|
|
|
@ -8,26 +8,11 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Engine.h"
|
||||
|
||||
#include "DrawTask.h"
|
||||
using namespace render;
|
||||
|
||||
RenderContext::RenderContext(ItemsConfig items, Tone tone, AmbientOcclusion ao, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode)
|
||||
: _deferredDebugMode{ deferredDebugMode }, _deferredDebugSize{ deferredDebugSize },
|
||||
_args{ nullptr },
|
||||
_drawStatus{ drawStatus }, _drawHitEffect{ drawHitEffect },
|
||||
_items{ items }, _tone{ tone }, _ambientOcclusion{ ao } {}
|
||||
|
||||
void RenderContext::setOptions(bool occlusion, bool fxaa, bool showOwned) {
|
||||
_occlusionStatus = occlusion;
|
||||
_fxaaStatus = fxaa;
|
||||
|
||||
if (showOwned) {
|
||||
_drawStatus |= render::showNetworkStatusFlag;
|
||||
}
|
||||
};
|
||||
|
||||
Engine::Engine() :
|
||||
_sceneContext(std::make_shared<SceneContext>()),
|
||||
_renderContext(std::make_shared<RenderContext>())
|
||||
|
@ -49,16 +34,8 @@ void Engine::addTask(const TaskPointer& task) {
|
|||
}
|
||||
|
||||
void Engine::run() {
|
||||
// TODO: Tasks will need to be specified such that their data can feed into each other
|
||||
for (auto task : _tasks) {
|
||||
task->run(_sceneContext, _renderContext);
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::buildStandardTaskPipeline() {
|
||||
if (!_tasks.empty()) {
|
||||
_tasks.clear();
|
||||
}
|
||||
|
||||
addTask(std::make_shared<DrawSceneTask>());
|
||||
}
|
||||
|
||||
|
|
|
@ -12,123 +12,11 @@
|
|||
#ifndef hifi_render_Engine_h
|
||||
#define hifi_render_Engine_h
|
||||
|
||||
#include "Scene.h"
|
||||
#include "Context.h"
|
||||
#include "Task.h"
|
||||
|
||||
namespace render {
|
||||
|
||||
|
||||
class SceneContext {
|
||||
public:
|
||||
ScenePointer _scene;
|
||||
|
||||
SceneContext() {}
|
||||
};
|
||||
using SceneContextPointer = std::shared_ptr<SceneContext>;
|
||||
|
||||
// see examples/utilities/tools/renderEngineDebug.js
|
||||
const int showDisplayStatusFlag = 1;
|
||||
const int showNetworkStatusFlag = 2;
|
||||
|
||||
|
||||
class RenderContext {
|
||||
public:
|
||||
class ItemsConfig {
|
||||
public:
|
||||
class Counter {
|
||||
public:
|
||||
Counter() {};
|
||||
Counter(const Counter& counter) {
|
||||
numFeed = numDrawn = 0;
|
||||
maxDrawn = counter.maxDrawn;
|
||||
};
|
||||
|
||||
void setCounts(const Counter& counter) {
|
||||
numFeed = counter.numFeed;
|
||||
numDrawn = counter.numDrawn;
|
||||
};
|
||||
|
||||
int numFeed = 0;
|
||||
int numDrawn = 0;
|
||||
int maxDrawn = -1;
|
||||
};
|
||||
|
||||
class State : public Counter {
|
||||
public:
|
||||
bool render = true;
|
||||
bool cull = true;
|
||||
bool sort = true;
|
||||
|
||||
Counter counter{};
|
||||
};
|
||||
|
||||
ItemsConfig(State opaqueState, State transparentState, Counter overlay3DCounter)
|
||||
: opaque{ opaqueState }, transparent{ transparentState }, overlay3D{ overlay3DCounter } {}
|
||||
ItemsConfig() : ItemsConfig{ {}, {}, {} } {}
|
||||
|
||||
// TODO: If member count increases, store counters in a map instead of multiple members
|
||||
State opaque{};
|
||||
State transparent{};
|
||||
Counter overlay3D{};
|
||||
};
|
||||
|
||||
class Tone {
|
||||
public:
|
||||
int toneCurve = 1; // Means just Gamma 2.2 correction
|
||||
float exposure = 0.0;
|
||||
};
|
||||
|
||||
class AmbientOcclusion {
|
||||
public:
|
||||
float radius = 0.5f; // radius in meters of the AO effect
|
||||
float level = 0.5f; // Level of the obscrance value
|
||||
};
|
||||
|
||||
RenderContext(ItemsConfig items, Tone tone, AmbientOcclusion ao, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode);
|
||||
RenderContext() : RenderContext({}, {}, {}, {}, {}, {}, {}) {};
|
||||
|
||||
void setArgs(RenderArgs* args) { _args = args; }
|
||||
inline RenderArgs* getArgs() { return _args; }
|
||||
inline ItemsConfig& getItemsConfig() { return _items; }
|
||||
inline Tone& getTone() { return _tone; }
|
||||
inline AmbientOcclusion& getAmbientOcclusion() { return _ambientOcclusion; }
|
||||
inline int getDrawStatus() { return _drawStatus; }
|
||||
inline bool getDrawHitEffect() { return _drawHitEffect; }
|
||||
inline bool getOcclusionStatus() { return _occlusionStatus; }
|
||||
inline bool getFxaaStatus() { return _fxaaStatus; }
|
||||
void setOptions(bool occlusion, bool fxaa, bool showOwned);
|
||||
|
||||
// Debugging
|
||||
int _deferredDebugMode;
|
||||
glm::vec4 _deferredDebugSize;
|
||||
|
||||
protected:
|
||||
RenderArgs* _args;
|
||||
|
||||
// Options
|
||||
int _drawStatus; // bitflag
|
||||
bool _drawHitEffect;
|
||||
bool _occlusionStatus = false;
|
||||
bool _fxaaStatus = false;
|
||||
|
||||
ItemsConfig _items;
|
||||
Tone _tone;
|
||||
AmbientOcclusion _ambientOcclusion;
|
||||
};
|
||||
typedef std::shared_ptr<RenderContext> RenderContextPointer;
|
||||
|
||||
// The base class for a task that runs on the SceneContext
|
||||
class Task {
|
||||
public:
|
||||
Task() {}
|
||||
~Task() {}
|
||||
|
||||
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {}
|
||||
|
||||
protected:
|
||||
};
|
||||
typedef std::shared_ptr<Task> TaskPointer;
|
||||
typedef std::vector<TaskPointer> Tasks;
|
||||
|
||||
// The root of the tasks, the Engine, should not be known from the Tasks,
|
||||
// The SceneContext is what navigates from the engine down to the Tasks
|
||||
class Engine {
|
||||
|
@ -150,11 +38,7 @@ public:
|
|||
|
||||
void run();
|
||||
|
||||
// standard pipeline of tasks
|
||||
void buildStandardTaskPipeline();
|
||||
|
||||
protected:
|
||||
|
||||
Tasks _tasks;
|
||||
|
||||
SceneContextPointer _sceneContext;
|
||||
|
@ -165,3 +49,4 @@ typedef std::shared_ptr<Engine> EnginePointer;
|
|||
}
|
||||
|
||||
#endif // hifi_render_Engine_h
|
||||
|
||||
|
|
227
libraries/render/src/render/Task.h
Normal file
227
libraries/render/src/render/Task.h
Normal file
|
@ -0,0 +1,227 @@
|
|||
//
|
||||
// Task.h
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Zach Pomerantz on 1/6/2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_render_Task_h
|
||||
#define hifi_render_Task_h
|
||||
|
||||
#include "Context.h"
|
||||
|
||||
#include "gpu/Batch.h"
|
||||
#include <PerfStat.h>
|
||||
|
||||
namespace render {
|
||||
|
||||
// A varying piece of data, to be used as Job/Task I/O
|
||||
// TODO: Task IO
|
||||
class Varying {
|
||||
public:
|
||||
Varying() {}
|
||||
Varying(const Varying& var) : _concept(var._concept) {}
|
||||
template <class T> Varying(const T& data) : _concept(std::make_shared<Model<T>>(data)) {}
|
||||
|
||||
template <class T> T& edit() { return std::static_pointer_cast<Model<T>>(_concept)->_data; }
|
||||
template <class T> const T& get() { return std::static_pointer_cast<const Model<T>>(_concept)->_data; }
|
||||
|
||||
protected:
|
||||
class Concept {
|
||||
public:
|
||||
virtual ~Concept() = default;
|
||||
};
|
||||
template <class T> class Model : public Concept {
|
||||
public:
|
||||
using Data = T;
|
||||
|
||||
Model(const Data& data) : _data(data) {}
|
||||
virtual ~Model() = default;
|
||||
|
||||
Data _data;
|
||||
};
|
||||
|
||||
std::shared_ptr<Concept> _concept;
|
||||
};
|
||||
|
||||
// FIXME: In c++17, use default classes of nullptr_t to combine these
|
||||
template <class T> void jobRun(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
jobModel.run(sceneContext, renderContext);
|
||||
}
|
||||
template <class T, class I> void jobRunI(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) {
|
||||
jobModel.run(sceneContext, renderContext, input);
|
||||
}
|
||||
template <class T, class O> void jobRunO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) {
|
||||
jobModel.run(sceneContext, renderContext, output);
|
||||
}
|
||||
template <class T, class I, class O> void jobRunIO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) {
|
||||
jobModel.run(sceneContext, renderContext, input, output);
|
||||
}
|
||||
|
||||
// The base class for a task that runs on the SceneContext
|
||||
class Task {
|
||||
public:
|
||||
// The guts of a task; tasks are composed of multiple Jobs that execute serially
|
||||
class Job {
|
||||
public:
|
||||
friend class Task;
|
||||
|
||||
// The guts of a job; jobs are composed of a concept
|
||||
class Concept {
|
||||
public:
|
||||
Concept() = default;
|
||||
virtual ~Concept() = default;
|
||||
|
||||
bool isEnabled() const { return _isEnabled; }
|
||||
void setEnabled(bool isEnabled) { _isEnabled = isEnabled; }
|
||||
|
||||
virtual const Varying getInput() const { return Varying(); }
|
||||
virtual const Varying getOutput() const { return Varying(); }
|
||||
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
bool _isEnabled = true;
|
||||
};
|
||||
using ConceptPointer = std::shared_ptr<Concept>;
|
||||
|
||||
|
||||
template <class T> class Model : public Concept {
|
||||
public:
|
||||
typedef T Data;
|
||||
|
||||
Data _data;
|
||||
|
||||
Model() {}
|
||||
Model(Data data): _data(data) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
if (isEnabled()) {
|
||||
jobRun(_data, sceneContext, renderContext);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class I> class ModelI : public Concept {
|
||||
public:
|
||||
typedef T Data;
|
||||
typedef I Input;
|
||||
|
||||
Data _data;
|
||||
Varying _input;
|
||||
|
||||
const Varying getInput() const { return _input; }
|
||||
|
||||
ModelI(const Varying& input, Data data = Data()) : _data(data), _input(input) {}
|
||||
ModelI(Data data) : _data(data) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
if (isEnabled()) {
|
||||
jobRunI(_data, sceneContext, renderContext, _input.get<I>());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class O> class ModelO : public Concept {
|
||||
public:
|
||||
typedef T Data;
|
||||
typedef O Output;
|
||||
|
||||
Data _data;
|
||||
Varying _output;
|
||||
|
||||
const Varying getOutput() const { return _output; }
|
||||
|
||||
ModelO(Data data) : _data(data), _output(Output()) {}
|
||||
ModelO() : _output(Output()) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
if (isEnabled()) {
|
||||
jobRunO(_data, sceneContext, renderContext, _output.edit<O>());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class I, class O> class ModelIO : public Concept {
|
||||
public:
|
||||
typedef T Data;
|
||||
typedef I Input;
|
||||
typedef O Output;
|
||||
|
||||
Data _data;
|
||||
Varying _input;
|
||||
Varying _output;
|
||||
|
||||
const Varying getInput() const { return _input; }
|
||||
const Varying getOutput() const { return _output; }
|
||||
|
||||
ModelIO(const Varying& input, Data data = Data()) : _data(data), _input(input), _output(Output()) {}
|
||||
ModelIO(Data data) : _data(data), _output(Output()) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
if (isEnabled()) {
|
||||
jobRunIO(_data, sceneContext, renderContext, _input.get<I>(), _output.edit<O>());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Job(ConceptPointer concept) : _concept(concept) {}
|
||||
Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {}
|
||||
|
||||
bool isEnabled() const { return _concept->isEnabled(); }
|
||||
void setEnabled(bool isEnabled) { _concept->setEnabled(isEnabled); }
|
||||
|
||||
const Varying getInput() const { return _concept->getInput(); }
|
||||
const Varying getOutput() const { return _concept->getOutput(); }
|
||||
|
||||
template <class T> T& edit() {
|
||||
auto concept = std::static_pointer_cast<typename T::JobModel>(_concept);
|
||||
assert(concept);
|
||||
return concept->_data;
|
||||
}
|
||||
template <class T> const T& get() const {
|
||||
auto concept = std::static_pointer_cast<typename T::JobModel>(_concept);
|
||||
assert(concept);
|
||||
return concept->_data;
|
||||
}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
PerformanceTimer perfTimer(_name.c_str());
|
||||
PROFILE_RANGE(_name.c_str());
|
||||
|
||||
_concept->run(sceneContext, renderContext);
|
||||
}
|
||||
protected:
|
||||
ConceptPointer _concept;
|
||||
std::string _name = "";
|
||||
|
||||
};
|
||||
using Jobs = std::vector<Job>;
|
||||
|
||||
public:
|
||||
Task() = default;
|
||||
virtual ~Task() = default;
|
||||
|
||||
// Queue a new job to the task; returns the job's index
|
||||
template <class T, class... A> size_t addJob(std::string name, A&&... args) {
|
||||
_jobs.emplace_back(name, std::make_shared<typename T::JobModel>(std::forward<A>(args)...));
|
||||
return _jobs.size() - 1;
|
||||
}
|
||||
|
||||
const Job& getJob(size_t i) const { return _jobs.at(i); }
|
||||
|
||||
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {}
|
||||
|
||||
protected:
|
||||
Jobs _jobs;
|
||||
};
|
||||
typedef std::shared_ptr<Task> TaskPointer;
|
||||
typedef std::vector<TaskPointer> Tasks;
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_render_Task_h
|
|
@ -28,7 +28,7 @@ public:
|
|||
// Plugin functions
|
||||
virtual bool isSupported() const override;
|
||||
virtual bool isJointController() const override { return true; }
|
||||
const QString& getName() const override { return NAME; }
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
const QString& getID() const override { return NEURON_ID_STRING; }
|
||||
|
||||
virtual void activate() override;
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
// Plugin functions
|
||||
virtual bool isSupported() const override;
|
||||
virtual bool isJointController() const override { return false; }
|
||||
const QString& getName() const override { return NAME; }
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
|
||||
virtual void init() override;
|
||||
virtual void deinit() override;
|
||||
|
|
|
@ -29,8 +29,8 @@ public:
|
|||
// Plugin functions
|
||||
virtual bool isSupported() const override;
|
||||
virtual bool isJointController() const override { return true; }
|
||||
const QString& getName() const override { return NAME; }
|
||||
const QString& getID() const override { return HYDRA_ID_STRING; }
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual const QString& getID() const override { return HYDRA_ID_STRING; }
|
||||
|
||||
virtual void activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
|
||||
const QString OculusDebugDisplayPlugin::NAME("Oculus Rift (Simulator)");
|
||||
|
||||
const QString & OculusDebugDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
static const QString DEBUG_FLAG("HIFI_DEBUG_OCULUS");
|
||||
static bool enableDebugOculus = QProcessEnvironment::systemEnvironment().contains("HIFI_DEBUG_OCULUS");
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
class OculusDebugDisplayPlugin : public OculusBaseDisplayPlugin {
|
||||
public:
|
||||
virtual const QString & getName() const override;
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual grouping getGrouping() const override { return DEVELOPER; }
|
||||
virtual bool isSupported() const override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -138,10 +138,6 @@ private:
|
|||
|
||||
const QString OculusDisplayPlugin::NAME("Oculus Rift");
|
||||
|
||||
const QString & OculusDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
static const QString MONO_PREVIEW = "Mono Preview";
|
||||
static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate";
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ const float TARGET_RATE_Oculus = 75.0f;
|
|||
class OculusDisplayPlugin : public OculusBaseDisplayPlugin {
|
||||
public:
|
||||
virtual void activate() override;
|
||||
virtual const QString & getName() const override;
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual void setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) override final;
|
||||
|
||||
virtual float getTargetFrameRate() override { return TARGET_RATE_Oculus; }
|
||||
|
|
|
@ -26,11 +26,7 @@
|
|||
|
||||
using namespace oglplus;
|
||||
|
||||
const QString OculusLegacyDisplayPlugin::NAME("Oculus Rift (0.5) (Simulated)");
|
||||
|
||||
const QString & OculusLegacyDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
const QString OculusLegacyDisplayPlugin::NAME("Oculus Rift (0.5) (Legacy)");
|
||||
|
||||
OculusLegacyDisplayPlugin::OculusLegacyDisplayPlugin() {
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class OculusLegacyDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
|||
public:
|
||||
OculusLegacyDisplayPlugin();
|
||||
virtual bool isSupported() const override;
|
||||
virtual const QString & getName() const override;
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
|
||||
virtual void activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
|
|
@ -31,10 +31,6 @@ const QString OpenVrDisplayPlugin::NAME("OpenVR (Vive)");
|
|||
|
||||
const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; // this probably shouldn't be hardcoded here
|
||||
|
||||
const QString & OpenVrDisplayPlugin::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
static vr::IVRCompositor* _compositor{ nullptr };
|
||||
vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||
mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
|
||||
|
|
|
@ -18,7 +18,7 @@ const float TARGET_RATE_OpenVr = 90.0f; // FIXME: get from sdk tracked device p
|
|||
class OpenVrDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
||||
public:
|
||||
virtual bool isSupported() const override;
|
||||
virtual const QString & getName() const override;
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual bool isHmd() const override { return true; }
|
||||
|
||||
virtual float getTargetFrameRate() override { return TARGET_RATE_OpenVr; }
|
||||
|
|
Loading…
Reference in a new issue