diff --git a/cmake/externals/qxmpp/CMakeLists.txt b/cmake/externals/qxmpp/CMakeLists.txt deleted file mode 100644 index 600aa7b2ff..0000000000 --- a/cmake/externals/qxmpp/CMakeLists.txt +++ /dev/null @@ -1,77 +0,0 @@ -set(EXTERNAL_NAME qxmpp) - -# we need to find qmake inside QT_DIR -find_program(QMAKE_COMMAND NAME qmake PATHS ${QT_DIR}/bin $ENV{QTTOOLDIR} NO_DEFAULT_PATH) - -if (NOT QMAKE_COMMAND) - message(FATAL_ERROR "Could not find qmake. Qxmpp cannot be compiled without qmake.") -endif () - -if (ANDROID) - set(ANDROID_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19") -endif () - -if (WIN32) - find_program(PLATFORM_BUILD_COMMAND nmake PATHS "C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin") - - if (NOT PLATFORM_BUILD_COMMAND) - message(FATAL_ERROR "You asked CMake to grap QXmpp and build it, but nmake was not found. Please make sure the folder containing nmake.exe is in your PATH.") - endif () -else () - find_program(PLATFORM_BUILD_COMMAND make) -endif () - -include(ExternalProject) -ExternalProject_Add( - ${EXTERNAL_NAME} - URL http://qxmpp.googlecode.com/files/qxmpp-0.7.6.tar.gz - URL_MD5 ee45a97313306ded2ff0f6618a3ed1e1 - BUILD_IN_SOURCE 1 - PATCH_COMMAND patch -p2 -t -N --verbose < ${CMAKE_CURRENT_SOURCE_DIR}/qxmpp.patch - CONFIGURE_COMMAND ${QMAKE_COMMAND} PREFIX= - BUILD_COMMAND ${PLATFORM_BUILD_COMMAND} - INSTALL_COMMAND ${PLATFORM_BUILD_COMMAND} install - LOG_DOWNLOAD 1 - LOG_CONFIGURE 1 - LOG_BUILD 1 -) - -# Hide this external target (for ide users) -set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") - -ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) - -if (CMAKE_GENERATOR STREQUAL Xcode) - find_program(DITTO_COMMAND ditto) - - ExternalProject_Add_Step( - ${EXTERNAL_NAME} - copy-from-xcode-install - COMMENT "Copying from /tmp/hifi.dst${INSTALL_DIR} to move install to proper location" - COMMAND ${DITTO_COMMAND} /tmp/hifi.dst${INSTALL_DIR} ${INSTALL_DIR} - DEPENDEES install - LOG 1 - ) -endif () - -string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE FILEPATH "Path to Qxmpp include directory") - -set(_LIB_DIR ${INSTALL_DIR}/lib) - -if (WIN32) - set(_LIB_EXT "0.lib") - - set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${_LIB_DIR} CACHE PATH "Location of QXmpp DLL") -else () - if (APPLE) - set(_LIB_EXT ".dylib") - else () - set(_LIB_EXT ".so") - endif () - - set(_LIB_PREFIX "lib") -endif () - -set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_LIB_DIR}/${_LIB_PREFIX}qxmpp${_LIB_EXT} CACHE FILEPATH "Path to QXmpp release library") -set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "Path to QXmpp debug library") diff --git a/examples/controllers/reticleHandRotationTest.js b/examples/controllers/reticleHandRotationTest.js index d413e531df..781dbf66ab 100644 --- a/examples/controllers/reticleHandRotationTest.js +++ b/examples/controllers/reticleHandRotationTest.js @@ -9,13 +9,14 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +var whichHand = Controller.Standard.RightHand; +var whichTrigger = Controller.Standard.RT; +var DEBUGGING = false; + Math.clamp=function(a,b,c) { return Math.max(b,Math.min(c,a)); } -var whichHand = Controller.Standard.RightHand; -var whichTrigger = Controller.Standard.RT; - function length(posA, posB) { var dx = posA.x - posB.x; var dy = posA.y - posB.y; @@ -61,35 +62,37 @@ mapping.from(whichHand).peek().to(function(pose) { var rotated = Vec3.multiplyQbyV(pose.rotation, Vec3.UNIT_NEG_Y); // var absolutePitch = rotated.y; // from 1 down to -1 up ... but note: if you rotate down "too far" it starts to go up again... - var absoluteYaw = rotated.z; // from -1 left to 1 right - //print("absolutePitch:" + absolutePitch); - //print("absoluteYaw:" + absoluteYaw); - //Vec3.print("rotated:", rotated); + var absoluteYaw = -rotated.x; // from -1 left to 1 right + + if (DEBUGGING) { + print("absolutePitch:" + absolutePitch); + print("absoluteYaw:" + absoluteYaw); + Vec3.print("rotated:", rotated); + } var ROTATION_BOUND = 0.6; var clampYaw = Math.clamp(absoluteYaw, -ROTATION_BOUND, ROTATION_BOUND); var clampPitch = Math.clamp(absolutePitch, -ROTATION_BOUND, ROTATION_BOUND); - //var clampYaw = absoluteYaw; - //print("clampYaw:" + clampYaw); - //print("clampPitch:" + clampPitch); + if (DEBUGGING) { + print("clampYaw:" + clampYaw); + print("clampPitch:" + clampPitch); + } - // if using entire span... - //var xRatio = (absoluteYaw + 1) / 2; - //var yRatio = (absolutePitch + 1) / 2; - - // if using only from -0.5 to 0.5 + // using only from -ROTATION_BOUND to ROTATION_BOUND var xRatio = (clampYaw + ROTATION_BOUND) / (2 * ROTATION_BOUND); var yRatio = (clampPitch + ROTATION_BOUND) / (2 * ROTATION_BOUND); - //print("xRatio:" + xRatio); - //print("yRatio:" + yRatio); - - //print("ratio x:" + xRatio + " y:" + yRatio); + if (DEBUGGING) { + print("xRatio:" + xRatio); + print("yRatio:" + yRatio); + } var x = screenSizeX * xRatio; var y = screenSizeY * yRatio; - //print("position x:" + x + " y:" + y); + if (DEBUGGING) { + print("position x:" + x + " y:" + y); + } if (!(xRatio == 0.5 && yRatio == 0)) { moveReticleAbsolute(x, y); } diff --git a/examples/edit.js b/examples/edit.js index 59b6ae3e7d..074b43c8c1 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -140,9 +140,33 @@ var importingSVOTextOverlay = Overlays.addOverlay("text", { }); var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; -var marketplaceWindow = new WebWindow('Marketplace', MARKETPLACE_URL, 900, 700, false); +var marketplaceWindow = new OverlayWebWindow('Marketplace', "about:blank", 900, 700, false); marketplaceWindow.setVisible(false); +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); + marketplaceWindow.raise(); +} + +function hideMarketplace() { + marketplaceWindow.setVisible(false); + marketplaceWindow.setURL("about:blank"); +} + +function toggleMarketplace() { + if (marketplaceWindow.visible) { + hideMarketplace(); + } else { + showMarketplace(); + } +} + var toolBar = (function() { var that = {}, toolBar, @@ -413,12 +437,9 @@ var toolBar = (function() { newModelButtonDown = true; return true; } + if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) { - if (marketplaceWindow.url != MARKETPLACE_URL) { - marketplaceWindow.setURL(MARKETPLACE_URL); - } - marketplaceWindow.setVisible(true); - marketplaceWindow.raise(); + toggleMarketplace(); return true; } @@ -1336,6 +1357,7 @@ function getPositionToCreateEntity() { } function importSVO(importURL) { + print("Import URL requested: " + importURL) if (!Entities.canAdjustLocks()) { Window.alert(INSUFFICIENT_PERMISSIONS_IMPORT_ERROR_MSG); return; @@ -1574,11 +1596,7 @@ PropertiesTool = function(opts) { pushCommandForSelections(); selectionManager._update(); } else if (data.type == "showMarketplace") { - if (marketplaceWindow.url != data.url) { - marketplaceWindow.setURL(data.url); - } - marketplaceWindow.setVisible(true); - marketplaceWindow.raise(); + showMarketplace(); } else if (data.type == "action") { if (data.action == "moveSelectionToGrid") { if (selectionManager.hasSelection()) { @@ -1859,12 +1877,7 @@ var propertyMenu = PopupMenu(); propertyMenu.onSelectMenuItem = function(name) { if (propertyMenu.marketplaceID) { - var url = MARKETPLACE_URL + "/items/" + propertyMenu.marketplaceID; - if (marketplaceWindow.url != url) { - marketplaceWindow.setURL(url); - } - marketplaceWindow.setVisible(true); - marketplaceWindow.raise(); + showMarketplace(propertyMenu.marketplaceID); } }; diff --git a/examples/utilities/tools/cookies.js b/examples/utilities/tools/cookies.js index d9fa999a13..edb0fb4330 100644 --- a/examples/utilities/tools/cookies.js +++ b/examples/utilities/tools/cookies.js @@ -384,10 +384,10 @@ var CHECK_MARK_COLOR = { y: newY }); Overlays.editOverlay(this.checkMark, { - y: newY + y: newY + (0.25 * this.thumbSize) }); Overlays.editOverlay(this.unCheckMark, { - y: newY + y: newY + (0.25 * this.thumbSize) }); }; @@ -399,10 +399,10 @@ var CHECK_MARK_COLOR = { y: this.y }); Overlays.editOverlay(this.checkMark, { - y: this.y + y: this.y + (0.25 * this.thumbSize) }); Overlays.editOverlay(this.unCheckMark, { - y: this.y + y: this.y+ (0.25 * this.thumbSize) }); }; diff --git a/examples/utilities/tools/renderEngineDebug.js b/examples/utilities/tools/renderEngineDebug.js index cca97b7184..cc04ddd8a2 100755 --- a/examples/utilities/tools/renderEngineDebug.js +++ b/examples/utilities/tools/renderEngineDebug.js @@ -1,6 +1,7 @@ // -// SunLightExample.js -// examples +// renderEngineDebug.js +// examples/utilities/tools +// // Sam Gateau // Copyright 2015 High Fidelity, Inc. // @@ -10,10 +11,18 @@ Script.include("cookies.js"); +var MENU = "Developer>Render>Debug Deferred Buffer"; +var ACTIONS = ["Off", "Diffuse", "Alpha", "Specular", "Roughness", "Normal", "Depth", "Lighting", "Custom"]; +var SETTINGS_KEY = "EngineDebugScript.DebugMode"; + +Number.prototype.clamp = function(min, max) { + return Math.min(Math.max(this, min), max); +}; + var panel = new Panel(10, 100); function CounterWidget(parentPanel, name, feedGetter, drawGetter, capSetter, capGetter) { - this.subPanel = panel.newSubPanel(name); + this.subPanel = parentPanel.newSubPanel(name); this.subPanel.newSlider("Num Feed", 0, 1, function(value) { }, @@ -28,12 +37,14 @@ function CounterWidget(parentPanel, name, feedGetter, drawGetter, capSetter, cap capGetter, function(value) { return (value); }); - this.update = function () { + this.update = function () { var numFeed = this.subPanel.get("Num Feed"); - this.subPanel.set("Num Feed", numFeed); - this.subPanel.set("Num Drawn", this.subPanel.get("Num Drawn")); - + var numDrawn = this.subPanel.get("Num Drawn"); var numMax = Math.max(numFeed, 1); + + this.subPanel.set("Num Feed", numFeed); + this.subPanel.set("Num Drawn", numDrawn); + this.subPanel.getWidget("Num Feed").setMaxValue(numMax); this.subPanel.getWidget("Num Drawn").setMaxValue(numMax); this.subPanel.getWidget("Max Drawn").setMaxValue(numMax); @@ -41,47 +52,74 @@ function CounterWidget(parentPanel, name, feedGetter, drawGetter, capSetter, cap }; var opaquesCounter = new CounterWidget(panel, "Opaques", - function () { return Scene.getEngineNumFeedOpaqueItems(); }, - function () { return Scene.getEngineNumDrawnOpaqueItems(); }, - function(value) { Scene.setEngineMaxDrawnOpaqueItems(value); }, - function () { return Scene.getEngineMaxDrawnOpaqueItems(); } + function () { return Render.opaque.numFeed; }, + function () { return Render.opaque.numDrawn; }, + function(value) { Render.opaque.maxDrawn = value; }, + function () { return Render.opaque.maxDrawn; } ); var transparentsCounter = new CounterWidget(panel, "Transparents", - function () { return Scene.getEngineNumFeedTransparentItems(); }, - function () { return Scene.getEngineNumDrawnTransparentItems(); }, - function(value) { Scene.setEngineMaxDrawnTransparentItems(value); }, - function () { return Scene.getEngineMaxDrawnTransparentItems(); } + function () { return Render.transparent.numFeed; }, + function () { return Render.transparent.numDrawn; }, + function(value) { Render.transparent.maxDrawn = value; }, + function () { return Render.transparent.maxDrawn; } ); var overlaysCounter = new CounterWidget(panel, "Overlays", - function () { return Scene.getEngineNumFeedOverlay3DItems(); }, - function () { return Scene.getEngineNumDrawnOverlay3DItems(); }, - function(value) { Scene.setEngineMaxDrawnOverlay3DItems(value); }, - function () { return Scene.getEngineMaxDrawnOverlay3DItems(); } + function () { return Render.overlay3D.numFeed; }, + function () { return Render.overlay3D.numDrawn; }, + function(value) { Render.overlay3D.maxDrawn = value; }, + function () { return Render.overlay3D.maxDrawn; } ); +var resizing = false; +var previousMode = Settings.getValue(SETTINGS_KEY, -1); +Menu.addActionGroup(MENU, ACTIONS, ACTIONS[previousMode + 1]); +Render.deferredDebugMode = previousMode; +Render.deferredDebugSize = { x: 0.0, y: -1.0, z: 1.0, w: 1.0 }; // Reset to default size + +function setEngineDeferredDebugSize(eventX) { + var scaledX = (2.0 * (eventX / Window.innerWidth) - 1.0).clamp(-1.0, 1.0); + Render.deferredDebugSize = { x: scaledX, y: -1.0, z: 1.0, w: 1.0 }; +} +function shouldStartResizing(eventX) { + var x = Math.abs(eventX - Window.innerWidth * (1.0 + Render.deferredDebugSize.x) / 2.0); + var mode = Render.deferredDebugMode; + return mode !== -1 && x < 20; +} + +function menuItemEvent(menuItem) { + var index = ACTIONS.indexOf(menuItem); + if (index >= 0) { + Render.deferredDebugMode = (index - 1); + } +} // see libraries/render/src/render/Engine.h var showDisplayStatusFlag = 1; var showNetworkStatusFlag = 2; panel.newCheckbox("Display status", - function(value) { Scene.setEngineDisplayItemStatus(value ? - Scene.doEngineDisplayItemStatus() | showDisplayStatusFlag : - Scene.doEngineDisplayItemStatus() & ~showDisplayStatusFlag); }, - function() { return (Scene.doEngineDisplayItemStatus() & showDisplayStatusFlag) > 0; }, + function(value) { Render.displayItemStatus = (value ? + Render.displayItemStatus | showDisplayStatusFlag : + Render.displayItemStatus & ~showDisplayStatusFlag); }, + function() { return (Render.displayItemStatus & showDisplayStatusFlag) > 0; }, function(value) { return (value & showDisplayStatusFlag) > 0; } ); panel.newCheckbox("Network/Physics status", - function(value) { Scene.setEngineDisplayItemStatus(value ? - Scene.doEngineDisplayItemStatus() | showNetworkStatusFlag : - Scene.doEngineDisplayItemStatus() & ~showNetworkStatusFlag); }, - function() { return (Scene.doEngineDisplayItemStatus() & showNetworkStatusFlag) > 0; }, + function(value) { Render.displayItemStatus = (value ? + Render.displayItemStatus | showNetworkStatusFlag : + Render.displayItemStatus & ~showNetworkStatusFlag); }, + function() { return (Render.displayItemStatus & showNetworkStatusFlag) > 0; }, function(value) { return (value & showNetworkStatusFlag) > 0; } ); +panel.newSlider("Tone Mapping Exposure", -10, 10, + function (value) { Render.tone.exposure = value; }, + function() { return Render.tone.exposure; }, + function (value) { return (value); }); + var tickTackPeriod = 500; function updateCounters() { @@ -91,11 +129,47 @@ function updateCounters() { } 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 mouseMoveEvent(event) { + if (resizing) { + setEngineDeferredDebugSize(event.x); + } else { + panel.mouseMoveEvent(event); + } +} + +function mousePressEvent(event) { + if (shouldStartResizing(event.x)) { + resizing = true; + } else { + panel.mousePressEvent(event); + } +} + +function mouseReleaseEvent(event) { + if (resizing) { + resizing = false; + } else { + panel.mouseReleaseEvent(event); + } +} + +Controller.mouseMoveEvent.connect(mouseMoveEvent); +Controller.mousePressEvent.connect(mousePressEvent); +Controller.mouseReleaseEvent.connect(mouseReleaseEvent); + +Menu.menuItemEvent.connect(menuItemEvent); function scriptEnding() { panel.destroy(); + Menu.removeActionGroup(MENU); + Settings.setValue(SETTINGS_KEY, Render.deferredDebugMode); + Render.deferredDebugMode = -1; + Render.deferredDebugSize = { x: 0.0, y: -1.0, z: 1.0, w: 1.0 }; // Reset to default size } Script.scriptEnding.connect(scriptEnding); + + +// Collapse items +panel.mousePressEvent({ x: panel.x, y: panel.items["Overlays"].y}); +panel.mousePressEvent({ x: panel.x, y: panel.items["Transparents"].y}); +panel.mousePressEvent({ x: panel.x, y: panel.items["Opaques"].y}); diff --git a/interface/resources/qml/QmlWebWindow.qml b/interface/resources/qml/QmlWebWindow.qml index 3eb01aa9ba..6e9502edb2 100644 --- a/interface/resources/qml/QmlWebWindow.qml +++ b/interface/resources/qml/QmlWebWindow.qml @@ -13,12 +13,18 @@ VrDialog { HifiConstants { id: hifi } title: "WebWindow" resizable: true + // Don't destroy on close... otherwise the JS/C++ will have a dangling pointer + destroyOnCloseButton: false contentImplicitWidth: clientArea.implicitWidth contentImplicitHeight: clientArea.implicitHeight backgroundColor: "#7f000000" property url source: "about:blank" signal navigating(string url) + function stop() { + webview.stop(); + } + Component.onCompleted: { enabled = true @@ -26,18 +32,14 @@ VrDialog { webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { console.log("Web Window JS message: " + sourceID + " " + lineNumber + " " + message); }); - webview.loadingChanged.connect(handleWebviewLoading) } function handleWebviewLoading(loadRequest) { - var HIFI_URL_PATTERN = /^hifi:\/\//; if (WebEngineView.LoadStartedStatus == loadRequest.status) { var newUrl = loadRequest.url.toString(); - if (newUrl.match(HIFI_URL_PATTERN)) { - root.navigating(newUrl); - } + root.navigating(newUrl) } } @@ -54,9 +56,18 @@ VrDialog { id: webview url: root.source anchors.fill: parent - profile: WebEngineProfile { - httpUserAgent: "Mozilla/5.0 (HighFidelityInterface)" + onUrlChanged: { + var currentUrl = url.toString(); + var newUrl = urlFixer.fixupUrl(currentUrl); + if (newUrl != currentUrl) { + url = newUrl; + } } + profile: WebEngineProfile { + id: webviewProfile + httpUserAgent: "Mozilla/5.0 (HighFidelityInterface)" + storageName: "qmlWebEngine" + } } } // item } // dialog diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f4fe919780..e36ad051b9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -89,6 +89,7 @@ #include #include #include +#include #include #include #include @@ -342,6 +343,7 @@ bool setupEssentials(int& argc, char** argv) { #endif DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -747,9 +749,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _applicationStateDevice->addInputVariant(QString("ComfortMode"), controller::StateController::ReadLambda([]() -> float { return (float)Menu::getInstance()->isOptionChecked(MenuOption::ComfortMode); })); - _applicationStateDevice->addInputVariant(QString("Grounded"), controller::StateController::ReadLambda([]() -> float { - return (float)qApp->getMyAvatar()->getCharacterController()->onGround(); - })); + _applicationStateDevice->addInputVariant(QString("Grounded"), controller::StateController::ReadLambda([]() -> float { + return (float)qApp->getMyAvatar()->getCharacterController()->onGround(); + })); userInputMapper->registerDevice(_applicationStateDevice); @@ -1202,7 +1204,7 @@ void Application::paintGL() { if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { PerformanceTimer perfTimer("Mirror"); - auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); + auto primaryFbo = DependencyManager::get()->getPrimaryFramebuffer(); renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; renderRearViewMirror(&renderArgs, _mirrorViewRect); @@ -1458,7 +1460,9 @@ void Application::paintGL() { { PROFILE_RANGE(__FUNCTION__ "/compositor"); PerformanceTimer perfTimer("compositor"); + auto primaryFbo = finalFramebuffer; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFbo)); if (displayPlugin->isStereo()) { QRect currentViewport(QPoint(0, 0), QSize(size.width() / 2, size.height())); @@ -1483,7 +1487,9 @@ void Application::paintGL() { { PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); PerformanceTimer perfTimer("pluginOutput"); + auto finalTexturePointer = finalFramebuffer->getRenderBuffer(0); + GLuint finalTexture = gpu::GLBackend::getTextureID(finalTexturePointer); Q_ASSERT(0 != finalTexture); @@ -2611,7 +2617,7 @@ void Application::init() { _environment.init(); - DependencyManager::get()->init(this); + DependencyManager::get()->init(); DependencyManager::get()->init(); _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); @@ -3444,7 +3450,7 @@ QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { renderArgs->_renderMode = RenderArgs::DEFAULT_RENDER_MODE; renderRearViewMirror(renderArgs, QRect(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), true); - auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); + auto primaryFbo = DependencyManager::get()->getPrimaryFramebuffer(); QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32); renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image); @@ -3714,34 +3720,19 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // For now every frame pass the renderContext { PerformanceTimer perfTimer("EngineRun"); - render::RenderContext renderContext; - auto sceneInterface = DependencyManager::get(); - - renderContext._cullOpaque = sceneInterface->doEngineCullOpaque(); - renderContext._sortOpaque = sceneInterface->doEngineSortOpaque(); - renderContext._renderOpaque = sceneInterface->doEngineRenderOpaque(); - renderContext._cullTransparent = sceneInterface->doEngineCullTransparent(); - renderContext._sortTransparent = sceneInterface->doEngineSortTransparent(); - renderContext._renderTransparent = sceneInterface->doEngineRenderTransparent(); - - renderContext._maxDrawnOpaqueItems = sceneInterface->getEngineMaxDrawnOpaqueItems(); - renderContext._maxDrawnTransparentItems = sceneInterface->getEngineMaxDrawnTransparentItems(); - renderContext._maxDrawnOverlay3DItems = sceneInterface->getEngineMaxDrawnOverlay3DItems(); - - renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus(); - if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned)) { - renderContext._drawItemStatus |= render::showNetworkStatusFlag; - } - renderContext._drawHitEffect = sceneInterface->doEngineDisplayHitEffect(); - - renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion); - renderContext._fxaaStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing); + auto renderInterface = DependencyManager::get(); + auto renderContext = renderInterface->getRenderContext(); renderArgs->_shouldRender = LODManager::shouldRender; - - renderContext.args = renderArgs; renderArgs->_viewFrustum = getDisplayViewFrustum(); + renderContext.setArgs(renderArgs); + + bool occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion); + bool antialiasingStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing); + bool showOwnedStatus = Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned); + renderContext.setOptions(occlusionStatus, antialiasingStatus, showOwnedStatus); + _renderEngine->setRenderContext(renderContext); // Before the deferred pass, let's try to use the render engine @@ -3749,15 +3740,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se _renderEngine->run(); myAvatar->endRenderRun(); - auto engineRC = _renderEngine->getRenderContext(); - sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); - sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems); - - sceneInterface->setEngineFeedTransparentItems(engineRC->_numFeedTransparentItems); - sceneInterface->setEngineDrawnTransparentItems(engineRC->_numDrawnTransparentItems); - - sceneInterface->setEngineFeedOverlay3DItems(engineRC->_numFeedOverlay3DItems); - sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems); + auto engineContext = _renderEngine->getRenderContext(); + renderInterface->setItemCounts(engineContext->getItemsConfig()); } activeRenderingThread = nullptr; @@ -4212,11 +4196,12 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerFunction("HMD", "getHUDLookAtPosition3D", HMDScriptingInterface::getHUDLookAtPosition3D, 0); scriptEngine->registerGlobalObject("Scene", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("Render", DependencyManager::get().data()); scriptEngine->registerGlobalObject("ScriptDiscoveryService", this->getRunningScriptsWidget()); } -bool Application::canAcceptURL(const QString& urlString) { +bool Application::canAcceptURL(const QString& urlString) const { QUrl url(urlString); if (urlString.startsWith(HIFI_URL_SCHEME)) { return true; diff --git a/interface/src/Application.h b/interface/src/Application.h index a665e925a9..0953aedd8c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -38,6 +38,7 @@ #include #include #include +#include #include "avatar/AvatarUpdate.h" #include "avatar/MyAvatar.h" @@ -88,7 +89,7 @@ class Application; #endif #define qApp (static_cast(QCoreApplication::instance())) -class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface { +class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface, public AbstractUriHandler { Q_OBJECT // TODO? Get rid of those @@ -219,8 +220,8 @@ public: QString getScriptsLocation(); void setScriptsLocation(const QString& scriptsLocation); - bool canAcceptURL(const QString& url); - bool acceptURL(const QString& url, bool defaultUpload = false); + virtual bool canAcceptURL(const QString& url) const override; + virtual bool acceptURL(const QString& url, bool defaultUpload = false) override; void setMaxOctreePacketsPerSecond(int maxOctreePPS); int getMaxOctreePacketsPerSecond(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ae22869273..85af912892 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1085,6 +1085,26 @@ void Menu::setGroupingIsVisible(const QString& grouping, bool isVisible) { QMenuBar::repaint(); } +void Menu::addActionGroup(const QString& groupName, const QStringList& actionList, const QString& selected) { + auto menu = addMenu(groupName); + + QActionGroup* actionGroup = new QActionGroup(menu); + actionGroup->setExclusive(true); + + auto menuScriptingInterface = MenuScriptingInterface::getInstance(); + for (auto action : actionList) { + auto item = addCheckableActionToQMenuAndActionHash(menu, action, 0, action == selected, + menuScriptingInterface, + SLOT(menuItemTriggered())); + actionGroup->addAction(item); + } + + QMenuBar::repaint(); +} + +void Menu::removeActionGroup(const QString& groupName) { + removeMenu(groupName); +} MenuWrapper::MenuWrapper(QMenu* menu) : _realMenu(menu) { VrMenu::executeOrQueue([=](VrMenu* vrMenu) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 55266cf062..4b77e96f79 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -105,6 +105,8 @@ public slots: void addMenuItem(const MenuItemProperties& properties); void removeMenuItem(const QString& menuName, const QString& menuitem); bool menuItemExists(const QString& menuName, const QString& menuitem); + void addActionGroup(const QString& groupName, const QStringList& actionList, const QString& selected = QString()); + void removeActionGroup(const QString& groupName); bool isOptionChecked(const QString& menuOption) const; void setIsOptionChecked(const QString& menuOption, bool isChecked); diff --git a/interface/src/scripting/MenuScriptingInterface.cpp b/interface/src/scripting/MenuScriptingInterface.cpp index ff7784b9ae..087d391daa 100644 --- a/interface/src/scripting/MenuScriptingInterface.cpp +++ b/interface/src/scripting/MenuScriptingInterface.cpp @@ -84,6 +84,19 @@ bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString& return result; } +void MenuScriptingInterface::addActionGroup(const QString& groupName, const QStringList& actionList, + const QString& selected) { + QMetaObject::invokeMethod(Menu::getInstance(), "addActionGroup", + Q_ARG(const QString&, groupName), + Q_ARG(const QStringList&, actionList), + Q_ARG(const QString&, selected)); +} + +void MenuScriptingInterface::removeActionGroup(const QString& groupName) { + QMetaObject::invokeMethod(Menu::getInstance(), "removeActionGroup", + Q_ARG(const QString&, groupName)); +} + bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) { bool result; QMetaObject::invokeMethod(Menu::getInstance(), "isOptionChecked", Qt::BlockingQueuedConnection, diff --git a/interface/src/scripting/MenuScriptingInterface.h b/interface/src/scripting/MenuScriptingInterface.h index 5c01318a38..51399c2fa5 100644 --- a/interface/src/scripting/MenuScriptingInterface.h +++ b/interface/src/scripting/MenuScriptingInterface.h @@ -42,6 +42,10 @@ public slots: void removeMenuItem(const QString& menuName, const QString& menuitem); bool menuItemExists(const QString& menuName, const QString& menuitem); + void addActionGroup(const QString& groupName, const QStringList& actionList, + const QString& selected = QString()); + void removeActionGroup(const QString& groupName); + bool isOptionChecked(const QString& menuOption); void setIsOptionChecked(const QString& menuOption, bool isChecked); diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index a0d78da7f8..1f15007339 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -289,7 +289,6 @@ uint64_t AudioInjector::injectNextFrame() { _currentSendOffset = 0; } else { // we weren't to loop, say that we're done now - qDebug() << "AudioInjector::injectNextFrame has sent all data and was not asked to loop - calling finish()."; finish(); return NEXT_FRAME_DELTA_ERROR_OR_FINISHED; } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index e3618d0e2a..996a8f3e1d 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -256,33 +256,38 @@ void EntityTreeRenderer::forceRecheckEntities() { void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr zone) { QSharedPointer scene = DependencyManager::get(); + auto sceneStage = scene->getStage(); + auto sceneKeyLight = sceneStage->getKeyLight(); + auto sceneLocation = sceneStage->getLocation(); + auto sceneTime = sceneStage->getTime(); + if (zone) { if (!_hasPreviousZone) { - _previousKeyLightColor = scene->getKeyLightColor(); - _previousKeyLightIntensity = scene->getKeyLightIntensity(); - _previousKeyLightAmbientIntensity = scene->getKeyLightAmbientIntensity(); - _previousKeyLightDirection = scene->getKeyLightDirection(); - _previousStageSunModelEnabled = scene->isStageSunModelEnabled(); - _previousStageLongitude = scene->getStageLocationLongitude(); - _previousStageLatitude = scene->getStageLocationLatitude(); - _previousStageAltitude = scene->getStageLocationAltitude(); - _previousStageHour = scene->getStageDayTime(); - _previousStageDay = scene->getStageYearTime(); + _previousKeyLightColor = sceneKeyLight->getColor(); + _previousKeyLightIntensity = sceneKeyLight->getIntensity(); + _previousKeyLightAmbientIntensity = sceneKeyLight->getAmbientIntensity(); + _previousKeyLightDirection = sceneKeyLight->getDirection(); + _previousStageSunModelEnabled = sceneStage->isSunModelEnabled(); + _previousStageLongitude = sceneLocation->getLongitude(); + _previousStageLatitude = sceneLocation->getLatitude(); + _previousStageAltitude = sceneLocation->getAltitude(); + _previousStageHour = sceneTime->getHour(); + _previousStageDay = sceneTime->getDay(); _hasPreviousZone = true; } - scene->setKeyLightColor(ColorUtils::toVec3(zone->getKeyLightProperties().getColor())); - scene->setKeyLightIntensity(zone->getKeyLightProperties().getIntensity()); - scene->setKeyLightAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity()); - scene->setKeyLightDirection(zone->getKeyLightProperties().getDirection()); - scene->setStageSunModelEnable(zone->getStageProperties().getSunModelEnabled()); - scene->setStageLocation(zone->getStageProperties().getLongitude(), zone->getStageProperties().getLatitude(), + sceneKeyLight->setColor(ColorUtils::toVec3(zone->getKeyLightProperties().getColor())); + sceneKeyLight->setIntensity(zone->getKeyLightProperties().getIntensity()); + sceneKeyLight->setAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity()); + sceneKeyLight->setDirection(zone->getKeyLightProperties().getDirection()); + sceneStage->setSunModelEnable(zone->getStageProperties().getSunModelEnabled()); + sceneStage->setLocation(zone->getStageProperties().getLongitude(), zone->getStageProperties().getLatitude(), zone->getStageProperties().getAltitude()); - scene->setStageDayTime(zone->getStageProperties().calculateHour()); - scene->setStageYearTime(zone->getStageProperties().calculateDay()); + sceneTime->setHour(zone->getStageProperties().calculateHour()); + sceneTime->setDay(zone->getStageProperties().calculateDay()); if (zone->getBackgroundMode() == BACKGROUND_MODE_ATMOSPHERE) { EnvironmentData data = zone->getEnvironmentData(); - glm::vec3 keyLightDirection = scene->getKeyLightDirection(); + glm::vec3 keyLightDirection = sceneKeyLight->getDirection(); glm::vec3 inverseKeyLightDirection = keyLightDirection * -1.0f; // NOTE: is this right? It seems like the "sun" should be based on the center of the @@ -293,7 +298,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetKeyLightIntensity() * KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO; + float sunBrightness = sceneKeyLight->getIntensity() * KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO; data.setSunBrightness(sunBrightness); _viewState->overrideEnvironmentData(data); @@ -339,15 +344,15 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrsetKeyLightColor(_previousKeyLightColor); - scene->setKeyLightIntensity(_previousKeyLightIntensity); - scene->setKeyLightAmbientIntensity(_previousKeyLightAmbientIntensity); - scene->setKeyLightDirection(_previousKeyLightDirection); - scene->setStageSunModelEnable(_previousStageSunModelEnabled); - scene->setStageLocation(_previousStageLongitude, _previousStageLatitude, + sceneKeyLight->setColor(_previousKeyLightColor); + sceneKeyLight->setIntensity(_previousKeyLightIntensity); + sceneKeyLight->setAmbientIntensity(_previousKeyLightAmbientIntensity); + sceneKeyLight->setDirection(_previousKeyLightDirection); + sceneStage->setSunModelEnable(_previousStageSunModelEnabled); + sceneStage->setLocation(_previousStageLongitude, _previousStageLatitude, _previousStageAltitude); - scene->setStageDayTime(_previousStageHour); - scene->setStageYearTime(_previousStageDay); + sceneTime->setHour(_previousStageHour); + sceneTime->setDay(_previousStageDay); _hasPreviousZone = false; } _viewState->endOverrideEnvironmentData(); diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 4abd8dbafd..379d1cc4a3 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -223,10 +223,10 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { particleUniforms.radius.middle = getParticleRadius(); particleUniforms.radius.finish = getRadiusFinish(); particleUniforms.radius.spread = getRadiusSpread(); - particleUniforms.color.start = toGlm(getColorStart(), getAlphaStart()); - particleUniforms.color.middle = toGlm(getXColor(), getAlpha()); - particleUniforms.color.finish = toGlm(getColorFinish(), getAlphaFinish()); - particleUniforms.color.spread = toGlm(getColorSpread(), getAlphaSpread()); + particleUniforms.color.start = glm::vec4(getColorStartRGB(), getAlphaStart()); + particleUniforms.color.middle = glm::vec4(getColorRGB(), getAlpha()); + particleUniforms.color.finish = glm::vec4(getColorFinishRGB(), getAlphaFinish()); + particleUniforms.color.spread = glm::vec4(getColorSpreadRGB(), getAlphaSpread()); particleUniforms.lifespan = getLifespan(); // Build particle primitives diff --git a/libraries/entities-renderer/src/paintStroke.slv b/libraries/entities-renderer/src/paintStroke.slv index 7d7523deb9..c7dd112bcc 100644 --- a/libraries/entities-renderer/src/paintStroke.slv +++ b/libraries/entities-renderer/src/paintStroke.slv @@ -13,8 +13,8 @@ // <@include gpu/Inputs.slh@> +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> // the interpolated normal @@ -30,7 +30,7 @@ void main(void) { varTexcoord = inTexCoord0.st; // pass along the diffuse color - varColor = inColor; + varColor = colorToLinearRGBA(inColor); // standard transform TransformCamera cam = getTransformCamera(); diff --git a/libraries/entities-renderer/src/untextured_particle.slv b/libraries/entities-renderer/src/untextured_particle.slv index 3d1d99c0dc..ab0ea15219 100644 --- a/libraries/entities-renderer/src/untextured_particle.slv +++ b/libraries/entities-renderer/src/untextured_particle.slv @@ -9,16 +9,15 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> out vec4 _color; void main(void) { // pass along the diffuse color - _color = inColor; + _color = colorToLinearRGBA(inColor); TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index c35a45baeb..cae9340b6d 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -15,6 +15,8 @@ #include "EntityItem.h" +#include "ColorUtils.h" + class ParticleEffectEntityItem : public EntityItem { public: ALLOW_INSTANTIATION // This class can be instantiated @@ -47,6 +49,7 @@ public: const rgbColor& getColor() const { return _color; } xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } + glm::vec3 getColorRGB() const { return ColorUtils::toLinearVec3(toGlm(getXColor())); } static const xColor DEFAULT_COLOR; void setColor(const rgbColor& value) { memcpy(_color, value, sizeof(_color)); } @@ -59,14 +62,17 @@ public: bool _isColorStartInitialized = false; void setColorStart(const xColor& colorStart) { _colorStart = colorStart; _isColorStartInitialized = true; } xColor getColorStart() const { return _isColorStartInitialized ? _colorStart : getXColor(); } + glm::vec3 getColorStartRGB() const { return _isColorStartInitialized ? ColorUtils::toLinearVec3(toGlm(_colorStart)) : getColorRGB(); } bool _isColorFinishInitialized = false; void setColorFinish(const xColor& colorFinish) { _colorFinish = colorFinish; _isColorFinishInitialized = true; } xColor getColorFinish() const { return _isColorFinishInitialized ? _colorFinish : getXColor(); } + glm::vec3 getColorFinishRGB() const { return _isColorStartInitialized ? ColorUtils::toLinearVec3(toGlm(_colorFinish)) : getColorRGB(); } static const xColor DEFAULT_COLOR_SPREAD; void setColorSpread(const xColor& colorSpread) { _colorSpread = colorSpread; } xColor getColorSpread() const { return _colorSpread; } + glm::vec3 getColorSpreadRGB() const { return ColorUtils::toLinearVec3(toGlm(_colorSpread)); } static const float MAXIMUM_ALPHA; static const float MINIMUM_ALPHA; diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 14871aafd1..f9c4131a1b 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -311,6 +311,12 @@ void Batch::blit(const FramebufferPointer& src, const Vec4i& srcViewport, _params.push_back(dstViewport.w); } +void Batch::generateTextureMips(const TexturePointer& texture) { + ADD_COMMAND(generateTextureMips); + + _params.push_back(_textures.cache(texture)); +} + void Batch::beginQuery(const QueryPointer& query) { ADD_COMMAND(beginQuery); diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 2afcc7caa9..88d28f9d10 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -211,6 +211,9 @@ public: // with xy and zw the bounding corners of the rect region. void blit(const FramebufferPointer& src, const Vec4i& srcRect, const FramebufferPointer& dst, const Vec4i& dstRect); + // Generate the mips for a texture + void generateTextureMips(const TexturePointer& texture); + // Query Section void beginQuery(const QueryPointer& query); void endQuery(const QueryPointer& query); @@ -292,6 +295,7 @@ public: COMMAND_setFramebuffer, COMMAND_clearFramebuffer, COMMAND_blit, + COMMAND_generateTextureMips, COMMAND_beginQuery, COMMAND_endQuery, diff --git a/libraries/gpu/src/gpu/Color.slh b/libraries/gpu/src/gpu/Color.slh new file mode 100644 index 0000000000..f633e6e2d4 --- /dev/null +++ b/libraries/gpu/src/gpu/Color.slh @@ -0,0 +1,52 @@ + +<@if not GPU_COLOR_SLH@> +<@def GPU_COLOR_SLH@> + 0.04045 + // constants: + // T = 0.04045 + // A = 1 / 1.055 = 0.94786729857 + // B = 0.055 * A = 0.05213270142 + // C = 1 / 12.92 = 0.0773993808 + // G = 2.4 + const float T = 0.04045; + const float A = 0.947867; + const float B = 0.052132; + const float C = 0.077399; + const float G = 2.4; + + if (cs > T) { + return pow((cs * A + B), G); + } else { + return cs * C; + } +} + +vec3 colorToLinear(vec3 srgb) { + return vec3(colorComponentToLinear(srgb.x), colorComponentToLinear(srgb.y), colorComponentToLinear(srgb.z)); +} +!> + +vec3 colorToLinearRGB(vec3 srgb) { + const float GAMMA_22 = 2.2; + return pow(srgb, vec3(GAMMA_22)); +} + +vec4 colorToLinearRGBA(vec4 srgba) { + return vec4(colorToLinearRGB(srgba.xyz), srgba.w); +} + +<@endif@> \ No newline at end of file diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 3022f47b51..41a95e2578 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -160,6 +160,7 @@ enum Semantic { RGB, RGBA, BGRA, + XY, XYZ, XYZW, @@ -176,6 +177,8 @@ enum Semantic { SRGBA, SBGRA, + R11G11B10, + UNIFORM, UNIFORM_BUFFER, SAMPLER, diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index d4f3c5c4b3..a730c06bd9 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -52,6 +52,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_setFramebuffer), (&::gpu::GLBackend::do_clearFramebuffer), (&::gpu::GLBackend::do_blit), + (&::gpu::GLBackend::do_generateTextureMips), (&::gpu::GLBackend::do_beginQuery), (&::gpu::GLBackend::do_endQuery), diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index f44fbe6c0d..400c9f08f8 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -376,12 +376,16 @@ protected: // Resource Stage void do_setResourceTexture(Batch& batch, size_t paramOffset); - + + // update resource cache and do the gl unbind call with the current gpu::Texture cached at slot s void releaseResourceTexture(uint32_t slot); + void resetResourceStage(); struct ResourceStageState { Textures _textures; + int findEmptyTextureSlot() const; + ResourceStageState(): _textures(MAX_NUM_RESOURCE_TEXTURES, nullptr) {} @@ -432,6 +436,7 @@ protected: void do_setFramebuffer(Batch& batch, size_t paramOffset); void do_clearFramebuffer(Batch& batch, size_t paramOffset); void do_blit(Batch& batch, size_t paramOffset); + void do_generateTextureMips(Batch& batch, size_t paramOffset); // Synchronize the state cache of this Backend with the actual real state of the GL Context void syncOutputStateCache(); diff --git a/libraries/gpu/src/gpu/GLBackendOutput.cpp b/libraries/gpu/src/gpu/GLBackendOutput.cpp index 6d8ce7b2c6..5f226141a8 100755 --- a/libraries/gpu/src/gpu/GLBackendOutput.cpp +++ b/libraries/gpu/src/gpu/GLBackendOutput.cpp @@ -361,4 +361,4 @@ void GLBackend::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, co glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); (void) CHECK_GL_ERROR(); -} \ No newline at end of file +} diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index 8601c7512b..8c9647e0f2 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -231,6 +231,7 @@ void GLBackend::releaseResourceTexture(uint32_t slot) { } } + void GLBackend::resetResourceStage() { for (uint32_t i = 0; i < _resource._textures.size(); i++) { releaseResourceTexture(i); @@ -268,3 +269,13 @@ void GLBackend::do_setResourceTexture(Batch& batch, size_t paramOffset) { } } +int GLBackend::ResourceStageState::findEmptyTextureSlot() const { + // start from the end of the slots, try to find an empty one that can be used + for (auto i = MAX_NUM_RESOURCE_TEXTURES - 1; i > 0; i--) { + if (!_textures[i]) { + return i; + } + } + return -1; +} + diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 65f2e5ca8a..17802ae6ed 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -224,6 +224,11 @@ public: case gpu::SRGBA: texel.internalFormat = GL_SRGB; // standard 2.2 gamma correction color break; + case gpu::R11G11B10: { + // the type should be float + texel.internalFormat = GL_R11F_G11F_B10F; + break; + } default: qCDebug(gpulogging) << "Unknown combination of texel format"; } @@ -240,6 +245,59 @@ public: break; case gpu::RGBA: texel.internalFormat = GL_RGBA; + switch (dstFormat.getType()) { + case gpu::UINT32: + texel.format = GL_RGBA_INTEGER; + texel.internalFormat = GL_RGBA32UI; + break; + case gpu::INT32: + texel.format = GL_RGBA_INTEGER; + texel.internalFormat = GL_RGBA32I; + break; + case gpu::FLOAT: + texel.internalFormat = GL_RGBA32F; + break; + case gpu::UINT16: + texel.format = GL_RGBA_INTEGER; + texel.internalFormat = GL_RGBA16UI; + break; + case gpu::INT16: + texel.format = GL_RGBA_INTEGER; + texel.internalFormat = GL_RGBA16I; + break; + case gpu::NUINT16: + texel.format = GL_RGBA; + texel.internalFormat = GL_RGBA16; + break; + case gpu::NINT16: + texel.format = GL_RGBA; + texel.internalFormat = GL_RGBA16_SNORM; + break; + case gpu::HALF: + texel.format = GL_RGBA; + texel.internalFormat = GL_RGBA16F; + break; + case gpu::UINT8: + texel.format = GL_RGBA_INTEGER; + texel.internalFormat = GL_RGBA8UI; + break; + case gpu::INT8: + texel.format = GL_RGBA_INTEGER; + texel.internalFormat = GL_RGBA8I; + break; + case gpu::NUINT8: + texel.format = GL_RGBA; + texel.internalFormat = GL_RGBA8; + break; + case gpu::NINT8: + texel.format = GL_RGBA; + texel.internalFormat = GL_RGBA8_SNORM; + break; + case gpu::NUINT32: + case gpu::NINT32: + case gpu::NUM_TYPES: // quiet compiler + Q_UNREACHABLE(); + } break; case gpu::SRGB: texel.internalFormat = GL_SRGB; @@ -347,7 +405,6 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } - object->_target = GL_TEXTURE_2D; syncSampler(texture.getSampler(), texture.getType(), object); @@ -530,3 +587,37 @@ void GLBackend::syncSampler(const Sampler& sampler, Texture::Type type, GLTextur glTexParameterf(object->_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy()); } + + + +void GLBackend::do_generateTextureMips(Batch& batch, size_t paramOffset) { + TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint); + if (!resourceTexture) { + return; + } + + GLTexture* object = GLBackend::syncGPUObject(*resourceTexture); + if (!object) { + return; + } + + // IN 4.1 we still need to find an available slot + auto freeSlot = _resource.findEmptyTextureSlot(); + auto bindingSlot = (freeSlot < 0 ? 0 : freeSlot); + glActiveTexture(GL_TEXTURE0 + bindingSlot); + glBindTexture(object->_target, object->_texture); + + glGenerateMipmap(object->_target); + + if (freeSlot < 0) { + // If had to use slot 0 then restore state + GLTexture* boundObject = GLBackend::syncGPUObject(*_resource._textures[0]); + if (boundObject) { + glBindTexture(boundObject->_target, boundObject->_texture); + } + } else { + // clean up + glBindTexture(object->_target, 0); + } + (void)CHECK_GL_ERROR(); +} diff --git a/libraries/gpu/src/gpu/Shader.cpp b/libraries/gpu/src/gpu/Shader.cpp index ddb3a0d755..74b7734618 100755 --- a/libraries/gpu/src/gpu/Shader.cpp +++ b/libraries/gpu/src/gpu/Shader.cpp @@ -23,7 +23,7 @@ Shader::Shader(Type type, const Source& source): { } -Shader::Shader(Type type, Pointer& vertex, Pointer& pixel): +Shader::Shader(Type type, const Pointer& vertex, const Pointer& pixel): _type(type) { _shaders.resize(2); @@ -44,7 +44,7 @@ Shader::Pointer Shader::createPixel(const Source& source) { return Pointer(new Shader(PIXEL, source)); } -Shader::Pointer Shader::createProgram(Pointer& vertexShader, Pointer& pixelShader) { +Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) { if (vertexShader && vertexShader->getType() == VERTEX && pixelShader && pixelShader->getType() == PIXEL) { return Pointer(new Shader(PROGRAM, vertexShader, pixelShader)); diff --git a/libraries/gpu/src/gpu/Shader.h b/libraries/gpu/src/gpu/Shader.h index bceb00c71e..b737a42e12 100755 --- a/libraries/gpu/src/gpu/Shader.h +++ b/libraries/gpu/src/gpu/Shader.h @@ -111,7 +111,7 @@ public: static Pointer createVertex(const Source& source); static Pointer createPixel(const Source& source); - static Pointer createProgram(Pointer& vertexShader, Pointer& pixelShader); + static Pointer createProgram(const Pointer& vertexShader, const Pointer& pixelShader); ~Shader(); @@ -157,7 +157,7 @@ public: protected: Shader(Type type, const Source& source); - Shader(Type type, Pointer& vertex, Pointer& pixel); + Shader(Type type, const Pointer& vertex, const Pointer& pixel); Shader(const Shader& shader); // deep copy of the sysmem shader Shader& operator=(const Shader& shader); // deep copy of the sysmem texture diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index c3e2809c4b..6e8eb10380 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -407,7 +407,7 @@ public: TexturePointer _texture = TexturePointer(NULL); uint16 _subresource = 0; - Element _element = Element(gpu::VEC4, gpu::UINT8, gpu::RGBA); + Element _element = Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); TextureView() {}; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index e1aeb92e41..4fd47affc2 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -308,10 +308,9 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const material._material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap); } if (!material.emissiveTexture.filename.isEmpty()) { - networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), EMISSIVE_TEXTURE, material.emissiveTexture.content); + networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), LIGHTMAP_TEXTURE, material.emissiveTexture.content); networkMaterial->emissiveTextureName = material.emissiveTexture.name; - //checkForTexcoordLightmap = true; auto lightmapMap = model::TextureMapPointer(new model::TextureMap()); lightmapMap->setTextureSource(networkMaterial->emissiveTexture->_textureSource); diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 3e80b6c7aa..ae705faf86 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -85,7 +85,7 @@ const gpu::TexturePointer& TextureCache::getPermutationNormalTexture() { data[i + 2] = ((randvec.z + 1.0f) / 2.0f) * 255.0f; } - _permutationNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB), 256, 2)); + _permutationNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB), 256, 2)); _permutationNormalTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(data), data); } return _permutationNormalTexture; @@ -98,7 +98,7 @@ const unsigned char OPAQUE_BLACK[] = { 0x00, 0x00, 0x00, 0xFF }; const gpu::TexturePointer& TextureCache::getWhiteTexture() { if (!_whiteTexture) { - _whiteTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1)); + _whiteTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1)); _whiteTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_WHITE); } return _whiteTexture; @@ -106,7 +106,7 @@ const gpu::TexturePointer& TextureCache::getWhiteTexture() { const gpu::TexturePointer& TextureCache::getGrayTexture() { if (!_grayTexture) { - _grayTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1)); + _grayTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1)); _grayTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_GRAY); } return _grayTexture; @@ -114,7 +114,7 @@ const gpu::TexturePointer& TextureCache::getGrayTexture() { const gpu::TexturePointer& TextureCache::getBlueTexture() { if (!_blueTexture) { - _blueTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1)); + _blueTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1)); _blueTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(OPAQUE_BLUE), OPAQUE_BLUE); } return _blueTexture; @@ -122,7 +122,7 @@ const gpu::TexturePointer& TextureCache::getBlueTexture() { const gpu::TexturePointer& TextureCache::getBlackTexture() { if (!_blackTexture) { - _blackTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1)); + _blackTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1)); _blackTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_BLACK), OPAQUE_BLACK); } return _blackTexture; @@ -151,11 +151,11 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type /// Returns a texture version of an image file gpu::TexturePointer TextureCache::getImageTexture(const QString& path) { QImage image = QImage(path).mirrored(false, true); - gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB); - gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB); + gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); + gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); if (image.hasAlphaChannel()) { - formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA); - formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::BGRA); + formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); + formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::BGRA); } gpu::TexturePointer texture = gpu::TexturePointer( gpu::Texture::create2D(formatGPU, image.width(), image.height(), diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index cc22509631..4171b6c1cb 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -29,7 +29,7 @@ class NetworkTexture; typedef QSharedPointer NetworkTexturePointer; -enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, BUMP_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, CUBE_TEXTURE, CUSTOM_TEXTURE }; +enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, BUMP_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, CUBE_TEXTURE, LIGHTMAP_TEXTURE, CUSTOM_TEXTURE }; /// Stores cached textures, including render-to-texture targets. class TextureCache : public ResourceCache, public Dependency { diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index c2ff828af3..1d0f6ee5d9 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -44,9 +44,9 @@ Material& Material::operator= (const Material& material) { Material::~Material() { } -void Material::setDiffuse(const Color& diffuse) { +void Material::setDiffuse(const Color& diffuse, bool isSRGB) { _key.setDiffuse(glm::any(glm::greaterThan(diffuse, Color(0.0f)))); - _schemaBuffer.edit()._diffuse = diffuse; + _schemaBuffer.edit()._diffuse = (isSRGB ? ColorUtils::toLinearVec3(diffuse) : diffuse); } void Material::setMetallic(float metallic) { @@ -54,9 +54,9 @@ void Material::setMetallic(float metallic) { _schemaBuffer.edit()._metallic = glm::vec3(metallic); } -void Material::setEmissive(const Color& emissive) { +void Material::setEmissive(const Color& emissive, bool isSRGB) { _key.setEmissive(glm::any(glm::greaterThan(emissive, Color(0.0f)))); - _schemaBuffer.edit()._emissive = emissive; + _schemaBuffer.edit()._emissive = (isSRGB ? ColorUtils::toLinearVec3(emissive) : emissive); } void Material::setGloss(float gloss) { diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index b0725d9908..cb5a285dba 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -14,7 +14,7 @@ #include #include -#include +#include #include @@ -219,28 +219,31 @@ public: virtual ~Material(); const MaterialKey& getKey() const { return _key; } - - const Color& getEmissive() const { return _schemaBuffer.get()._emissive; } - const Color& getDiffuse() const { return _schemaBuffer.get()._diffuse; } - float getMetallic() const { return _schemaBuffer.get()._metallic.x; } - float getGloss() const { return _schemaBuffer.get()._gloss; } - float getOpacity() const { return _schemaBuffer.get()._opacity; } - void setEmissive(const Color& emissive); - void setDiffuse(const Color& diffuse); + void setEmissive(const Color& emissive, bool isSRGB = true); + Color getEmissive(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get()._emissive) : _schemaBuffer.get()._emissive); } + + void setDiffuse(const Color& diffuse, bool isSRGB = true); + Color getDiffuse(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get()._diffuse) : _schemaBuffer.get()._diffuse); } + void setMetallic(float metallic); + float getMetallic() const { return _schemaBuffer.get()._metallic.x; } + void setGloss(float gloss); + float getGloss() const { return _schemaBuffer.get()._gloss; } + void setOpacity(float opacity); + float getOpacity() const { return _schemaBuffer.get()._opacity; } // Schema to access the attribute values of the material class Schema { public: - Color _diffuse{0.5f}; + glm::vec3 _diffuse{ 0.5f }; float _opacity{1.f}; - Color _metallic{0.03f}; + glm::vec3 _metallic{ 0.03f }; float _gloss{0.1f}; - Color _emissive{0.0f}; + glm::vec3 _emissive{ 0.0f }; float _spare0{0.0f}; glm::vec4 _spareVec4{0.0f}; // for alignment beauty, Material size == Mat4x4 diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index 6246bbd9d3..f8a568bcf9 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -52,8 +52,7 @@ void main(void) { } } - vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction - _fragColor = vec4(pixel, 0.0); + _fragColor = vec4(color, 0.0); #endif diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 67f0262b61..47d3ba3063 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -225,6 +225,21 @@ void SunSkyStage::setOriginOrientation(const Quat& orientation) { invalidate(); } +void SunSkyStage::setOriginLongitude(float longitude) { + _earthSunModel.setLongitude(longitude); + invalidate(); +} + +void SunSkyStage::setOriginLatitude(float latitude) { + _earthSunModel.setLatitude(latitude); + invalidate(); +} + +void SunSkyStage::setOriginSurfaceAltitude(float altitude) { + _earthSunModel.setAltitude(altitude); + invalidate(); +} + void SunSkyStage::setOriginLocation(float longitude, float latitude, float altitude) { _earthSunModel.setLongitude(longitude); _earthSunModel.setLatitude(latitude); diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index 978c308ac6..bf586b6b55 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -184,6 +184,9 @@ public: const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } // Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km] + void setOriginLatitude(float latitude); + void setOriginLongitude(float longitude); + void setOriginSurfaceAltitude(float surfaceAltitude); void setOriginLocation(float longitude, float latitude, float surfaceAltitude); float getOriginLatitude() const { return _earthSunModel.getLatitude(); } float getOriginLongitude() const { return _earthSunModel.getLongitude(); } diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index d443522a6f..a86c7cdbec 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -119,13 +119,13 @@ gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, con if ((image.width() > 0) && (image.height() > 0)) { // bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); - bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); + bool isLinearRGB = false; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); - gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); - gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); if (image.hasAlphaChannel()) { - formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); - formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); + formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); + formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); } @@ -156,11 +156,11 @@ gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& src bool isLinearRGB = true; - gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); - gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); if (image.hasAlphaChannel()) { - formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); - formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); + formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); + formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); } theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); @@ -246,11 +246,11 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm // bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); - gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); - gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); if (image.hasAlphaChannel()) { - formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); - formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); + formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); + formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); } @@ -368,11 +368,11 @@ gpu::Texture* TextureUsage::createCubeTextureFromImage(const QImage& srcImage, c // bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); bool isLinearRGB = false; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); - gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); - gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); if (image.hasAlphaChannel()) { - formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); - formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); + formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); + formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); } @@ -520,3 +520,89 @@ gpu::Texture* TextureUsage::createCubeTextureFromImage(const QImage& srcImage, c return theTexture; } + + +gpu::Texture* TextureUsage::createLightmapTextureFromImage(const QImage& srcImage, const std::string& srcImageName) { + QImage image = srcImage; + + int imageArea = image.width() * image.height(); + + int opaquePixels = 0; + int translucentPixels = 0; + //bool isTransparent = false; + int redTotal = 0, greenTotal = 0, blueTotal = 0, alphaTotal = 0; + const int EIGHT_BIT_MAXIMUM = 255; + QColor averageColor(EIGHT_BIT_MAXIMUM, EIGHT_BIT_MAXIMUM, EIGHT_BIT_MAXIMUM); + + if (!image.hasAlphaChannel()) { + if (image.format() != QImage::Format_RGB888) { + image = image.convertToFormat(QImage::Format_RGB888); + } + // int redTotal = 0, greenTotal = 0, blueTotal = 0; + for (int y = 0; y < image.height(); y++) { + for (int x = 0; x < image.width(); x++) { + QRgb rgb = image.pixel(x, y); + redTotal += qRed(rgb); + greenTotal += qGreen(rgb); + blueTotal += qBlue(rgb); + } + } + if (imageArea > 0) { + averageColor.setRgb(redTotal / imageArea, greenTotal / imageArea, blueTotal / imageArea); + } + } else { + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + + // check for translucency/false transparency + // int opaquePixels = 0; + // int translucentPixels = 0; + // int redTotal = 0, greenTotal = 0, blueTotal = 0, alphaTotal = 0; + for (int y = 0; y < image.height(); y++) { + for (int x = 0; x < image.width(); x++) { + QRgb rgb = image.pixel(x, y); + redTotal += qRed(rgb); + greenTotal += qGreen(rgb); + blueTotal += qBlue(rgb); + int alpha = qAlpha(rgb); + alphaTotal += alpha; + if (alpha == EIGHT_BIT_MAXIMUM) { + opaquePixels++; + } else if (alpha != 0) { + translucentPixels++; + } + } + } + if (opaquePixels == imageArea) { + qCDebug(modelLog) << "Image with alpha channel is completely opaque:" << QString(srcImageName.c_str()); + image = image.convertToFormat(QImage::Format_RGB888); + } + + averageColor = QColor(redTotal / imageArea, + greenTotal / imageArea, blueTotal / imageArea, alphaTotal / imageArea); + + //isTransparent = (translucentPixels >= imageArea / 2); + } + + gpu::Texture* theTexture = nullptr; + if ((image.width() > 0) && (image.height() > 0)) { + + // bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); + bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); + + gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); + if (image.hasAlphaChannel()) { + formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); + formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); + } + + + theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); + theTexture->autoGenerateMips(-1); + } + + return theTexture; +} diff --git a/libraries/model/src/model/TextureMap.h b/libraries/model/src/model/TextureMap.h index 107ca2e879..6bc5b8228c 100755 --- a/libraries/model/src/model/TextureMap.h +++ b/libraries/model/src/model/TextureMap.h @@ -35,6 +35,8 @@ public: static gpu::Texture* createNormalTextureFromNormalImage(const QImage& image, const std::string& srcImageName); static gpu::Texture* createNormalTextureFromBumpImage(const QImage& image, const std::string& srcImageName); static gpu::Texture* createCubeTextureFromImage(const QImage& image, const std::string& srcImageName); + static gpu::Texture* createLightmapTextureFromImage(const QImage& image, const std::string& srcImageName); + }; diff --git a/libraries/networking/src/AbstractUriHandler.h b/libraries/networking/src/AbstractUriHandler.h new file mode 100644 index 0000000000..3d6ed472ec --- /dev/null +++ b/libraries/networking/src/AbstractUriHandler.h @@ -0,0 +1,19 @@ +// +// Created by Bradley Austin Davis on 2015/12/17 +// Copyright 2013-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 +// + +#pragma once +#ifndef hifi_network_AbstractUriHandler_h +#define hifi_network_AbstractUriHandler_h + +class AbstractUriHandler { +public: + virtual bool canAcceptURL(const QString& url) const = 0; + virtual bool acceptURL(const QString& url, bool defaultUpload = false) = 0; +}; + +#endif diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index e591ee8a31..5075d78597 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -94,7 +94,7 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned _keepAlivePingTimer.setInterval(KEEPALIVE_PING_INTERVAL_MS); connect(&_keepAlivePingTimer, &QTimer::timeout, this, &NodeList::sendKeepAlivePings); connect(&_domainHandler, SIGNAL(connectedToDomain(QString)), &_keepAlivePingTimer, SLOT(start())); - connect(&_domainHandler, &DomainHandler::disconnectedFromDomain, this, &NodeList::stopKeepalivePingTimer); + connect(&_domainHandler, &DomainHandler::disconnectedFromDomain, &_keepAlivePingTimer, &QTimer::stop); // we definitely want STUN to update our public socket, so call the LNL to kick that off startSTUNPublicSocketUpdate(); diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 9aeddbc99c..2f5ab7a015 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -122,8 +122,10 @@ void ThreadedAssignment::startSendingStats() { } void ThreadedAssignment::stopSendingStats() { - // stop sending stats, we just disconnected from domain - _statsTimer->stop(); + if (_statsTimer) { + // stop sending stats, we just disconnected from domain + _statsTimer->stop(); + } } void ThreadedAssignment::checkInWithDomainServerOrExit() { diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 636d1a9a1a..652089ebb1 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -1867,7 +1867,7 @@ bool Octree::readJSONFromStream(unsigned long streamLength, QDataStream& inputSt QByteArray jsonBuffer; char* rawData = new char[READ_JSON_BUFFER_SIZE]; - while (true) { + while (!inputStream.atEnd()) { int got = inputStream.readRawData(rawData, READ_JSON_BUFFER_SIZE - 1); if (got < 0) { qCritical() << "error while reading from json stream"; diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.slf b/libraries/procedural/src/procedural/ProceduralSkybox.slf index 382801f52d..7ad6f6b5a1 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.slf +++ b/libraries/procedural/src/procedural/ProceduralSkybox.slf @@ -35,6 +35,8 @@ void main(void) { #ifdef PROCEDURAL vec3 color = getSkyboxColor(); + // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline + color = pow(color, vec3(2.2)); _fragColor = vec4(color, 0.0); #else @@ -42,8 +44,7 @@ void main(void) { vec3 coord = normalize(_normal); vec3 texel = texture(cubeMap, coord).rgb; vec3 color = texel * _skybox._color.rgb; - vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction - _fragColor = vec4(pixel, 0.0); + _fragColor = vec4(color, 0.0); #endif diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index e54f55fc94..c32bf2654d 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -175,10 +175,10 @@ const gpu::PipelinePointer& AmbientOcclusion::getBlendPipeline() { } void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { auto framebufferCache = DependencyManager::get(); QSize framebufferSize = framebufferCache->getFrameBufferSize(); @@ -201,7 +201,7 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons // Occlusion step getOcclusionPipeline(); batch.setResourceTexture(0, framebufferCache->getPrimaryDepthTexture()); - batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture()); + batch.setResourceTexture(1, framebufferCache->getDeferredNormalTexture()); _occlusionBuffer->setRenderBuffer(0, _occlusionTexture); batch.setFramebuffer(_occlusionBuffer); @@ -276,7 +276,7 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons // Blend step getBlendPipeline(); batch.setResourceTexture(0, _hBlurTexture); - batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer()); + batch.setFramebuffer(framebufferCache->getDeferredFramebuffer()); // Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture batch.setPipeline(getBlendPipeline()); diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index d4707c172d..3acc88f953 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -93,14 +93,14 @@ const gpu::PipelinePointer& Antialiasing::getBlendPipeline() { } void Antialiasing::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); - if (renderContext->args->_renderMode == RenderArgs::MIRROR_RENDER_MODE) { + if (renderContext->getArgs()->_renderMode == RenderArgs::MIRROR_RENDER_MODE) { return; } - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); @@ -123,7 +123,7 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re // FXAA step getAntialiasingPipeline(); - batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture()); + batch.setResourceTexture(0, framebufferCache->getDeferredColorTexture()); _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); batch.setFramebuffer(_antialiasingBuffer); batch.setPipeline(getAntialiasingPipeline()); @@ -153,7 +153,7 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re // Blend step getBlendPipeline(); batch.setResourceTexture(0, _antialiasingTexture); - batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer()); + batch.setFramebuffer(framebufferCache->getDeferredFramebuffer()); batch.setPipeline(getBlendPipeline()); DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp new file mode 100644 index 0000000000..23150a1779 --- /dev/null +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -0,0 +1,214 @@ +// +// DebugDeferredBuffer.cpp +// libraries/render-utils/src +// +// Created by Clement on 12/3/15. +// 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 "DebugDeferredBuffer.h" + +#include + +#include +#include +#include +#include + +#include "GeometryCache.h" +#include "FramebufferCache.h" + +#include "debug_deferred_buffer_vert.h" +#include "debug_deferred_buffer_frag.h" + +using namespace render; + +enum Slots { + Diffuse = 0, + Normal, + Specular, + Depth, + Lighting +}; + +static const std::string DEEFAULT_DIFFUSE_SHADER { + "vec4 getFragmentColor() {" + " return vec4(pow(texture(diffuseMap, uv).xyz, vec3(1.0 / 2.2)), 1.0);" + " }" +}; +static const std::string DEEFAULT_ALPHA_SHADER { + "vec4 getFragmentColor() {" + " return vec4(vec3(texture(diffuseMap, uv).a), 1.0);" + " }" +}; +static const std::string DEEFAULT_SPECULAR_SHADER { + "vec4 getFragmentColor() {" + " return vec4(texture(specularMap, uv).xyz, 1.0);" + " }" +}; +static const std::string DEEFAULT_ROUGHNESS_SHADER { + "vec4 getFragmentColor() {" + " return vec4(vec3(texture(specularMap, uv).a), 1.0);" + " }" +}; +static const std::string DEEFAULT_NORMAL_SHADER { + "vec4 getFragmentColor() {" + " return vec4(texture(normalMap, uv).xyz, 1.0);" + " }" +}; +static const std::string DEEFAULT_DEPTH_SHADER { + "vec4 getFragmentColor() {" + " return vec4(vec3(texture(depthMap, uv).x), 1.0);" + " }" +}; +static const std::string DEEFAULT_LIGHTING_SHADER { + "vec4 getFragmentColor() {" + " return vec4(pow(texture(lightingMap, uv).xyz, vec3(1.0 / 2.2)), 1.0);" + " }" +}; +static const std::string DEEFAULT_CUSTOM_SHADER { + "vec4 getFragmentColor() {" + " return vec4(1.0, 0.0, 0.0, 1.0);" + " }" +}; + +static std::string getFileContent(std::string fileName, std::string defaultContent = std::string()) { + QFile customFile(QString::fromStdString(fileName)); + if (customFile.open(QIODevice::ReadOnly)) { + return customFile.readAll().toStdString(); + } + qWarning() << "DebugDeferredBuffer::getFileContent(): Could not open" + << QString::fromStdString(fileName); + return defaultContent; +} + +#include // TODO REMOVE: Temporary until UI +DebugDeferredBuffer::DebugDeferredBuffer() { + // TODO REMOVE: Temporary until UI + static const auto DESKTOP_PATH = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + static const auto CUSTOM_FILE = DESKTOP_PATH.toStdString() + "/custom.slh"; + CustomPipeline pipeline; + pipeline.info = QFileInfo(QString::fromStdString(CUSTOM_FILE)); + _customPipelines.emplace(CUSTOM_FILE, pipeline); +} + +std::string DebugDeferredBuffer::getShaderSourceCode(Modes mode, std::string customFile) { + switch (mode) { + case DiffuseMode: + return DEEFAULT_DIFFUSE_SHADER; + case AlphaMode: + return DEEFAULT_ALPHA_SHADER; + case SpecularMode: + return DEEFAULT_SPECULAR_SHADER; + case RoughnessMode: + return DEEFAULT_ROUGHNESS_SHADER; + case NormalMode: + return DEEFAULT_NORMAL_SHADER; + case DepthMode: + return DEEFAULT_DEPTH_SHADER; + case LightingMode: + return DEEFAULT_LIGHTING_SHADER; + case CustomMode: + return getFileContent(customFile, DEEFAULT_CUSTOM_SHADER); + } + Q_UNREACHABLE(); + return std::string(); +} + +bool DebugDeferredBuffer::pipelineNeedsUpdate(Modes mode, std::string customFile) const { + if (mode != CustomMode) { + return !_pipelines[mode]; + } + + auto it = _customPipelines.find(customFile); + if (it != _customPipelines.end() && it->second.pipeline) { + auto& info = it->second.info; + + auto lastModified = info.lastModified(); + info.refresh(); + return lastModified != info.lastModified(); + } + + return true; +} + +const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Modes mode, std::string customFile) { + if (pipelineNeedsUpdate(mode, customFile)) { + static const std::string VERTEX_SHADER { debug_deferred_buffer_vert }; + static const std::string FRAGMENT_SHADER { debug_deferred_buffer_frag }; + static const std::string SOURCE_PLACEHOLDER { "//SOURCE_PLACEHOLDER" }; + static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER.find(SOURCE_PLACEHOLDER); + Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO, + "Could not find source placeholder"); + + auto bakedFragmentShader = FRAGMENT_SHADER; + bakedFragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(), + getShaderSourceCode(mode, customFile)); + + static const auto vs = gpu::Shader::createVertex(VERTEX_SHADER); + const auto ps = gpu::Shader::createPixel(bakedFragmentShader); + const auto program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding("diffuseMap", Diffuse)); + slotBindings.insert(gpu::Shader::Binding("normalMap", Normal)); + slotBindings.insert(gpu::Shader::Binding("specularMap", Specular)); + slotBindings.insert(gpu::Shader::Binding("depthMap", Depth)); + slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting)); + gpu::Shader::makeProgram(*program, slotBindings); + + auto pipeline = gpu::Pipeline::create(program, std::make_shared()); + + // Good to go add the brand new pipeline + if (mode != CustomMode) { + _pipelines[mode] = pipeline; + } else { + _customPipelines[customFile].pipeline = pipeline; + } + } + + if (mode != CustomMode) { + return _pipelines[mode]; + } else { + return _customPipelines[customFile].pipeline; + } +} + + +void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); + RenderArgs* args = renderContext->getArgs(); + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + const auto geometryBuffer = DependencyManager::get(); + const auto framebufferCache = DependencyManager::get(); + + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setModelTransform(Transform()); + + // TODO REMOVE: Temporary until UI + auto first = _customPipelines.begin()->first; + + batch.setPipeline(getPipeline(Modes(renderContext->_deferredDebugMode), first)); + + batch.setResourceTexture(Diffuse, framebufferCache->getDeferredColorTexture()); + batch.setResourceTexture(Normal, framebufferCache->getDeferredNormalTexture()); + batch.setResourceTexture(Specular, framebufferCache->getDeferredSpecularTexture()); + batch.setResourceTexture(Depth, framebufferCache->getPrimaryDepthTexture()); + batch.setResourceTexture(Lighting, framebufferCache->getLightingTexture()); + + const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); + const glm::vec2 bottomLeft(renderContext->_deferredDebugSize.x, renderContext->_deferredDebugSize.y); + const glm::vec2 topRight(renderContext->_deferredDebugSize.z, renderContext->_deferredDebugSize.w); + geometryBuffer->renderQuad(batch, bottomLeft, topRight, color); + }); +} diff --git a/libraries/render-utils/src/DebugDeferredBuffer.h b/libraries/render-utils/src/DebugDeferredBuffer.h new file mode 100644 index 0000000000..682888b2af --- /dev/null +++ b/libraries/render-utils/src/DebugDeferredBuffer.h @@ -0,0 +1,54 @@ +// +// DebugDeferredBuffer.h +// libraries/render-utils/src +// +// Created by Clement on 12/3/15. +// 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_DebugDeferredBuffer_h +#define hifi_DebugDeferredBuffer_h + +#include + +#include + +class DebugDeferredBuffer { +public: + using JobModel = render::Job::Model; + + DebugDeferredBuffer(); + + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + +private: + enum Modes : uint8_t { + DiffuseMode = 0, + AlphaMode, + SpecularMode, + RoughnessMode, + NormalMode, + DepthMode, + LightingMode, + + CustomMode // Needs to stay last + }; + struct CustomPipeline { + gpu::PipelinePointer pipeline; + mutable QFileInfo info; + }; + using StandardPipelines = std::array; + using CustomPipelines = std::unordered_map; + + bool pipelineNeedsUpdate(Modes mode, std::string customFile = std::string()) const; + const gpu::PipelinePointer& getPipeline(Modes mode, std::string customFile = std::string()); + std::string getShaderSourceCode(Modes mode, std::string customFile = std::string()); + + StandardPipelines _pipelines; + CustomPipelines _customPipelines; +}; + +#endif // hifi_DebugDeferredBuffer_h \ No newline at end of file diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index 275966534a..18606f2525 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -24,6 +24,9 @@ uniform sampler2D specularMap; // the depth texture uniform sampler2D depthMap; +// the lighting texture +uniform sampler2D lightingMap; + struct DeferredTransform { mat4 projection; diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index 1c1330f0c0..d3a5ff1e31 100755 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -51,7 +51,7 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, discard; } - _fragColor0 = vec4(diffuse.rgb, alpha); + _fragColor0 = vec4(diffuse.rgb, 1.0); // Opaque _fragColor1 = vec4(bestFitNormal(normal), 1.0); _fragColor2 = vec4(specular, shininess / 128.0); } @@ -61,8 +61,7 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 s discard; } - _fragColor0 = vec4(diffuse.rgb, alpha); - //_fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); + _fragColor0 = vec4(diffuse.rgb, 0.5); _fragColor1 = vec4(bestFitNormal(normal), 0.5); _fragColor2 = vec4(emissive, shininess / 128.0); } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 983b8002f7..11e157a50c 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -83,7 +83,7 @@ vec3 evalAmbienGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 positi vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); - color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); + color += vec3(diffuse * shading.w + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light); return color; } @@ -106,7 +106,7 @@ vec3 evalAmbienSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); - color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); + color += vec3(diffuse * shading.w + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light); return color; } @@ -129,7 +129,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 positi vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); - color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); + color += vec3(diffuse * shading.w + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light); return color; } diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 888742bb18..cf03861c2f 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -23,17 +23,16 @@ vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 sp // Specular Lighting depends on the half vector and the gloss vec3 halfDir = normalize(fragEyeDir + fragLightDir); - // float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); float specularPower = pow(max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); specularPower *= (gloss * 128.0 * 0.125 + 0.25); float shlickPower = (1.0 - dot(fragLightDir,halfDir)); float shlickPower2 = shlickPower * shlickPower; float shlickPower5 = shlickPower2 * shlickPower2 * shlickPower; - vec3 schlick = specular * (1.0 - shlickPower5) + vec3(shlickPower5); - vec3 reflect = specularPower * schlick; + vec3 fresnel = specular * (1.0 - shlickPower5) + vec3(shlickPower5); + vec3 reflect = specularPower * fresnel * diffuse; - return vec4(reflect, diffuse); + return vec4(reflect, diffuse * (1 - fresnel.x)); } <@endfunc@> @@ -49,7 +48,7 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 vec3 halfDir = normalize(fragEyeDir + fragLightDir); float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); - vec3 reflect = specularPower * specular; + vec3 reflect = specularPower * specular * diffuse; return vec4(reflect, diffuse); } @@ -59,14 +58,9 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 <$declareEvalPBRShading()$> - +// Return xyz the specular/reflection component and w the diffuse component vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { - - /*if (gl_FragCoord.x > 1000) { - return evalBlinnShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss); - } else {*/ - return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss); - //} + return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss); } <@endif@> diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index dcadaa5177..4e4799612d 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -34,16 +34,8 @@ #include "deferred_light_spot_vert.h" #include "directional_light_frag.h" -#include "directional_light_shadow_map_frag.h" -#include "directional_light_cascaded_shadow_map_frag.h" - #include "directional_ambient_light_frag.h" -#include "directional_ambient_light_shadow_map_frag.h" -#include "directional_ambient_light_cascaded_shadow_map_frag.h" - #include "directional_skybox_light_frag.h" -#include "directional_skybox_light_shadow_map_frag.h" -#include "directional_skybox_light_cascaded_shadow_map_frag.h" #include "point_light_frag.h" #include "spot_light_frag.h" @@ -51,8 +43,6 @@ static const std::string glowIntensityShaderHandle = "glowIntensity"; struct LightLocations { - int shadowDistances; - int shadowScale; int radius; int ambientSphere; int lightBufferUnit; @@ -92,7 +82,7 @@ gpu::PipelinePointer DeferredLightingEffect::getPipeline(SimpleProgramKey config return pipeline; } -void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { +void DeferredLightingEffect::init() { auto VS = gpu::Shader::createVertex(std::string(simple_vert)); auto PS = gpu::Shader::createPixel(std::string(simple_textured_frag)); auto PSEmissive = gpu::Shader::createPixel(std::string(simple_textured_emisive_frag)); @@ -105,54 +95,23 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { gpu::Shader::makeProgram(*_simpleShader, slotBindings); gpu::Shader::makeProgram(*_emissiveShader, slotBindings); - _viewState = viewState; + _directionalLightLocations = std::make_shared(); - _directionalLightShadowMapLocations = std::make_shared(); - _directionalLightCascadedShadowMapLocations = std::make_shared(); _directionalAmbientSphereLightLocations = std::make_shared(); - _directionalAmbientSphereLightShadowMapLocations = std::make_shared(); - _directionalAmbientSphereLightCascadedShadowMapLocations = std::make_shared(); _directionalSkyboxLightLocations = std::make_shared(); - _directionalSkyboxLightShadowMapLocations = std::make_shared(); - _directionalSkyboxLightCascadedShadowMapLocations = std::make_shared(); _pointLightLocations = std::make_shared(); _spotLightLocations = std::make_shared(); loadLightProgram(deferred_light_vert, directional_light_frag, false, _directionalLight, _directionalLightLocations); - loadLightProgram(deferred_light_vert, directional_light_shadow_map_frag, false, _directionalLightShadowMap, - _directionalLightShadowMapLocations); - loadLightProgram(deferred_light_vert, directional_light_cascaded_shadow_map_frag, false, _directionalLightCascadedShadowMap, - _directionalLightCascadedShadowMapLocations); loadLightProgram(deferred_light_vert, directional_ambient_light_frag, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations); - loadLightProgram(deferred_light_vert, directional_ambient_light_shadow_map_frag, false, _directionalAmbientSphereLightShadowMap, - _directionalAmbientSphereLightShadowMapLocations); - loadLightProgram(deferred_light_vert, directional_ambient_light_cascaded_shadow_map_frag, false, _directionalAmbientSphereLightCascadedShadowMap, - _directionalAmbientSphereLightCascadedShadowMapLocations); loadLightProgram(deferred_light_vert, directional_skybox_light_frag, false, _directionalSkyboxLight, _directionalSkyboxLightLocations); - loadLightProgram(deferred_light_vert, directional_skybox_light_shadow_map_frag, false, _directionalSkyboxLightShadowMap, - _directionalSkyboxLightShadowMapLocations); - loadLightProgram(deferred_light_vert, directional_skybox_light_cascaded_shadow_map_frag, false, _directionalSkyboxLightCascadedShadowMap, - _directionalSkyboxLightCascadedShadowMapLocations); loadLightProgram(deferred_light_limited_vert, point_light_frag, true, _pointLight, _pointLightLocations); loadLightProgram(deferred_light_spot_vert, spot_light_frag, true, _spotLight, _spotLightLocations); - { - //auto VSFS = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); - //auto PSBlit = gpu::StandardShaderLib::getDrawTexturePS(); - auto blitProgram = gpu::StandardShaderLib::getProgram(gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS, gpu::StandardShaderLib::getDrawTexturePS); - gpu::Shader::makeProgram(*blitProgram); - auto blitState = std::make_shared(); - blitState->setBlendFunction(true, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, - gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - blitState->setColorWriteMask(true, true, true, false); - _blitLightBuffer = gpu::Pipeline::create(blitProgram, blitState); - } - // Allocate a global light representing the Global Directional light casting shadow (the sun) and the ambient light _globalLights.push_back(0); _allocatedLights.push_back(std::make_shared()); @@ -342,11 +301,27 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu void DeferredLightingEffect::prepare(RenderArgs* args) { gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); + batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - auto primaryFbo = DependencyManager::get()->getPrimaryFramebuffer(); + // Clear Lighting buffer + auto lightingFbo = DependencyManager::get()->getLightingFramebuffer(); + + batch.setFramebuffer(lightingFbo); + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(vec3(0), 0), true); + + // Clear deferred + auto deferredFbo = DependencyManager::get()->getDeferredFramebuffer(); + + batch.setFramebuffer(deferredFbo); + + // Clear Color, Depth and Stencil + batch.clearFramebuffer( + gpu::Framebuffer::BUFFER_COLOR0 | + gpu::Framebuffer::BUFFER_DEPTH | + gpu::Framebuffer::BUFFER_STENCIL, + vec4(vec3(0), 1), 1.0, 0.0, true); - batch.setFramebuffer(primaryFbo); // clear the normal and specular buffers batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true); const float MAX_SPECULAR_EXPONENT = 128.0f; @@ -354,8 +329,6 @@ void DeferredLightingEffect::prepare(RenderArgs* args) { }); } -gpu::FramebufferPointer _copyFBO; - void DeferredLightingEffect::render(RenderArgs* args) { gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { @@ -375,18 +348,16 @@ void DeferredLightingEffect::render(RenderArgs* args) { QSize framebufferSize = framebufferCache->getFrameBufferSize(); // binding the first framebuffer - _copyFBO = framebufferCache->getFramebuffer(); - batch.setFramebuffer(_copyFBO); + auto lightingFBO = framebufferCache->getLightingFramebuffer(); + batch.setFramebuffer(lightingFBO); - // Clearing it batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true); // BInd the G-Buffer surfaces - batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture()); - batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture()); - batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture()); + batch.setResourceTexture(0, framebufferCache->getDeferredColorTexture()); + batch.setResourceTexture(1, framebufferCache->getDeferredNormalTexture()); + batch.setResourceTexture(2, framebufferCache->getDeferredSpecularTexture()); batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture()); // THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport) @@ -679,42 +650,6 @@ void DeferredLightingEffect::render(RenderArgs* args) { } } - -void DeferredLightingEffect::copyBack(RenderArgs* args) { - auto framebufferCache = DependencyManager::get(); - gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { - batch.enableStereo(false); - QSize framebufferSize = framebufferCache->getFrameBufferSize(); - - // TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror. - // auto destFbo = framebufferCache->getPrimaryFramebuffer(); - auto destFbo = framebufferCache->getPrimaryFramebufferDepthColor(); - // gpu::Vec4i vp = args->_viewport; - // batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp); - batch.setFramebuffer(destFbo); - batch.setViewportTransform(args->_viewport); - batch.setProjectionTransform(glm::mat4()); - batch.setViewTransform(Transform()); - { - float sMin = args->_viewport.x / (float)framebufferSize.width(); - float sWidth = args->_viewport.z / (float)framebufferSize.width(); - float tMin = args->_viewport.y / (float)framebufferSize.height(); - float tHeight = args->_viewport.w / (float)framebufferSize.height(); - Transform model; - batch.setPipeline(_blitLightBuffer); - model.setTranslation(glm::vec3(sMin, tMin, 0.0)); - model.setScale(glm::vec3(sWidth, tHeight, 1.0)); - batch.setModelTransform(model); - } - - batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0)); - batch.draw(gpu::TRIANGLE_STRIP, 4); - - args->_context->render(batch); - }); - framebufferCache->releaseFramebuffer(_copyFBO); -} - void DeferredLightingEffect::setupTransparent(RenderArgs* args, int lightBufferUnit) { auto globalLight = _allocatedLights[_globalLights.front()]; args->_batch->setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer()); @@ -731,7 +666,6 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1)); slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2)); slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), 3)); - slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), 4)); slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), 5)); const int LIGHT_GPU_SLOT = 3; slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT)); @@ -742,8 +676,6 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo gpu::Shader::makeProgram(*program, slotBindings); - locations->shadowDistances = program->getUniforms().findLocation("shadowDistances"); - locations->shadowScale = program->getUniforms().findLocation("shadowScale"); locations->radius = program->getUniforms().findLocation("radius"); locations->ambientSphere = program->getUniforms().findLocation("ambientSphere.L00"); @@ -756,6 +688,11 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo locations->deferredTransformBuffer = program->getBuffers().findLocation("deferredTransformBuffer"); auto state = std::make_shared(); + state->setColorWriteMask(true, true, true, false); + + // Stencil test all the light passes for objects pixels only, not the background + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + if (lightVolume) { state->setCullMode(gpu::State::CULL_BACK); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index eee5993c29..dfb0ecbffb 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -21,7 +21,6 @@ #include "model/Stage.h" #include "model/Geometry.h" -class AbstractViewStateInterface; class RenderArgs; class SimpleProgramKey; struct LightLocations; @@ -34,7 +33,7 @@ public: static const int NORMAL_FITTING_MAP_SLOT = 10; static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 2; - void init(AbstractViewStateInterface* viewState); + void init(); /// Sets up the state necessary to render static untextured geometry with the simple program. gpu::PipelinePointer bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true, @@ -78,7 +77,6 @@ public: void prepare(RenderArgs* args); void render(RenderArgs* args); - void copyBack(RenderArgs* args); void setupTransparent(RenderArgs* args, int lightBufferUnit); @@ -101,29 +99,15 @@ private: gpu::ShaderPointer _simpleShader; gpu::ShaderPointer _emissiveShader; QHash _simplePrograms; - - gpu::PipelinePointer _blitLightBuffer; - + gpu::PipelinePointer _directionalSkyboxLight; LightLocationsPtr _directionalSkyboxLightLocations; - gpu::PipelinePointer _directionalSkyboxLightShadowMap; - LightLocationsPtr _directionalSkyboxLightShadowMapLocations; - gpu::PipelinePointer _directionalSkyboxLightCascadedShadowMap; - LightLocationsPtr _directionalSkyboxLightCascadedShadowMapLocations; gpu::PipelinePointer _directionalAmbientSphereLight; LightLocationsPtr _directionalAmbientSphereLightLocations; - gpu::PipelinePointer _directionalAmbientSphereLightShadowMap; - LightLocationsPtr _directionalAmbientSphereLightShadowMapLocations; - gpu::PipelinePointer _directionalAmbientSphereLightCascadedShadowMap; - LightLocationsPtr _directionalAmbientSphereLightCascadedShadowMapLocations; gpu::PipelinePointer _directionalLight; LightLocationsPtr _directionalLightLocations; - gpu::PipelinePointer _directionalLightShadowMap; - LightLocationsPtr _directionalLightShadowMapLocations; - gpu::PipelinePointer _directionalLightCascadedShadowMap; - LightLocationsPtr _directionalLightCascadedShadowMapLocations; gpu::PipelinePointer _pointLight; LightLocationsPtr _pointLightLocations; @@ -155,8 +139,6 @@ private: std::vector _globalLights; std::vector _pointLights; std::vector _spotLights; - - AbstractViewStateInterface* _viewState; int _ambientLightMode = 0; model::AtmospherePointer _atmosphere; diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index 5907d3fa27..9f3d4ba0fe 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -33,61 +33,76 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { //If the size changed, we need to delete our FBOs if (_frameBufferSize != frameBufferSize) { _frameBufferSize = frameBufferSize; - _primaryFramebufferFull.reset(); - _primaryFramebufferDepthColor.reset(); + _primaryFramebuffer.reset(); _primaryDepthTexture.reset(); _primaryColorTexture.reset(); - _primaryNormalTexture.reset(); - _primarySpecularTexture.reset(); + _deferredFramebuffer.reset(); + _deferredFramebufferDepthColor.reset(); + _deferredColorTexture.reset(); + _deferredNormalTexture.reset(); + _deferredSpecularTexture.reset(); _selfieFramebuffer.reset(); _cachedFramebuffers.clear(); + _lightingTexture.reset(); + _lightingFramebuffer.reset(); } } void FramebufferCache::createPrimaryFramebuffer() { - _primaryFramebufferFull = gpu::FramebufferPointer(gpu::Framebuffer::create()); - _primaryFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _deferredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _deferredFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); - auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); + auto colorFormat = gpu::Element::COLOR_RGBA_32; auto width = _frameBufferSize.width(); auto height = _frameBufferSize.height(); auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); _primaryColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); - _primaryNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); - _primarySpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); - _primaryFramebufferFull->setRenderBuffer(0, _primaryColorTexture); - _primaryFramebufferFull->setRenderBuffer(1, _primaryNormalTexture); - _primaryFramebufferFull->setRenderBuffer(2, _primarySpecularTexture); + _primaryFramebuffer->setRenderBuffer(0, _primaryColorTexture); - _primaryFramebufferDepthColor->setRenderBuffer(0, _primaryColorTexture); + _deferredColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); + _deferredNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); + _deferredSpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); + + _deferredFramebuffer->setRenderBuffer(0, _deferredColorTexture); + _deferredFramebuffer->setRenderBuffer(1, _deferredNormalTexture); + _deferredFramebuffer->setRenderBuffer(2, _deferredSpecularTexture); + + _deferredFramebufferDepthColor->setRenderBuffer(0, _deferredColorTexture); // auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler)); - - _primaryFramebufferFull->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); - _primaryFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); - + _primaryFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); + + _deferredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); + + _deferredFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); + + _selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler)); _selfieFramebuffer->setRenderBuffer(0, tex); + + auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR); + + // FIXME: Decide on the proper one, let s stick to R11G11B10 for now + //_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, defaultSampler)); + _lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::R11G11B10), width, height, defaultSampler)); + //_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::HALF, gpu::RGBA), width, height, defaultSampler)); + _lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _lightingFramebuffer->setRenderBuffer(0, _lightingTexture); + _lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); } gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() { - if (!_primaryFramebufferFull) { + if (!_primaryFramebuffer) { createPrimaryFramebuffer(); } - return _primaryFramebufferFull; -} - -gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthColor() { - if (!_primaryFramebufferDepthColor) { - createPrimaryFramebuffer(); - } - return _primaryFramebufferDepthColor; + return _primaryFramebuffer; } gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() { @@ -104,18 +119,53 @@ gpu::TexturePointer FramebufferCache::getPrimaryColorTexture() { return _primaryColorTexture; } -gpu::TexturePointer FramebufferCache::getPrimaryNormalTexture() { - if (!_primaryNormalTexture) { +gpu::FramebufferPointer FramebufferCache::getDeferredFramebuffer() { + if (!_deferredFramebuffer) { createPrimaryFramebuffer(); } - return _primaryNormalTexture; + return _deferredFramebuffer; } -gpu::TexturePointer FramebufferCache::getPrimarySpecularTexture() { - if (!_primarySpecularTexture) { +gpu::FramebufferPointer FramebufferCache::getDeferredFramebufferDepthColor() { + if (!_deferredFramebufferDepthColor) { createPrimaryFramebuffer(); } - return _primarySpecularTexture; + return _deferredFramebufferDepthColor; +} + +gpu::TexturePointer FramebufferCache::getDeferredColorTexture() { + if (!_deferredColorTexture) { + createPrimaryFramebuffer(); + } + return _deferredColorTexture; +} + +gpu::TexturePointer FramebufferCache::getDeferredNormalTexture() { + if (!_deferredNormalTexture) { + createPrimaryFramebuffer(); + } + return _deferredNormalTexture; +} + +gpu::TexturePointer FramebufferCache::getDeferredSpecularTexture() { + if (!_deferredSpecularTexture) { + createPrimaryFramebuffer(); + } + return _deferredSpecularTexture; +} + +gpu::FramebufferPointer FramebufferCache::getLightingFramebuffer() { + if (!_lightingFramebuffer) { + createPrimaryFramebuffer(); + } + return _lightingFramebuffer; +} + +gpu::TexturePointer FramebufferCache::getLightingTexture() { + if (!_lightingTexture) { + createPrimaryFramebuffer(); + } + return _lightingTexture; } gpu::FramebufferPointer FramebufferCache::getFramebuffer() { diff --git a/libraries/render-utils/src/FramebufferCache.h b/libraries/render-utils/src/FramebufferCache.h index e9a1bbf8e8..7ac5e4af63 100644 --- a/libraries/render-utils/src/FramebufferCache.h +++ b/libraries/render-utils/src/FramebufferCache.h @@ -30,12 +30,20 @@ public: /// Returns a pointer to the primary framebuffer object. This render target includes a depth component, and is /// used for scene rendering. gpu::FramebufferPointer getPrimaryFramebuffer(); - gpu::FramebufferPointer getPrimaryFramebufferDepthColor(); gpu::TexturePointer getPrimaryDepthTexture(); gpu::TexturePointer getPrimaryColorTexture(); - gpu::TexturePointer getPrimaryNormalTexture(); - gpu::TexturePointer getPrimarySpecularTexture(); + + gpu::FramebufferPointer getDeferredFramebuffer(); + gpu::FramebufferPointer getDeferredFramebufferDepthColor(); + + gpu::TexturePointer getDeferredColorTexture(); + gpu::TexturePointer getDeferredNormalTexture(); + gpu::TexturePointer getDeferredSpecularTexture(); + + + gpu::TexturePointer getLightingTexture(); + gpu::FramebufferPointer getLightingFramebuffer(); /// Returns the framebuffer object used to render shadow maps; gpu::FramebufferPointer getShadowFramebuffer(); @@ -56,14 +64,21 @@ private: void createPrimaryFramebuffer(); - gpu::FramebufferPointer _primaryFramebufferFull; - gpu::FramebufferPointer _primaryFramebufferDepthColor; + gpu::FramebufferPointer _primaryFramebuffer; gpu::TexturePointer _primaryDepthTexture; gpu::TexturePointer _primaryColorTexture; - gpu::TexturePointer _primaryNormalTexture; - gpu::TexturePointer _primarySpecularTexture; - + + gpu::FramebufferPointer _deferredFramebuffer; + gpu::FramebufferPointer _deferredFramebufferDepthColor; + + gpu::TexturePointer _deferredColorTexture; + gpu::TexturePointer _deferredNormalTexture; + gpu::TexturePointer _deferredSpecularTexture; + + gpu::TexturePointer _lightingTexture; + gpu::FramebufferPointer _lightingFramebuffer; + gpu::FramebufferPointer _shadowFramebuffer; gpu::FramebufferPointer _selfieFramebuffer; diff --git a/libraries/render-utils/src/HitEffect.cpp b/libraries/render-utils/src/HitEffect.cpp index 7e8b5f5fa0..bf65eaf059 100644 --- a/libraries/render-utils/src/HitEffect.cpp +++ b/libraries/render-utils/src/HitEffect.cpp @@ -14,6 +14,7 @@ #include +#include #include #include @@ -60,9 +61,9 @@ const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() { } void HitEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); - RenderArgs* args = renderContext->args; + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); + RenderArgs* args = renderContext->getArgs(); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { glm::mat4 projMat; diff --git a/libraries/render-utils/src/HitEffect.h b/libraries/render-utils/src/HitEffect.h index b560cf5550..0a96a5300d 100644 --- a/libraries/render-utils/src/HitEffect.h +++ b/libraries/render-utils/src/HitEffect.h @@ -9,11 +9,7 @@ #ifndef hifi_hitEffect_h #define hifi_hitEffect_h -#include -#include "render/DrawTask.h" - -class AbstractViewStateInterface; -class ProgramObject; +#include class HitEffect { public: @@ -23,7 +19,7 @@ public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); typedef render::Job::Model JobModel; - const gpu::PipelinePointer& getHitEffectPipeline(); + const gpu::PipelinePointer& getHitEffectPipeline(); private: gpu::PipelinePointer _hitEffectPipeline; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 2d8d7b598b..2fae09a158 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -470,6 +470,9 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { ModelRender::pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, args, locations); + if (!locations) { // the pipeline could not be found + return; + } // Bind the model transform and the skinCLusterMatrices if needed bindTransform(batch, locations); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 275e8af29c..4dcda425a1 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -18,10 +18,11 @@ #include #include -#include "FramebufferCache.h" +#include "DebugDeferredBuffer.h" #include "DeferredLightingEffect.h" -#include "TextureCache.h" +#include "FramebufferCache.h" #include "HitEffect.h" +#include "TextureCache.h" #include "render/DrawStatus.h" #include "AmbientOcclusionEffect.h" @@ -34,92 +35,91 @@ using namespace render; -void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - RenderArgs* args = renderContext->args; - gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { - - auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); - - batch.enableStereo(false); - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - - batch.setFramebuffer(primaryFbo); - batch.clearFramebuffer( - gpu::Framebuffer::BUFFER_COLOR0 | - gpu::Framebuffer::BUFFER_DEPTH | - gpu::Framebuffer::BUFFER_STENCIL, - vec4(vec3(0), 1), 1.0, 0.0, true); - }); -} void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - DependencyManager::get()->prepare(renderContext->args); + DependencyManager::get()->prepare(renderContext->getArgs()); } void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - DependencyManager::get()->render(renderContext->args); + DependencyManager::get()->render(renderContext->getArgs()); } -void ResolveDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - PerformanceTimer perfTimer("ResolveDeferred"); - DependencyManager::get()->copyBack(renderContext->args); +void ToneMappingDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("ToneMappingDeferred"); + _toneMappingEffect.render(renderContext->getArgs()); } RenderDeferredTask::RenderDeferredTask() : Task() { - _jobs.push_back(Job(new SetupDeferred::JobModel("SetupFramebuffer"))); - - _jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred"))); + // CPU only, create the list of renderedOpaques items _jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque", - FetchItems( - [] (const RenderContextPointer& context, int count) { - context->_numFeedOpaqueItems = count; - } - ) + 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()))); auto& renderedOpaques = _jobs.back().getOutput(); - _jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", _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)))); + auto& renderedTransparents = _jobs.back().getOutput(); + + // GPU Jobs: Start preparing the deferred and lighting buffer + _jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred"))); + + // Render opaque objects in DeferredBuffer + _jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", renderedOpaques))); + + // Once opaque is all rendered create stencil background _jobs.push_back(Job(new DrawStencilDeferred::JobModel("DrawOpaqueStencil"))); + + // Use Stencil and start drawing background in Lighting buffer _jobs.push_back(Job(new DrawBackgroundDeferred::JobModel("DrawBackgroundDeferred"))); + // 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"))); - _jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred"))); - _jobs.push_back(Job(new ResolveDeferred::JobModel("ResolveDeferred"))); - _jobs.push_back(Job(new AmbientOcclusion::JobModel("AmbientOcclusion"))); + // DeferredBuffer is complete, now let's shade it into the LightingBuffer + _jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred"))); + + // AO job, to be revisited + _jobs.push_back(Job(new AmbientOcclusion::JobModel("AmbientOcclusion"))); _jobs.back().setEnabled(false); _occlusionJobIndex = (int)_jobs.size() - 1; + // AA job to be revisited _jobs.push_back(Job(new Antialiasing::JobModel("Antialiasing"))); - _jobs.back().setEnabled(false); _antialiasingJobIndex = (int)_jobs.size() - 1; - _jobs.push_back(Job(new FetchItems::JobModel("FetchTransparent", - FetchItems( - ItemFilter::Builder::transparentShape().withoutLayered(), - [] (const RenderContextPointer& context, int count) { - context->_numFeedTransparentItems = 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)))); - _jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", _jobs.back().getOutput()))); + // Render transparent objects forward in LigthingBuffer + _jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", renderedTransparents))); - // 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()->getImageTexture(iconMapPath); - _jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques, DrawStatus(statusIconMap)))); + // Lighting Buffer ready for tone mapping + _jobs.push_back(Job(new ToneMappingDeferred::JobModel("ToneMapping"))); + _toneMappingJobIndex = (int)_jobs.size() - 1; + // Debugging Deferred buffer job + _jobs.push_back(Job(new DebugDeferredBuffer::JobModel("DebugDeferredBuffer"))); _jobs.back().setEnabled(false); - _drawStatusJobIndex = (int)_jobs.size() - 1; + _drawDebugDeferredBufferIndex = (int)_jobs.size() - 1; + + // Status icon rendering job + { + // 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()->getImageTexture(iconMapPath); + _jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques, DrawStatus(statusIconMap)))); + _jobs.back().setEnabled(false); + _drawStatusJobIndex = (int)_jobs.size() - 1; + } _jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D"))); @@ -127,7 +127,6 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.back().setEnabled(false); _drawHitEffectJobIndex = (int)_jobs.size() -1; - // Give ourselves 3 frmaes of timer queries _timerQueries.push_back(std::make_shared()); _timerQueries.push_back(std::make_shared()); @@ -147,23 +146,29 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend // Is it possible that we render without a viewFrustum ? - if (!(renderContext->args && renderContext->args->_viewFrustum)) { + if (!(renderContext->getArgs() && renderContext->getArgs()->_viewFrustum)) { return; } - // Make sure we turn the displayItemStatus on/off - setDrawItemStatus(renderContext->_drawItemStatus); + // Make sure we turn the deferred buffer debug on/off + setDrawDebugDeferredBuffer(renderContext->_deferredDebugMode); - //Make sure we display hit effect on screen, as desired from a script - setDrawHitEffect(renderContext->_drawHitEffect); + // Make sure we turn the displayItemStatus on/off + setDrawItemStatus(renderContext->getDrawStatus()); + + // Make sure we display hit effect on screen, as desired from a script + setDrawHitEffect(renderContext->getDrawHitEffect()); // TODO: turn on/off AO through menu item - setOcclusionStatus(renderContext->_occlusionStatus); + setOcclusionStatus(renderContext->getOcclusionStatus()); - setAntialiasingStatus(renderContext->_fxaaStatus); + setAntialiasingStatus(renderContext->getFxaaStatus()); - renderContext->args->_context->syncCache(); + setToneMappingExposure(renderContext->getTone().exposure); + setToneMappingToneCurve(renderContext->getTone().toneCurve); + + renderContext->getArgs()->_context->syncCache(); for (auto job : _jobs) { job.run(sceneContext, renderContext); @@ -172,16 +177,17 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend }; void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); args->_batch = &batch; - renderContext->_numDrawnOpaqueItems = (int)inItems.size(); + auto& opaque = renderContext->getItemsConfig().opaque; + opaque.numDrawn = (int)inItems.size(); glm::mat4 projMat; Transform viewMat; @@ -195,22 +201,23 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend const float OPAQUE_ALPHA_THRESHOLD = 0.5f; args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD; } - renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems); + renderItems(sceneContext, renderContext, inItems, opaque.maxDrawn); args->_batch = nullptr; }); } void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); args->_batch = &batch; - renderContext->_numDrawnTransparentItems = (int)inItems.size(); + auto& transparent = renderContext->getItemsConfig().transparent; + transparent.numDrawn = (int)inItems.size(); glm::mat4 projMat; Transform viewMat; @@ -223,7 +230,7 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; - renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems); + renderItems(sceneContext, renderContext, inItems, transparent.maxDrawn); args->_batch = nullptr; }); } @@ -246,8 +253,8 @@ const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() { } void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); // render backgrounds auto& scene = sceneContext->_scene; @@ -262,11 +269,12 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon inItems.emplace_back(id); } } - renderContext->_numFeedOverlay3DItems = (int)inItems.size(); - renderContext->_numDrawnOverlay3DItems = (int)inItems.size(); + auto& overlay3D = renderContext->getItemsConfig().overlay3D; + overlay3D.numFeed = (int)inItems.size(); + overlay3D.numDrawn = (int)inItems.size(); if (!inItems.empty()) { - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); // Clear the framebuffer without stereo // Needs to be distinct from the other batch because using the clear call @@ -295,7 +303,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, args->_whiteTexture); - renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOverlay3DItems); + renderItems(sceneContext, renderContext, inItems, renderContext->getItemsConfig().overlay3D.maxDrawn); }); args->_batch = nullptr; args->_whiteTexture.reset(); @@ -324,19 +332,19 @@ const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { } void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); // from the touched pixel generate the stencil buffer - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; - auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthColor(); + auto deferredFboColorDepthStencil = DependencyManager::get()->getDeferredFramebufferDepthColor(); batch.enableStereo(false); - batch.setFramebuffer(primaryFboColorDepthStencil); + batch.setFramebuffer(deferredFboColorDepthStencil); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); @@ -350,8 +358,8 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren } void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); // render backgrounds auto& scene = sceneContext->_scene; @@ -363,16 +371,15 @@ void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const for (auto id : items) { inItems.emplace_back(id); } - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; - auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthColor(); - auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); + auto lightingFBO = DependencyManager::get()->getLightingFramebuffer(); batch.enableSkybox(true); - batch.setFramebuffer(primaryFboColorDepthStencil); + batch.setFramebuffer(lightingFBO); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); @@ -387,8 +394,36 @@ void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const renderItems(sceneContext, renderContext, inItems); - batch.setFramebuffer(primaryFboFull); - }); args->_batch = nullptr; } + + +void RenderDeferredTask::setToneMappingExposure(float exposure) { + if (_toneMappingJobIndex >= 0) { + _jobs[_toneMappingJobIndex].edit()._toneMappingEffect.setExposure(exposure); + } +} + +float RenderDeferredTask::getToneMappingExposure() const { + if (_toneMappingJobIndex >= 0) { + return _jobs[_toneMappingJobIndex].get()._toneMappingEffect.getExposure(); + } else { + return 0.0f; + } +} + +void RenderDeferredTask::setToneMappingToneCurve(int toneCurve) { + if (_toneMappingJobIndex >= 0) { + _jobs[_toneMappingJobIndex].edit()._toneMappingEffect.setToneCurve((ToneMappingEffect::ToneCurve)toneCurve); + } +} + +int RenderDeferredTask::getToneMappingToneCurve() const { + if (_toneMappingJobIndex >= 0) { + return _jobs[_toneMappingJobIndex].get()._toneMappingEffect.getToneCurve(); + } else { + return 0.0f; + } +} + diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 6daa90b1ed..b84db31a26 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -16,6 +16,8 @@ #include "gpu/Pipeline.h" +#include "ToneMappingEffect.h" + class SetupDeferred { public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); @@ -38,11 +40,13 @@ public: typedef render::Job::Model JobModel; }; -class ResolveDeferred { +class ToneMappingDeferred { public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + ToneMappingEffect _toneMappingEffect; + + typedef render::Job::Model JobModel; }; class DrawOpaqueDeferred { @@ -80,9 +84,9 @@ class DrawOverlay3D { static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable public: static const gpu::PipelinePointer& getOpaquePipeline(); - + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - + typedef render::Job::Model JobModel; }; @@ -93,16 +97,23 @@ public: ~RenderDeferredTask(); render::Jobs _jobs; - + + int _drawDebugDeferredBufferIndex = -1; int _drawStatusJobIndex = -1; int _drawHitEffectJobIndex = -1; - + + void setDrawDebugDeferredBuffer(int draw) { + if (_drawDebugDeferredBufferIndex >= 0) { + _jobs[_drawDebugDeferredBufferIndex].setEnabled(draw >= 0); + } + } + bool doDrawDebugDeferredBuffer() const { if (_drawDebugDeferredBufferIndex >= 0) { return _jobs[_drawDebugDeferredBufferIndex].isEnabled(); } else { return false; } } + void setDrawItemStatus(int draw) { if (_drawStatusJobIndex >= 0) { _jobs[_drawStatusJobIndex].setEnabled(draw > 0); } } - bool doDrawItemStatus() const { if (_drawStatusJobIndex >= 0) { return _jobs[_drawStatusJobIndex].isEnabled(); } else { return false; } } void setDrawHitEffect(bool draw) { if (_drawHitEffectJobIndex >= 0) { _jobs[_drawHitEffectJobIndex].setEnabled(draw); } } @@ -118,6 +129,14 @@ public: void setAntialiasingStatus(bool draw) { if (_antialiasingJobIndex >= 0) { _jobs[_antialiasingJobIndex].setEnabled(draw); } } bool doAntialiasingStatus() const { if (_antialiasingJobIndex >= 0) { return _jobs[_antialiasingJobIndex].isEnabled(); } else { return false; } } + int _toneMappingJobIndex = -1; + + void setToneMappingExposure(float exposure); + float getToneMappingExposure() const; + + void setToneMappingToneCurve(int toneCurve); + int getToneMappingToneCurve() const; + virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); diff --git a/libraries/render-utils/src/RenderScriptingInterface.cpp b/libraries/render-utils/src/RenderScriptingInterface.cpp new file mode 100644 index 0000000000..a99dc814d5 --- /dev/null +++ b/libraries/render-utils/src/RenderScriptingInterface.cpp @@ -0,0 +1,52 @@ +// +// RenderScriptingInterface.cpp +// libraries/render-utils +// +// Created by Zach Pomerantz on 12/16/15. +// 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 "RenderScriptingInterface.h" + +RenderScriptingInterface::RenderScriptingInterface() {}; + +void RenderScripting::Tone::setCurve(const QString& curve) { + if (curve == QString("None")) { + toneCurve = 0; + } else if (curve == QString("Gamma22")) { + toneCurve = 1; + } else if (curve == QString("Reinhard")) { + toneCurve = 2; + } else if (curve == QString("Filmic")) { + toneCurve = 3; + } +} + +QString RenderScripting::Tone::getCurve() const { + switch (toneCurve) { + case 0: + return QString("None"); + case 1: + return QString("Gamma22"); + case 2: + return QString("Reinhard"); + case 3: + return QString("Filmic"); + default: + return QString("Filmic"); + }; +} + +render::RenderContext RenderScriptingInterface::getRenderContext() { + render::RenderContext::ItemsConfig items{ *_opaque, *_transparent, *_overlay3D }; + return render::RenderContext{ items, *_tone, _drawStatus, _drawHitEffect, _deferredDebugSize, _deferredDebugMode }; +} + +void RenderScriptingInterface::setItemCounts(const render::RenderContext::ItemsConfig& items) { + _opaque->setCounts(items.opaque); + _transparent->setCounts(items.transparent); + _overlay3D->setCounts(items.overlay3D); +} \ No newline at end of file diff --git a/libraries/render-utils/src/RenderScriptingInterface.h b/libraries/render-utils/src/RenderScriptingInterface.h new file mode 100644 index 0000000000..08226ef6df --- /dev/null +++ b/libraries/render-utils/src/RenderScriptingInterface.h @@ -0,0 +1,115 @@ +// +// RenderScriptingInterface.h +// libraries/render-utils +// +// Created by Zach Pomerantz on 12/16/15. +// Copyright 2014 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_RenderScriptingInterface_h +#define hifi_RenderScriptingInterface_h + +#include // QObject +#include // Dependency + +#include "render/Engine.h" + +namespace RenderScripting { + using State = render::RenderContext::ItemsConfig::State; + using Counter = render::RenderContext::ItemsConfig::Counter; + + class ItemCounter : public QObject, public Counter { + Q_OBJECT + + public: + Q_PROPERTY(int numFeed READ getNumFeed) + Q_PROPERTY(int numDrawn READ getNumDrawn) + Q_PROPERTY(int maxDrawn MEMBER maxDrawn) + + protected: + int getNumFeed() const { return numFeed; } + int getNumDrawn() const { return numDrawn; } + }; + using ItemCounterPointer = std::unique_ptr; + + class ItemState : public QObject, public State { + Q_OBJECT + + public: + Q_PROPERTY(bool render MEMBER render) + Q_PROPERTY(bool cull MEMBER cull) + Q_PROPERTY(bool sort MEMBER sort) + + Q_PROPERTY(int numFeed READ getNumFeed) + Q_PROPERTY(int numDrawn READ getNumDrawn) + Q_PROPERTY(int maxDrawn MEMBER maxDrawn) + + protected: + int getNumFeed() const { return numFeed; } + int getNumDrawn() const { return numDrawn; } + }; + using ItemStatePointer = std::unique_ptr; + + class Tone : public QObject, public render::RenderContext::Tone { + Q_OBJECT + + public: + Q_PROPERTY(float exposure MEMBER exposure) + Q_PROPERTY(QString curve READ getCurve WRITE setCurve) + + QString getCurve() const; + int getCurveValue() const { return toneCurve; } + void setCurve(const QString& curve); + }; + using TonePointer = std::unique_ptr; +}; + +class RenderScriptingInterface : public QObject, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY + + public: + Q_PROPERTY(RenderScripting::ItemState* opaque READ getOpaque) + Q_PROPERTY(RenderScripting::ItemState* transparent READ getTransparent) + Q_PROPERTY(RenderScripting::ItemCounter* overlay3D READ getOverlay3D) + + Q_PROPERTY(RenderScripting::Tone* tone READ getTone) + + Q_PROPERTY(int displayItemStatus MEMBER _drawStatus) + Q_PROPERTY(bool displayHitEffect MEMBER _drawHitEffect) + + Q_PROPERTY(int deferredDebugMode MEMBER _deferredDebugMode) + Q_PROPERTY(glm::vec4 deferredDebugSize MEMBER _deferredDebugSize) + + render::RenderContext getRenderContext(); + void setItemCounts(const render::RenderContext::ItemsConfig& items); + +protected: + RenderScriptingInterface(); + ~RenderScriptingInterface() {}; + + RenderScripting::ItemState* getOpaque() const { return _opaque.get(); } + RenderScripting::ItemState* getTransparent() const { return _transparent.get(); } + RenderScripting::ItemCounter* getOverlay3D() const { return _overlay3D.get(); } + + RenderScripting::Tone* getTone() const { return _tone.get(); } + + RenderScripting::ItemStatePointer _opaque = RenderScripting::ItemStatePointer{new RenderScripting::ItemState{}}; + RenderScripting::ItemStatePointer _transparent = RenderScripting::ItemStatePointer{new RenderScripting::ItemState{}}; + RenderScripting::ItemCounterPointer _overlay3D = RenderScripting::ItemCounterPointer{new RenderScripting::ItemCounter{}}; + + RenderScripting::TonePointer _tone = RenderScripting::TonePointer{ new RenderScripting::Tone{} }; + + // Options + int _drawStatus = 0; + bool _drawHitEffect = false; + + // Debugging + int _deferredDebugMode = -1; + glm::vec4 _deferredDebugSize { 0.0f, -1.0f, 1.0f, 1.0f }; +}; + +#endif // hifi_RenderScriptingInterface_h diff --git a/libraries/render-utils/src/SkyFromAtmosphere.slf b/libraries/render-utils/src/SkyFromAtmosphere.slf index c2a3635f07..10b39dc210 100755 --- a/libraries/render-utils/src/SkyFromAtmosphere.slf +++ b/libraries/render-utils/src/SkyFromAtmosphere.slf @@ -108,5 +108,6 @@ void main (void) vec3 finalColor = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb; outFragColor.a = finalColor.b; - outFragColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2)); + // outFragColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2)); + outFragColor.rgb = finalColor.rgb; } diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp new file mode 100644 index 0000000000..2583719424 --- /dev/null +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -0,0 +1,145 @@ +// +// ToneMappingEffect.cpp +// libraries/render-utils/src +// +// Created by Sam Gateau on 12/7/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 "ToneMappingEffect.h" + +#include +#include + +#include + +#include "FramebufferCache.h" + + +ToneMappingEffect::ToneMappingEffect() { + Parameters parameters; + _parametersBuffer = gpu::BufferView(std::make_shared(sizeof(Parameters), (const gpu::Byte*) ¶meters)); +} + +void ToneMappingEffect::init() { + const char BlitTextureGamma_frag[] = R"SCRIBE(#version 410 core + // Generated on Sat Oct 24 09:34:37 2015 + // + // Draw texture 0 fetched at texcoord.xy + // + // Created by Sam Gateau on 6/22/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 + // + + struct ToneMappingParams { + vec4 _exp_2powExp_s0_s1; + ivec4 _toneCurve_s0_s1_s2; + }; + + const float INV_GAMMA_22 = 1.0 / 2.2; + const int ToneCurveNone = 0; + const int ToneCurveGamma22 = 1; + const int ToneCurveReinhard = 2; + const int ToneCurveFilmic = 3; + + uniform toneMappingParamsBuffer { + ToneMappingParams params; + }; + float getTwoPowExposure() { + return params._exp_2powExp_s0_s1.y; + } + int getToneCurve() { + return params._toneCurve_s0_s1_s2.x; + } + + uniform sampler2D colorMap; + + in vec2 varTexCoord0; + out vec4 outFragColor; + + void main(void) { + vec4 fragColorRaw = texture(colorMap, varTexCoord0); + vec3 fragColor = fragColorRaw.xyz; + + vec3 srcColor = fragColor * getTwoPowExposure(); + + int toneCurve = getToneCurve(); + vec3 tonedColor = srcColor; + if (toneCurve == ToneCurveFilmic) { + vec3 x = max(vec3(0.0), srcColor-0.004); + tonedColor = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); + } else if (toneCurve == ToneCurveReinhard) { + tonedColor = srcColor/(1.0 + srcColor); + tonedColor = pow(tonedColor, vec3(INV_GAMMA_22)); + } else if (toneCurve == ToneCurveGamma22) { + tonedColor = pow(srcColor, vec3(INV_GAMMA_22)); + } // else None toned = src + + outFragColor = vec4(tonedColor, 1.0); + } + + )SCRIBE"; + auto blitPS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(BlitTextureGamma_frag))); + + auto blitVS = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + auto blitProgram = gpu::ShaderPointer(gpu::Shader::createProgram(blitVS, blitPS)); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("toneMappingParamsBuffer"), 3)); + gpu::Shader::makeProgram(*blitProgram, slotBindings); + auto blitState = std::make_shared(); + blitState->setColorWriteMask(true, true, true, true); + _blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); +} + +void ToneMappingEffect::setExposure(float exposure) { + _parametersBuffer.edit()._exposure = exposure; + _parametersBuffer.edit()._twoPowExposure = pow(2.0, exposure); +} + +void ToneMappingEffect::setToneCurve(ToneCurve curve) { + _parametersBuffer.edit()._toneCurve = curve; +} + +void ToneMappingEffect::render(RenderArgs* args) { + if (!_blitLightBuffer) { + init(); + } + auto framebufferCache = DependencyManager::get(); + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { + batch.enableStereo(false); + QSize framebufferSize = framebufferCache->getFrameBufferSize(); + + auto lightingBuffer = framebufferCache->getLightingTexture(); + auto destFbo = framebufferCache->getPrimaryFramebuffer(); + batch.setFramebuffer(destFbo); + + // FIXME: Generate the Luminosity map + //batch.generateTextureMips(lightingBuffer); + + batch.setViewportTransform(args->_viewport); + batch.setProjectionTransform(glm::mat4()); + batch.setViewTransform(Transform()); + { + float sMin = args->_viewport.x / (float)framebufferSize.width(); + float sWidth = args->_viewport.z / (float)framebufferSize.width(); + float tMin = args->_viewport.y / (float)framebufferSize.height(); + float tHeight = args->_viewport.w / (float)framebufferSize.height(); + Transform model; + batch.setPipeline(_blitLightBuffer); + model.setTranslation(glm::vec3(sMin, tMin, 0.0)); + model.setScale(glm::vec3(sWidth, tHeight, 1.0)); + batch.setModelTransform(model); + } + + batch.setUniformBuffer(3, _parametersBuffer); + batch.setResourceTexture(0, lightingBuffer); + batch.draw(gpu::TRIANGLE_STRIP, 4); + }); +} \ No newline at end of file diff --git a/libraries/render-utils/src/ToneMappingEffect.h b/libraries/render-utils/src/ToneMappingEffect.h new file mode 100644 index 0000000000..20ee9024cf --- /dev/null +++ b/libraries/render-utils/src/ToneMappingEffect.h @@ -0,0 +1,64 @@ +// +// ToneMappingEffect.h +// libraries/render-utils/src +// +// Created by Sam Gateau on 12/7/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_ToneMappingEffect_h +#define hifi_ToneMappingEffect_h + +#include +#include + +#include +#include + +class RenderArgs; + +class ToneMappingEffect { +public: + ToneMappingEffect(); + virtual ~ToneMappingEffect() {} + + void render(RenderArgs* args); + + void setExposure(float exposure); + float getExposure() const { return _parametersBuffer.get()._exposure; } + + // Different tone curve available + enum ToneCurve { + None = 0, + Gamma22, + Reinhard, + Filmic, + }; + void setToneCurve(ToneCurve curve); + ToneCurve getToneCurve() const { return (ToneCurve)_parametersBuffer.get()._toneCurve; } + +private: + + gpu::PipelinePointer _blitLightBuffer; + + // Class describing the uniform buffer with all the parameters common to the tone mapping shaders + class Parameters { + public: + float _exposure = 0.0f; + float _twoPowExposure = 1.0f; + glm::vec2 spareA; + int _toneCurve = Filmic; + glm::vec3 spareB; + + Parameters() {} + }; + typedef gpu::BufferView UniformBufferView; + gpu::BufferView _parametersBuffer; + + void init(); +}; + +#endif // hifi_ToneMappingEffect_h diff --git a/libraries/render-utils/src/animdebugdraw.slv b/libraries/render-utils/src/animdebugdraw.slv index f3117714b0..3cb356c055 100644 --- a/libraries/render-utils/src/animdebugdraw.slv +++ b/libraries/render-utils/src/animdebugdraw.slv @@ -9,16 +9,15 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> out vec4 _color; void main(void) { // pass along the diffuse color - _color = inColor.rgba; + _color = colorToLinearRGBA(inColor.rgba); TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); diff --git a/libraries/render-utils/src/debug_deferred_buffer.slf b/libraries/render-utils/src/debug_deferred_buffer.slf new file mode 100644 index 0000000000..375972cdc3 --- /dev/null +++ b/libraries/render-utils/src/debug_deferred_buffer.slf @@ -0,0 +1,24 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// debug_deferred_buffer.slf +// fragment shader +// +// Created by Clement on 12/3 +// 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 DeferredBuffer.slh@> + +in vec2 uv; +out vec4 outFragColor; + +//SOURCE_PLACEHOLDER + +void main(void) { + outFragColor = getFragmentColor(); +} \ No newline at end of file diff --git a/libraries/render-utils/src/debug_deferred_buffer.slv b/libraries/render-utils/src/debug_deferred_buffer.slv new file mode 100644 index 0000000000..85ff2b651d --- /dev/null +++ b/libraries/render-utils/src/debug_deferred_buffer.slv @@ -0,0 +1,22 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// debug_deferred_buffer.slv +// vertex shader +// +// Created by Clement on 12/3 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include gpu/Inputs.slh@> + +out vec2 uv; + +void main(void) { + uv = (inPosition.xy + 1.0) * 0.5; + gl_Position = inPosition; +} \ No newline at end of file diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 52ecc71a14..ae3b05862e 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -27,7 +27,6 @@ void main(void) { DeferredTransform deferredTransform = getDeferredTransform(); DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { vec3 color = evalLightmappedColor( deferredTransform.viewInverse, diff --git a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf deleted file mode 100755 index 8b0212636e..0000000000 --- a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf +++ /dev/null @@ -1,57 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light.frag -// fragment shader -// -// Created by Andrzej Kapolka on 9/3/14. -// Copyright 2014 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 -// - -// Everything about deferred buffer -<@include DeferredBuffer.slh@> - -<@include DeferredGlobalLight.slh@> - -<$declareEvalLightmappedColor()$> -<$declareEvalAmbientSphereGlobalColor()$> - -// Everything about shadow -<@include Shadow.slh@> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredTransform deferredTransform = getDeferredTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - // Eval shadow Texcoord and then Attenuation - vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position); - float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); - - // Light mapped or not ? - if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - vec3 color = evalLightmappedColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.normal, - frag.diffuse, - frag.specularVal.xyz); - _fragColor = vec4(color, 1.0); - } else { - vec3 color = evalAmbienSphereGlobalColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - _fragColor = vec4(color, frag.normalVal.a); - } -} diff --git a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf deleted file mode 100755 index 97d69f2e63..0000000000 --- a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf +++ /dev/null @@ -1,56 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light.frag -// fragment shader -// -// Created by Andrzej Kapolka on 9/3/14. -// Copyright 2014 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 -// - -// Everything about deferred buffer -<@include DeferredBuffer.slh@> - -<@include DeferredGlobalLight.slh@> -<$declareEvalLightmappedColor()$> -<$declareEvalAmbientSphereGlobalColor()$> - -// Everything about shadow -<@include Shadow.slh@> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredTransform deferredTransform = getDeferredTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - // Eval shadow Texcoord and then Attenuation - vec4 shadowTexcoord = evalShadowTexcoord(frag.position); - float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); - - // Light mapped or not ? - if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - vec3 color = evalLightmappedColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.normal, - frag.diffuse, - frag.specularVal.xyz); - _fragColor = vec4(color, 1.0); - } else { - vec3 color = evalAmbienSphereGlobalColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - _fragColor = vec4(color, frag.normalVal.a); - } -} diff --git a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf deleted file mode 100644 index 4abe8e2e9d..0000000000 --- a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf +++ /dev/null @@ -1,59 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light.frag -// fragment shader -// -// Created by Andrzej Kapolka on 9/3/14. -// Copyright 2014 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 -// - -// Everything about deferred buffer -<@include DeferredBuffer.slh@> - -<@include DeferredGlobalLight.slh@> - -<$declareEvalLightmappedColor()$> -<$declareEvalAmbientGlobalColor()$> - -// Everything about shadow -<@include Shadow.slh@> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredTransform deferredTransform = getDeferredTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - - // Eval shadow Texcoord and then Attenuation - vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position); - float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); - - // Light mapped or not ? - if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - vec3 color = evalLightmappedColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.normal, - frag.diffuse, - frag.specularVal.xyz); - _fragColor = vec4(color, 1.0); - } else { - vec3 color = evalAmbienGlobalColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - - _fragColor = vec4(color, frag.normalVal.a); - } -} diff --git a/libraries/render-utils/src/directional_light_shadow_map.slf b/libraries/render-utils/src/directional_light_shadow_map.slf deleted file mode 100644 index 4249b2787c..0000000000 --- a/libraries/render-utils/src/directional_light_shadow_map.slf +++ /dev/null @@ -1,58 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light.frag -// fragment shader -// -// Created by Andrzej Kapolka on 9/3/14. -// Copyright 2014 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 -// - -// Everything about deferred buffer -<@include DeferredBuffer.slh@> - -<@include DeferredGlobalLight.slh@> - -<$declareEvalLightmappedColor()$> -<$declareEvalAmbientGlobalColor()$> - -// Everything about shadow -<@include Shadow.slh@> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredTransform deferredTransform = getDeferredTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - // Eval shadow Texcoord and then Attenuation - vec4 shadowTexcoord = evalShadowTexcoord(frag.position); - float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); - - // Light mapped or not ? - if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - vec3 color = evalLightmappedColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.normal, - frag.diffuse, - frag.specularVal.xyz); - _fragColor = vec4(color, 1.0); - } else { - vec3 color = evalAmbienGlobalColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - - _fragColor = vec4(color, frag.normalVal.a); - } -} diff --git a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf deleted file mode 100755 index 3c09bf62b6..0000000000 --- a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf +++ /dev/null @@ -1,59 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light.frag -// fragment shader -// -// Created by Sam Gateau on 5/8/2015. -// Copyright 2014 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 -// - -// Everything about deferred buffer -<@include DeferredBuffer.slh@> - -<@include DeferredGlobalLight.slh@> - -<$declareEvalLightmappedColor()$> -<$declareEvalSkyboxGlobalColor()$> - -// Everything about shadow -<@include Shadow.slh@> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredTransform deferredTransform = getDeferredTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - // Eval shadow Texcoord and then Attenuation - vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position); - float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); - - // Light mapped or not ? - if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - vec3 color = evalLightmappedColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.normal, - frag.diffuse, - frag.specularVal.xyz); - - _fragColor = vec4(color, 1.0); - } else { - vec3 color = evalSkyboxGlobalColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - - _fragColor = vec4(color, frag.normalVal.a); - } -} diff --git a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_shadow_map.slf deleted file mode 100755 index 6f709f31fa..0000000000 --- a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf +++ /dev/null @@ -1,58 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light.frag -// fragment shader -// -// Created by Sam Gateau on 5/8/2015. -// Copyright 2014 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 -// - -// Everything about deferred buffer -<@include DeferredBuffer.slh@> - -<@include DeferredGlobalLight.slh@> - -<$declareEvalLightmappedColor()$> -<$declareEvalSkyboxGlobalColor()$> - -// Everything about shadow -<@include Shadow.slh@> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredTransform deferredTransform = getDeferredTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - // Eval shadow Texcoord and then Attenuation - vec4 shadowTexcoord = evalShadowTexcoord(frag.position); - float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); - - // Light mapped or not ? - if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - vec3 color = evalLightmappedColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.normal, - frag.diffuse, - frag.specularVal.xyz); - _fragColor = vec4(color, 1.0); - } else { - vec3 color = evalSkyboxGlobalColor( - deferredTransform.viewInverse, - shadowAttenuation, - frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss); - - _fragColor = vec4(color, frag.normalVal.a); - } -} diff --git a/libraries/render-utils/src/hit_effect.slf b/libraries/render-utils/src/hit_effect.slf index c059488ba1..cc4484442f 100644 --- a/libraries/render-utils/src/hit_effect.slf +++ b/libraries/render-utils/src/hit_effect.slf @@ -20,8 +20,8 @@ in vec2 varQuadPosition; out vec4 outFragColor; void main(void) { - vec2 center = vec2(0.0, 0.0); - float distFromCenter = distance( vec2(0.0, 0.0), varQuadPosition); - float alpha = mix(0.0, 0.5, pow(distFromCenter,5.)); - outFragColor = vec4(1.0, 0.0, 0.0, alpha); + vec2 center = vec2(0.0, 0.0); + float distFromCenter = distance( vec2(0.0, 0.0), varQuadPosition); + float alpha = mix(0.0, 0.5, pow(distFromCenter,5.)); + outFragColor = vec4(1.0, 0.0, 0.0, alpha); } \ No newline at end of file diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv index 6d56833de1..47de20a5d9 100755 --- a/libraries/render-utils/src/model.slv +++ b/libraries/render-utils/src/model.slv @@ -12,9 +12,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> const int MAX_TEXCOORDS = 2; @@ -27,9 +26,8 @@ out vec3 _color; out vec2 _texCoord0; void main(void) { - - // pass along the diffuse color - _color = inColor.xyz; + // pass along the diffuse color in linear space + _color = colorToLinearRGB(inColor.xyz); // and the texture coordinates _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; diff --git a/libraries/render-utils/src/model_lightmap.slv b/libraries/render-utils/src/model_lightmap.slv index 7742896228..eacc91245c 100755 --- a/libraries/render-utils/src/model_lightmap.slv +++ b/libraries/render-utils/src/model_lightmap.slv @@ -13,9 +13,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> const int MAX_TEXCOORDS = 2; @@ -29,7 +28,8 @@ out vec3 _normal; out vec3 _color; void main(void) { - _color = inColor.xyz; + // pass along the diffuse color in linear space + _color = colorToLinearRGB(inColor.xyz); // and the texture coordinates _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slv b/libraries/render-utils/src/model_lightmap_normal_map.slv index f63030301f..6046a67e10 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slv +++ b/libraries/render-utils/src/model_lightmap_normal_map.slv @@ -13,9 +13,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> const int MAX_TEXCOORDS = 2; @@ -30,7 +29,8 @@ out vec3 _tangent; out vec3 _color; void main(void) { - _color = inColor.xyz; + // pass along the diffuse color in linear space + _color = colorToLinearRGB(inColor.xyz); // and the texture coordinates _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; diff --git a/libraries/render-utils/src/model_normal_map.slv b/libraries/render-utils/src/model_normal_map.slv index e989c1c294..5ed4e37278 100755 --- a/libraries/render-utils/src/model_normal_map.slv +++ b/libraries/render-utils/src/model_normal_map.slv @@ -13,9 +13,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> const int MAX_TEXCOORDS = 2; @@ -30,7 +29,7 @@ out vec3 _color; void main(void) { // pass along the diffuse color - _color = inColor.rgb; + _color = colorToLinearRGB(inColor.xyz); // and the texture coordinates _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.xy, 0.0, 1.0)).st; diff --git a/libraries/render-utils/src/overlay3D.slv b/libraries/render-utils/src/overlay3D.slv index a57f02d854..74416f0c1f 100644 --- a/libraries/render-utils/src/overlay3D.slv +++ b/libraries/render-utils/src/overlay3D.slv @@ -11,9 +11,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> out vec2 varTexcoord; @@ -30,7 +29,7 @@ void main(void) { varTexcoord = inTexCoord0.xy; // pass along the color - varColor = inColor; + varColor = colorToLinearRGBA(inColor); // standard transform TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index e9045e18c5..716a39aee9 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -66,7 +66,7 @@ void main(void) { float radialAttenuation = evalLightAttenuation(light, fragLightDistance); // Final Lighting color - vec3 fragColor = shading.w * (frag.diffuse + shading.xyz); + vec3 fragColor = (shading.w * frag.diffuse + shading.xyz); _fragColor = vec4(fragColor * radialAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); if (getLightShowContour(light) > 0.0) { diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 576acf9340..8c93ee564e 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -40,6 +40,8 @@ void main(void) { #ifdef PROCEDURAL_V1 specular = getProceduralColor().rgb; + // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline + specular = pow(specular, vec3(2.2)); emissiveAmount = 1.0; #else emissiveAmount = getProceduralColors(diffuse, specular, shininess); diff --git a/libraries/render-utils/src/simple.slv b/libraries/render-utils/src/simple.slv index 823654ec27..59b16cf0e5 100644 --- a/libraries/render-utils/src/simple.slv +++ b/libraries/render-utils/src/simple.slv @@ -13,9 +13,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> uniform bool Instanced = false; @@ -28,7 +27,7 @@ out vec2 _texCoord0; out vec4 _position; void main(void) { - _color = inColor.rgb; + _color = colorToLinearRGB(inColor.rgb); _texCoord0 = inTexCoord0.st; _position = inPosition; _modelNormal = inNormal.xyz; diff --git a/libraries/render-utils/src/skin_model.slv b/libraries/render-utils/src/skin_model.slv index cba419dd4d..8ab475e1fd 100755 --- a/libraries/render-utils/src/skin_model.slv +++ b/libraries/render-utils/src/skin_model.slv @@ -13,9 +13,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> <@include Skinning.slh@> @@ -34,7 +33,7 @@ void main(void) { skinPositionNormal(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, position, interpolatedNormal); // pass along the diffuse color - _color = inColor.rgb; + _color = colorToLinearRGB(inColor.rgb); // and the texture coordinates _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; diff --git a/libraries/render-utils/src/skin_model_normal_map.slv b/libraries/render-utils/src/skin_model_normal_map.slv index 5dfe5ba957..cec93a024e 100755 --- a/libraries/render-utils/src/skin_model_normal_map.slv +++ b/libraries/render-utils/src/skin_model_normal_map.slv @@ -13,9 +13,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> <@include Skinning.slh@> @@ -36,7 +35,7 @@ void main(void) { skinPositionNormalTangent(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, inTangent.xyz, position, interpolatedNormal.xyz, interpolatedTangent.xyz); // pass along the diffuse color - _color = inColor.rgb; + _color = colorToLinearRGB(inColor.rgb); // and the texture coordinates _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 73b081260e..d7a20fc5e5 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -73,7 +73,7 @@ void main(void) { float angularAttenuation = evalLightSpotAttenuation(light, cosSpotAngle); // Final Lighting color - vec3 fragColor = shading.w * (frag.diffuse + shading.xyz); + vec3 fragColor = (shading.w * frag.diffuse + shading.xyz); _fragColor = vec4(fragColor * angularAttenuation * radialAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); if (getLightShowContour(light) > 0.0) { diff --git a/libraries/render-utils/src/standardTransformPNTC.slv b/libraries/render-utils/src/standardTransformPNTC.slv index 340dfd9c8e..f7e72b6997 100644 --- a/libraries/render-utils/src/standardTransformPNTC.slv +++ b/libraries/render-utils/src/standardTransformPNTC.slv @@ -13,9 +13,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> out vec3 varPosition; @@ -25,7 +24,7 @@ out vec4 varColor; void main(void) { varTexCoord0 = inTexCoord0.st; - varColor = inColor; + varColor = colorToLinearRGBA(inColor); // standard transform TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/stars.slv b/libraries/render-utils/src/stars.slv index b9ad736d5e..d00bb8b7dd 100644 --- a/libraries/render-utils/src/stars.slv +++ b/libraries/render-utils/src/stars.slv @@ -13,9 +13,8 @@ // <@include gpu/Inputs.slh@> - +<@include gpu/Color.slh@> <@include gpu/Transform.slh@> - <$declareStandardTransform()$> // TODO we need to get the viewport resolution and FOV passed to us so we can modify the point size @@ -26,7 +25,7 @@ out vec4 varColor; out float varSize; void main(void) { - varColor = inColor.rgba; + varColor = colorToLinearRGBA(inColor); // standard transform TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 5587185ead..43202c29c2 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -198,11 +198,11 @@ void Font::read(QIODevice& in) { image = image.convertToFormat(QImage::Format_RGBA8888); - gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB); - gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB); + gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); + gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); if (image.hasAlphaChannel()) { - formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA); - formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::BGRA); + formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); + formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::BGRA); } _texture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR))); diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 3f37ce378b..fa177bd0d4 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -97,9 +97,9 @@ const gpu::TexturePointer DrawStatus::getStatusIconMap() const { void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); - RenderArgs* args = renderContext->args; + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); + RenderArgs* args = renderContext->getArgs(); auto& scene = sceneContext->_scene; const int NUM_STATUS_VEC4_PER_ITEM = 2; const int VEC4_LENGTH = 4; @@ -179,7 +179,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const unsigned int VEC3_ADRESS_OFFSET = 3; - if ((renderContext->_drawItemStatus & showDisplayStatusFlag) > 0) { + if ((renderContext->getDrawStatus() & showDisplayStatusFlag) > 0) { for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i)); batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); @@ -192,7 +192,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, batch.setPipeline(getDrawItemStatusPipeline()); - if ((renderContext->_drawItemStatus & showNetworkStatusFlag) > 0) { + if ((renderContext->getDrawStatus() & showNetworkStatusFlag) > 0) { for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i)); batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index c0e50037e0..44ba57143f 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -37,7 +37,7 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon // Is it possible that we render without a viewFrustum ? - if (!(renderContext->args && renderContext->args->_viewFrustum)) { + if (!(renderContext->getArgs() && renderContext->getArgs()->_viewFrustum)) { return; } @@ -54,11 +54,11 @@ Job::~Job() { void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); - RenderArgs* args = renderContext->args; - auto renderDetails = renderContext->args->_details._item; + RenderArgs* args = renderContext->getArgs(); + auto renderDetails = renderContext->getArgs()->_details._item; renderDetails->_considered += inItems.size(); @@ -115,7 +115,7 @@ void CullItems::run(const SceneContextPointer& sceneContext, const RenderContext outItems.clear(); outItems.reserve(inItems.size()); - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); args->_details.pointTo(RenderDetails::OTHER_ITEM); cullItems(sceneContext, renderContext, inItems, outItems); } @@ -124,7 +124,7 @@ void CullItemsOpaque::run(const SceneContextPointer& sceneContext, const RenderC outItems.clear(); outItems.reserve(inItems.size()); - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); args->_details.pointTo(RenderDetails::OPAQUE_ITEM); cullItems(sceneContext, renderContext, inItems, outItems); } @@ -133,7 +133,7 @@ void CullItemsTransparent::run(const SceneContextPointer& sceneContext, const Re outItems.clear(); outItems.reserve(inItems.size()); - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); args->_details.pointTo(RenderDetails::TRANSLUCENT_ITEM); cullItems(sceneContext, renderContext, inItems, outItems); } @@ -163,11 +163,11 @@ struct BackToFrontSort { }; void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); auto& scene = sceneContext->_scene; - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); // Allocate and simply copy @@ -211,7 +211,7 @@ void DepthSortItems::run(const SceneContextPointer& sceneContext, const RenderCo void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, int maxDrawnItems) { auto& scene = sceneContext->_scene; - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); // render if ((maxDrawnItems < 0) || (maxDrawnItems > (int) inItems.size())) { for (auto itemDetails : inItems) { @@ -236,8 +236,8 @@ void render::renderItems(const SceneContextPointer& sceneContext, const RenderCo } void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); // render lights auto& scene = sceneContext->_scene; @@ -253,7 +253,7 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext ItemIDsBounds culledItems; culledItems.reserve(inItems.size()); - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); args->_details.pointTo(RenderDetails::OTHER_ITEM); cullItems(sceneContext, renderContext, inItems, culledItems); @@ -265,8 +265,8 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext } void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); + assert(renderContext->getArgs()); + assert(renderContext->getArgs()->_viewFrustum); // render backgrounds auto& scene = sceneContext->_scene; @@ -278,7 +278,7 @@ void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderCo for (auto id : items) { inItems.emplace_back(id); } - RenderArgs* args = renderContext->args; + RenderArgs* args = renderContext->getArgs(); doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; batch.enableSkybox(true); diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 3f628c3a02..ab102e32a7 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -84,6 +84,17 @@ public: const Varying getInput() const { return _concept->getInput(); } const Varying getOutput() const { return _concept->getOutput(); } + template T& edit() { + auto theConcept = std::dynamic_pointer_cast(_concept); + assert(theConcept); + return theConcept->_data; + } + template const T& get() const { + auto theConcept = std::dynamic_pointer_cast(_concept); + assert(theConcept); + return theConcept->_data; + } + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer(getName().c_str()); PROFILE_RANGE(getName().c_str()); diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp index 86f35eb831..c38ceda034 100644 --- a/libraries/render/src/render/Engine.cpp +++ b/libraries/render/src/render/Engine.cpp @@ -13,6 +13,19 @@ #include "DrawTask.h" using namespace render; +RenderContext::RenderContext(ItemsConfig items, Tone tone, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode) + : _args{ nullptr }, _items{ items }, _tone{ tone }, + _drawStatus{ drawStatus }, _drawHitEffect{ drawHitEffect }, + _deferredDebugSize{ deferredDebugSize }, _deferredDebugMode{ deferredDebugMode } {}; + +void RenderContext::setOptions(bool occlusion, bool fxaa, bool showOwned) { + _occlusionStatus = occlusion; + _fxaaStatus = fxaa; + + if (showOwned) { + _drawStatus |= render::showNetworkStatusFlag; + } +}; Engine::Engine() : _sceneContext(std::make_shared()), diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 7c11246cff..02f3bf3b2c 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -23,7 +23,7 @@ public: SceneContext() {} }; -typedef std::shared_ptr SceneContextPointer; +using SceneContextPointer = std::shared_ptr; // see examples/utilities/tools/renderEngineDebug.js const int showDisplayStatusFlag = 1; @@ -32,38 +32,83 @@ const int showNetworkStatusFlag = 2; class RenderContext { public: - RenderArgs* args; + class ItemsConfig { + public: + class Counter { + public: + Counter() {}; + Counter(const Counter& counter) { + numFeed = numDrawn = 0; + maxDrawn = counter.maxDrawn; + }; - bool _cullOpaque = true; - bool _sortOpaque = true; - bool _renderOpaque = true; - bool _cullTransparent = true; - bool _sortTransparent = true; - bool _renderTransparent = true; + void setCounts(const Counter& counter) { + numFeed = counter.numFeed; + numDrawn = counter.numDrawn; + }; - int _numFeedOpaqueItems = 0; - int _numDrawnOpaqueItems = 0; - int _maxDrawnOpaqueItems = -1; + 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; + }; - int _numFeedTransparentItems = 0; - int _numDrawnTransparentItems = 0; - int _maxDrawnTransparentItems = -1; + RenderContext(ItemsConfig items, Tone tone, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode); + RenderContext() : RenderContext({}, {}, {}, {}, {}, {}) {}; - int _numFeedOverlay3DItems = 0; - int _numDrawnOverlay3DItems = 0; - int _maxDrawnOverlay3DItems = -1; + void setArgs(RenderArgs* args) { _args = args; } + inline RenderArgs* getArgs() { return _args; } + inline ItemsConfig& getItemsConfig() { return _items; } + inline Tone& getTone() { return _tone; } + 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); - int _drawItemStatus = 0; + // Debugging + int _deferredDebugMode = -1; + glm::vec4 _deferredDebugSize { 0.0f, -1.0f, 1.0f, 1.0f }; + +protected: + RenderArgs* _args; + + // Options + int _drawStatus = 0; // bitflag bool _drawHitEffect = false; - bool _occlusionStatus = false; bool _fxaaStatus = false; - RenderContext() {} + ItemsConfig _items; + Tone _tone; }; typedef std::shared_ptr RenderContextPointer; -// THe base class for a task that runs on the SceneContext +// The base class for a task that runs on the SceneContext class Task { public: Task() {} @@ -76,7 +121,7 @@ protected: typedef std::shared_ptr TaskPointer; typedef std::vector Tasks; -// The root of the takss, the Engine, should not be known from the 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 { public: diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index 59d2765659..062e502d6e 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -1,6 +1,6 @@ // // SceneScriptingInterface.cpp -// interface/src/scripting +// libraries/script-engine // // Created by Sam Gateau on 2/24/15. // Copyright 2014 High Fidelity, Inc. @@ -11,90 +11,97 @@ #include "SceneScriptingInterface.h" -#include - - #include -SceneScriptingInterface::SceneScriptingInterface() { - // Let's make sure the sunSkyStage is using a proceduralSKybox - _skyStage->setSkybox(model::SkyboxPointer(new ProceduralSkybox())); -} - -void SceneScriptingInterface::setStageOrientation(const glm::quat& orientation) { - _skyStage->setOriginOrientation(orientation); -} -void SceneScriptingInterface::setStageLocation(float longitude, float latitude, float altitude) { - _skyStage->setOriginLocation(longitude, latitude, altitude); -} - -float SceneScriptingInterface::getStageLocationLongitude() const { +float SceneScripting::Location::getLongitude() const { return _skyStage->getOriginLongitude(); } -float SceneScriptingInterface::getStageLocationLatitude() const { + +float SceneScripting::Location::getLatitude() const { return _skyStage->getOriginLatitude(); } -float SceneScriptingInterface::getStageLocationAltitude() const { + +float SceneScripting::Location::getAltitude() const { return _skyStage->getOriginSurfaceAltitude(); } -void SceneScriptingInterface::setStageDayTime(float hour) { +void SceneScripting::Location::setLongitude(float longitude) { + _skyStage->setOriginLongitude(longitude); +} + +void SceneScripting::Location::setLatitude(float latitude) { + _skyStage->setOriginLatitude(latitude); +} + +void SceneScripting::Location::setAltitude(float altitude) { + _skyStage->setOriginSurfaceAltitude(altitude); +} + +void SceneScripting::Time::setHour(float hour) { _skyStage->setDayTime(hour); } -float SceneScriptingInterface::getStageDayTime() const { +float SceneScripting::Time::getHour() const { return _skyStage->getDayTime(); } -void SceneScriptingInterface::setStageYearTime(int day) { +void SceneScripting::Time::setDay(int day) { _skyStage->setYearTime(day); } -int SceneScriptingInterface::getStageYearTime() const { +int SceneScripting::Time::getDay() const { return _skyStage->getYearTime(); } -void SceneScriptingInterface::setKeyLightColor(const glm::vec3& color) { - _skyStage->setSunColor(color); -} - -glm::vec3 SceneScriptingInterface::getKeyLightColor() const { +glm::vec3 SceneScripting::KeyLight::getColor() const { return _skyStage->getSunColor(); } -void SceneScriptingInterface::setKeyLightIntensity(float intensity) { - _skyStage->setSunIntensity(intensity); +void SceneScripting::KeyLight::setColor(const glm::vec3& color) { + _skyStage->setSunColor(color); } -float SceneScriptingInterface::getKeyLightIntensity() const { +float SceneScripting::KeyLight::getIntensity() const { return _skyStage->getSunIntensity(); } -void SceneScriptingInterface::setKeyLightAmbientIntensity(float intensity) { - _skyStage->setSunAmbientIntensity(intensity); +void SceneScripting::KeyLight::setIntensity(float intensity) { + _skyStage->setSunIntensity(intensity); } -float SceneScriptingInterface::getKeyLightAmbientIntensity() const { +float SceneScripting::KeyLight::getAmbientIntensity() const { return _skyStage->getSunAmbientIntensity(); } -void SceneScriptingInterface::setKeyLightDirection(const glm::vec3& direction) { - _skyStage->setSunDirection(direction); +void SceneScripting::KeyLight::setAmbientIntensity(float intensity) { + _skyStage->setSunAmbientIntensity(intensity); } -glm::vec3 SceneScriptingInterface::getKeyLightDirection() const { +glm::vec3 SceneScripting::KeyLight::getDirection() const { return _skyStage->getSunDirection(); } -void SceneScriptingInterface::setStageSunModelEnable(bool isEnabled) { +void SceneScripting::KeyLight::setDirection(const glm::vec3& direction) { + _skyStage->setSunDirection(direction); +} + +void SceneScripting::Stage::setOrientation(const glm::quat& orientation) const { + _skyStage->setOriginOrientation(orientation); +} + +void SceneScripting::Stage::setLocation(float longitude, float latitude, float altitude) { + _skyStage->setOriginLocation(longitude, latitude, altitude); +} + +void SceneScripting::Stage::setSunModelEnable(bool isEnabled) { _skyStage->setSunModelEnable(isEnabled); } -bool SceneScriptingInterface::isStageSunModelEnabled() const { +bool SceneScripting::Stage::isSunModelEnabled() const { return _skyStage->isSunModelEnabled(); } -void SceneScriptingInterface::setBackgroundMode(const QString& mode) { +void SceneScripting::Stage::setBackgroundMode(const QString& mode) { if (mode == QString("inherit")) { _skyStage->setBackgroundMode(model::SunSkyStage::NO_BACKGROUND); } else if (mode == QString("atmosphere")) { @@ -104,7 +111,7 @@ void SceneScriptingInterface::setBackgroundMode(const QString& mode) { } } -QString SceneScriptingInterface::getBackgroundMode() const { +QString SceneScripting::Stage::getBackgroundMode() const { switch (_skyStage->getBackgroundMode()) { case model::SunSkyStage::NO_BACKGROUND: return QString("inherit"); @@ -117,8 +124,9 @@ QString SceneScriptingInterface::getBackgroundMode() const { }; } -model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { - return _skyStage; +SceneScriptingInterface::SceneScriptingInterface() : _stage{ new SceneScripting::Stage{ _skyStage } } { + // Let's make sure the sunSkyStage is using a proceduralSkybox + _skyStage->setSkybox(model::SkyboxPointer(new ProceduralSkybox())); } void SceneScriptingInterface::setShouldRenderAvatars(bool shouldRenderAvatars) { @@ -135,35 +143,6 @@ void SceneScriptingInterface::setShouldRenderEntities(bool 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; - _numFeedOverlay3DItems = 0; - _numDrawnOverlay3DItems = 0; +model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { + return _skyStage; } diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 8cd48d9ddd..0be8b066aa 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -1,6 +1,6 @@ // // SceneScriptingInterface.h -// interface/src/scripting +// libraries/script-engine // // Created by Sam Gateau on 2/24/15. // Copyright 2014 High Fidelity, Inc. @@ -12,141 +12,149 @@ #ifndef hifi_SceneScriptingInterface_h #define hifi_SceneScriptingInterface_h -#include - -#include +#include // QObject +#include // Dependency #include "model/Stage.h" +// TODO: if QT moc ever supports nested classes, subclass these to the interface instead of namespacing +namespace SceneScripting { + class Location : public QObject { + Q_OBJECT + + public: + Location(model::SunSkyStagePointer skyStage) : _skyStage{ skyStage } {} + + Q_PROPERTY(float longitude READ getLongitude WRITE setLongitude) + Q_PROPERTY(float latitude READ getLatitude WRITE setLatitude) + Q_PROPERTY(float altitude READ getAltitude WRITE setAltitude) + + float getLongitude() const; + float getLatitude() const; + float getAltitude() const; + void setLongitude(float longitude); + void setLatitude(float latitude); + void setAltitude(float altitude); + + protected: + model::SunSkyStagePointer _skyStage; + }; + using LocationPointer = std::unique_ptr; + + class Time : public QObject { + Q_OBJECT + + public: + Time(model::SunSkyStagePointer skyStage) : _skyStage{ skyStage } {} + + Q_PROPERTY(float hour READ getHour WRITE setHour) + Q_PROPERTY(int day READ getDay WRITE setDay) + + float getHour() const; + void setHour(float hour); + int getDay() const; + void setDay(int day); + + protected: + model::SunSkyStagePointer _skyStage; + }; + using TimePointer = std::unique_ptr