mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 08:03:34 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into raypick-avatars
This commit is contained in:
commit
5c69e55475
38 changed files with 1623 additions and 578 deletions
|
@ -44,6 +44,8 @@ function(AUTOSCRIBE_SHADER SHADER_FILE)
|
||||||
set(SHADER_TARGET ${SHADER_TARGET}_vert.h)
|
set(SHADER_TARGET ${SHADER_TARGET}_vert.h)
|
||||||
elseif(${SHADER_EXT} STREQUAL .slf)
|
elseif(${SHADER_EXT} STREQUAL .slf)
|
||||||
set(SHADER_TARGET ${SHADER_TARGET}_frag.h)
|
set(SHADER_TARGET ${SHADER_TARGET}_frag.h)
|
||||||
|
elseif(${SHADER_EXT} STREQUAL .slg)
|
||||||
|
set(SHADER_TARGET ${SHADER_TARGET}_geom.h)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_TARGET}")
|
set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_TARGET}")
|
||||||
|
@ -87,7 +89,7 @@ macro(AUTOSCRIBE_SHADER_LIB)
|
||||||
#message(${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
|
#message(${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
|
||||||
|
|
||||||
file(GLOB_RECURSE SHADER_INCLUDE_FILES src/*.slh)
|
file(GLOB_RECURSE SHADER_INCLUDE_FILES src/*.slh)
|
||||||
file(GLOB_RECURSE SHADER_SOURCE_FILES src/*.slv src/*.slf)
|
file(GLOB_RECURSE SHADER_SOURCE_FILES src/*.slv src/*.slf src/*.slg)
|
||||||
|
|
||||||
#make the shader folder
|
#make the shader folder
|
||||||
set(SHADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders/${TARGET_NAME}")
|
set(SHADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders/${TARGET_NAME}")
|
||||||
|
|
|
@ -389,6 +389,8 @@ void DomainServer::setupNodeListAndAssignments() {
|
||||||
const QVariant* idValueVariant = valueForKeyPath(settingsMap, METAVERSE_DOMAIN_ID_KEY_PATH);
|
const QVariant* idValueVariant = valueForKeyPath(settingsMap, METAVERSE_DOMAIN_ID_KEY_PATH);
|
||||||
if (idValueVariant) {
|
if (idValueVariant) {
|
||||||
nodeList->setSessionUUID(idValueVariant->toString());
|
nodeList->setSessionUUID(idValueVariant->toString());
|
||||||
|
} else {
|
||||||
|
nodeList->setSessionUUID(QUuid::createUuid()); // Use random UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded);
|
connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded);
|
||||||
|
|
BIN
interface/resources/images/Loading-Inner-H.png
Normal file
BIN
interface/resources/images/Loading-Inner-H.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
interface/resources/images/Loading-Outer-Ring.png
Normal file
BIN
interface/resources/images/Loading-Outer-Ring.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
|
@ -3,12 +3,14 @@ import QtQuick.Controls 1.2
|
||||||
import QtWebEngine 1.1
|
import QtWebEngine 1.1
|
||||||
|
|
||||||
import "controls-uit"
|
import "controls-uit"
|
||||||
|
import "styles" as HifiStyles
|
||||||
import "styles-uit"
|
import "styles-uit"
|
||||||
import "windows"
|
import "windows"
|
||||||
|
|
||||||
ScrollingWindow {
|
ScrollingWindow {
|
||||||
id: root
|
id: root
|
||||||
HifiConstants { id: hifi }
|
HifiConstants { id: hifi }
|
||||||
|
HifiStyles.HifiConstants { id: hifistyles }
|
||||||
title: "Browser"
|
title: "Browser"
|
||||||
resizable: true
|
resizable: true
|
||||||
destroyOnHidden: true
|
destroyOnHidden: true
|
||||||
|
@ -46,7 +48,7 @@ ScrollingWindow {
|
||||||
id: back;
|
id: back;
|
||||||
enabled: webview.canGoBack;
|
enabled: webview.canGoBack;
|
||||||
text: hifi.glyphs.backward
|
text: hifi.glyphs.backward
|
||||||
color: enabled ? hifi.colors.text : hifi.colors.disabledText
|
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
|
||||||
size: 48
|
size: 48
|
||||||
MouseArea { anchors.fill: parent; onClicked: webview.goBack() }
|
MouseArea { anchors.fill: parent; onClicked: webview.goBack() }
|
||||||
}
|
}
|
||||||
|
@ -55,7 +57,7 @@ ScrollingWindow {
|
||||||
id: forward;
|
id: forward;
|
||||||
enabled: webview.canGoForward;
|
enabled: webview.canGoForward;
|
||||||
text: hifi.glyphs.forward
|
text: hifi.glyphs.forward
|
||||||
color: enabled ? hifi.colors.text : hifi.colors.disabledText
|
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
|
||||||
size: 48
|
size: 48
|
||||||
MouseArea { anchors.fill: parent; onClicked: webview.goForward() }
|
MouseArea { anchors.fill: parent; onClicked: webview.goForward() }
|
||||||
}
|
}
|
||||||
|
@ -64,7 +66,7 @@ ScrollingWindow {
|
||||||
id: reload;
|
id: reload;
|
||||||
enabled: webview.canGoForward;
|
enabled: webview.canGoForward;
|
||||||
text: webview.loading ? hifi.glyphs.close : hifi.glyphs.reload
|
text: webview.loading ? hifi.glyphs.close : hifi.glyphs.reload
|
||||||
color: enabled ? hifi.colors.text : hifi.colors.disabledText
|
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
|
||||||
size: 48
|
size: 48
|
||||||
MouseArea { anchors.fill: parent; onClicked: webview.goForward() }
|
MouseArea { anchors.fill: parent; onClicked: webview.goForward() }
|
||||||
}
|
}
|
||||||
|
@ -105,7 +107,7 @@ ScrollingWindow {
|
||||||
focus: true
|
focus: true
|
||||||
colorScheme: hifi.colorSchemes.dark
|
colorScheme: hifi.colorSchemes.dark
|
||||||
placeholderText: "Enter URL"
|
placeholderText: "Enter URL"
|
||||||
Component.onCompleted: scriptsModel.filterRegExp = new RegExp("^.*$", "i")
|
Component.onCompleted: ScriptDiscoveryService.scriptsModelFilter.filterRegExp = new RegExp("^.*$", "i")
|
||||||
Keys.onPressed: {
|
Keys.onPressed: {
|
||||||
switch(event.key) {
|
switch(event.key) {
|
||||||
case Qt.Key_Enter:
|
case Qt.Key_Enter:
|
||||||
|
|
|
@ -3,13 +3,16 @@ import QtQuick 2.3
|
||||||
import QtQuick.Controls 1.3
|
import QtQuick.Controls 1.3
|
||||||
import QtQuick.Controls.Styles 1.3
|
import QtQuick.Controls.Styles 1.3
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import "controls-uit"
|
import "controls-uit"
|
||||||
|
import "styles" as HifiStyles
|
||||||
import "styles-uit"
|
import "styles-uit"
|
||||||
import "windows"
|
import "windows"
|
||||||
|
|
||||||
ScrollingWindow {
|
ScrollingWindow {
|
||||||
id: root
|
id: root
|
||||||
HifiConstants { id: hifi }
|
HifiConstants { id: hifi }
|
||||||
|
HifiStyles.HifiConstants { id: hifistyles }
|
||||||
objectName: "UpdateDialog"
|
objectName: "UpdateDialog"
|
||||||
width: updateDialog.implicitWidth
|
width: updateDialog.implicitWidth
|
||||||
height: updateDialog.implicitHeight
|
height: updateDialog.implicitHeight
|
||||||
|
@ -40,22 +43,6 @@ ScrollingWindow {
|
||||||
|
|
||||||
width: updateDialog.contentWidth + updateDialog.borderWidth * 2
|
width: updateDialog.contentWidth + updateDialog.borderWidth * 2
|
||||||
height: mainContent.height + updateDialog.borderWidth * 2 - updateDialog.closeMargin / 2
|
height: mainContent.height + updateDialog.borderWidth * 2 - updateDialog.closeMargin / 2
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
drag {
|
|
||||||
target: root
|
|
||||||
minimumX: 0
|
|
||||||
minimumY: 0
|
|
||||||
maximumX: root.parent ? root.maximumX : 0
|
|
||||||
maximumY: root.parent ? root.maximumY : 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -89,7 +76,7 @@ ScrollingWindow {
|
||||||
text: "Update Available"
|
text: "Update Available"
|
||||||
font {
|
font {
|
||||||
family: updateDialog.fontFamily
|
family: updateDialog.fontFamily
|
||||||
pixelSize: hifi.fonts.pixelSize * 1.5
|
pixelSize: hifistyles.fonts.pixelSize * 1.5
|
||||||
weight: Font.DemiBold
|
weight: Font.DemiBold
|
||||||
}
|
}
|
||||||
color: "#303030"
|
color: "#303030"
|
||||||
|
@ -100,10 +87,10 @@ ScrollingWindow {
|
||||||
text: updateDialog.updateAvailableDetails
|
text: updateDialog.updateAvailableDetails
|
||||||
font {
|
font {
|
||||||
family: updateDialog.fontFamily
|
family: updateDialog.fontFamily
|
||||||
pixelSize: hifi.fonts.pixelSize * 0.6
|
pixelSize: hifistyles.fonts.pixelSize * 0.6
|
||||||
letterSpacing: -0.5
|
letterSpacing: -0.5
|
||||||
}
|
}
|
||||||
color: hifi.colors.text
|
color: hifistyles.colors.text
|
||||||
anchors {
|
anchors {
|
||||||
top: updateAvailable.bottom
|
top: updateAvailable.bottom
|
||||||
}
|
}
|
||||||
|
@ -130,12 +117,12 @@ ScrollingWindow {
|
||||||
Text {
|
Text {
|
||||||
id: releaseNotes
|
id: releaseNotes
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
width: parent.width - updateDialog.closeMargin
|
width: parent.parent.width - updateDialog.closeMargin
|
||||||
text: updateDialog.releaseNotes
|
text: updateDialog.releaseNotes
|
||||||
color: hifi.colors.text
|
color: hifistyles.colors.text
|
||||||
font {
|
font {
|
||||||
family: updateDialog.fontFamily
|
family: updateDialog.fontFamily
|
||||||
pixelSize: hifi.fonts.pixelSize * 0.65
|
pixelSize: hifistyles.fonts.pixelSize * 0.65
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +144,7 @@ ScrollingWindow {
|
||||||
color: "#0c9ab4" // Same as logo
|
color: "#0c9ab4" // Same as logo
|
||||||
font {
|
font {
|
||||||
family: updateDialog.fontFamily
|
family: updateDialog.fontFamily
|
||||||
pixelSize: hifi.fonts.pixelSize * 1.2
|
pixelSize: hifistyles.fonts.pixelSize * 1.2
|
||||||
weight: Font.DemiBold
|
weight: Font.DemiBold
|
||||||
}
|
}
|
||||||
anchors {
|
anchors {
|
||||||
|
@ -169,7 +156,7 @@ ScrollingWindow {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: cancelButtonAction
|
id: cancelButtonAction
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: updateDialog.closeDialog()
|
onClicked: root.shown = false
|
||||||
cursorShape: "PointingHandCursor"
|
cursorShape: "PointingHandCursor"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +172,7 @@ ScrollingWindow {
|
||||||
color: "#0c9ab4" // Same as logo
|
color: "#0c9ab4" // Same as logo
|
||||||
font {
|
font {
|
||||||
family: updateDialog.fontFamily
|
family: updateDialog.fontFamily
|
||||||
pixelSize: hifi.fonts.pixelSize * 1.2
|
pixelSize: hifistyles.fonts.pixelSize * 1.2
|
||||||
weight: Font.DemiBold
|
weight: Font.DemiBold
|
||||||
}
|
}
|
||||||
anchors {
|
anchors {
|
||||||
|
|
|
@ -209,6 +209,9 @@ Fadable {
|
||||||
|
|
||||||
var targetVisibility = getTargetVisibility();
|
var targetVisibility = getTargetVisibility();
|
||||||
if (targetVisibility === visible) {
|
if (targetVisibility === visible) {
|
||||||
|
if (force) {
|
||||||
|
window.raise();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,8 @@ static QTimer pingTimer;
|
||||||
|
|
||||||
static const QString SNAPSHOT_EXTENSION = ".jpg";
|
static const QString SNAPSHOT_EXTENSION = ".jpg";
|
||||||
static const QString SVO_EXTENSION = ".svo";
|
static const QString SVO_EXTENSION = ".svo";
|
||||||
static const QString SVO_JSON_EXTENSION = ".svo.json";
|
static const QString SVO_JSON_EXTENSION = ".svo.json";
|
||||||
|
static const QString JSON_EXTENSION = ".json";
|
||||||
static const QString JS_EXTENSION = ".js";
|
static const QString JS_EXTENSION = ".js";
|
||||||
static const QString FST_EXTENSION = ".fst";
|
static const QString FST_EXTENSION = ".fst";
|
||||||
static const QString FBX_EXTENSION = ".fbx";
|
static const QString FBX_EXTENSION = ".fbx";
|
||||||
|
@ -202,13 +203,16 @@ static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStanda
|
||||||
|
|
||||||
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
|
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
|
||||||
|
|
||||||
|
static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com";
|
||||||
|
|
||||||
const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensions {
|
const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensions {
|
||||||
{ SNAPSHOT_EXTENSION, &Application::acceptSnapshot },
|
{ SNAPSHOT_EXTENSION, &Application::acceptSnapshot },
|
||||||
{ SVO_EXTENSION, &Application::importSVOFromURL },
|
{ SVO_EXTENSION, &Application::importSVOFromURL },
|
||||||
{ SVO_JSON_EXTENSION, &Application::importSVOFromURL },
|
{ SVO_JSON_EXTENSION, &Application::importSVOFromURL },
|
||||||
|
{ AVA_JSON_EXTENSION, &Application::askToWearAvatarAttachmentUrl },
|
||||||
|
{ JSON_EXTENSION, &Application::importJSONFromURL },
|
||||||
{ JS_EXTENSION, &Application::askToLoadScript },
|
{ JS_EXTENSION, &Application::askToLoadScript },
|
||||||
{ FST_EXTENSION, &Application::askToSetAvatarUrl },
|
{ FST_EXTENSION, &Application::askToSetAvatarUrl }
|
||||||
{ AVA_JSON_EXTENSION, &Application::askToWearAvatarAttachmentUrl }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeadlockWatchdogThread : public QThread {
|
class DeadlockWatchdogThread : public QThread {
|
||||||
|
@ -1969,7 +1973,22 @@ void Application::resizeGL() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Application::importJSONFromURL(const QString& urlString) {
|
||||||
|
// we only load files that terminate in just .json (not .svo.json and not .ava.json)
|
||||||
|
// if they come from the High Fidelity Marketplace Assets CDN
|
||||||
|
|
||||||
|
QUrl jsonURL { urlString };
|
||||||
|
|
||||||
|
if (jsonURL.host().endsWith(MARKETPLACE_CDN_HOSTNAME)) {
|
||||||
|
emit svoImportRequested(urlString);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Application::importSVOFromURL(const QString& urlString) {
|
bool Application::importSVOFromURL(const QString& urlString) {
|
||||||
|
|
||||||
emit svoImportRequested(urlString);
|
emit svoImportRequested(urlString);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4806,7 +4825,17 @@ bool Application::askToSetAvatarUrl(const QString& url) {
|
||||||
|
|
||||||
bool Application::askToLoadScript(const QString& scriptFilenameOrURL) {
|
bool Application::askToLoadScript(const QString& scriptFilenameOrURL) {
|
||||||
QMessageBox::StandardButton reply;
|
QMessageBox::StandardButton reply;
|
||||||
QString message = "Would you like to run this script:\n" + scriptFilenameOrURL;
|
|
||||||
|
QString shortName = scriptFilenameOrURL;
|
||||||
|
|
||||||
|
QUrl scriptURL { scriptFilenameOrURL };
|
||||||
|
|
||||||
|
if (scriptURL.host().endsWith(MARKETPLACE_CDN_HOSTNAME)) {
|
||||||
|
shortName = shortName.mid(shortName.lastIndexOf('/') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString message = "Would you like to run this script:\n" + shortName;
|
||||||
|
|
||||||
reply = OffscreenUi::question(getWindow(), "Run Script", message, QMessageBox::Yes | QMessageBox::No);
|
reply = OffscreenUi::question(getWindow(), "Run Script", message, QMessageBox::Yes | QMessageBox::No);
|
||||||
|
|
||||||
if (reply == QMessageBox::Yes) {
|
if (reply == QMessageBox::Yes) {
|
||||||
|
|
|
@ -380,6 +380,7 @@ private:
|
||||||
|
|
||||||
void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false);
|
void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false);
|
||||||
|
|
||||||
|
bool importJSONFromURL(const QString& urlString);
|
||||||
bool importSVOFromURL(const QString& urlString);
|
bool importSVOFromURL(const QString& urlString);
|
||||||
|
|
||||||
bool nearbyEntitiesAreReadyForPhysics();
|
bool nearbyEntitiesAreReadyForPhysics();
|
||||||
|
|
|
@ -48,14 +48,6 @@ const QString& UpdateDialog::releaseNotes() const {
|
||||||
return _releaseNotes;
|
return _releaseNotes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDialog::closeDialog() {
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateDialog::hide() {
|
|
||||||
((QQuickItem*)parent())->setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateDialog::triggerUpgrade() {
|
void UpdateDialog::triggerUpgrade() {
|
||||||
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||||
applicationUpdater.data()->performAutoUpdate(applicationUpdater.data()->getBuildData().lastKey());
|
applicationUpdater.data()->performAutoUpdate(applicationUpdater.data()->getBuildData().lastKey());
|
||||||
|
|
|
@ -21,22 +21,20 @@ class UpdateDialog : public OffscreenQmlDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
HIFI_QML_DECL
|
HIFI_QML_DECL
|
||||||
|
|
||||||
Q_PROPERTY(QString updateAvailableDetails READ updateAvailableDetails)
|
Q_PROPERTY(QString updateAvailableDetails READ updateAvailableDetails CONSTANT)
|
||||||
Q_PROPERTY(QString releaseNotes READ releaseNotes)
|
Q_PROPERTY(QString releaseNotes READ releaseNotes CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UpdateDialog(QQuickItem* parent = nullptr);
|
UpdateDialog(QQuickItem* parent = nullptr);
|
||||||
const QString& updateAvailableDetails() const;
|
const QString& updateAvailableDetails() const;
|
||||||
const QString& releaseNotes() const;
|
const QString& releaseNotes() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _updateAvailableDetails;
|
QString _updateAvailableDetails;
|
||||||
QString _releaseNotes;
|
QString _releaseNotes;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void hide();
|
|
||||||
Q_INVOKABLE void triggerUpgrade();
|
Q_INVOKABLE void triggerUpgrade();
|
||||||
Q_INVOKABLE void closeDialog();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -55,12 +55,14 @@ void Line3DOverlay::render(RenderArgs* args) {
|
||||||
batch->setModelTransform(_transform);
|
batch->setModelTransform(_transform);
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
|
|
||||||
if (getIsDashedLine()) {
|
if (getIsDashedLine()) {
|
||||||
// TODO: add support for color to renderDashedLine()
|
// TODO: add support for color to renderDashedLine()
|
||||||
|
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
|
||||||
geometryCache->renderDashedLine(*batch, _start, _end, colorv4, _geometryCacheID);
|
geometryCache->renderDashedLine(*batch, _start, _end, colorv4, _geometryCacheID);
|
||||||
|
} else if (_glow > 0.0f) {
|
||||||
|
geometryCache->renderGlowLine(*batch, _start, _end, colorv4, _glow, _glowWidth, _geometryCacheID);
|
||||||
} else {
|
} else {
|
||||||
|
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
|
||||||
geometryCache->renderLine(*batch, _start, _end, colorv4, _geometryCacheID);
|
geometryCache->renderLine(*batch, _start, _end, colorv4, _geometryCacheID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +70,7 @@ void Line3DOverlay::render(RenderArgs* args) {
|
||||||
|
|
||||||
const render::ShapeKey Line3DOverlay::getShapeKey() {
|
const render::ShapeKey Line3DOverlay::getShapeKey() {
|
||||||
auto builder = render::ShapeKey::Builder().withOwnPipeline();
|
auto builder = render::ShapeKey::Builder().withOwnPipeline();
|
||||||
if (getAlpha() != 1.0f) {
|
if (getAlpha() != 1.0f || _glow > 0.0f) {
|
||||||
builder.withTranslucent();
|
builder.withTranslucent();
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
@ -94,6 +96,19 @@ void Line3DOverlay::setProperties(const QVariantMap& properties) {
|
||||||
if (end.isValid()) {
|
if (end.isValid()) {
|
||||||
setEnd(vec3FromVariant(end));
|
setEnd(vec3FromVariant(end));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto glow = properties["glow"];
|
||||||
|
if (glow.isValid()) {
|
||||||
|
setGlow(glow.toFloat());
|
||||||
|
if (_glow > 0.0f) {
|
||||||
|
_alpha = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto glowWidth = properties["glow"];
|
||||||
|
if (glowWidth.isValid()) {
|
||||||
|
setGlow(glowWidth.toFloat());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant Line3DOverlay::getProperty(const QString& property) {
|
QVariant Line3DOverlay::getProperty(const QString& property) {
|
||||||
|
|
|
@ -30,10 +30,14 @@ public:
|
||||||
// getters
|
// getters
|
||||||
const glm::vec3& getStart() const { return _start; }
|
const glm::vec3& getStart() const { return _start; }
|
||||||
const glm::vec3& getEnd() const { return _end; }
|
const glm::vec3& getEnd() const { return _end; }
|
||||||
|
const float& getGlow() const { return _glow; }
|
||||||
|
const float& getGlowWidth() const { return _glowWidth; }
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
void setStart(const glm::vec3& start) { _start = start; }
|
void setStart(const glm::vec3& start) { _start = start; }
|
||||||
void setEnd(const glm::vec3& end) { _end = end; }
|
void setEnd(const glm::vec3& end) { _end = end; }
|
||||||
|
void setGlow(const float& glow) { _glow = glow; }
|
||||||
|
void setGlowWidth(const float& glowWidth) { _glowWidth = glowWidth; }
|
||||||
|
|
||||||
void setProperties(const QVariantMap& properties) override;
|
void setProperties(const QVariantMap& properties) override;
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
@ -43,6 +47,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _start;
|
glm::vec3 _start;
|
||||||
glm::vec3 _end;
|
glm::vec3 _end;
|
||||||
|
float _glow { 0.0 };
|
||||||
|
float _glowWidth { 0.0 };
|
||||||
int _geometryCacheID;
|
int _geometryCacheID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ void Sphere3DOverlay::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const render::ShapeKey Sphere3DOverlay::getShapeKey() {
|
const render::ShapeKey Sphere3DOverlay::getShapeKey() {
|
||||||
auto builder = render::ShapeKey::Builder().withOwnPipeline();
|
auto builder = render::ShapeKey::Builder();
|
||||||
if (getAlpha() != 1.0f) {
|
if (getAlpha() != 1.0f) {
|
||||||
builder.withTranslucent();
|
builder.withTranslucent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,16 +342,23 @@ void RenderableModelEntityItem::updateModelBounds() {
|
||||||
if (!hasModel() || !_model) {
|
if (!hasModel() || !_model) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!_dimensionsInitialized || !_model->isActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool movingOrAnimating = isMovingRelativeToParent() || isAnimatingSomething();
|
bool movingOrAnimating = isMovingRelativeToParent() || isAnimatingSomething();
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getDimensions();
|
||||||
if ((movingOrAnimating ||
|
bool success;
|
||||||
|
auto transform = getTransform(success);
|
||||||
|
|
||||||
|
if (movingOrAnimating ||
|
||||||
_needsInitialSimulation ||
|
_needsInitialSimulation ||
|
||||||
_needsJointSimulation ||
|
_needsJointSimulation ||
|
||||||
_model->getTranslation() != getPosition() ||
|
_model->getTranslation() != transform.getTranslation() ||
|
||||||
_model->getScaleToFitDimensions() != dimensions ||
|
_model->getScaleToFitDimensions() != dimensions ||
|
||||||
_model->getRotation() != getRotation() ||
|
_model->getRotation() != transform.getRotation() ||
|
||||||
_model->getRegistrationPoint() != getRegistrationPoint())
|
_model->getRegistrationPoint() != getRegistrationPoint()) {
|
||||||
&& _model->isActive() && _dimensionsInitialized) {
|
|
||||||
doInitialModelSimulation();
|
doInitialModelSimulation();
|
||||||
_needsJointSimulation = false;
|
_needsJointSimulation = false;
|
||||||
}
|
}
|
||||||
|
@ -423,7 +430,8 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
|
|
||||||
// check to see if when we added our models to the scene they were ready, if they were not ready, then
|
// check to see if when we added our models to the scene they were ready, if they were not ready, then
|
||||||
// fix them up in the scene
|
// fix them up in the scene
|
||||||
bool shouldShowCollisionHull = (args->_debugFlags & (int)RenderArgs::RENDER_DEBUG_HULLS) > 0;
|
bool shouldShowCollisionHull = (args->_debugFlags & (int)RenderArgs::RENDER_DEBUG_HULLS) > 0
|
||||||
|
&& getShapeType() == SHAPE_TYPE_COMPOUND;
|
||||||
if (_model->needsFixupInScene() || _showCollisionHull != shouldShowCollisionHull) {
|
if (_model->needsFixupInScene() || _showCollisionHull != shouldShowCollisionHull) {
|
||||||
_showCollisionHull = shouldShowCollisionHull;
|
_showCollisionHull = shouldShowCollisionHull;
|
||||||
render::PendingChanges pendingChanges;
|
render::PendingChanges pendingChanges;
|
||||||
|
@ -593,7 +601,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
|
||||||
|
|
||||||
// the model is still being downloaded.
|
// the model is still being downloaded.
|
||||||
return false;
|
return false;
|
||||||
} else if (type == SHAPE_TYPE_STATIC_MESH) {
|
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
||||||
return (_model && _model->isLoaded());
|
return (_model && _model->isLoaded());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -607,7 +615,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
|
|
||||||
// should never fall in here when collision model not fully loaded
|
// should never fall in here when collision model not fully loaded
|
||||||
// hence we assert that all geometries exist and are loaded
|
// hence we assert that all geometries exist and are loaded
|
||||||
assert(_model->isLoaded() && _model->isCollisionLoaded());
|
assert(_model && _model->isLoaded() && _model->isCollisionLoaded());
|
||||||
const FBXGeometry& collisionGeometry = _model->getCollisionFBXGeometry();
|
const FBXGeometry& collisionGeometry = _model->getCollisionFBXGeometry();
|
||||||
|
|
||||||
ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
|
ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
|
||||||
|
@ -691,14 +699,19 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info.setParams(type, dimensions, _compoundShapeURL);
|
info.setParams(type, dimensions, _compoundShapeURL);
|
||||||
} else if (type == SHAPE_TYPE_STATIC_MESH) {
|
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
||||||
|
updateModelBounds();
|
||||||
|
|
||||||
|
// should never fall in here when model not fully loaded
|
||||||
|
assert(_model && _model->isLoaded());
|
||||||
|
|
||||||
// compute meshPart local transforms
|
// compute meshPart local transforms
|
||||||
QVector<glm::mat4> localTransforms;
|
QVector<glm::mat4> localTransforms;
|
||||||
const FBXGeometry& geometry = _model->getFBXGeometry();
|
const FBXGeometry& fbxGeometry = _model->getFBXGeometry();
|
||||||
int numberOfMeshes = geometry.meshes.size();
|
int numberOfMeshes = fbxGeometry.meshes.size();
|
||||||
int totalNumVertices = 0;
|
int totalNumVertices = 0;
|
||||||
for (int i = 0; i < numberOfMeshes; i++) {
|
for (int i = 0; i < numberOfMeshes; i++) {
|
||||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
const FBXMesh& mesh = fbxGeometry.meshes.at(i);
|
||||||
if (mesh.clusters.size() > 0) {
|
if (mesh.clusters.size() > 0) {
|
||||||
const FBXCluster& cluster = mesh.clusters.at(0);
|
const FBXCluster& cluster = mesh.clusters.at(0);
|
||||||
auto jointMatrix = _model->getRig()->getJointTransform(cluster.jointIndex);
|
auto jointMatrix = _model->getRig()->getJointTransform(cluster.jointIndex);
|
||||||
|
@ -716,30 +729,42 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateModelBounds();
|
auto& meshes = _model->getGeometry()->getGeometry()->getMeshes();
|
||||||
|
int32_t numMeshes = (int32_t)(meshes.size());
|
||||||
// should never fall in here when collision model not fully loaded
|
|
||||||
assert(_model->isLoaded());
|
|
||||||
|
|
||||||
ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
|
ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
|
||||||
pointCollection.clear();
|
pointCollection.clear();
|
||||||
|
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||||
ShapeInfo::PointList points;
|
pointCollection.resize(numMeshes);
|
||||||
ShapeInfo::TriangleIndices& triangleIndices = info.getTriangleIndices();
|
} else {
|
||||||
auto& meshes = _model->getGeometry()->getGeometry()->getMeshes();
|
pointCollection.resize(1);
|
||||||
|
}
|
||||||
|
|
||||||
Extents extents;
|
Extents extents;
|
||||||
int meshCount = 0;
|
int meshCount = 0;
|
||||||
|
int pointListIndex = 0;
|
||||||
for (auto& mesh : meshes) {
|
for (auto& mesh : meshes) {
|
||||||
const gpu::BufferView& vertices = mesh->getVertexBuffer();
|
const gpu::BufferView& vertices = mesh->getVertexBuffer();
|
||||||
const gpu::BufferView& indices = mesh->getIndexBuffer();
|
const gpu::BufferView& indices = mesh->getIndexBuffer();
|
||||||
const gpu::BufferView& parts = mesh->getPartBuffer();
|
const gpu::BufferView& parts = mesh->getPartBuffer();
|
||||||
|
|
||||||
|
ShapeInfo::PointList& points = pointCollection[pointListIndex];
|
||||||
|
|
||||||
|
// reserve room
|
||||||
|
int32_t sizeToReserve = (int32_t)(vertices.getNumElements());
|
||||||
|
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||||
|
// a list of points for each mesh
|
||||||
|
pointListIndex++;
|
||||||
|
} else {
|
||||||
|
// only one list of points
|
||||||
|
sizeToReserve += (int32_t)((gpu::Size)points.size());
|
||||||
|
}
|
||||||
|
points.reserve(sizeToReserve);
|
||||||
|
|
||||||
// copy points
|
// copy points
|
||||||
const glm::mat4& localTransform = localTransforms[meshCount];
|
|
||||||
uint32_t meshIndexOffset = (uint32_t)points.size();
|
uint32_t meshIndexOffset = (uint32_t)points.size();
|
||||||
|
const glm::mat4& localTransform = localTransforms[meshCount];
|
||||||
gpu::BufferView::Iterator<const glm::vec3> vertexItr = vertices.cbegin<const glm::vec3>();
|
gpu::BufferView::Iterator<const glm::vec3> vertexItr = vertices.cbegin<const glm::vec3>();
|
||||||
points.reserve((int32_t)((gpu::Size)points.size() + vertices.getNumElements()));
|
|
||||||
while (vertexItr != vertices.cend<const glm::vec3>()) {
|
while (vertexItr != vertices.cend<const glm::vec3>()) {
|
||||||
glm::vec3 point = extractTranslation(localTransform * glm::translate(*vertexItr));
|
glm::vec3 point = extractTranslation(localTransform * glm::translate(*vertexItr));
|
||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
|
@ -747,55 +772,57 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
++vertexItr;
|
++vertexItr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy triangleIndices
|
if (type == SHAPE_TYPE_STATIC_MESH) {
|
||||||
triangleIndices.reserve((int32_t)((gpu::Size)(triangleIndices.size()) + indices.getNumElements()));
|
// copy into triangleIndices
|
||||||
gpu::BufferView::Iterator<const model::Mesh::Part> partItr = parts.cbegin<const model::Mesh::Part>();
|
ShapeInfo::TriangleIndices& triangleIndices = info.getTriangleIndices();
|
||||||
while (partItr != parts.cend<const model::Mesh::Part>()) {
|
triangleIndices.reserve((int32_t)((gpu::Size)(triangleIndices.size()) + indices.getNumElements()));
|
||||||
|
gpu::BufferView::Iterator<const model::Mesh::Part> partItr = parts.cbegin<const model::Mesh::Part>();
|
||||||
if (partItr->_topology == model::Mesh::TRIANGLES) {
|
while (partItr != parts.cend<const model::Mesh::Part>()) {
|
||||||
assert(partItr->_numIndices % 3 == 0);
|
if (partItr->_topology == model::Mesh::TRIANGLES) {
|
||||||
auto indexItr = indices.cbegin<const gpu::BufferView::Index>() + partItr->_startIndex;
|
assert(partItr->_numIndices % 3 == 0);
|
||||||
auto indexEnd = indexItr + partItr->_numIndices;
|
auto indexItr = indices.cbegin<const gpu::BufferView::Index>() + partItr->_startIndex;
|
||||||
while (indexItr != indexEnd) {
|
auto indexEnd = indexItr + partItr->_numIndices;
|
||||||
triangleIndices.push_back(*indexItr + meshIndexOffset);
|
while (indexItr != indexEnd) {
|
||||||
++indexItr;
|
|
||||||
}
|
|
||||||
} else if (partItr->_topology == model::Mesh::TRIANGLE_STRIP) {
|
|
||||||
assert(partItr->_numIndices > 2);
|
|
||||||
uint32_t approxNumIndices = 3 * partItr->_numIndices;
|
|
||||||
if (approxNumIndices > (uint32_t)(triangleIndices.capacity() - triangleIndices.size())) {
|
|
||||||
// we underestimated the final size of triangleIndices so we pre-emptively expand it
|
|
||||||
triangleIndices.reserve(triangleIndices.size() + approxNumIndices);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto indexItr = indices.cbegin<const gpu::BufferView::Index>() + partItr->_startIndex;
|
|
||||||
auto indexEnd = indexItr + (partItr->_numIndices - 2);
|
|
||||||
|
|
||||||
// first triangle uses the first three indices
|
|
||||||
triangleIndices.push_back(*(indexItr++) + meshIndexOffset);
|
|
||||||
triangleIndices.push_back(*(indexItr++) + meshIndexOffset);
|
|
||||||
triangleIndices.push_back(*(indexItr++) + meshIndexOffset);
|
|
||||||
|
|
||||||
// the rest use previous and next index
|
|
||||||
uint32_t triangleCount = 1;
|
|
||||||
while (indexItr != indexEnd) {
|
|
||||||
if ((*indexItr) != model::Mesh::PRIMITIVE_RESTART_INDEX) {
|
|
||||||
if (triangleCount % 2 == 0) {
|
|
||||||
// even triangles use first two indices in order
|
|
||||||
triangleIndices.push_back(*(indexItr - 2) + meshIndexOffset);
|
|
||||||
triangleIndices.push_back(*(indexItr - 1) + meshIndexOffset);
|
|
||||||
} else {
|
|
||||||
// odd triangles swap order of first two indices
|
|
||||||
triangleIndices.push_back(*(indexItr - 1) + meshIndexOffset);
|
|
||||||
triangleIndices.push_back(*(indexItr - 2) + meshIndexOffset);
|
|
||||||
}
|
|
||||||
triangleIndices.push_back(*indexItr + meshIndexOffset);
|
triangleIndices.push_back(*indexItr + meshIndexOffset);
|
||||||
++triangleCount;
|
++indexItr;
|
||||||
|
}
|
||||||
|
} else if (partItr->_topology == model::Mesh::TRIANGLE_STRIP) {
|
||||||
|
assert(partItr->_numIndices > 2);
|
||||||
|
uint32_t approxNumIndices = 3 * partItr->_numIndices;
|
||||||
|
if (approxNumIndices > (uint32_t)(triangleIndices.capacity() - triangleIndices.size())) {
|
||||||
|
// we underestimated the final size of triangleIndices so we pre-emptively expand it
|
||||||
|
triangleIndices.reserve(triangleIndices.size() + approxNumIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto indexItr = indices.cbegin<const gpu::BufferView::Index>() + partItr->_startIndex;
|
||||||
|
auto indexEnd = indexItr + (partItr->_numIndices - 2);
|
||||||
|
|
||||||
|
// first triangle uses the first three indices
|
||||||
|
triangleIndices.push_back(*(indexItr++) + meshIndexOffset);
|
||||||
|
triangleIndices.push_back(*(indexItr++) + meshIndexOffset);
|
||||||
|
triangleIndices.push_back(*(indexItr++) + meshIndexOffset);
|
||||||
|
|
||||||
|
// the rest use previous and next index
|
||||||
|
uint32_t triangleCount = 1;
|
||||||
|
while (indexItr != indexEnd) {
|
||||||
|
if ((*indexItr) != model::Mesh::PRIMITIVE_RESTART_INDEX) {
|
||||||
|
if (triangleCount % 2 == 0) {
|
||||||
|
// even triangles use first two indices in order
|
||||||
|
triangleIndices.push_back(*(indexItr - 2) + meshIndexOffset);
|
||||||
|
triangleIndices.push_back(*(indexItr - 1) + meshIndexOffset);
|
||||||
|
} else {
|
||||||
|
// odd triangles swap order of first two indices
|
||||||
|
triangleIndices.push_back(*(indexItr - 1) + meshIndexOffset);
|
||||||
|
triangleIndices.push_back(*(indexItr - 2) + meshIndexOffset);
|
||||||
|
}
|
||||||
|
triangleIndices.push_back(*indexItr + meshIndexOffset);
|
||||||
|
++triangleCount;
|
||||||
|
}
|
||||||
|
++indexItr;
|
||||||
}
|
}
|
||||||
++indexItr;
|
|
||||||
}
|
}
|
||||||
|
++partItr;
|
||||||
}
|
}
|
||||||
++partItr;
|
|
||||||
}
|
}
|
||||||
++meshCount;
|
++meshCount;
|
||||||
}
|
}
|
||||||
|
@ -808,12 +835,13 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
scaleToFit[i] = 1.0f;
|
scaleToFit[i] = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < points.size(); ++i) {
|
for (auto points : pointCollection) {
|
||||||
points[i] = (points[i] * scaleToFit);
|
for (int i = 0; i < points.size(); ++i) {
|
||||||
|
points[i] = (points[i] * scaleToFit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pointCollection.push_back(points);
|
info.setParams(type, 0.5f * dimensions, _modelURL);
|
||||||
info.setParams(SHAPE_TYPE_STATIC_MESH, 0.5f * dimensions, _modelURL);
|
|
||||||
} else {
|
} else {
|
||||||
ModelEntityItem::computeShapeInfo(info);
|
ModelEntityItem::computeShapeInfo(info);
|
||||||
info.setParams(type, 0.5f * dimensions);
|
info.setParams(type, 0.5f * dimensions);
|
||||||
|
|
|
@ -101,6 +101,8 @@ const char* shapeTypeNames[] = {
|
||||||
"hull",
|
"hull",
|
||||||
"plane",
|
"plane",
|
||||||
"compound",
|
"compound",
|
||||||
|
"simple-hull",
|
||||||
|
"simple-compound",
|
||||||
"static-mesh"
|
"static-mesh"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,6 +125,8 @@ void buildStringToShapeTypeLookup() {
|
||||||
addShapeType(SHAPE_TYPE_HULL);
|
addShapeType(SHAPE_TYPE_HULL);
|
||||||
addShapeType(SHAPE_TYPE_PLANE);
|
addShapeType(SHAPE_TYPE_PLANE);
|
||||||
addShapeType(SHAPE_TYPE_COMPOUND);
|
addShapeType(SHAPE_TYPE_COMPOUND);
|
||||||
|
addShapeType(SHAPE_TYPE_SIMPLE_HULL);
|
||||||
|
addShapeType(SHAPE_TYPE_SIMPLE_COMPOUND);
|
||||||
addShapeType(SHAPE_TYPE_STATIC_MESH);
|
addShapeType(SHAPE_TYPE_STATIC_MESH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,40 +25,45 @@ GLShader::~GLShader() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GLSL version
|
||||||
|
static const std::string glslVersion {
|
||||||
|
"#version 410 core"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Shader domain
|
||||||
|
static const size_t NUM_SHADER_DOMAINS = 3;
|
||||||
|
|
||||||
|
// GL Shader type enums
|
||||||
|
// Must match the order of type specified in gpu::Shader::Type
|
||||||
|
static const std::array<GLenum, NUM_SHADER_DOMAINS> SHADER_DOMAINS { {
|
||||||
|
GL_VERTEX_SHADER,
|
||||||
|
GL_FRAGMENT_SHADER,
|
||||||
|
GL_GEOMETRY_SHADER,
|
||||||
|
} };
|
||||||
|
|
||||||
|
// Domain specific defines
|
||||||
|
// Must match the order of type specified in gpu::Shader::Type
|
||||||
|
static const std::array<std::string, NUM_SHADER_DOMAINS> DOMAIN_DEFINES { {
|
||||||
|
"#define GPU_VERTEX_SHADER",
|
||||||
|
"#define GPU_PIXEL_SHADER",
|
||||||
|
"#define GPU_GEOMETRY_SHADER",
|
||||||
|
} };
|
||||||
|
|
||||||
|
// Versions specific of the shader
|
||||||
|
static const std::array<std::string, GLShader::NumVersions> VERSION_DEFINES { {
|
||||||
|
""
|
||||||
|
} };
|
||||||
|
|
||||||
GLShader* compileBackendShader(const Shader& shader) {
|
GLShader* compileBackendShader(const Shader& shader) {
|
||||||
// Any GLSLprogram ? normally yes...
|
// Any GLSLprogram ? normally yes...
|
||||||
const std::string& shaderSource = shader.getSource().getCode();
|
const std::string& shaderSource = shader.getSource().getCode();
|
||||||
|
|
||||||
// GLSL version
|
|
||||||
const std::string glslVersion = {
|
|
||||||
"#version 410 core"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Shader domain
|
|
||||||
const int NUM_SHADER_DOMAINS = 2;
|
|
||||||
const GLenum SHADER_DOMAINS[NUM_SHADER_DOMAINS] = {
|
|
||||||
GL_VERTEX_SHADER,
|
|
||||||
GL_FRAGMENT_SHADER
|
|
||||||
};
|
|
||||||
GLenum shaderDomain = SHADER_DOMAINS[shader.getType()];
|
GLenum shaderDomain = SHADER_DOMAINS[shader.getType()];
|
||||||
|
|
||||||
// Domain specific defines
|
|
||||||
const std::string domainDefines[NUM_SHADER_DOMAINS] = {
|
|
||||||
"#define GPU_VERTEX_SHADER",
|
|
||||||
"#define GPU_PIXEL_SHADER"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Versions specific of the shader
|
|
||||||
const std::string versionDefines[GLShader::NumVersions] = {
|
|
||||||
""
|
|
||||||
};
|
|
||||||
|
|
||||||
GLShader::ShaderObjects shaderObjects;
|
GLShader::ShaderObjects shaderObjects;
|
||||||
|
|
||||||
for (int version = 0; version < GLShader::NumVersions; version++) {
|
for (int version = 0; version < GLShader::NumVersions; version++) {
|
||||||
auto& shaderObject = shaderObjects[version];
|
auto& shaderObject = shaderObjects[version];
|
||||||
|
|
||||||
std::string shaderDefines = glslVersion + "\n" + domainDefines[shader.getType()] + "\n" + versionDefines[version];
|
std::string shaderDefines = glslVersion + "\n" + DOMAIN_DEFINES[shader.getType()] + "\n" + VERSION_DEFINES[version];
|
||||||
|
|
||||||
bool result = compileShader(shaderDomain, shaderSource, shaderDefines, shaderObject.glshader, shaderObject.glprogram);
|
bool result = compileShader(shaderDomain, shaderSource, shaderDefines, shaderObject.glshader, shaderObject.glprogram);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|
|
@ -26,28 +26,43 @@ ProfileRangeBatch::~ProfileRangeBatch() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ADD_COMMAND(call) _commands.push_back(COMMAND_##call); _commandOffsets.push_back(_params.size());
|
#define ADD_COMMAND(call) _commands.emplace_back(COMMAND_##call); _commandOffsets.emplace_back(_params.size());
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
Batch::Batch(const CacheState& cacheState) : Batch() {
|
size_t Batch::_commandsMax { BATCH_PREALLOCATE_MIN };
|
||||||
_commands.reserve(cacheState.commandsSize);
|
size_t Batch::_commandOffsetsMax { BATCH_PREALLOCATE_MIN };
|
||||||
_commandOffsets.reserve(cacheState.offsetsSize);
|
size_t Batch::_paramsMax { BATCH_PREALLOCATE_MIN };
|
||||||
_params.reserve(cacheState.paramsSize);
|
size_t Batch::_dataMax { BATCH_PREALLOCATE_MIN };
|
||||||
_data.reserve(cacheState.dataSize);
|
size_t Batch::_objectsMax { BATCH_PREALLOCATE_MIN };
|
||||||
}
|
size_t Batch::_drawCallInfosMax { BATCH_PREALLOCATE_MIN };
|
||||||
|
|
||||||
Batch::CacheState Batch::getCacheState() {
|
Batch::Batch() {
|
||||||
return CacheState(_commands.size(), _commandOffsets.size(), _params.size(), _data.size(),
|
_commands.reserve(_commandsMax);
|
||||||
_buffers.size(), _textures.size(), _streamFormats.size(), _transforms.size(), _pipelines.size(),
|
_commandOffsets.reserve(_commandOffsetsMax);
|
||||||
_framebuffers.size(), _queries.size());
|
_params.reserve(_paramsMax);
|
||||||
|
_data.reserve(_dataMax);
|
||||||
|
_objects.reserve(_objectsMax);
|
||||||
|
_drawCallInfos.reserve(_drawCallInfosMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
Batch::~Batch() {
|
Batch::~Batch() {
|
||||||
//qDebug() << "Batch::~Batch()... " << getCacheState();
|
_commandsMax = std::max(_commands.size(), _commandsMax);
|
||||||
|
_commandOffsetsMax = std::max(_commandOffsets.size(), _commandOffsetsMax);
|
||||||
|
_paramsMax = std::max(_params.size(), _paramsMax);
|
||||||
|
_dataMax = std::max(_data.size(), _dataMax);
|
||||||
|
_objectsMax = std::max(_objects.size(), _objectsMax);
|
||||||
|
_drawCallInfosMax = std::max(_drawCallInfos.size(), _drawCallInfosMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::clear() {
|
void Batch::clear() {
|
||||||
|
_commandsMax = std::max(_commands.size(), _commandsMax);
|
||||||
|
_commandOffsetsMax = std::max(_commandOffsets.size(), _commandOffsetsMax);
|
||||||
|
_paramsMax = std::max(_params.size(), _paramsMax);
|
||||||
|
_dataMax = std::max(_data.size(), _dataMax);
|
||||||
|
_objectsMax = std::max(_objects.size(), _objectsMax);
|
||||||
|
_drawCallInfosMax = std::max(_drawCallInfos.size(), _drawCallInfosMax);
|
||||||
|
|
||||||
_commands.clear();
|
_commands.clear();
|
||||||
_commandOffsets.clear();
|
_commandOffsets.clear();
|
||||||
_params.clear();
|
_params.clear();
|
||||||
|
@ -58,6 +73,8 @@ void Batch::clear() {
|
||||||
_transforms.clear();
|
_transforms.clear();
|
||||||
_pipelines.clear();
|
_pipelines.clear();
|
||||||
_framebuffers.clear();
|
_framebuffers.clear();
|
||||||
|
_objects.clear();
|
||||||
|
_drawCallInfos.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Batch::cacheData(size_t size, const void* data) {
|
size_t Batch::cacheData(size_t size, const void* data) {
|
||||||
|
@ -72,9 +89,9 @@ size_t Batch::cacheData(size_t size, const void* data) {
|
||||||
void Batch::draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex) {
|
void Batch::draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex) {
|
||||||
ADD_COMMAND(draw);
|
ADD_COMMAND(draw);
|
||||||
|
|
||||||
_params.push_back(startVertex);
|
_params.emplace_back(startVertex);
|
||||||
_params.push_back(numVertices);
|
_params.emplace_back(numVertices);
|
||||||
_params.push_back(primitiveType);
|
_params.emplace_back(primitiveType);
|
||||||
|
|
||||||
captureDrawCallInfo();
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
@ -82,9 +99,9 @@ void Batch::draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex
|
||||||
void Batch::drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 startIndex) {
|
void Batch::drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 startIndex) {
|
||||||
ADD_COMMAND(drawIndexed);
|
ADD_COMMAND(drawIndexed);
|
||||||
|
|
||||||
_params.push_back(startIndex);
|
_params.emplace_back(startIndex);
|
||||||
_params.push_back(numIndices);
|
_params.emplace_back(numIndices);
|
||||||
_params.push_back(primitiveType);
|
_params.emplace_back(primitiveType);
|
||||||
|
|
||||||
captureDrawCallInfo();
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
@ -92,11 +109,11 @@ void Batch::drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 start
|
||||||
void Batch::drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 numVertices, uint32 startVertex, uint32 startInstance) {
|
void Batch::drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 numVertices, uint32 startVertex, uint32 startInstance) {
|
||||||
ADD_COMMAND(drawInstanced);
|
ADD_COMMAND(drawInstanced);
|
||||||
|
|
||||||
_params.push_back(startInstance);
|
_params.emplace_back(startInstance);
|
||||||
_params.push_back(startVertex);
|
_params.emplace_back(startVertex);
|
||||||
_params.push_back(numVertices);
|
_params.emplace_back(numVertices);
|
||||||
_params.push_back(primitiveType);
|
_params.emplace_back(primitiveType);
|
||||||
_params.push_back(numInstances);
|
_params.emplace_back(numInstances);
|
||||||
|
|
||||||
captureDrawCallInfo();
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
@ -104,11 +121,11 @@ void Batch::drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 n
|
||||||
void Batch::drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, uint32 numIndices, uint32 startIndex, uint32 startInstance) {
|
void Batch::drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, uint32 numIndices, uint32 startIndex, uint32 startInstance) {
|
||||||
ADD_COMMAND(drawIndexedInstanced);
|
ADD_COMMAND(drawIndexedInstanced);
|
||||||
|
|
||||||
_params.push_back(startInstance);
|
_params.emplace_back(startInstance);
|
||||||
_params.push_back(startIndex);
|
_params.emplace_back(startIndex);
|
||||||
_params.push_back(numIndices);
|
_params.emplace_back(numIndices);
|
||||||
_params.push_back(primitiveType);
|
_params.emplace_back(primitiveType);
|
||||||
_params.push_back(numInstances);
|
_params.emplace_back(numInstances);
|
||||||
|
|
||||||
captureDrawCallInfo();
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
@ -116,16 +133,16 @@ void Batch::drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, u
|
||||||
|
|
||||||
void Batch::multiDrawIndirect(uint32 numCommands, Primitive primitiveType) {
|
void Batch::multiDrawIndirect(uint32 numCommands, Primitive primitiveType) {
|
||||||
ADD_COMMAND(multiDrawIndirect);
|
ADD_COMMAND(multiDrawIndirect);
|
||||||
_params.push_back(numCommands);
|
_params.emplace_back(numCommands);
|
||||||
_params.push_back(primitiveType);
|
_params.emplace_back(primitiveType);
|
||||||
|
|
||||||
captureDrawCallInfo();
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::multiDrawIndexedIndirect(uint32 nbCommands, Primitive primitiveType) {
|
void Batch::multiDrawIndexedIndirect(uint32 nbCommands, Primitive primitiveType) {
|
||||||
ADD_COMMAND(multiDrawIndexedIndirect);
|
ADD_COMMAND(multiDrawIndexedIndirect);
|
||||||
_params.push_back(nbCommands);
|
_params.emplace_back(nbCommands);
|
||||||
_params.push_back(primitiveType);
|
_params.emplace_back(primitiveType);
|
||||||
|
|
||||||
captureDrawCallInfo();
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
@ -133,16 +150,16 @@ void Batch::multiDrawIndexedIndirect(uint32 nbCommands, Primitive primitiveType)
|
||||||
void Batch::setInputFormat(const Stream::FormatPointer& format) {
|
void Batch::setInputFormat(const Stream::FormatPointer& format) {
|
||||||
ADD_COMMAND(setInputFormat);
|
ADD_COMMAND(setInputFormat);
|
||||||
|
|
||||||
_params.push_back(_streamFormats.cache(format));
|
_params.emplace_back(_streamFormats.cache(format));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride) {
|
void Batch::setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride) {
|
||||||
ADD_COMMAND(setInputBuffer);
|
ADD_COMMAND(setInputBuffer);
|
||||||
|
|
||||||
_params.push_back(stride);
|
_params.emplace_back(stride);
|
||||||
_params.push_back(offset);
|
_params.emplace_back(offset);
|
||||||
_params.push_back(_buffers.cache(buffer));
|
_params.emplace_back(_buffers.cache(buffer));
|
||||||
_params.push_back(channel);
|
_params.emplace_back(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setInputBuffer(Slot channel, const BufferView& view) {
|
void Batch::setInputBuffer(Slot channel, const BufferView& view) {
|
||||||
|
@ -163,9 +180,9 @@ void Batch::setInputStream(Slot startChannel, const BufferStream& stream) {
|
||||||
void Batch::setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset) {
|
void Batch::setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset) {
|
||||||
ADD_COMMAND(setIndexBuffer);
|
ADD_COMMAND(setIndexBuffer);
|
||||||
|
|
||||||
_params.push_back(offset);
|
_params.emplace_back(offset);
|
||||||
_params.push_back(_buffers.cache(buffer));
|
_params.emplace_back(_buffers.cache(buffer));
|
||||||
_params.push_back(type);
|
_params.emplace_back(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setIndexBuffer(const BufferView& buffer) {
|
void Batch::setIndexBuffer(const BufferView& buffer) {
|
||||||
|
@ -175,9 +192,9 @@ void Batch::setIndexBuffer(const BufferView& buffer) {
|
||||||
void Batch::setIndirectBuffer(const BufferPointer& buffer, Offset offset, Offset stride) {
|
void Batch::setIndirectBuffer(const BufferPointer& buffer, Offset offset, Offset stride) {
|
||||||
ADD_COMMAND(setIndirectBuffer);
|
ADD_COMMAND(setIndirectBuffer);
|
||||||
|
|
||||||
_params.push_back(_buffers.cache(buffer));
|
_params.emplace_back(_buffers.cache(buffer));
|
||||||
_params.push_back(offset);
|
_params.emplace_back(offset);
|
||||||
_params.push_back(stride);
|
_params.emplace_back(stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,56 +208,56 @@ void Batch::setModelTransform(const Transform& model) {
|
||||||
void Batch::setViewTransform(const Transform& view) {
|
void Batch::setViewTransform(const Transform& view) {
|
||||||
ADD_COMMAND(setViewTransform);
|
ADD_COMMAND(setViewTransform);
|
||||||
|
|
||||||
_params.push_back(_transforms.cache(view));
|
_params.emplace_back(_transforms.cache(view));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setProjectionTransform(const Mat4& proj) {
|
void Batch::setProjectionTransform(const Mat4& proj) {
|
||||||
ADD_COMMAND(setProjectionTransform);
|
ADD_COMMAND(setProjectionTransform);
|
||||||
|
|
||||||
_params.push_back(cacheData(sizeof(Mat4), &proj));
|
_params.emplace_back(cacheData(sizeof(Mat4), &proj));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setViewportTransform(const Vec4i& viewport) {
|
void Batch::setViewportTransform(const Vec4i& viewport) {
|
||||||
ADD_COMMAND(setViewportTransform);
|
ADD_COMMAND(setViewportTransform);
|
||||||
|
|
||||||
_params.push_back(cacheData(sizeof(Vec4i), &viewport));
|
_params.emplace_back(cacheData(sizeof(Vec4i), &viewport));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setDepthRangeTransform(float nearDepth, float farDepth) {
|
void Batch::setDepthRangeTransform(float nearDepth, float farDepth) {
|
||||||
ADD_COMMAND(setDepthRangeTransform);
|
ADD_COMMAND(setDepthRangeTransform);
|
||||||
|
|
||||||
_params.push_back(farDepth);
|
_params.emplace_back(farDepth);
|
||||||
_params.push_back(nearDepth);
|
_params.emplace_back(nearDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setPipeline(const PipelinePointer& pipeline) {
|
void Batch::setPipeline(const PipelinePointer& pipeline) {
|
||||||
ADD_COMMAND(setPipeline);
|
ADD_COMMAND(setPipeline);
|
||||||
|
|
||||||
_params.push_back(_pipelines.cache(pipeline));
|
_params.emplace_back(_pipelines.cache(pipeline));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setStateBlendFactor(const Vec4& factor) {
|
void Batch::setStateBlendFactor(const Vec4& factor) {
|
||||||
ADD_COMMAND(setStateBlendFactor);
|
ADD_COMMAND(setStateBlendFactor);
|
||||||
|
|
||||||
_params.push_back(factor.x);
|
_params.emplace_back(factor.x);
|
||||||
_params.push_back(factor.y);
|
_params.emplace_back(factor.y);
|
||||||
_params.push_back(factor.z);
|
_params.emplace_back(factor.z);
|
||||||
_params.push_back(factor.w);
|
_params.emplace_back(factor.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setStateScissorRect(const Vec4i& rect) {
|
void Batch::setStateScissorRect(const Vec4i& rect) {
|
||||||
ADD_COMMAND(setStateScissorRect);
|
ADD_COMMAND(setStateScissorRect);
|
||||||
|
|
||||||
_params.push_back(cacheData(sizeof(Vec4i), &rect));
|
_params.emplace_back(cacheData(sizeof(Vec4i), &rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) {
|
void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) {
|
||||||
ADD_COMMAND(setUniformBuffer);
|
ADD_COMMAND(setUniformBuffer);
|
||||||
|
|
||||||
_params.push_back(size);
|
_params.emplace_back(size);
|
||||||
_params.push_back(offset);
|
_params.emplace_back(offset);
|
||||||
_params.push_back(_buffers.cache(buffer));
|
_params.emplace_back(_buffers.cache(buffer));
|
||||||
_params.push_back(slot);
|
_params.emplace_back(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setUniformBuffer(uint32 slot, const BufferView& view) {
|
void Batch::setUniformBuffer(uint32 slot, const BufferView& view) {
|
||||||
|
@ -251,8 +268,8 @@ void Batch::setUniformBuffer(uint32 slot, const BufferView& view) {
|
||||||
void Batch::setResourceTexture(uint32 slot, const TexturePointer& texture) {
|
void Batch::setResourceTexture(uint32 slot, const TexturePointer& texture) {
|
||||||
ADD_COMMAND(setResourceTexture);
|
ADD_COMMAND(setResourceTexture);
|
||||||
|
|
||||||
_params.push_back(_textures.cache(texture));
|
_params.emplace_back(_textures.cache(texture));
|
||||||
_params.push_back(slot);
|
_params.emplace_back(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setResourceTexture(uint32 slot, const TextureView& view) {
|
void Batch::setResourceTexture(uint32 slot, const TextureView& view) {
|
||||||
|
@ -262,21 +279,21 @@ void Batch::setResourceTexture(uint32 slot, const TextureView& view) {
|
||||||
void Batch::setFramebuffer(const FramebufferPointer& framebuffer) {
|
void Batch::setFramebuffer(const FramebufferPointer& framebuffer) {
|
||||||
ADD_COMMAND(setFramebuffer);
|
ADD_COMMAND(setFramebuffer);
|
||||||
|
|
||||||
_params.push_back(_framebuffers.cache(framebuffer));
|
_params.emplace_back(_framebuffers.cache(framebuffer));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor) {
|
void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor) {
|
||||||
ADD_COMMAND(clearFramebuffer);
|
ADD_COMMAND(clearFramebuffer);
|
||||||
|
|
||||||
_params.push_back(enableScissor);
|
_params.emplace_back(enableScissor);
|
||||||
_params.push_back(stencil);
|
_params.emplace_back(stencil);
|
||||||
_params.push_back(depth);
|
_params.emplace_back(depth);
|
||||||
_params.push_back(color.w);
|
_params.emplace_back(color.w);
|
||||||
_params.push_back(color.z);
|
_params.emplace_back(color.z);
|
||||||
_params.push_back(color.y);
|
_params.emplace_back(color.y);
|
||||||
_params.push_back(color.x);
|
_params.emplace_back(color.x);
|
||||||
_params.push_back(targets);
|
_params.emplace_back(targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor) {
|
void Batch::clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor) {
|
||||||
|
@ -299,40 +316,40 @@ void Batch::blit(const FramebufferPointer& src, const Vec4i& srcViewport,
|
||||||
const FramebufferPointer& dst, const Vec4i& dstViewport) {
|
const FramebufferPointer& dst, const Vec4i& dstViewport) {
|
||||||
ADD_COMMAND(blit);
|
ADD_COMMAND(blit);
|
||||||
|
|
||||||
_params.push_back(_framebuffers.cache(src));
|
_params.emplace_back(_framebuffers.cache(src));
|
||||||
_params.push_back(srcViewport.x);
|
_params.emplace_back(srcViewport.x);
|
||||||
_params.push_back(srcViewport.y);
|
_params.emplace_back(srcViewport.y);
|
||||||
_params.push_back(srcViewport.z);
|
_params.emplace_back(srcViewport.z);
|
||||||
_params.push_back(srcViewport.w);
|
_params.emplace_back(srcViewport.w);
|
||||||
_params.push_back(_framebuffers.cache(dst));
|
_params.emplace_back(_framebuffers.cache(dst));
|
||||||
_params.push_back(dstViewport.x);
|
_params.emplace_back(dstViewport.x);
|
||||||
_params.push_back(dstViewport.y);
|
_params.emplace_back(dstViewport.y);
|
||||||
_params.push_back(dstViewport.z);
|
_params.emplace_back(dstViewport.z);
|
||||||
_params.push_back(dstViewport.w);
|
_params.emplace_back(dstViewport.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::generateTextureMips(const TexturePointer& texture) {
|
void Batch::generateTextureMips(const TexturePointer& texture) {
|
||||||
ADD_COMMAND(generateTextureMips);
|
ADD_COMMAND(generateTextureMips);
|
||||||
|
|
||||||
_params.push_back(_textures.cache(texture));
|
_params.emplace_back(_textures.cache(texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::beginQuery(const QueryPointer& query) {
|
void Batch::beginQuery(const QueryPointer& query) {
|
||||||
ADD_COMMAND(beginQuery);
|
ADD_COMMAND(beginQuery);
|
||||||
|
|
||||||
_params.push_back(_queries.cache(query));
|
_params.emplace_back(_queries.cache(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::endQuery(const QueryPointer& query) {
|
void Batch::endQuery(const QueryPointer& query) {
|
||||||
ADD_COMMAND(endQuery);
|
ADD_COMMAND(endQuery);
|
||||||
|
|
||||||
_params.push_back(_queries.cache(query));
|
_params.emplace_back(_queries.cache(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::getQuery(const QueryPointer& query) {
|
void Batch::getQuery(const QueryPointer& query) {
|
||||||
ADD_COMMAND(getQuery);
|
ADD_COMMAND(getQuery);
|
||||||
|
|
||||||
_params.push_back(_queries.cache(query));
|
_params.emplace_back(_queries.cache(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::resetStages() {
|
void Batch::resetStages() {
|
||||||
|
@ -341,12 +358,12 @@ void Batch::resetStages() {
|
||||||
|
|
||||||
void Batch::runLambda(std::function<void()> f) {
|
void Batch::runLambda(std::function<void()> f) {
|
||||||
ADD_COMMAND(runLambda);
|
ADD_COMMAND(runLambda);
|
||||||
_params.push_back(_lambdas.cache(f));
|
_params.emplace_back(_lambdas.cache(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::startNamedCall(const std::string& name) {
|
void Batch::startNamedCall(const std::string& name) {
|
||||||
ADD_COMMAND(startNamedCall);
|
ADD_COMMAND(startNamedCall);
|
||||||
_params.push_back(_names.cache(name));
|
_params.emplace_back(_names.cache(name));
|
||||||
|
|
||||||
_currentNamedCall = name;
|
_currentNamedCall = name;
|
||||||
}
|
}
|
||||||
|
@ -422,14 +439,14 @@ void Batch::captureDrawCallInfoImpl() {
|
||||||
//_model.getInverseMatrix(_object._modelInverse);
|
//_model.getInverseMatrix(_object._modelInverse);
|
||||||
object._modelInverse = glm::inverse(object._model);
|
object._modelInverse = glm::inverse(object._model);
|
||||||
|
|
||||||
_objects.push_back(object);
|
_objects.emplace_back(object);
|
||||||
|
|
||||||
// Flag is clean
|
// Flag is clean
|
||||||
_invalidModel = false;
|
_invalidModel = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& drawCallInfos = getDrawCallInfoBuffer();
|
auto& drawCallInfos = getDrawCallInfoBuffer();
|
||||||
drawCallInfos.push_back((uint16)_objects.size() - 1);
|
drawCallInfos.emplace_back((uint16)_objects.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::captureDrawCallInfo() {
|
void Batch::captureDrawCallInfo() {
|
||||||
|
@ -458,22 +475,11 @@ void Batch::preExecute() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug& operator<<(QDebug& debug, const Batch::CacheState& cacheState) {
|
|
||||||
debug << "Batch::CacheState[ "
|
|
||||||
<< "commandsSize:" << cacheState.commandsSize
|
|
||||||
<< "offsetsSize:" << cacheState.offsetsSize
|
|
||||||
<< "paramsSize:" << cacheState.paramsSize
|
|
||||||
<< "dataSize:" << cacheState.dataSize
|
|
||||||
<< "]";
|
|
||||||
|
|
||||||
return debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
void Batch::pushProfileRange(const char* name) {
|
void Batch::pushProfileRange(const char* name) {
|
||||||
#if defined(NSIGHT_FOUND)
|
#if defined(NSIGHT_FOUND)
|
||||||
ADD_COMMAND(pushProfileRange);
|
ADD_COMMAND(pushProfileRange);
|
||||||
_params.push_back(_profileRanges.cache(name));
|
_params.emplace_back(_profileRanges.cache(name));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,9 +496,9 @@ void Batch::_glActiveBindTexture(uint32 unit, uint32 target, uint32 texture) {
|
||||||
setResourceTexture(unit - GL_TEXTURE0, nullptr);
|
setResourceTexture(unit - GL_TEXTURE0, nullptr);
|
||||||
|
|
||||||
ADD_COMMAND(glActiveBindTexture);
|
ADD_COMMAND(glActiveBindTexture);
|
||||||
_params.push_back(texture);
|
_params.emplace_back(texture);
|
||||||
_params.push_back(target);
|
_params.emplace_back(target);
|
||||||
_params.push_back(unit);
|
_params.emplace_back(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniform1i(int32 location, int32 v0) {
|
void Batch::_glUniform1i(int32 location, int32 v0) {
|
||||||
|
@ -500,8 +506,8 @@ void Batch::_glUniform1i(int32 location, int32 v0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ADD_COMMAND(glUniform1i);
|
ADD_COMMAND(glUniform1i);
|
||||||
_params.push_back(v0);
|
_params.emplace_back(v0);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniform1f(int32 location, float v0) {
|
void Batch::_glUniform1f(int32 location, float v0) {
|
||||||
|
@ -509,89 +515,89 @@ void Batch::_glUniform1f(int32 location, float v0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ADD_COMMAND(glUniform1f);
|
ADD_COMMAND(glUniform1f);
|
||||||
_params.push_back(v0);
|
_params.emplace_back(v0);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniform2f(int32 location, float v0, float v1) {
|
void Batch::_glUniform2f(int32 location, float v0, float v1) {
|
||||||
ADD_COMMAND(glUniform2f);
|
ADD_COMMAND(glUniform2f);
|
||||||
|
|
||||||
_params.push_back(v1);
|
_params.emplace_back(v1);
|
||||||
_params.push_back(v0);
|
_params.emplace_back(v0);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniform3f(int32 location, float v0, float v1, float v2) {
|
void Batch::_glUniform3f(int32 location, float v0, float v1, float v2) {
|
||||||
ADD_COMMAND(glUniform3f);
|
ADD_COMMAND(glUniform3f);
|
||||||
|
|
||||||
_params.push_back(v2);
|
_params.emplace_back(v2);
|
||||||
_params.push_back(v1);
|
_params.emplace_back(v1);
|
||||||
_params.push_back(v0);
|
_params.emplace_back(v0);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniform4f(int32 location, float v0, float v1, float v2, float v3) {
|
void Batch::_glUniform4f(int32 location, float v0, float v1, float v2, float v3) {
|
||||||
ADD_COMMAND(glUniform4f);
|
ADD_COMMAND(glUniform4f);
|
||||||
|
|
||||||
_params.push_back(v3);
|
_params.emplace_back(v3);
|
||||||
_params.push_back(v2);
|
_params.emplace_back(v2);
|
||||||
_params.push_back(v1);
|
_params.emplace_back(v1);
|
||||||
_params.push_back(v0);
|
_params.emplace_back(v0);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniform3fv(int32 location, int count, const float* value) {
|
void Batch::_glUniform3fv(int32 location, int count, const float* value) {
|
||||||
ADD_COMMAND(glUniform3fv);
|
ADD_COMMAND(glUniform3fv);
|
||||||
|
|
||||||
const int VEC3_SIZE = 3 * sizeof(float);
|
const int VEC3_SIZE = 3 * sizeof(float);
|
||||||
_params.push_back(cacheData(count * VEC3_SIZE, value));
|
_params.emplace_back(cacheData(count * VEC3_SIZE, value));
|
||||||
_params.push_back(count);
|
_params.emplace_back(count);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniform4fv(int32 location, int count, const float* value) {
|
void Batch::_glUniform4fv(int32 location, int count, const float* value) {
|
||||||
ADD_COMMAND(glUniform4fv);
|
ADD_COMMAND(glUniform4fv);
|
||||||
|
|
||||||
const int VEC4_SIZE = 4 * sizeof(float);
|
const int VEC4_SIZE = 4 * sizeof(float);
|
||||||
_params.push_back(cacheData(count * VEC4_SIZE, value));
|
_params.emplace_back(cacheData(count * VEC4_SIZE, value));
|
||||||
_params.push_back(count);
|
_params.emplace_back(count);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniform4iv(int32 location, int count, const int32* value) {
|
void Batch::_glUniform4iv(int32 location, int count, const int32* value) {
|
||||||
ADD_COMMAND(glUniform4iv);
|
ADD_COMMAND(glUniform4iv);
|
||||||
|
|
||||||
const int VEC4_SIZE = 4 * sizeof(int);
|
const int VEC4_SIZE = 4 * sizeof(int);
|
||||||
_params.push_back(cacheData(count * VEC4_SIZE, value));
|
_params.emplace_back(cacheData(count * VEC4_SIZE, value));
|
||||||
_params.push_back(count);
|
_params.emplace_back(count);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniformMatrix3fv(int32 location, int count, uint8 transpose, const float* value) {
|
void Batch::_glUniformMatrix3fv(int32 location, int count, uint8 transpose, const float* value) {
|
||||||
ADD_COMMAND(glUniformMatrix3fv);
|
ADD_COMMAND(glUniformMatrix3fv);
|
||||||
|
|
||||||
const int MATRIX3_SIZE = 9 * sizeof(float);
|
const int MATRIX3_SIZE = 9 * sizeof(float);
|
||||||
_params.push_back(cacheData(count * MATRIX3_SIZE, value));
|
_params.emplace_back(cacheData(count * MATRIX3_SIZE, value));
|
||||||
_params.push_back(transpose);
|
_params.emplace_back(transpose);
|
||||||
_params.push_back(count);
|
_params.emplace_back(count);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glUniformMatrix4fv(int32 location, int count, uint8 transpose, const float* value) {
|
void Batch::_glUniformMatrix4fv(int32 location, int count, uint8 transpose, const float* value) {
|
||||||
ADD_COMMAND(glUniformMatrix4fv);
|
ADD_COMMAND(glUniformMatrix4fv);
|
||||||
|
|
||||||
const int MATRIX4_SIZE = 16 * sizeof(float);
|
const int MATRIX4_SIZE = 16 * sizeof(float);
|
||||||
_params.push_back(cacheData(count * MATRIX4_SIZE, value));
|
_params.emplace_back(cacheData(count * MATRIX4_SIZE, value));
|
||||||
_params.push_back(transpose);
|
_params.emplace_back(transpose);
|
||||||
_params.push_back(count);
|
_params.emplace_back(count);
|
||||||
_params.push_back(location);
|
_params.emplace_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::_glColor4f(float red, float green, float blue, float alpha) {
|
void Batch::_glColor4f(float red, float green, float blue, float alpha) {
|
||||||
ADD_COMMAND(glColor4f);
|
ADD_COMMAND(glColor4f);
|
||||||
|
|
||||||
_params.push_back(alpha);
|
_params.emplace_back(alpha);
|
||||||
_params.push_back(blue);
|
_params.emplace_back(blue);
|
||||||
_params.push_back(green);
|
_params.emplace_back(green);
|
||||||
_params.push_back(red);
|
_params.emplace_back(red);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "Transform.h"
|
#include "Transform.h"
|
||||||
|
|
||||||
class QDebug;
|
class QDebug;
|
||||||
|
#define BATCH_PREALLOCATE_MIN 128
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
enum ReservedSlot {
|
enum ReservedSlot {
|
||||||
|
@ -87,6 +87,7 @@ public:
|
||||||
using NamedBatchDataMap = std::map<std::string, NamedBatchData>;
|
using NamedBatchDataMap = std::map<std::string, NamedBatchData>;
|
||||||
|
|
||||||
DrawCallInfoBuffer _drawCallInfos;
|
DrawCallInfoBuffer _drawCallInfos;
|
||||||
|
static size_t _drawCallInfosMax;
|
||||||
|
|
||||||
std::string _currentNamedCall;
|
std::string _currentNamedCall;
|
||||||
|
|
||||||
|
@ -96,34 +97,7 @@ public:
|
||||||
void captureDrawCallInfo();
|
void captureDrawCallInfo();
|
||||||
void captureNamedDrawCallInfo(std::string name);
|
void captureNamedDrawCallInfo(std::string name);
|
||||||
|
|
||||||
class CacheState {
|
Batch();
|
||||||
public:
|
|
||||||
size_t commandsSize;
|
|
||||||
size_t offsetsSize;
|
|
||||||
size_t paramsSize;
|
|
||||||
size_t dataSize;
|
|
||||||
|
|
||||||
size_t buffersSize;
|
|
||||||
size_t texturesSize;
|
|
||||||
size_t streamFormatsSize;
|
|
||||||
size_t transformsSize;
|
|
||||||
size_t pipelinesSize;
|
|
||||||
size_t framebuffersSize;
|
|
||||||
size_t queriesSize;
|
|
||||||
|
|
||||||
CacheState() : commandsSize(0), offsetsSize(0), paramsSize(0), dataSize(0), buffersSize(0), texturesSize(0),
|
|
||||||
streamFormatsSize(0), transformsSize(0), pipelinesSize(0), framebuffersSize(0), queriesSize(0) { }
|
|
||||||
|
|
||||||
CacheState(size_t commandsSize, size_t offsetsSize, size_t paramsSize, size_t dataSize, size_t buffersSize,
|
|
||||||
size_t texturesSize, size_t streamFormatsSize, size_t transformsSize, size_t pipelinesSize,
|
|
||||||
size_t framebuffersSize, size_t queriesSize) :
|
|
||||||
commandsSize(commandsSize), offsetsSize(offsetsSize), paramsSize(paramsSize), dataSize(dataSize),
|
|
||||||
buffersSize(buffersSize), texturesSize(texturesSize), streamFormatsSize(streamFormatsSize),
|
|
||||||
transformsSize(transformsSize), pipelinesSize(pipelinesSize), framebuffersSize(framebuffersSize), queriesSize(queriesSize) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
Batch() {}
|
|
||||||
Batch(const CacheState& cacheState);
|
|
||||||
explicit Batch(const Batch& batch);
|
explicit Batch(const Batch& batch);
|
||||||
~Batch();
|
~Batch();
|
||||||
|
|
||||||
|
@ -131,9 +105,6 @@ public:
|
||||||
|
|
||||||
void preExecute();
|
void preExecute();
|
||||||
|
|
||||||
CacheState getCacheState();
|
|
||||||
|
|
||||||
|
|
||||||
// Batches may need to override the context level stereo settings
|
// Batches may need to override the context level stereo settings
|
||||||
// if they're performing framebuffer copy operations, like the
|
// if they're performing framebuffer copy operations, like the
|
||||||
// deferred lighting resolution mechanism
|
// deferred lighting resolution mechanism
|
||||||
|
@ -401,15 +372,25 @@ public:
|
||||||
typedef T Data;
|
typedef T Data;
|
||||||
Data _data;
|
Data _data;
|
||||||
Cache<T>(const Data& data) : _data(data) {}
|
Cache<T>(const Data& data) : _data(data) {}
|
||||||
|
static size_t _max;
|
||||||
|
|
||||||
class Vector {
|
class Vector {
|
||||||
public:
|
public:
|
||||||
std::vector< Cache<T> > _items;
|
std::vector< Cache<T> > _items;
|
||||||
|
|
||||||
|
Vector() {
|
||||||
|
_items.reserve(_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Vector() {
|
||||||
|
_max = std::max(_items.size(), _max);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t size() const { return _items.size(); }
|
size_t size() const { return _items.size(); }
|
||||||
size_t cache(const Data& data) {
|
size_t cache(const Data& data) {
|
||||||
size_t offset = _items.size();
|
size_t offset = _items.size();
|
||||||
_items.push_back(Cache<T>(data));
|
_items.emplace_back(data);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,9 +430,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Commands _commands;
|
Commands _commands;
|
||||||
|
static size_t _commandsMax;
|
||||||
|
|
||||||
CommandOffsets _commandOffsets;
|
CommandOffsets _commandOffsets;
|
||||||
|
static size_t _commandOffsetsMax;
|
||||||
|
|
||||||
Params _params;
|
Params _params;
|
||||||
|
static size_t _paramsMax;
|
||||||
|
|
||||||
Bytes _data;
|
Bytes _data;
|
||||||
|
static size_t _dataMax;
|
||||||
|
|
||||||
// SSBO class... layout MUST match the layout in Transform.slh
|
// SSBO class... layout MUST match the layout in Transform.slh
|
||||||
class TransformObject {
|
class TransformObject {
|
||||||
|
@ -464,6 +452,7 @@ public:
|
||||||
bool _invalidModel { true };
|
bool _invalidModel { true };
|
||||||
Transform _currentModel;
|
Transform _currentModel;
|
||||||
TransformObjects _objects;
|
TransformObjects _objects;
|
||||||
|
static size_t _objectsMax;
|
||||||
|
|
||||||
BufferCaches _buffers;
|
BufferCaches _buffers;
|
||||||
TextureCaches _textures;
|
TextureCaches _textures;
|
||||||
|
@ -491,6 +480,9 @@ protected:
|
||||||
void captureDrawCallInfoImpl();
|
void captureDrawCallInfoImpl();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t Batch::Cache<T>::_max = BATCH_PREALLOCATE_MIN;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(NSIGHT_FOUND)
|
#if defined(NSIGHT_FOUND)
|
||||||
|
@ -512,6 +504,4 @@ private:
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QDebug& operator<<(QDebug& debug, const gpu::Batch::CacheState& cacheState);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -231,11 +231,9 @@ typedef std::shared_ptr<Context> ContextPointer;
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
void doInBatch(std::shared_ptr<gpu::Context> context, F f) {
|
void doInBatch(std::shared_ptr<gpu::Context> context, F f) {
|
||||||
static gpu::Batch::CacheState cacheState;
|
gpu::Batch batch;
|
||||||
gpu::Batch batch(cacheState);
|
|
||||||
f(batch);
|
f(batch);
|
||||||
context->render(batch);
|
context->render(batch);
|
||||||
cacheState = batch.getCacheState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,6 +31,13 @@ Shader::Shader(Type type, const Pointer& vertex, const Pointer& pixel):
|
||||||
_shaders[PIXEL] = pixel;
|
_shaders[PIXEL] = pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shader::Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel) :
|
||||||
|
_type(type) {
|
||||||
|
_shaders.resize(3);
|
||||||
|
_shaders[VERTEX] = vertex;
|
||||||
|
_shaders[GEOMETRY] = geometry;
|
||||||
|
_shaders[PIXEL] = pixel;
|
||||||
|
}
|
||||||
|
|
||||||
Shader::~Shader()
|
Shader::~Shader()
|
||||||
{
|
{
|
||||||
|
@ -44,6 +51,10 @@ Shader::Pointer Shader::createPixel(const Source& source) {
|
||||||
return Pointer(new Shader(PIXEL, source));
|
return Pointer(new Shader(PIXEL, source));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shader::Pointer Shader::createGeometry(const Source& source) {
|
||||||
|
return Pointer(new Shader(GEOMETRY, source));
|
||||||
|
}
|
||||||
|
|
||||||
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) {
|
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) {
|
||||||
if (vertexShader && vertexShader->getType() == VERTEX &&
|
if (vertexShader && vertexShader->getType() == VERTEX &&
|
||||||
pixelShader && pixelShader->getType() == PIXEL) {
|
pixelShader && pixelShader->getType() == PIXEL) {
|
||||||
|
@ -52,6 +63,15 @@ Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer
|
||||||
return Pointer();
|
return Pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& geometryShader, const Pointer& pixelShader) {
|
||||||
|
if (vertexShader && vertexShader->getType() == VERTEX &&
|
||||||
|
geometryShader && geometryShader->getType() == GEOMETRY &&
|
||||||
|
pixelShader && pixelShader->getType() == PIXEL) {
|
||||||
|
return Pointer(new Shader(PROGRAM, vertexShader, geometryShader, pixelShader));
|
||||||
|
}
|
||||||
|
return Pointer();
|
||||||
|
}
|
||||||
|
|
||||||
void Shader::defineSlots(const SlotSet& uniforms, const SlotSet& buffers, const SlotSet& textures, const SlotSet& samplers, const SlotSet& inputs, const SlotSet& outputs) {
|
void Shader::defineSlots(const SlotSet& uniforms, const SlotSet& buffers, const SlotSet& textures, const SlotSet& samplers, const SlotSet& inputs, const SlotSet& outputs) {
|
||||||
_uniforms = uniforms;
|
_uniforms = uniforms;
|
||||||
_buffers = buffers;
|
_buffers = buffers;
|
||||||
|
|
|
@ -110,8 +110,10 @@ public:
|
||||||
|
|
||||||
static Pointer createVertex(const Source& source);
|
static Pointer createVertex(const Source& source);
|
||||||
static Pointer createPixel(const Source& source);
|
static Pointer createPixel(const Source& source);
|
||||||
|
static Pointer createGeometry(const Source& source);
|
||||||
|
|
||||||
static Pointer createProgram(const Pointer& vertexShader, const Pointer& pixelShader);
|
static Pointer createProgram(const Pointer& vertexShader, const Pointer& pixelShader);
|
||||||
|
static Pointer createProgram(const Pointer& vertexShader, const Pointer& geometryShader, const Pointer& pixelShader);
|
||||||
|
|
||||||
|
|
||||||
~Shader();
|
~Shader();
|
||||||
|
@ -163,6 +165,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
Shader(Type type, const Source& source);
|
Shader(Type type, const Source& source);
|
||||||
Shader(Type type, const Pointer& vertex, const Pointer& pixel);
|
Shader(Type type, const Pointer& vertex, const Pointer& pixel);
|
||||||
|
Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel);
|
||||||
|
|
||||||
Shader(const Shader& shader); // deep copy of the sysmem shader
|
Shader(const Shader& shader); // deep copy of the sysmem shader
|
||||||
Shader& operator=(const Shader& shader); // deep copy of the sysmem texture
|
Shader& operator=(const Shader& shader); // deep copy of the sysmem texture
|
||||||
|
|
|
@ -522,6 +522,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||||
const NodePermissions& permissions,
|
const NodePermissions& permissions,
|
||||||
const QUuid& connectionSecret) {
|
const QUuid& connectionSecret) {
|
||||||
|
QReadLocker readLocker(&_nodeMutex);
|
||||||
NodeHash::const_iterator it = _nodeHash.find(uuid);
|
NodeHash::const_iterator it = _nodeHash.find(uuid);
|
||||||
|
|
||||||
if (it != _nodeHash.end()) {
|
if (it != _nodeHash.end()) {
|
||||||
|
|
|
@ -131,7 +131,7 @@ public:
|
||||||
|
|
||||||
std::function<void(Node*)> linkedDataCreateCallback;
|
std::function<void(Node*)> linkedDataCreateCallback;
|
||||||
|
|
||||||
size_t size() const { return _nodeHash.size(); }
|
size_t size() const { QReadLocker readLock(&_nodeMutex); return _nodeHash.size(); }
|
||||||
|
|
||||||
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID);
|
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID);
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ protected:
|
||||||
|
|
||||||
QUuid _sessionUUID;
|
QUuid _sessionUUID;
|
||||||
NodeHash _nodeHash;
|
NodeHash _nodeHash;
|
||||||
QReadWriteLock _nodeMutex;
|
mutable QReadWriteLock _nodeMutex;
|
||||||
udt::Socket _nodeSocket;
|
udt::Socket _nodeSocket;
|
||||||
QUdpSocket* _dtlsSocket;
|
QUdpSocket* _dtlsSocket;
|
||||||
HifiSockAddr _localSockAddr;
|
HifiSockAddr _localSockAddr;
|
||||||
|
|
|
@ -513,9 +513,16 @@ void NodeList::processDomainServerConnectionTokenPacket(QSharedPointer<ReceivedM
|
||||||
|
|
||||||
void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message) {
|
void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message) {
|
||||||
if (_domainHandler.getSockAddr().isNull()) {
|
if (_domainHandler.getSockAddr().isNull()) {
|
||||||
|
qWarning() << "IGNORING DomainList packet while not connected to a Domain Server";
|
||||||
// refuse to process this packet if we aren't currently connected to the DS
|
// refuse to process this packet if we aren't currently connected to the DS
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
QUuid domainHandlerUUID = _domainHandler.getUUID();
|
||||||
|
QUuid messageSourceUUID = message->getSourceID();
|
||||||
|
if (!domainHandlerUUID.isNull() && domainHandlerUUID != messageSourceUUID) {
|
||||||
|
qWarning() << "IGNORING DomainList packet from" << messageSourceUUID << "while connected to" << domainHandlerUUID;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// this is a packet from the domain server, reset the count of un-replied check-ins
|
// this is a packet from the domain server, reset the count of un-replied check-ins
|
||||||
_numNoReplyDomainCheckIns = 0;
|
_numNoReplyDomainCheckIns = 0;
|
||||||
|
|
|
@ -49,7 +49,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
||||||
case PacketType::EntityAdd:
|
case PacketType::EntityAdd:
|
||||||
case PacketType::EntityEdit:
|
case PacketType::EntityEdit:
|
||||||
case PacketType::EntityData:
|
case PacketType::EntityData:
|
||||||
return VERSION_MODEL_ENTITIES_SUPPORT_STATIC_MESH;
|
return VERSION_MODEL_ENTITIES_SUPPORT_SIMPLE_HULLS;
|
||||||
case PacketType::AvatarIdentity:
|
case PacketType::AvatarIdentity:
|
||||||
case PacketType::AvatarData:
|
case PacketType::AvatarData:
|
||||||
case PacketType::BulkAvatarData:
|
case PacketType::BulkAvatarData:
|
||||||
|
|
|
@ -181,6 +181,7 @@ const PacketVersion VERSION_ENTITIES_NO_FLY_ZONES = 58;
|
||||||
const PacketVersion VERSION_ENTITIES_MORE_SHAPES = 59;
|
const PacketVersion VERSION_ENTITIES_MORE_SHAPES = 59;
|
||||||
const PacketVersion VERSION_ENTITIES_PROPERLY_ENCODE_SHAPE_EDITS = 60;
|
const PacketVersion VERSION_ENTITIES_PROPERLY_ENCODE_SHAPE_EDITS = 60;
|
||||||
const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_STATIC_MESH = 61;
|
const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_STATIC_MESH = 61;
|
||||||
|
const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_SIMPLE_HULLS = 62;
|
||||||
|
|
||||||
enum class AvatarMixerPacketVersion : PacketVersion {
|
enum class AvatarMixerPacketVersion : PacketVersion {
|
||||||
TranslationSupport = 17,
|
TranslationSupport = 17,
|
||||||
|
|
|
@ -204,7 +204,7 @@ btTriangleIndexVertexArray* createStaticMeshArray(const ShapeInfo& info) {
|
||||||
if (numIndices < INT16_MAX) {
|
if (numIndices < INT16_MAX) {
|
||||||
int16_t* indices = static_cast<int16_t*>((void*)(mesh.m_triangleIndexBase));
|
int16_t* indices = static_cast<int16_t*>((void*)(mesh.m_triangleIndexBase));
|
||||||
for (int32_t i = 0; i < numIndices; ++i) {
|
for (int32_t i = 0; i < numIndices; ++i) {
|
||||||
indices[i] = triangleIndices[i];
|
indices[i] = (int16_t)triangleIndices[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int32_t* indices = static_cast<int32_t*>((void*)(mesh.m_triangleIndexBase));
|
int32_t* indices = static_cast<int32_t*>((void*)(mesh.m_triangleIndexBase));
|
||||||
|
@ -257,7 +257,9 @@ btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info) {
|
||||||
shape = new btCapsuleShape(radius, height);
|
shape = new btCapsuleShape(radius, height);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHAPE_TYPE_COMPOUND: {
|
case SHAPE_TYPE_COMPOUND:
|
||||||
|
case SHAPE_TYPE_SIMPLE_HULL:
|
||||||
|
case SHAPE_TYPE_SIMPLE_COMPOUND: {
|
||||||
const ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
|
const ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
|
||||||
uint32_t numSubShapes = info.getNumSubShapes();
|
uint32_t numSubShapes = info.getNumSubShapes();
|
||||||
if (numSubShapes == 1) {
|
if (numSubShapes == 1) {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -259,6 +259,9 @@ public:
|
||||||
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
|
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
|
||||||
const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID);
|
const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID);
|
||||||
|
|
||||||
|
void renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
|
||||||
|
const glm::vec4& color, float glowIntensity = 1.0f, float glowWidth = 0.05f, int id = UNKNOWN_ID);
|
||||||
|
|
||||||
void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color,
|
void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color,
|
||||||
int id = UNKNOWN_ID)
|
int id = UNKNOWN_ID)
|
||||||
{ renderDashedLine(batch, start, end, color, 0.05f, 0.025f, id); }
|
{ renderDashedLine(batch, start, end, color, 0.05f, 0.025f, id); }
|
||||||
|
@ -403,6 +406,7 @@ private:
|
||||||
gpu::ShaderPointer _unlitShader;
|
gpu::ShaderPointer _unlitShader;
|
||||||
static render::ShapePipelinePointer _simplePipeline;
|
static render::ShapePipelinePointer _simplePipeline;
|
||||||
static render::ShapePipelinePointer _simpleWirePipeline;
|
static render::ShapePipelinePointer _simpleWirePipeline;
|
||||||
|
gpu::PipelinePointer _glowLinePipeline;
|
||||||
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
35
libraries/render-utils/src/glowLine.slf
Normal file
35
libraries/render-utils/src/glowLine.slf
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/07/05
|
||||||
|
// Copyright 2013-2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 inColor;
|
||||||
|
layout(location = 1) in vec3 inLineDistance;
|
||||||
|
|
||||||
|
out vec4 _fragColor;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 d = inLineDistance.xy;
|
||||||
|
d.y = abs(d.y);
|
||||||
|
d.x = abs(d.x);
|
||||||
|
if (d.x > 1.0) {
|
||||||
|
d.x = (d.x - 1.0) / 0.02;
|
||||||
|
} else {
|
||||||
|
d.x = 0.0;
|
||||||
|
}
|
||||||
|
float alpha = 1.0 - length(d);
|
||||||
|
if (alpha <= 0.0) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
alpha = pow(alpha, 10.0);
|
||||||
|
if (alpha < 0.05) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
_fragColor = vec4(inColor.rgb, alpha);
|
||||||
|
}
|
106
libraries/render-utils/src/glowLine.slg
Normal file
106
libraries/render-utils/src/glowLine.slg
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/07/05
|
||||||
|
// Copyright 2013-2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#extension GL_EXT_geometry_shader4 : enable
|
||||||
|
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
|
<$declareStandardCameraTransform()$>
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 inColor[];
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
layout(location = 1) out vec3 outLineDistance;
|
||||||
|
|
||||||
|
layout(lines) in;
|
||||||
|
layout(triangle_strip, max_vertices = 24) out;
|
||||||
|
|
||||||
|
vec3 ndcToEyeSpace(in vec4 v) {
|
||||||
|
TransformCamera cam = getTransformCamera();
|
||||||
|
vec4 u = cam._projectionInverse * v;
|
||||||
|
return u.xyz / u.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 toScreenSpace(in vec4 v)
|
||||||
|
{
|
||||||
|
TransformCamera cam = getTransformCamera();
|
||||||
|
vec4 u = cam._projection * cam._view * v;
|
||||||
|
return u.xy / u.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3[2] getOrthogonals(in vec3 n, float scale) {
|
||||||
|
float yDot = abs(dot(n, vec3(0, 1, 0)));
|
||||||
|
|
||||||
|
vec3 result[2];
|
||||||
|
if (yDot < 0.9) {
|
||||||
|
result[0] = normalize(cross(n, vec3(0, 1, 0)));
|
||||||
|
} else {
|
||||||
|
result[0] = normalize(cross(n, vec3(1, 0, 0)));
|
||||||
|
}
|
||||||
|
// The cross of result[0] and n is orthogonal to both, which are orthogonal to each other
|
||||||
|
result[1] = cross(result[0], n);
|
||||||
|
result[0] *= scale;
|
||||||
|
result[1] *= scale;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec2 orthogonal(vec2 v) {
|
||||||
|
vec2 result = v.yx;
|
||||||
|
result.y *= -1.0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 endpoints[2];
|
||||||
|
vec3 eyeSpace[2];
|
||||||
|
TransformCamera cam = getTransformCamera();
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
eyeSpace[i] = ndcToEyeSpace(gl_PositionIn[i]);
|
||||||
|
endpoints[i] = gl_PositionIn[i].xy / gl_PositionIn[i].w;
|
||||||
|
}
|
||||||
|
vec2 lineNormal = normalize(endpoints[1] - endpoints[0]);
|
||||||
|
vec2 lineOrthogonal = orthogonal(lineNormal);
|
||||||
|
lineNormal *= 0.02;
|
||||||
|
lineOrthogonal *= 0.02;
|
||||||
|
|
||||||
|
gl_Position = gl_PositionIn[0];
|
||||||
|
gl_Position.xy -= lineNormal;
|
||||||
|
gl_Position.xy -= lineOrthogonal;
|
||||||
|
outColor = inColor[0];
|
||||||
|
outLineDistance = vec3(-1.02, -1, gl_Position.z);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
gl_Position = gl_PositionIn[0];
|
||||||
|
gl_Position.xy -= lineNormal;
|
||||||
|
gl_Position.xy += lineOrthogonal;
|
||||||
|
outColor = inColor[0];
|
||||||
|
outLineDistance = vec3(-1.02, 1, gl_Position.z);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
gl_Position = gl_PositionIn[1];
|
||||||
|
gl_Position.xy += lineNormal;
|
||||||
|
gl_Position.xy -= lineOrthogonal;
|
||||||
|
outColor = inColor[1];
|
||||||
|
outLineDistance = vec3(1.02, -1, gl_Position.z);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
gl_Position = gl_PositionIn[1];
|
||||||
|
gl_Position.xy += lineNormal;
|
||||||
|
gl_Position.xy += lineOrthogonal;
|
||||||
|
outColor = inColor[1];
|
||||||
|
outLineDistance = vec3(1.02, 1, gl_Position.z);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
26
libraries/render-utils/src/glowLine.slv
Normal file
26
libraries/render-utils/src/glowLine.slv
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/07/05
|
||||||
|
// Copyright 2013-2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
<@include gpu/Inputs.slh@>
|
||||||
|
<@include gpu/Color.slh@>
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 _color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
_color = inColor;
|
||||||
|
|
||||||
|
// standard transform
|
||||||
|
TransformCamera cam = getTransformCamera();
|
||||||
|
TransformObject obj = getTransformObject();
|
||||||
|
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||||
|
}
|
|
@ -83,12 +83,19 @@ void ShapeInfo::setOffset(const glm::vec3& offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ShapeInfo::getNumSubShapes() const {
|
uint32_t ShapeInfo::getNumSubShapes() const {
|
||||||
if (_type == SHAPE_TYPE_NONE) {
|
switch (_type) {
|
||||||
return 0;
|
case SHAPE_TYPE_NONE:
|
||||||
} else if (_type == SHAPE_TYPE_COMPOUND) {
|
return 0;
|
||||||
return _pointCollection.size();
|
case SHAPE_TYPE_COMPOUND:
|
||||||
|
case SHAPE_TYPE_SIMPLE_COMPOUND:
|
||||||
|
return _pointCollection.size();
|
||||||
|
case SHAPE_TYPE_SIMPLE_HULL:
|
||||||
|
case SHAPE_TYPE_STATIC_MESH:
|
||||||
|
assert(_pointCollection.size() == 1);
|
||||||
|
// yes fall through to default
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ShapeInfo::getLargestSubshapePointCount() const {
|
int ShapeInfo::getLargestSubshapePointCount() const {
|
||||||
|
|
|
@ -39,6 +39,8 @@ enum ShapeType {
|
||||||
SHAPE_TYPE_HULL,
|
SHAPE_TYPE_HULL,
|
||||||
SHAPE_TYPE_PLANE,
|
SHAPE_TYPE_PLANE,
|
||||||
SHAPE_TYPE_COMPOUND,
|
SHAPE_TYPE_COMPOUND,
|
||||||
|
SHAPE_TYPE_SIMPLE_HULL,
|
||||||
|
SHAPE_TYPE_SIMPLE_COMPOUND,
|
||||||
SHAPE_TYPE_STATIC_MESH
|
SHAPE_TYPE_STATIC_MESH
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1646,6 +1646,8 @@
|
||||||
<option value="box">Box</option>
|
<option value="box">Box</option>
|
||||||
<option value="sphere">Sphere</option>
|
<option value="sphere">Sphere</option>
|
||||||
<option value="compound">Compound</option>
|
<option value="compound">Compound</option>
|
||||||
|
<option value="simple-hull">One Hull</option>
|
||||||
|
<option value="simple-compound">Hull Per Submesh</option>
|
||||||
<option value="static-mesh">Static Mesh</option>
|
<option value="static-mesh">Static Mesh</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
18
tests/render-perf/CMakeLists.txt
Normal file
18
tests/render-perf/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
set(TARGET_NAME render-perf-test)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049 /ignore:4217")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# This is not a testcase -- just set it up as a regular hifi project
|
||||||
|
setup_hifi_project(Quick Gui OpenGL)
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/")
|
||||||
|
|
||||||
|
# link in the shared libraries
|
||||||
|
link_hifi_libraries(shared octree gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics)
|
||||||
|
|
||||||
|
package_libraries_for_deployment()
|
||||||
|
|
||||||
|
|
||||||
|
target_bullet()
|
651
tests/render-perf/src/main.cpp
Normal file
651
tests/render-perf/src/main.cpp
Normal file
|
@ -0,0 +1,651 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/07/01
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QElapsedTimer>
|
||||||
|
#include <QtCore/QLoggingCategory>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
|
||||||
|
#include <QtGui/QGuiApplication>
|
||||||
|
#include <QtGui/QResizeEvent>
|
||||||
|
#include <QtGui/QWindow>
|
||||||
|
|
||||||
|
#include <QtWidgets/QFileDialog>
|
||||||
|
#include <QtWidgets/QInputDialog>
|
||||||
|
#include <QtWidgets/QMessageBox>
|
||||||
|
#include <QtWidgets/QApplication>
|
||||||
|
|
||||||
|
#include <shared/RateCounter.h>
|
||||||
|
|
||||||
|
#include <gl/GLHelpers.h>
|
||||||
|
#include <gl/QOpenGLContextWrapper.h>
|
||||||
|
#include <gl/QOpenGLDebugLoggerWrapper.h>
|
||||||
|
|
||||||
|
#include <gpu/gl/GLBackend.h>
|
||||||
|
#include <gpu/gl/GLFramebuffer.h>
|
||||||
|
|
||||||
|
#include <render/Engine.h>
|
||||||
|
#include <Model.h>
|
||||||
|
#include <model/Stage.h>
|
||||||
|
#include <TextureCache.h>
|
||||||
|
#include <FramebufferCache.h>
|
||||||
|
#include <model-networking/ModelCache.h>
|
||||||
|
#include <GeometryCache.h>
|
||||||
|
#include <DeferredLightingEffect.h>
|
||||||
|
#include <RenderShadowTask.h>
|
||||||
|
#include <RenderDeferredTask.h>
|
||||||
|
#include <OctreeConstants.h>
|
||||||
|
|
||||||
|
#include <EntityTreeRenderer.h>
|
||||||
|
#include <AbstractViewStateInterface.h>
|
||||||
|
#include <AddressManager.h>
|
||||||
|
#include <SceneScriptingInterface.h>
|
||||||
|
|
||||||
|
static const QString LAST_SCENE_KEY = "lastSceneFile";
|
||||||
|
|
||||||
|
class ParentFinder : public SpatialParentFinder {
|
||||||
|
public:
|
||||||
|
EntityTreePointer _tree;
|
||||||
|
ParentFinder(EntityTreePointer tree) : _tree(tree) {}
|
||||||
|
|
||||||
|
SpatiallyNestableWeakPointer find(QUuid parentID, bool& success, SpatialParentTree* entityTree = nullptr) const override {
|
||||||
|
SpatiallyNestableWeakPointer parent;
|
||||||
|
|
||||||
|
if (parentID.isNull()) {
|
||||||
|
success = true;
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// search entities
|
||||||
|
if (entityTree) {
|
||||||
|
parent = entityTree->findByID(parentID);
|
||||||
|
} else {
|
||||||
|
parent = _tree ? _tree->findEntityByEntityItemID(parentID) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parent.expired()) {
|
||||||
|
success = true;
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
success = false;
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Camera {
|
||||||
|
protected:
|
||||||
|
float fov { 60.0f };
|
||||||
|
float znear { 0.1f }, zfar { 512.0f };
|
||||||
|
float aspect { 1.0f };
|
||||||
|
|
||||||
|
void updateViewMatrix() {
|
||||||
|
matrices.view = glm::inverse(glm::translate(glm::mat4(), position) * glm::mat4_cast(getOrientation()));
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat getOrientation() const {
|
||||||
|
return glm::angleAxis(yaw, Vectors::UP);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
float yaw { 0 };
|
||||||
|
glm::vec3 position;
|
||||||
|
|
||||||
|
float rotationSpeed { 1.0f };
|
||||||
|
float movementSpeed { 1.0f };
|
||||||
|
|
||||||
|
struct Matrices {
|
||||||
|
glm::mat4 perspective;
|
||||||
|
glm::mat4 view;
|
||||||
|
} matrices;
|
||||||
|
enum Key {
|
||||||
|
RIGHT,
|
||||||
|
LEFT,
|
||||||
|
UP,
|
||||||
|
DOWN,
|
||||||
|
BACK,
|
||||||
|
FORWARD,
|
||||||
|
KEYS_SIZE,
|
||||||
|
INVALID = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::bitset<KEYS_SIZE> keys;
|
||||||
|
|
||||||
|
Camera() {
|
||||||
|
matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool moving() {
|
||||||
|
return keys.any();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFieldOfView(float fov) {
|
||||||
|
this->fov = fov;
|
||||||
|
matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAspectRatio(const glm::vec2& size) {
|
||||||
|
setAspectRatio(size.x / size.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAspectRatio(float aspect) {
|
||||||
|
this->aspect = aspect;
|
||||||
|
matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPerspective(float fov, const glm::vec2& size, float znear = 0.1f, float zfar = 512.0f) {
|
||||||
|
setPerspective(fov, size.x / size.y, znear, zfar);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPerspective(float fov, float aspect, float znear = 0.1f, float zfar = 512.0f) {
|
||||||
|
this->aspect = aspect;
|
||||||
|
this->fov = fov;
|
||||||
|
this->znear = znear;
|
||||||
|
this->zfar = zfar;
|
||||||
|
matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
|
||||||
|
};
|
||||||
|
|
||||||
|
void rotate(const float delta) {
|
||||||
|
yaw += delta;
|
||||||
|
updateViewMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPosition(const glm::vec3& position) {
|
||||||
|
this->position = position;
|
||||||
|
updateViewMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate in the Z axis of the camera
|
||||||
|
void dolly(float delta) {
|
||||||
|
auto direction = glm::vec3(0, 0, delta);
|
||||||
|
translate(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate in the XY plane of the camera
|
||||||
|
void translate(const glm::vec2& delta) {
|
||||||
|
auto move = glm::vec3(delta.x, delta.y, 0);
|
||||||
|
translate(move);
|
||||||
|
}
|
||||||
|
|
||||||
|
void translate(const glm::vec3& delta) {
|
||||||
|
position += getOrientation() * delta;
|
||||||
|
updateViewMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(float deltaTime) {
|
||||||
|
if (moving()) {
|
||||||
|
glm::vec3 camFront = getOrientation() * Vectors::FRONT;
|
||||||
|
glm::vec3 camRight = getOrientation() * Vectors::RIGHT;
|
||||||
|
glm::vec3 camUp = getOrientation() * Vectors::UP;
|
||||||
|
float moveSpeed = deltaTime * movementSpeed;
|
||||||
|
|
||||||
|
if (keys[FORWARD]) {
|
||||||
|
position += camFront * moveSpeed;
|
||||||
|
}
|
||||||
|
if (keys[BACK]) {
|
||||||
|
position -= camFront * moveSpeed;
|
||||||
|
}
|
||||||
|
if (keys[LEFT]) {
|
||||||
|
position -= camRight * moveSpeed;
|
||||||
|
}
|
||||||
|
if (keys[RIGHT]) {
|
||||||
|
position += camRight * moveSpeed;
|
||||||
|
}
|
||||||
|
if (keys[UP]) {
|
||||||
|
position += camUp * moveSpeed;
|
||||||
|
}
|
||||||
|
if (keys[DOWN]) {
|
||||||
|
position -= camUp * moveSpeed;
|
||||||
|
}
|
||||||
|
updateViewMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class QWindowCamera : public Camera {
|
||||||
|
Key forKey(int key) {
|
||||||
|
switch (key) {
|
||||||
|
case Qt::Key_W: return FORWARD;
|
||||||
|
case Qt::Key_S: return BACK;
|
||||||
|
case Qt::Key_A: return LEFT;
|
||||||
|
case Qt::Key_D: return RIGHT;
|
||||||
|
case Qt::Key_E: return UP;
|
||||||
|
case Qt::Key_C: return DOWN;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 _lastMouse;
|
||||||
|
public:
|
||||||
|
void onKeyPress(QKeyEvent* event) {
|
||||||
|
Key k = forKey(event->key());
|
||||||
|
if (k == INVALID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
keys.set(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onKeyRelease(QKeyEvent* event) {
|
||||||
|
Key k = forKey(event->key());
|
||||||
|
if (k == INVALID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
keys.reset(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onMouseMove(QMouseEvent* event) {
|
||||||
|
vec2 mouse = toGlm(event->localPos());
|
||||||
|
vec2 delta = mouse - _lastMouse;
|
||||||
|
auto buttons = event->buttons();
|
||||||
|
if (buttons & Qt::RightButton) {
|
||||||
|
dolly(delta.y * 0.01f);
|
||||||
|
} else if (buttons & Qt::LeftButton) {
|
||||||
|
rotate(delta.x * -0.01f);
|
||||||
|
} else if (buttons & Qt::MiddleButton) {
|
||||||
|
delta.y *= -1.0f;
|
||||||
|
translate(delta * -0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastMouse = mouse;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a simple OpenGL window that renders text in various ways
|
||||||
|
class QTestWindow : public QWindow, public AbstractViewStateInterface {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void copyCurrentViewFrustum(ViewFrustum& viewOut) const override {
|
||||||
|
viewOut = _viewFrustum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyShadowViewFrustum(ViewFrustum& viewOut) const override {
|
||||||
|
viewOut = _shadowViewFrustum;
|
||||||
|
}
|
||||||
|
|
||||||
|
QThread* getMainThread() override {
|
||||||
|
return QThread::currentThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
PickRay computePickRay(float x, float y) const override {
|
||||||
|
return PickRay();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 getAvatarPosition() const override {
|
||||||
|
return vec3();
|
||||||
|
}
|
||||||
|
|
||||||
|
void postLambdaEvent(std::function<void()> f) override {}
|
||||||
|
qreal getDevicePixelRatio() override {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
render::ScenePointer getMain3DScene() override {
|
||||||
|
return _main3DScene;
|
||||||
|
}
|
||||||
|
render::EnginePointer getRenderEngine() override {
|
||||||
|
return _renderEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushPostUpdateLambda(void* key, std::function<void()> func) override {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
//"/-17.2049,-8.08629,-19.4153/0,0.881994,0,-0.47126"
|
||||||
|
static void setup() {
|
||||||
|
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
||||||
|
DependencyManager::registerInheritance<SpatialParentFinder, ParentFinder>();
|
||||||
|
DependencyManager::set<AddressManager>();
|
||||||
|
DependencyManager::set<NodeList>(NodeType::Agent, 0);
|
||||||
|
DependencyManager::set<DeferredLightingEffect>();
|
||||||
|
DependencyManager::set<ResourceCacheSharedItems>();
|
||||||
|
DependencyManager::set<TextureCache>();
|
||||||
|
DependencyManager::set<FramebufferCache>();
|
||||||
|
DependencyManager::set<GeometryCache>();
|
||||||
|
DependencyManager::set<ModelCache>();
|
||||||
|
DependencyManager::set<AnimationCache>();
|
||||||
|
DependencyManager::set<ModelBlender>();
|
||||||
|
DependencyManager::set<PathUtils>();
|
||||||
|
DependencyManager::set<SceneScriptingInterface>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTestWindow() {
|
||||||
|
QThread::currentThread()->setPriority(QThread::HighestPriority);
|
||||||
|
AbstractViewStateInterface::setInstance(this);
|
||||||
|
_octree = DependencyManager::set<EntityTreeRenderer>(false, this, nullptr);
|
||||||
|
_octree->init();
|
||||||
|
DependencyManager::set<ParentFinder>(_octree->getTree());
|
||||||
|
getEntities()->setViewFrustum(_viewFrustum);
|
||||||
|
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||||
|
NodePermissions permissions;
|
||||||
|
permissions.setAll(true);
|
||||||
|
nodeList->setPermissions(permissions);
|
||||||
|
|
||||||
|
ResourceManager::init();
|
||||||
|
setSurfaceType(QSurface::OpenGLSurface);
|
||||||
|
auto format = getDefaultOpenGLSurfaceFormat();
|
||||||
|
format.setOption(QSurfaceFormat::DebugContext);
|
||||||
|
setFormat(format);
|
||||||
|
|
||||||
|
_context.setFormat(format);
|
||||||
|
_context.create();
|
||||||
|
|
||||||
|
show();
|
||||||
|
makeCurrent();
|
||||||
|
glewInit();
|
||||||
|
glGetError();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
wglSwapIntervalEXT(0);
|
||||||
|
#endif
|
||||||
|
_camera.movementSpeed = 3.0f;
|
||||||
|
|
||||||
|
setupDebugLogger(this);
|
||||||
|
qDebug() << (const char*)glGetString(GL_VERSION);
|
||||||
|
|
||||||
|
// GPU library init
|
||||||
|
{
|
||||||
|
gpu::Context::init<gpu::gl::GLBackend>();
|
||||||
|
_gpuContext = std::make_shared<gpu::Context>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render engine library init
|
||||||
|
{
|
||||||
|
makeCurrent();
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->init();
|
||||||
|
_renderEngine->addJob<RenderShadowTask>("RenderShadowTask", _cullFunctor);
|
||||||
|
_renderEngine->addJob<RenderDeferredTask>("RenderDeferredTask", _cullFunctor);
|
||||||
|
_renderEngine->load();
|
||||||
|
_renderEngine->registerScene(_main3DScene);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant lastScene = _settings.value(LAST_SCENE_KEY);
|
||||||
|
if (lastScene.isValid()) {
|
||||||
|
auto result = QMessageBox::question(nullptr, "Question", "Load last scene " + lastScene.toString());
|
||||||
|
if (result != QMessageBox::No) {
|
||||||
|
importScene(lastScene.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resize(QSize(800, 600));
|
||||||
|
_elapsed.start();
|
||||||
|
|
||||||
|
QTimer* timer = new QTimer(this);
|
||||||
|
timer->setInterval(0);
|
||||||
|
connect(timer, &QTimer::timeout, this, [this] {
|
||||||
|
draw();
|
||||||
|
});
|
||||||
|
timer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~QTestWindow() {
|
||||||
|
ResourceManager::cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent* event) override {
|
||||||
|
switch (event->key()) {
|
||||||
|
case Qt::Key_F1:
|
||||||
|
importScene();
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Qt::Key_F2:
|
||||||
|
goTo();
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_camera.onKeyPress(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyReleaseEvent(QKeyEvent* event) override {
|
||||||
|
_camera.onKeyRelease(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouseMoveEvent(QMouseEvent* event) override {
|
||||||
|
_camera.onMouseMove(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent* ev) override {
|
||||||
|
resizeWindow(ev->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static bool cull(const RenderArgs* renderArgs, const AABox& box) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
auto now = usecTimestampNow();
|
||||||
|
static auto last = now;
|
||||||
|
|
||||||
|
float delta = now - last;
|
||||||
|
// Update the camera
|
||||||
|
_camera.update(delta / USECS_PER_SECOND);
|
||||||
|
|
||||||
|
|
||||||
|
// load the view frustum
|
||||||
|
{
|
||||||
|
_viewFrustum.setProjection(_camera.matrices.perspective);
|
||||||
|
auto view = glm::inverse(_camera.matrices.view);
|
||||||
|
_viewFrustum.setPosition(glm::vec3(view[3]));
|
||||||
|
_viewFrustum.setOrientation(glm::quat_cast(view));
|
||||||
|
}
|
||||||
|
last = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw() {
|
||||||
|
if (!isVisible()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
|
||||||
|
makeCurrent();
|
||||||
|
#define RENDER_SCENE 1
|
||||||
|
|
||||||
|
#if RENDER_SCENE
|
||||||
|
RenderArgs renderArgs(_gpuContext, _octree.data(), DEFAULT_OCTREE_SIZE_SCALE,
|
||||||
|
0, RenderArgs::DEFAULT_RENDER_MODE,
|
||||||
|
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
||||||
|
|
||||||
|
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
|
QSize windowSize = size();
|
||||||
|
framebufferCache->setFrameBufferSize(windowSize);
|
||||||
|
// Viewport is assigned to the size of the framebuffer
|
||||||
|
renderArgs._viewport = ivec4(0, 0, windowSize.width(), windowSize.height());
|
||||||
|
|
||||||
|
renderArgs.setViewFrustum(_viewFrustum);
|
||||||
|
|
||||||
|
// Final framebuffer that will be handled to the display-plugin
|
||||||
|
{
|
||||||
|
auto finalFramebuffer = framebufferCache->getFramebuffer();
|
||||||
|
renderArgs._blitFramebuffer = finalFramebuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(&renderArgs);
|
||||||
|
|
||||||
|
{
|
||||||
|
gpu::gl::GLFramebuffer* framebuffer = gpu::Backend::getGPUObject<gpu::gl::GLFramebuffer>(*renderArgs._blitFramebuffer);
|
||||||
|
auto fbo = framebuffer->_id;
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
const auto& vp = renderArgs._viewport;
|
||||||
|
glBlitFramebuffer(vp.x, vp.y, vp.z, vp.w, vp.x, vp.y, vp.z, vp.w, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
glClearColor(0.0f, 0.5f, 0.8f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_context.swapBuffers(this);
|
||||||
|
|
||||||
|
#if RENDER_SCENE
|
||||||
|
framebufferCache->releaseFramebuffer(renderArgs._blitFramebuffer);
|
||||||
|
renderArgs._blitFramebuffer.reset();
|
||||||
|
gpu::doInBatch(renderArgs._context, [&](gpu::Batch& batch) {
|
||||||
|
batch.resetStages();
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
fps.increment();
|
||||||
|
static size_t _frameCount { 0 };
|
||||||
|
++_frameCount;
|
||||||
|
if (_elapsed.elapsed() >= 4000) {
|
||||||
|
qDebug() << "FPS " << fps.rate();
|
||||||
|
_frameCount = 0;
|
||||||
|
_elapsed.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == ++_frameCount % 100) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(RenderArgs* renderArgs) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
|
PerformanceTimer perfTimer("draw");
|
||||||
|
// The pending changes collecting the changes here
|
||||||
|
render::PendingChanges pendingChanges;
|
||||||
|
// Setup the current Zone Entity lighting
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(_sunSkyStage.getSunLight());
|
||||||
|
{
|
||||||
|
PerformanceTimer perfTimer("SceneProcessPendingChanges");
|
||||||
|
_main3DScene->enqueuePendingChanges(pendingChanges);
|
||||||
|
_main3DScene->processPendingChangesQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// For now every frame pass the renderContext
|
||||||
|
{
|
||||||
|
PerformanceTimer perfTimer("EngineRun");
|
||||||
|
_renderEngine->getRenderContext()->args = renderArgs;
|
||||||
|
// Before the deferred pass, let's try to use the render engine
|
||||||
|
_renderEngine->run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeCurrent() {
|
||||||
|
_context.makeCurrent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resizeWindow(const QSize& size) {
|
||||||
|
_size = size;
|
||||||
|
_camera.setAspectRatio((float)_size.width() / (float)_size.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsePath(const QString& viewpointString) {
|
||||||
|
static const QString FLOAT_REGEX_STRING = "([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)";
|
||||||
|
static const QString SPACED_COMMA_REGEX_STRING = "\\s*,\\s*";
|
||||||
|
static const QString POSITION_REGEX_STRING = QString("\\/") + FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING +
|
||||||
|
FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING + FLOAT_REGEX_STRING + "\\s*(?:$|\\/)";
|
||||||
|
static const QString QUAT_REGEX_STRING = QString("\\/") + FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING +
|
||||||
|
FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING + FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING +
|
||||||
|
FLOAT_REGEX_STRING + "\\s*$";
|
||||||
|
|
||||||
|
static QRegExp orientationRegex(QUAT_REGEX_STRING);
|
||||||
|
static QRegExp positionRegex(POSITION_REGEX_STRING);
|
||||||
|
|
||||||
|
if (positionRegex.indexIn(viewpointString) != -1) {
|
||||||
|
// we have at least a position, so emit our signal to say we need to change position
|
||||||
|
glm::vec3 newPosition(positionRegex.cap(1).toFloat(),
|
||||||
|
positionRegex.cap(2).toFloat(),
|
||||||
|
positionRegex.cap(3).toFloat());
|
||||||
|
_camera.setPosition(newPosition);
|
||||||
|
|
||||||
|
if (!glm::any(glm::isnan(newPosition))) {
|
||||||
|
// we may also have an orientation
|
||||||
|
if (viewpointString[positionRegex.matchedLength() - 1] == QChar('/')
|
||||||
|
&& orientationRegex.indexIn(viewpointString, positionRegex.matchedLength() - 1) != -1) {
|
||||||
|
//glm::vec4 v = glm::vec4(
|
||||||
|
// orientationRegex.cap(1).toFloat(),
|
||||||
|
// orientationRegex.cap(2).toFloat(),
|
||||||
|
// orientationRegex.cap(3).toFloat(),
|
||||||
|
// orientationRegex.cap(4).toFloat());
|
||||||
|
//if (!glm::any(glm::isnan(v))) {
|
||||||
|
// _camera.setRotation(glm::normalize(glm::quat(v.w, v.x, v.y, v.z)));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void importScene(const QString& fileName) {
|
||||||
|
_settings.setValue(LAST_SCENE_KEY, fileName);
|
||||||
|
_octree->clear();
|
||||||
|
_octree->getTree()->readFromURL(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void importScene() {
|
||||||
|
QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open File"), "/home", tr("Hifi Exports (*.json *.svo)"));
|
||||||
|
if (fileName.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
importScene(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void goTo() {
|
||||||
|
QString destination = QInputDialog::getText(nullptr, tr("Go To Location"), "Enter path");
|
||||||
|
if (destination.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parsePath(destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
render::CullFunctor _cullFunctor { cull };
|
||||||
|
gpu::ContextPointer _gpuContext; // initialized during window creation
|
||||||
|
render::EnginePointer _renderEngine { new render::Engine() };
|
||||||
|
render::ScenePointer _main3DScene { new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) };
|
||||||
|
QOpenGLContextWrapper _context;
|
||||||
|
QSize _size;
|
||||||
|
RateCounter<> fps;
|
||||||
|
QSettings _settings;
|
||||||
|
|
||||||
|
QWindowCamera _camera;
|
||||||
|
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||||
|
ViewFrustum _shadowViewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||||
|
model::SunSkyStage _sunSkyStage;
|
||||||
|
model::LightPointer _globalLight { std::make_shared<model::Light>() };
|
||||||
|
QElapsedTimer _elapsed;
|
||||||
|
QSharedPointer<EntityTreeRenderer> _octree;
|
||||||
|
QSharedPointer<EntityTreeRenderer> getEntities() {
|
||||||
|
return _octree;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||||
|
if (!message.isEmpty()) {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
OutputDebugStringA(message.toLocal8Bit().constData());
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
#endif
|
||||||
|
std::cout << message.toLocal8Bit().constData() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * LOG_FILTER_RULES = R"V0G0N(
|
||||||
|
hifi.gpu=true
|
||||||
|
)V0G0N";
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
QCoreApplication::setApplicationName("RenderPerf");
|
||||||
|
QCoreApplication::setOrganizationName("High Fidelity");
|
||||||
|
QCoreApplication::setOrganizationDomain("highfidelity.com");
|
||||||
|
|
||||||
|
qInstallMessageHandler(messageHandler);
|
||||||
|
QLoggingCategory::setFilterRules(LOG_FILTER_RULES);
|
||||||
|
QTestWindow::setup();
|
||||||
|
QTestWindow window;
|
||||||
|
app.exec();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "main.moc"
|
Loading…
Reference in a new issue