mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 06:53:01 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into fix/script-thread-dtor
This commit is contained in:
commit
7d4276d15f
80 changed files with 1299 additions and 773 deletions
|
@ -290,7 +290,6 @@ void Agent::executeScript() {
|
||||||
packetReceiver.registerListener(PacketType::BulkAvatarData, avatarHashMap.data(), "processAvatarDataPacket");
|
packetReceiver.registerListener(PacketType::BulkAvatarData, avatarHashMap.data(), "processAvatarDataPacket");
|
||||||
packetReceiver.registerListener(PacketType::KillAvatar, avatarHashMap.data(), "processKillAvatar");
|
packetReceiver.registerListener(PacketType::KillAvatar, avatarHashMap.data(), "processKillAvatar");
|
||||||
packetReceiver.registerListener(PacketType::AvatarIdentity, avatarHashMap.data(), "processAvatarIdentityPacket");
|
packetReceiver.registerListener(PacketType::AvatarIdentity, avatarHashMap.data(), "processAvatarIdentityPacket");
|
||||||
packetReceiver.registerListener(PacketType::AvatarBillboard, avatarHashMap.data(), "processAvatarBillboardPacket");
|
|
||||||
|
|
||||||
// register ourselves to the script engine
|
// register ourselves to the script engine
|
||||||
_scriptEngine->registerGlobalObject("Agent", this);
|
_scriptEngine->registerGlobalObject("Agent", this);
|
||||||
|
@ -341,15 +340,12 @@ void Agent::setIsAvatar(bool isAvatar) {
|
||||||
if (_isAvatar && !_avatarIdentityTimer) {
|
if (_isAvatar && !_avatarIdentityTimer) {
|
||||||
// set up the avatar timers
|
// set up the avatar timers
|
||||||
_avatarIdentityTimer = new QTimer(this);
|
_avatarIdentityTimer = new QTimer(this);
|
||||||
_avatarBillboardTimer = new QTimer(this);
|
|
||||||
|
|
||||||
// connect our slot
|
// connect our slot
|
||||||
connect(_avatarIdentityTimer, &QTimer::timeout, this, &Agent::sendAvatarIdentityPacket);
|
connect(_avatarIdentityTimer, &QTimer::timeout, this, &Agent::sendAvatarIdentityPacket);
|
||||||
connect(_avatarBillboardTimer, &QTimer::timeout, this, &Agent::sendAvatarBillboardPacket);
|
|
||||||
|
|
||||||
// start the timers
|
// start the timers
|
||||||
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
|
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
|
||||||
_avatarBillboardTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_isAvatar) {
|
if (!_isAvatar) {
|
||||||
|
@ -359,12 +355,6 @@ void Agent::setIsAvatar(bool isAvatar) {
|
||||||
delete _avatarIdentityTimer;
|
delete _avatarIdentityTimer;
|
||||||
_avatarIdentityTimer = nullptr;
|
_avatarIdentityTimer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_avatarBillboardTimer) {
|
|
||||||
_avatarBillboardTimer->stop();
|
|
||||||
delete _avatarBillboardTimer;
|
|
||||||
_avatarBillboardTimer = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,14 +365,6 @@ void Agent::sendAvatarIdentityPacket() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Agent::sendAvatarBillboardPacket() {
|
|
||||||
if (_isAvatar) {
|
|
||||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
|
||||||
scriptedAvatar->sendBillboardPacket();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::processAgentAvatarAndAudio(float deltaTime) {
|
void Agent::processAgentAvatarAndAudio(float deltaTime) {
|
||||||
if (!_scriptEngine->isFinished() && _isAvatar) {
|
if (!_scriptEngine->isFinished() && _isAvatar) {
|
||||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||||
|
@ -491,7 +473,7 @@ void Agent::processAgentAvatarAndAudio(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Agent::aboutToFinish() {
|
void Agent::aboutToFinish() {
|
||||||
setIsAvatar(false);// will stop timers for sending billboards and identity packets
|
setIsAvatar(false);// will stop timers for sending identity packets
|
||||||
|
|
||||||
if (_scriptEngine) {
|
if (_scriptEngine) {
|
||||||
_scriptEngine->stop();
|
_scriptEngine->stop();
|
||||||
|
|
|
@ -82,7 +82,6 @@ private:
|
||||||
void setAvatarSound(SharedSoundPointer avatarSound) { _avatarSound = avatarSound; }
|
void setAvatarSound(SharedSoundPointer avatarSound) { _avatarSound = avatarSound; }
|
||||||
|
|
||||||
void sendAvatarIdentityPacket();
|
void sendAvatarIdentityPacket();
|
||||||
void sendAvatarBillboardPacket();
|
|
||||||
|
|
||||||
QString _scriptContents;
|
QString _scriptContents;
|
||||||
QTimer* _scriptRequestTimeout { nullptr };
|
QTimer* _scriptRequestTimeout { nullptr };
|
||||||
|
@ -92,7 +91,6 @@ private:
|
||||||
int _numAvatarSoundSentBytes = 0;
|
int _numAvatarSoundSentBytes = 0;
|
||||||
bool _isAvatar = false;
|
bool _isAvatar = false;
|
||||||
QTimer* _avatarIdentityTimer = nullptr;
|
QTimer* _avatarIdentityTimer = nullptr;
|
||||||
QTimer* _avatarBillboardTimer = nullptr;
|
|
||||||
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -864,10 +864,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
|
|
||||||
if (action == controller::toInt(controller::Action::RETICLE_CLICK)) {
|
if (action == controller::toInt(controller::Action::RETICLE_CLICK)) {
|
||||||
auto reticlePos = getApplicationCompositor().getReticlePosition();
|
auto reticlePos = getApplicationCompositor().getReticlePosition();
|
||||||
QPoint globalPos(reticlePos.x, reticlePos.y);
|
QPoint localPos(reticlePos.x, reticlePos.y); // both hmd and desktop already handle this in our coordinates.
|
||||||
|
|
||||||
// FIXME - it would be nice if this was self contained in the _compositor or Reticle class
|
|
||||||
auto localPos = isHMDMode() ? globalPos : _glWidget->mapFromGlobal(globalPos);
|
|
||||||
if (state) {
|
if (state) {
|
||||||
QMouseEvent mousePress(QEvent::MouseButtonPress, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
QMouseEvent mousePress(QEvent::MouseButtonPress, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||||
sendEvent(_glWidget, &mousePress);
|
sendEvent(_glWidget, &mousePress);
|
||||||
|
@ -888,15 +885,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
} else if (action == controller::toInt(controller::Action::UI_NAV_SELECT)) {
|
} else if (action == controller::toInt(controller::Action::UI_NAV_SELECT)) {
|
||||||
if (!offscreenUi->navigationFocused()) {
|
if (!offscreenUi->navigationFocused()) {
|
||||||
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
||||||
offscreenUi->toggleMenu(_glWidget->mapFromGlobal(QPoint(reticlePosition.x, reticlePosition.y)));
|
offscreenUi->toggleMenu(QPoint(reticlePosition.x, reticlePosition.y));
|
||||||
}
|
}
|
||||||
} else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {
|
} else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {
|
||||||
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
||||||
offscreenUi->toggleMenu(_glWidget->mapFromGlobal(QPoint(reticlePosition.x, reticlePosition.y)));
|
offscreenUi->toggleMenu(QPoint(reticlePosition.x, reticlePosition.y));
|
||||||
} else if (action == controller::toInt(controller::Action::UI_NAV_SELECT)) {
|
} else if (action == controller::toInt(controller::Action::UI_NAV_SELECT)) {
|
||||||
if (!offscreenUi->navigationFocused()) {
|
if (!offscreenUi->navigationFocused()) {
|
||||||
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
||||||
offscreenUi->toggleMenu(_glWidget->mapFromGlobal(QPoint(reticlePosition.x, reticlePosition.y)));
|
offscreenUi->toggleMenu(QPoint(reticlePosition.x, reticlePosition.y));
|
||||||
}
|
}
|
||||||
} else if (action == controller::toInt(controller::Action::RETICLE_X)) {
|
} else if (action == controller::toInt(controller::Action::RETICLE_X)) {
|
||||||
auto oldPos = getApplicationCompositor().getReticlePosition();
|
auto oldPos = getApplicationCompositor().getReticlePosition();
|
||||||
|
@ -1071,6 +1068,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
// in the queue, which can be pretty damn frequent. Hence the idle function has a bunch
|
// in the queue, which can be pretty damn frequent. Hence the idle function has a bunch
|
||||||
// of logic to abort early if it's being called too often.
|
// of logic to abort early if it's being called too often.
|
||||||
_idleTimer->start(0);
|
_idleTimer->start(0);
|
||||||
|
|
||||||
|
// After all of the constructor is completed, then set firstRun to false.
|
||||||
|
Setting::Handle<bool> firstRun{ Settings::firstRun, true };
|
||||||
|
firstRun.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1088,11 +1089,6 @@ void Application::checkChangeCursor() {
|
||||||
|
|
||||||
_cursorNeedsChanging = false;
|
_cursorNeedsChanging = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// After all of the constructor is completed, then set firstRun to false.
|
|
||||||
Setting::Handle<bool> firstRun{ Settings::firstRun, true };
|
|
||||||
firstRun.set(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::showCursor(const QCursor& cursor) {
|
void Application::showCursor(const QCursor& cursor) {
|
||||||
|
@ -1160,10 +1156,16 @@ void Application::cleanupBeforeQuit() {
|
||||||
|
|
||||||
getEntities()->shutdown(); // tell the entities system we're shutting down, so it will stop running scripts
|
getEntities()->shutdown(); // tell the entities system we're shutting down, so it will stop running scripts
|
||||||
|
|
||||||
|
// Clear any queued processing (I/O, FBX/OBJ/Texture parsing)
|
||||||
|
QThreadPool::globalInstance()->clear();
|
||||||
|
|
||||||
DependencyManager::get<ScriptEngines>()->saveScripts();
|
DependencyManager::get<ScriptEngines>()->saveScripts();
|
||||||
DependencyManager::get<ScriptEngines>()->shutdownScripting(); // stop all currently running global scripts
|
DependencyManager::get<ScriptEngines>()->shutdownScripting(); // stop all currently running global scripts
|
||||||
DependencyManager::destroy<ScriptEngines>();
|
DependencyManager::destroy<ScriptEngines>();
|
||||||
|
|
||||||
|
// Cleanup all overlays after the scripts, as scripts might add more
|
||||||
|
_overlays.cleanupAllOverlays();
|
||||||
|
|
||||||
// first stop all timers directly or by invokeMethod
|
// first stop all timers directly or by invokeMethod
|
||||||
// depending on what thread they run in
|
// depending on what thread they run in
|
||||||
locationUpdateTimer.stop();
|
locationUpdateTimer.stop();
|
||||||
|
@ -2269,7 +2271,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
||||||
if (event->key() == Qt::Key_Alt && _altPressed && hasFocus()) {
|
if (event->key() == Qt::Key_Alt && _altPressed && hasFocus()) {
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
||||||
offscreenUi->toggleMenu(_glWidget->mapFromGlobal(QPoint(reticlePosition.x, reticlePosition.y)));
|
offscreenUi->toggleMenu(QPoint(reticlePosition.x, reticlePosition.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
_keysPressed.remove(event->key());
|
_keysPressed.remove(event->key());
|
||||||
|
@ -2738,15 +2740,7 @@ void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ivec2 Application::getMouse() const {
|
ivec2 Application::getMouse() const {
|
||||||
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
return getApplicationCompositor().getReticlePosition();
|
||||||
|
|
||||||
// in the HMD, the reticlePosition is the mouse position
|
|
||||||
if (isHMDMode()) {
|
|
||||||
return reticlePosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// in desktop mode, we need to map from global to widget space
|
|
||||||
return toGlm(_glWidget->mapFromGlobal(QPoint(reticlePosition.x, reticlePosition.y)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FaceTracker* Application::getActiveFaceTracker() {
|
FaceTracker* Application::getActiveFaceTracker() {
|
||||||
|
|
|
@ -73,7 +73,6 @@ AvatarManager::AvatarManager(QObject* parent) :
|
||||||
packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket");
|
packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket");
|
||||||
packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar");
|
packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar");
|
||||||
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket");
|
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket");
|
||||||
packetReceiver.registerListener(PacketType::AvatarBillboard, this, "processAvatarBillboardPacket");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarManager::~AvatarManager() {
|
AvatarManager::~AvatarManager() {
|
||||||
|
|
|
@ -675,7 +675,11 @@ void MyAvatar::saveData() {
|
||||||
settings.setValue("leanScale", _leanScale);
|
settings.setValue("leanScale", _leanScale);
|
||||||
settings.setValue("scale", _targetScale);
|
settings.setValue("scale", _targetScale);
|
||||||
|
|
||||||
settings.setValue("fullAvatarURL", _fullAvatarURLFromPreferences);
|
settings.setValue("fullAvatarURL",
|
||||||
|
_fullAvatarURLFromPreferences == AvatarData::defaultFullAvatarModelUrl() ?
|
||||||
|
"" :
|
||||||
|
_fullAvatarURLFromPreferences.toString());
|
||||||
|
|
||||||
settings.setValue("fullAvatarModelName", _fullAvatarModelName);
|
settings.setValue("fullAvatarModelName", _fullAvatarModelName);
|
||||||
settings.setValue("animGraphURL", _animGraphUrl);
|
settings.setValue("animGraphURL", _animGraphUrl);
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ void Image3DOverlay::render(RenderArgs* args) {
|
||||||
const render::ShapeKey Image3DOverlay::getShapeKey() {
|
const render::ShapeKey Image3DOverlay::getShapeKey() {
|
||||||
auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias();
|
auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias();
|
||||||
if (_emissive) {
|
if (_emissive) {
|
||||||
builder.withEmissive();
|
builder.withUnlit();
|
||||||
}
|
}
|
||||||
if (getAlpha() != 1.0f) {
|
if (getAlpha() != 1.0f) {
|
||||||
builder.withTranslucent();
|
builder.withTranslucent();
|
||||||
|
|
|
@ -36,15 +36,8 @@
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
|
|
||||||
|
|
||||||
Overlays::Overlays() : _nextOverlayID(1) {
|
Overlays::Overlays() :
|
||||||
connect(qApp, &Application::beforeAboutToQuit, [=] {
|
_nextOverlayID(1) {}
|
||||||
cleanupAllOverlays();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Overlays::~Overlays() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Overlays::cleanupAllOverlays() {
|
void Overlays::cleanupAllOverlays() {
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,7 +62,6 @@ class Overlays : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Overlays();
|
Overlays();
|
||||||
~Overlays();
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void update(float deltatime);
|
void update(float deltatime);
|
||||||
|
@ -73,6 +72,8 @@ public:
|
||||||
Overlay::Pointer getOverlay(unsigned int id) const;
|
Overlay::Pointer getOverlay(unsigned int id) const;
|
||||||
OverlayPanel::Pointer getPanel(unsigned int id) const { return _panels[id]; }
|
OverlayPanel::Pointer getPanel(unsigned int id) const { return _panels[id]; }
|
||||||
|
|
||||||
|
void cleanupAllOverlays();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/// adds an overlay with the specific properties
|
/// adds an overlay with the specific properties
|
||||||
unsigned int addOverlay(const QString& type, const QVariant& properties);
|
unsigned int addOverlay(const QString& type, const QVariant& properties);
|
||||||
|
@ -145,7 +146,6 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cleanupOverlaysToDelete();
|
void cleanupOverlaysToDelete();
|
||||||
void cleanupAllOverlays();
|
|
||||||
|
|
||||||
QMap<unsigned int, Overlay::Pointer> _overlaysHUD;
|
QMap<unsigned int, Overlay::Pointer> _overlaysHUD;
|
||||||
QMap<unsigned int, Overlay::Pointer> _overlaysWorld;
|
QMap<unsigned int, Overlay::Pointer> _overlaysWorld;
|
||||||
|
|
|
@ -58,7 +58,6 @@ AvatarData::AvatarData() :
|
||||||
_headData(NULL),
|
_headData(NULL),
|
||||||
_displayNameTargetAlpha(1.0f),
|
_displayNameTargetAlpha(1.0f),
|
||||||
_displayNameAlpha(1.0f),
|
_displayNameAlpha(1.0f),
|
||||||
_billboard(),
|
|
||||||
_errorLogExpiry(0),
|
_errorLogExpiry(0),
|
||||||
_owningAvatarMixer(),
|
_owningAvatarMixer(),
|
||||||
_targetVelocity(0.0f),
|
_targetVelocity(0.0f),
|
||||||
|
@ -990,7 +989,7 @@ QByteArray AvatarData::identityByteArray() {
|
||||||
QByteArray identityData;
|
QByteArray identityData;
|
||||||
QDataStream identityStream(&identityData, QIODevice::Append);
|
QDataStream identityStream(&identityData, QIODevice::Append);
|
||||||
QUrl emptyURL("");
|
QUrl emptyURL("");
|
||||||
const QUrl& urlToSend = (_skeletonModelURL == AvatarData::defaultFullAvatarModelUrl()) ? emptyURL : _skeletonModelURL;
|
const QUrl& urlToSend = _skeletonModelURL.scheme() == "file" ? emptyURL : _skeletonModelURL;
|
||||||
|
|
||||||
QUrl unusedModelURL; // legacy faceModel support
|
QUrl unusedModelURL; // legacy faceModel support
|
||||||
|
|
||||||
|
@ -999,13 +998,6 @@ QByteArray AvatarData::identityByteArray() {
|
||||||
return identityData;
|
return identityData;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvatarData::hasBillboardChangedAfterParsing(const QByteArray& data) {
|
|
||||||
if (data == _billboard) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_billboard = data;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||||
const QUrl& expanded = skeletonModelURL.isEmpty() ? AvatarData::defaultFullAvatarModelUrl() : skeletonModelURL;
|
const QUrl& expanded = skeletonModelURL.isEmpty() ? AvatarData::defaultFullAvatarModelUrl() : skeletonModelURL;
|
||||||
|
@ -1103,33 +1095,6 @@ void AvatarData::detachAll(const QString& modelURL, const QString& jointName) {
|
||||||
setAttachmentData(attachmentData);
|
setAttachmentData(attachmentData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::setBillboard(const QByteArray& billboard) {
|
|
||||||
_billboard = billboard;
|
|
||||||
|
|
||||||
qCDebug(avatars) << "Changing billboard for avatar.";
|
|
||||||
}
|
|
||||||
|
|
||||||
void AvatarData::setBillboardFromURL(const QString &billboardURL) {
|
|
||||||
_billboardURL = billboardURL;
|
|
||||||
|
|
||||||
|
|
||||||
qCDebug(avatars) << "Changing billboard for avatar to PNG at" << qPrintable(billboardURL);
|
|
||||||
|
|
||||||
QNetworkRequest billboardRequest;
|
|
||||||
billboardRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
|
||||||
billboardRequest.setUrl(QUrl(billboardURL));
|
|
||||||
|
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
|
||||||
QNetworkReply* networkReply = networkAccessManager.get(billboardRequest);
|
|
||||||
connect(networkReply, SIGNAL(finished()), this, SLOT(setBillboardFromNetworkReply()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AvatarData::setBillboardFromNetworkReply() {
|
|
||||||
QNetworkReply* networkReply = static_cast<QNetworkReply*>(sender());
|
|
||||||
setBillboard(networkReply->readAll());
|
|
||||||
networkReply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AvatarData::setJointMappingsFromNetworkReply() {
|
void AvatarData::setJointMappingsFromNetworkReply() {
|
||||||
QNetworkReply* networkReply = static_cast<QNetworkReply*>(sender());
|
QNetworkReply* networkReply = static_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
|
@ -1204,21 +1169,6 @@ void AvatarData::sendIdentityPacket() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::sendBillboardPacket() {
|
|
||||||
if (!_billboard.isEmpty()) {
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
|
||||||
|
|
||||||
// This makes sure the billboard won't be too large to send.
|
|
||||||
// Once more protocol changes are done and we can send blocks of data we can support sending > MTU sized billboards.
|
|
||||||
if (_billboard.size() <= NLPacket::maxPayloadSize(PacketType::AvatarBillboard)) {
|
|
||||||
auto billboardPacket = NLPacket::create(PacketType::AvatarBillboard, _billboard.size());
|
|
||||||
billboardPacket->write(_billboard);
|
|
||||||
|
|
||||||
nodeList->broadcastToNodes(std::move(billboardPacket), NodeSet() << NodeType::AvatarMixer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AvatarData::updateJointMappings() {
|
void AvatarData::updateJointMappings() {
|
||||||
_jointIndices.clear();
|
_jointIndices.clear();
|
||||||
_jointNames.clear();
|
_jointNames.clear();
|
||||||
|
|
|
@ -107,7 +107,6 @@ static const float MIN_AVATAR_SCALE = .005f;
|
||||||
const float MAX_AUDIO_LOUDNESS = 1000.0f; // close enough for mouth animation
|
const float MAX_AUDIO_LOUDNESS = 1000.0f; // close enough for mouth animation
|
||||||
|
|
||||||
const int AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS = 1000;
|
const int AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS = 1000;
|
||||||
const int AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS = 5000;
|
|
||||||
|
|
||||||
// See also static AvatarData::defaultFullAvatarModelUrl().
|
// See also static AvatarData::defaultFullAvatarModelUrl().
|
||||||
const QString DEFAULT_FULL_AVATAR_MODEL_NAME = QString("Default");
|
const QString DEFAULT_FULL_AVATAR_MODEL_NAME = QString("Default");
|
||||||
|
@ -160,7 +159,6 @@ class AvatarData : public QObject, public SpatiallyNestable {
|
||||||
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName)
|
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName)
|
||||||
Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript WRITE setSkeletonModelURLFromScript)
|
Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript WRITE setSkeletonModelURLFromScript)
|
||||||
Q_PROPERTY(QVector<AttachmentData> attachmentData READ getAttachmentData WRITE setAttachmentData)
|
Q_PROPERTY(QVector<AttachmentData> attachmentData READ getAttachmentData WRITE setAttachmentData)
|
||||||
Q_PROPERTY(QString billboardURL READ getBillboardURL WRITE setBillboardFromURL)
|
|
||||||
|
|
||||||
Q_PROPERTY(QStringList jointNames READ getJointNames)
|
Q_PROPERTY(QStringList jointNames READ getJointNames)
|
||||||
|
|
||||||
|
@ -285,8 +283,6 @@ public:
|
||||||
bool hasIdentityChangedAfterParsing(const QByteArray& data);
|
bool hasIdentityChangedAfterParsing(const QByteArray& data);
|
||||||
QByteArray identityByteArray();
|
QByteArray identityByteArray();
|
||||||
|
|
||||||
bool hasBillboardChangedAfterParsing(const QByteArray& data);
|
|
||||||
|
|
||||||
const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; }
|
const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; }
|
||||||
const QString& getDisplayName() const { return _displayName; }
|
const QString& getDisplayName() const { return _displayName; }
|
||||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
||||||
|
@ -304,12 +300,6 @@ public:
|
||||||
Q_INVOKABLE void detachOne(const QString& modelURL, const QString& jointName = QString());
|
Q_INVOKABLE void detachOne(const QString& modelURL, const QString& jointName = QString());
|
||||||
Q_INVOKABLE void detachAll(const QString& modelURL, const QString& jointName = QString());
|
Q_INVOKABLE void detachAll(const QString& modelURL, const QString& jointName = QString());
|
||||||
|
|
||||||
virtual void setBillboard(const QByteArray& billboard);
|
|
||||||
const QByteArray& getBillboard() const { return _billboard; }
|
|
||||||
|
|
||||||
void setBillboardFromURL(const QString& billboardURL);
|
|
||||||
const QString& getBillboardURL() { return _billboardURL; }
|
|
||||||
|
|
||||||
QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); }
|
QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); }
|
||||||
void setSkeletonModelURLFromScript(const QString& skeletonModelString) { setSkeletonModelURL(QUrl(skeletonModelString)); }
|
void setSkeletonModelURLFromScript(const QString& skeletonModelString) { setSkeletonModelURL(QUrl(skeletonModelString)); }
|
||||||
|
|
||||||
|
@ -336,9 +326,7 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void sendAvatarDataPacket();
|
void sendAvatarDataPacket();
|
||||||
void sendIdentityPacket();
|
void sendIdentityPacket();
|
||||||
void sendBillboardPacket();
|
|
||||||
|
|
||||||
void setBillboardFromNetworkReply();
|
|
||||||
void setJointMappingsFromNetworkReply();
|
void setJointMappingsFromNetworkReply();
|
||||||
void setSessionUUID(const QUuid& sessionUUID) { setID(sessionUUID); }
|
void setSessionUUID(const QUuid& sessionUUID) { setID(sessionUUID); }
|
||||||
|
|
||||||
|
@ -377,9 +365,6 @@ protected:
|
||||||
float _displayNameTargetAlpha;
|
float _displayNameTargetAlpha;
|
||||||
float _displayNameAlpha;
|
float _displayNameAlpha;
|
||||||
|
|
||||||
QByteArray _billboard;
|
|
||||||
QString _billboardURL;
|
|
||||||
|
|
||||||
QHash<QString, int> _jointIndices; ///< 1-based, since zero is returned for missing keys
|
QHash<QString, int> _jointIndices; ///< 1-based, since zero is returned for missing keys
|
||||||
QStringList _jointNames; ///< in order of depth-first traversal
|
QStringList _jointNames; ///< in order of depth-first traversal
|
||||||
|
|
||||||
|
|
|
@ -136,17 +136,6 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarHashMap::processAvatarBillboardPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
|
||||||
QUuid sessionUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
|
||||||
|
|
||||||
auto avatar = newOrExistingAvatar(sessionUUID, sendingNode);
|
|
||||||
|
|
||||||
QByteArray billboard = message->read(message->getBytesLeftToRead());
|
|
||||||
if (avatar->getBillboard() != billboard) {
|
|
||||||
avatar->setBillboard(billboard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AvatarHashMap::processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
void AvatarHashMap::processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||||
// read the node id
|
// read the node id
|
||||||
QUuid sessionUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
QUuid sessionUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
|
@ -53,7 +53,6 @@ private slots:
|
||||||
|
|
||||||
void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||||
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||||
void processAvatarBillboardPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
|
||||||
void processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
void processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -267,7 +267,7 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
|
||||||
if (numBytes == 0) {
|
if (numBytes == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(particleBuffer->editData(), particlePrimitives->data(), numBytes);
|
particleBuffer->setData(numBytes, (const gpu::Byte*)particlePrimitives->data());
|
||||||
|
|
||||||
// Update transform and bounds
|
// Update transform and bounds
|
||||||
payload.setModelTransform(transform);
|
payload.setModelTransform(transform);
|
||||||
|
|
|
@ -210,7 +210,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, textured, culled, emissive);
|
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, textured, culled, emissive);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f));
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableWebEntityItem::setSourceUrl(const QString& value) {
|
void RenderableWebEntityItem::setSourceUrl(const QString& value) {
|
||||||
|
|
|
@ -892,7 +892,10 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
properties = true;
|
properties = true;
|
||||||
propertyName = "P";
|
propertyName = "P";
|
||||||
index = 4;
|
index = 4;
|
||||||
|
} else if (subobject.name == "ShadingModel") {
|
||||||
|
material.shadingModel = subobject.properties.at(0).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties) {
|
if (properties) {
|
||||||
std::vector<std::string> unknowns;
|
std::vector<std::string> unknowns;
|
||||||
foreach(const FBXNode& property, subobject.children) {
|
foreach(const FBXNode& property, subobject.children) {
|
||||||
|
@ -988,7 +991,6 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
QString propname = subobject.name.data();
|
QString propname = subobject.name.data();
|
||||||
int unknown = 0;
|
int unknown = 0;
|
||||||
if ( (propname == "Version")
|
if ( (propname == "Version")
|
||||||
||(propname == "ShadingModel")
|
|
||||||
||(propname == "Multilayer")) {
|
||(propname == "Multilayer")) {
|
||||||
} else {
|
} else {
|
||||||
unknown++;
|
unknown++;
|
||||||
|
@ -1130,7 +1132,6 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
ambientTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
ambientTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
} else if (type.contains("tex_ao_map")) {
|
} else if (type.contains("tex_ao_map")) {
|
||||||
occlusionTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
occlusionTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
|
|
||||||
} else if (type == "lcl rotation") {
|
} else if (type == "lcl rotation") {
|
||||||
localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
} else if (type == "lcl translation") {
|
} else if (type == "lcl translation") {
|
||||||
|
@ -1331,7 +1332,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: shapeVertices are in joint-frame
|
// NOTE: shapeVertices are in joint-frame
|
||||||
QVector<ShapeVertices> shapeVertices;
|
std::vector<ShapeVertices> shapeVertices;
|
||||||
shapeVertices.resize(geometry.joints.size());
|
shapeVertices.resize(geometry.joints.size());
|
||||||
|
|
||||||
// find our special joints
|
// find our special joints
|
||||||
|
@ -1522,7 +1523,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
|
|
||||||
float clusterScale = extractUniformScale(fbxCluster.inverseBindMatrix);
|
float clusterScale = extractUniformScale(fbxCluster.inverseBindMatrix);
|
||||||
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
|
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
|
||||||
ShapeVertices& points = shapeVertices[jointIndex];
|
ShapeVertices& points = shapeVertices.at(jointIndex);
|
||||||
|
|
||||||
float totalWeight = 0.0f;
|
float totalWeight = 0.0f;
|
||||||
for (int j = 0; j < cluster.indices.size(); j++) {
|
for (int j = 0; j < cluster.indices.size(); j++) {
|
||||||
|
@ -1584,7 +1585,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
// transform cluster vertices to joint-frame and save for later
|
// transform cluster vertices to joint-frame and save for later
|
||||||
float clusterScale = extractUniformScale(firstFBXCluster.inverseBindMatrix);
|
float clusterScale = extractUniformScale(firstFBXCluster.inverseBindMatrix);
|
||||||
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
|
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
|
||||||
ShapeVertices& points = shapeVertices[jointIndex];
|
ShapeVertices& points = shapeVertices.at(jointIndex);
|
||||||
foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
|
foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
|
||||||
const glm::mat4 vertexTransform = meshToJoint * glm::translate(vertex);
|
const glm::mat4 vertexTransform = meshToJoint * glm::translate(vertex);
|
||||||
points.push_back(extractTranslation(vertexTransform) * clusterScale);
|
points.push_back(extractTranslation(vertexTransform) * clusterScale);
|
||||||
|
@ -1625,7 +1626,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
FBXJoint& joint = geometry.joints[i];
|
FBXJoint& joint = geometry.joints[i];
|
||||||
|
|
||||||
// NOTE: points are in joint-frame
|
// NOTE: points are in joint-frame
|
||||||
ShapeVertices& points = shapeVertices[i];
|
ShapeVertices& points = shapeVertices.at(i);
|
||||||
if (points.size() > 0) {
|
if (points.size() > 0) {
|
||||||
// compute average point
|
// compute average point
|
||||||
glm::vec3 avgPoint = glm::vec3(0.0f);
|
glm::vec3 avgPoint = glm::vec3(0.0f);
|
||||||
|
|
|
@ -154,6 +154,7 @@ public:
|
||||||
|
|
||||||
QString materialID;
|
QString materialID;
|
||||||
QString name;
|
QString name;
|
||||||
|
QString shadingModel;
|
||||||
model::MaterialPointer _material;
|
model::MaterialPointer _material;
|
||||||
|
|
||||||
FBXTexture normalTexture;
|
FBXTexture normalTexture;
|
||||||
|
|
|
@ -72,6 +72,10 @@ void FBXReader::consolidateFBXMaterials() {
|
||||||
// foreach (const QString& materialID, materials) {
|
// foreach (const QString& materialID, materials) {
|
||||||
for (QHash<QString, FBXMaterial>::iterator it = _fbxMaterials.begin(); it != _fbxMaterials.end(); it++) {
|
for (QHash<QString, FBXMaterial>::iterator it = _fbxMaterials.begin(); it != _fbxMaterials.end(); it++) {
|
||||||
FBXMaterial& material = (*it);
|
FBXMaterial& material = (*it);
|
||||||
|
|
||||||
|
// Maya is the exporting the shading model and we aretrying to use it
|
||||||
|
bool isMaterialLambert = (material.shadingModel.toLower() == "lambert");
|
||||||
|
|
||||||
// the pure material associated with this part
|
// the pure material associated with this part
|
||||||
bool detectDifferentUVs = false;
|
bool detectDifferentUVs = false;
|
||||||
FBXTexture diffuseTexture;
|
FBXTexture diffuseTexture;
|
||||||
|
@ -171,6 +175,13 @@ void FBXReader::consolidateFBXMaterials() {
|
||||||
emissiveTexture = getTexture(emissiveTextureID);
|
emissiveTexture = getTexture(emissiveTextureID);
|
||||||
detectDifferentUVs |= (emissiveTexture.texcoordSet != 0) || (!emissiveTexture.transform.isIdentity());
|
detectDifferentUVs |= (emissiveTexture.texcoordSet != 0) || (!emissiveTexture.transform.isIdentity());
|
||||||
material.emissiveTexture = emissiveTexture;
|
material.emissiveTexture = emissiveTexture;
|
||||||
|
|
||||||
|
if (isMaterialLambert) {
|
||||||
|
// If the emissiveTextureID comes from the Texture bound to Emissive when material is lambert, we know it s exported from maya
|
||||||
|
// And the EMissiveColor is forced to 0.5 by Maya which is bad
|
||||||
|
// So we need to force it to 1.0
|
||||||
|
material.emissiveColor = vec3(1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FBXTexture occlusionTexture;
|
FBXTexture occlusionTexture;
|
||||||
|
@ -198,7 +209,7 @@ void FBXReader::consolidateFBXMaterials() {
|
||||||
material._material = std::make_shared<model::Material>();
|
material._material = std::make_shared<model::Material>();
|
||||||
|
|
||||||
// Emissive color is the mix of emissiveColor with emissiveFactor
|
// Emissive color is the mix of emissiveColor with emissiveFactor
|
||||||
auto emissive = material.emissiveColor * material.emissiveFactor;
|
auto emissive = material.emissiveColor * (isMaterialLambert ? 1.0f : material.emissiveFactor); // In lambert there is not emissiveFactor
|
||||||
material._material->setEmissive(emissive);
|
material._material->setEmissive(emissive);
|
||||||
|
|
||||||
// Final diffuse color is the mix of diffuseColor with diffuseFactor
|
// Final diffuse color is the mix of diffuseColor with diffuseFactor
|
||||||
|
@ -212,6 +223,18 @@ void FBXReader::consolidateFBXMaterials() {
|
||||||
material._material->setRoughness(model::Material::shininessToRoughness(material.shininess));
|
material._material->setRoughness(model::Material::shininessToRoughness(material.shininess));
|
||||||
float metallic = std::max(material.specularColor.x, std::max(material.specularColor.y, material.specularColor.z));
|
float metallic = std::max(material.specularColor.x, std::max(material.specularColor.y, material.specularColor.z));
|
||||||
material._material->setMetallic(metallic);
|
material._material->setMetallic(metallic);
|
||||||
|
|
||||||
|
if (isMaterialLambert) {
|
||||||
|
if (!material._material->getKey().isAlbedo()) {
|
||||||
|
// switch emissive to material albedo as we tag the material to unlit
|
||||||
|
material._material->setUnlit(true);
|
||||||
|
material._material->setAlbedo(emissive);
|
||||||
|
|
||||||
|
if (!material.emissiveTexture.isNull()) {
|
||||||
|
material.albedoTexture = material.emissiveTexture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material.opacity <= 0.0f) {
|
if (material.opacity <= 0.0f) {
|
||||||
|
|
|
@ -624,7 +624,6 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
|
||||||
return geometryPtr;
|
return geometryPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fbxDebugDump(const FBXGeometry& fbxgeo) {
|
void fbxDebugDump(const FBXGeometry& fbxgeo) {
|
||||||
qCDebug(modelformat) << "---------------- fbxGeometry ----------------";
|
qCDebug(modelformat) << "---------------- fbxGeometry ----------------";
|
||||||
qCDebug(modelformat) << " hasSkeletonJoints =" << fbxgeo.hasSkeletonJoints;
|
qCDebug(modelformat) << " hasSkeletonJoints =" << fbxgeo.hasSkeletonJoints;
|
||||||
|
|
|
@ -65,15 +65,22 @@ public:
|
||||||
|
|
||||||
class GLBuffer : public GPUObject {
|
class GLBuffer : public GPUObject {
|
||||||
public:
|
public:
|
||||||
Stamp _stamp;
|
const GLuint _buffer;
|
||||||
GLuint _buffer;
|
const GLuint _size;
|
||||||
GLuint _size;
|
const Stamp _stamp;
|
||||||
|
|
||||||
GLBuffer();
|
GLBuffer(const Buffer& buffer, GLBuffer* original = nullptr);
|
||||||
~GLBuffer();
|
~GLBuffer();
|
||||||
|
|
||||||
void setSize(GLuint size);
|
void transfer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool getNextTransferBlock(GLintptr& outOffset, GLsizeiptr& outSize, size_t& currentPage) const;
|
||||||
|
|
||||||
|
// The owning texture
|
||||||
|
const Buffer& _gpuBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GLBuffer* syncGPUObject(const Buffer& buffer);
|
static GLBuffer* syncGPUObject(const Buffer& buffer);
|
||||||
static GLuint getBufferID(const Buffer& buffer);
|
static GLuint getBufferID(const Buffer& buffer);
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,40 @@
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
GLBackend::GLBuffer::GLBuffer() :
|
GLuint allocateSingleBuffer() {
|
||||||
_stamp(0),
|
GLuint result;
|
||||||
_buffer(0),
|
glGenBuffers(1, &result);
|
||||||
_size(0)
|
(void)CHECK_GL_ERROR();
|
||||||
{
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLBackend::GLBuffer::GLBuffer(const Buffer& buffer, GLBuffer* original) :
|
||||||
|
_buffer(allocateSingleBuffer()),
|
||||||
|
_size((GLuint)buffer._sysmem.getSize()),
|
||||||
|
_stamp(buffer._sysmem.getStamp()),
|
||||||
|
_gpuBuffer(buffer) {
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _buffer);
|
||||||
|
if (GLEW_VERSION_4_4 || GLEW_ARB_buffer_storage) {
|
||||||
|
glBufferStorage(GL_ARRAY_BUFFER, _size, nullptr, GL_DYNAMIC_STORAGE_BIT);
|
||||||
|
(void)CHECK_GL_ERROR();
|
||||||
|
} else {
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, _size, nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
(void)CHECK_GL_ERROR();
|
||||||
|
}
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
if (original) {
|
||||||
|
glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer);
|
||||||
|
glBindBuffer(GL_COPY_READ_BUFFER, original->_buffer);
|
||||||
|
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, original->_size);
|
||||||
|
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_COPY_READ_BUFFER, 0);
|
||||||
|
(void)CHECK_GL_ERROR();
|
||||||
|
}
|
||||||
|
|
||||||
|
Backend::setGPUObject(buffer, this);
|
||||||
Backend::incrementBufferGPUCount();
|
Backend::incrementBufferGPUCount();
|
||||||
|
Backend::updateBufferGPUMemoryUsage(0, _size);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLBackend::GLBuffer::~GLBuffer() {
|
GLBackend::GLBuffer::~GLBuffer() {
|
||||||
|
@ -28,37 +56,56 @@ GLBackend::GLBuffer::~GLBuffer() {
|
||||||
Backend::decrementBufferGPUCount();
|
Backend::decrementBufferGPUCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::GLBuffer::setSize(GLuint size) {
|
void GLBackend::GLBuffer::transfer() {
|
||||||
Backend::updateBufferGPUMemoryUsage(_size, size);
|
glBindBuffer(GL_ARRAY_BUFFER, _buffer);
|
||||||
_size = size;
|
(void)CHECK_GL_ERROR();
|
||||||
|
GLintptr offset;
|
||||||
|
GLsizeiptr size;
|
||||||
|
size_t currentPage { 0 };
|
||||||
|
auto data = _gpuBuffer.getSysmem().readData();
|
||||||
|
while (getNextTransferBlock(offset, size, currentPage)) {
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, offset, size, data + offset);
|
||||||
|
(void)CHECK_GL_ERROR();
|
||||||
|
}
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
(void)CHECK_GL_ERROR();
|
||||||
|
_gpuBuffer._flags &= ~Buffer::DIRTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLBackend::GLBuffer::getNextTransferBlock(GLintptr& outOffset, GLsizeiptr& outSize, size_t& currentPage) const {
|
||||||
|
size_t pageCount = _gpuBuffer._pages.size();
|
||||||
|
// Advance to the first dirty page
|
||||||
|
while (currentPage < pageCount && (0 == (Buffer::DIRTY & _gpuBuffer._pages[currentPage]))) {
|
||||||
|
++currentPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got to the end, we're done
|
||||||
|
if (currentPage >= pageCount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advance to the next clean page
|
||||||
|
outOffset = static_cast<GLintptr>(currentPage * _gpuBuffer._pageSize);
|
||||||
|
while (currentPage < pageCount && (0 != (Buffer::DIRTY & _gpuBuffer._pages[currentPage]))) {
|
||||||
|
_gpuBuffer._pages[currentPage] &= ~Buffer::DIRTY;
|
||||||
|
++currentPage;
|
||||||
|
}
|
||||||
|
outSize = static_cast<GLsizeiptr>((currentPage * _gpuBuffer._pageSize) - outOffset);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLBackend::GLBuffer* GLBackend::syncGPUObject(const Buffer& buffer) {
|
GLBackend::GLBuffer* GLBackend::syncGPUObject(const Buffer& buffer) {
|
||||||
GLBuffer* object = Backend::getGPUObject<GLBackend::GLBuffer>(buffer);
|
GLBuffer* object = Backend::getGPUObject<GLBackend::GLBuffer>(buffer);
|
||||||
|
|
||||||
if (object && (object->_stamp == buffer.getSysmem().getStamp())) {
|
// Has the storage size changed?
|
||||||
return object;
|
if (!object || object->_stamp != buffer.getSysmem().getStamp()) {
|
||||||
|
object = new GLBuffer(buffer, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to have a gpu object?
|
if (0 != (buffer._flags & Buffer::DIRTY)) {
|
||||||
if (!object) {
|
object->transfer();
|
||||||
object = new GLBuffer();
|
|
||||||
glGenBuffers(1, &object->_buffer);
|
|
||||||
(void) CHECK_GL_ERROR();
|
|
||||||
Backend::setGPUObject(buffer, object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now let's update the content of the bo with the sysmem version
|
|
||||||
// TODO: in the future, be smarter about when to actually upload the glBO version based on the data that did change
|
|
||||||
//if () {
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, object->_buffer);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, buffer.getSysmem().getSize(), buffer.getSysmem().readData(), GL_DYNAMIC_DRAW);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
object->_stamp = buffer.getSysmem().getStamp();
|
|
||||||
object->setSize((GLuint)buffer.getSysmem().getSize());
|
|
||||||
//}
|
|
||||||
(void) CHECK_GL_ERROR();
|
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,6 +209,8 @@ void GLBackend::resetOutputStage() {
|
||||||
_output._drawFBO = 0;
|
_output._drawFBO = 0;
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_setFramebuffer(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_setFramebuffer(Batch& batch, size_t paramOffset) {
|
||||||
|
|
|
@ -535,13 +535,12 @@ void GLBackend::syncSampler(const Sampler& sampler, Texture::Type type, const GL
|
||||||
GLint minFilter;
|
GLint minFilter;
|
||||||
GLint magFilter;
|
GLint magFilter;
|
||||||
};
|
};
|
||||||
static const GLFilterMode filterModes[] = {
|
static const GLFilterMode filterModes[Sampler::NUM_FILTERS] = {
|
||||||
{ GL_NEAREST, GL_NEAREST }, //FILTER_MIN_MAG_POINT,
|
{ GL_NEAREST, GL_NEAREST }, //FILTER_MIN_MAG_POINT,
|
||||||
{ GL_NEAREST, GL_LINEAR }, //FILTER_MIN_POINT_MAG_LINEAR,
|
{ GL_NEAREST, GL_LINEAR }, //FILTER_MIN_POINT_MAG_LINEAR,
|
||||||
{ GL_LINEAR, GL_NEAREST }, //FILTER_MIN_LINEAR_MAG_POINT,
|
{ GL_LINEAR, GL_NEAREST }, //FILTER_MIN_LINEAR_MAG_POINT,
|
||||||
{ GL_LINEAR, GL_LINEAR }, //FILTER_MIN_MAG_LINEAR,
|
{ GL_LINEAR, GL_LINEAR }, //FILTER_MIN_MAG_LINEAR,
|
||||||
|
|
||||||
{ GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST }, //FILTER_MIN_MAG_MIP_POINT,
|
|
||||||
{ GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST }, //FILTER_MIN_MAG_MIP_POINT,
|
{ GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST }, //FILTER_MIN_MAG_MIP_POINT,
|
||||||
{ GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST }, //FILTER_MIN_MAG_POINT_MIP_LINEAR,
|
{ GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST }, //FILTER_MIN_MAG_POINT_MIP_LINEAR,
|
||||||
{ GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR }, //FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT,
|
{ GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR }, //FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT,
|
||||||
|
@ -557,7 +556,7 @@ void GLBackend::syncSampler(const Sampler& sampler, Texture::Type type, const GL
|
||||||
glTexParameteri(object->_target, GL_TEXTURE_MIN_FILTER, fm.minFilter);
|
glTexParameteri(object->_target, GL_TEXTURE_MIN_FILTER, fm.minFilter);
|
||||||
glTexParameteri(object->_target, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
glTexParameteri(object->_target, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
||||||
|
|
||||||
static const GLenum comparisonFuncs[] = {
|
static const GLenum comparisonFuncs[NUM_COMPARISON_FUNCS] = {
|
||||||
GL_NEVER,
|
GL_NEVER,
|
||||||
GL_LESS,
|
GL_LESS,
|
||||||
GL_EQUAL,
|
GL_EQUAL,
|
||||||
|
@ -574,7 +573,7 @@ void GLBackend::syncSampler(const Sampler& sampler, Texture::Type type, const GL
|
||||||
glTexParameteri(object->_target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
glTexParameteri(object->_target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GLenum wrapModes[] = {
|
static const GLenum wrapModes[Sampler::NUM_WRAP_MODES] = {
|
||||||
GL_REPEAT, // WRAP_REPEAT,
|
GL_REPEAT, // WRAP_REPEAT,
|
||||||
GL_MIRRORED_REPEAT, // WRAP_MIRROR,
|
GL_MIRRORED_REPEAT, // WRAP_MIRROR,
|
||||||
GL_CLAMP_TO_EDGE, // WRAP_CLAMP,
|
GL_CLAMP_TO_EDGE, // WRAP_CLAMP,
|
||||||
|
|
|
@ -109,40 +109,18 @@ void Resource::Sysmem::deallocateMemory(Byte* dataAllocated, Size size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource::Sysmem::Sysmem() :
|
Resource::Sysmem::Sysmem() {}
|
||||||
_stamp(0),
|
|
||||||
_size(0),
|
|
||||||
_data(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Resource::Sysmem::Sysmem(Size size, const Byte* bytes) :
|
Resource::Sysmem::Sysmem(Size size, const Byte* bytes) {
|
||||||
_stamp(0),
|
if (size > 0 && bytes) {
|
||||||
_size(0),
|
setData(_size, bytes);
|
||||||
_data(NULL)
|
|
||||||
{
|
|
||||||
if (size > 0) {
|
|
||||||
_size = allocateMemory(&_data, size);
|
|
||||||
if (_size >= size) {
|
|
||||||
if (bytes) {
|
|
||||||
memcpy(_data, bytes, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource::Sysmem::Sysmem(const Sysmem& sysmem) :
|
Resource::Sysmem::Sysmem(const Sysmem& sysmem) {
|
||||||
_stamp(0),
|
|
||||||
_size(0),
|
|
||||||
_data(NULL)
|
|
||||||
{
|
|
||||||
if (sysmem.getSize() > 0) {
|
if (sysmem.getSize() > 0) {
|
||||||
_size = allocateMemory(&_data, sysmem.getSize());
|
allocate(sysmem._size);
|
||||||
if (_size >= sysmem.getSize()) {
|
setData(_size, sysmem._data);
|
||||||
if (sysmem.readData()) {
|
|
||||||
memcpy(_data, sysmem.readData(), sysmem.getSize());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +186,6 @@ Resource::Size Resource::Sysmem::setData( Size size, const Byte* bytes ) {
|
||||||
if (allocate(size) == size) {
|
if (allocate(size) == size) {
|
||||||
if (size && bytes) {
|
if (size && bytes) {
|
||||||
memcpy( _data, bytes, _size );
|
memcpy( _data, bytes, _size );
|
||||||
_stamp++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _size;
|
return _size;
|
||||||
|
@ -217,7 +194,6 @@ Resource::Size Resource::Sysmem::setData( Size size, const Byte* bytes ) {
|
||||||
Resource::Size Resource::Sysmem::setSubData( Size offset, Size size, const Byte* bytes) {
|
Resource::Size Resource::Sysmem::setSubData( Size offset, Size size, const Byte* bytes) {
|
||||||
if (size && ((offset + size) <= getSize()) && bytes) {
|
if (size && ((offset + size) <= getSize()) && bytes) {
|
||||||
memcpy( _data + offset, bytes, size );
|
memcpy( _data + offset, bytes, size );
|
||||||
_stamp++;
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -264,65 +240,105 @@ Buffer::Size Buffer::getBufferGPUMemoryUsage() {
|
||||||
return Context::getBufferGPUMemoryUsage();
|
return Context::getBufferGPUMemoryUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Buffer() :
|
Buffer::Buffer(Size pageSize) :
|
||||||
Resource(),
|
_pageSize(pageSize) {
|
||||||
_sysmem(new Sysmem()) {
|
|
||||||
_bufferCPUCount++;
|
_bufferCPUCount++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Buffer(Size size, const Byte* bytes) :
|
Buffer::Buffer(Size size, const Byte* bytes, Size pageSize) : Buffer(pageSize) {
|
||||||
Resource(),
|
setData(size, bytes);
|
||||||
_sysmem(new Sysmem(size, bytes)) {
|
|
||||||
_bufferCPUCount++;
|
|
||||||
Buffer::updateBufferCPUMemoryUsage(0, _sysmem->getSize());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Buffer(const Buffer& buf) :
|
Buffer::Buffer(const Buffer& buf) : Buffer(buf._pageSize) {
|
||||||
Resource(),
|
setData(buf.getSize(), buf.getData());
|
||||||
_sysmem(new Sysmem(buf.getSysmem())) {
|
|
||||||
_bufferCPUCount++;
|
|
||||||
Buffer::updateBufferCPUMemoryUsage(0, _sysmem->getSize());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer& Buffer::operator=(const Buffer& buf) {
|
Buffer& Buffer::operator=(const Buffer& buf) {
|
||||||
(*_sysmem) = buf.getSysmem();
|
const_cast<Size&>(_pageSize) = buf._pageSize;
|
||||||
|
setData(buf.getSize(), buf.getData());
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::~Buffer() {
|
Buffer::~Buffer() {
|
||||||
_bufferCPUCount--;
|
_bufferCPUCount--;
|
||||||
|
Buffer::updateBufferCPUMemoryUsage(_sysmem.getSize(), 0);
|
||||||
if (_sysmem) {
|
|
||||||
Buffer::updateBufferCPUMemoryUsage(_sysmem->getSize(), 0);
|
|
||||||
delete _sysmem;
|
|
||||||
_sysmem = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Size Buffer::resize(Size size) {
|
Buffer::Size Buffer::resize(Size size) {
|
||||||
|
_end = size;
|
||||||
auto prevSize = editSysmem().getSize();
|
auto prevSize = editSysmem().getSize();
|
||||||
auto newSize = editSysmem().resize(size);
|
if (prevSize < size) {
|
||||||
Buffer::updateBufferCPUMemoryUsage(prevSize, newSize);
|
auto newPages = getRequiredPageCount();
|
||||||
return newSize;
|
auto newSize = newPages * _pageSize;
|
||||||
|
editSysmem().resize(newSize);
|
||||||
|
// All new pages start off as clean, because they haven't been populated by data
|
||||||
|
_pages.resize(newPages, 0);
|
||||||
|
Buffer::updateBufferCPUMemoryUsage(prevSize, newSize);
|
||||||
|
}
|
||||||
|
return _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Buffer::markDirty(Size offset, Size bytes) {
|
||||||
|
if (!bytes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_flags |= DIRTY;
|
||||||
|
// Find the starting page
|
||||||
|
Size startPage = (offset / _pageSize);
|
||||||
|
// Non-zero byte count, so at least one page is dirty
|
||||||
|
Size pageCount = 1;
|
||||||
|
// How much of the page is after the offset?
|
||||||
|
Size remainder = _pageSize - (offset % _pageSize);
|
||||||
|
// If there are more bytes than page space remaining, we need to increase the page count
|
||||||
|
if (bytes > remainder) {
|
||||||
|
// Get rid of the amount that will fit in the current page
|
||||||
|
bytes -= remainder;
|
||||||
|
|
||||||
|
pageCount += (bytes / _pageSize);
|
||||||
|
if (bytes % _pageSize) {
|
||||||
|
++pageCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark the pages dirty
|
||||||
|
for (Size i = 0; i < pageCount; ++i) {
|
||||||
|
_pages[i + startPage] |= DIRTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Buffer::Size Buffer::setData(Size size, const Byte* data) {
|
Buffer::Size Buffer::setData(Size size, const Byte* data) {
|
||||||
auto prevSize = editSysmem().getSize();
|
resize(size);
|
||||||
auto newSize = editSysmem().setData(size, data);
|
setSubData(0, size, data);
|
||||||
Buffer::updateBufferCPUMemoryUsage(prevSize, newSize);
|
return _end;
|
||||||
return newSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Size Buffer::setSubData(Size offset, Size size, const Byte* data) {
|
Buffer::Size Buffer::setSubData(Size offset, Size size, const Byte* data) {
|
||||||
return editSysmem().setSubData( offset, size, data);
|
auto changedBytes = editSysmem().setSubData(offset, size, data);
|
||||||
|
if (changedBytes) {
|
||||||
|
markDirty(offset, changedBytes);
|
||||||
|
}
|
||||||
|
return changedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Size Buffer::append(Size size, const Byte* data) {
|
Buffer::Size Buffer::append(Size size, const Byte* data) {
|
||||||
auto prevSize = editSysmem().getSize();
|
auto offset = _end;
|
||||||
auto newSize = editSysmem().append( size, data);
|
resize(_end + size);
|
||||||
Buffer::updateBufferCPUMemoryUsage(prevSize, newSize);
|
setSubData(offset, size, data);
|
||||||
return newSize;
|
return _end;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::Size Buffer::getSize() const {
|
||||||
|
Q_ASSERT(getSysmem().getSize() >= _end);
|
||||||
|
return _end;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::Size Buffer::getRequiredPageCount() const {
|
||||||
|
Size result = _end / _pageSize;
|
||||||
|
if (_end % _pageSize) {
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Element BufferView::DEFAULT_ELEMENT = Element( gpu::SCALAR, gpu::UINT8, gpu::RAW );
|
const Element BufferView::DEFAULT_ELEMENT = Element( gpu::SCALAR, gpu::UINT8, gpu::RAW );
|
||||||
|
|
|
@ -88,10 +88,10 @@ protected:
|
||||||
// Access the byte array.
|
// Access the byte array.
|
||||||
// The edit version allow to map data.
|
// The edit version allow to map data.
|
||||||
const Byte* readData() const { return _data; }
|
const Byte* readData() const { return _data; }
|
||||||
Byte* editData() { _stamp++; return _data; }
|
Byte* editData() { return _data; }
|
||||||
|
|
||||||
template< typename T > const T* read() const { return reinterpret_cast< T* > ( _data ); }
|
template< typename T > const T* read() const { return reinterpret_cast< T* > ( _data ); }
|
||||||
template< typename T > T* edit() { _stamp++; return reinterpret_cast< T* > ( _data ); }
|
template< typename T > T* edit() { return reinterpret_cast< T* > ( _data ); }
|
||||||
|
|
||||||
// Access the current version of the sysmem, used to compare if copies are in sync
|
// Access the current version of the sysmem, used to compare if copies are in sync
|
||||||
Stamp getStamp() const { return _stamp; }
|
Stamp getStamp() const { return _stamp; }
|
||||||
|
@ -102,9 +102,9 @@ protected:
|
||||||
bool isAvailable() const { return (_data != 0); }
|
bool isAvailable() const { return (_data != 0); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Stamp _stamp;
|
Stamp _stamp { 0 };
|
||||||
Size _size;
|
Size _size { 0 };
|
||||||
Byte* _data;
|
Byte* _data { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -115,21 +115,27 @@ class Buffer : public Resource {
|
||||||
static void updateBufferCPUMemoryUsage(Size prevObjectSize, Size newObjectSize);
|
static void updateBufferCPUMemoryUsage(Size prevObjectSize, Size newObjectSize);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum Flag {
|
||||||
|
DIRTY = 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Currently only one flag... 'dirty'
|
||||||
|
using PageFlags = std::vector<uint8_t>;
|
||||||
|
static const Size DEFAULT_PAGE_SIZE = 4096;
|
||||||
static uint32_t getBufferCPUCount();
|
static uint32_t getBufferCPUCount();
|
||||||
static Size getBufferCPUMemoryUsage();
|
static Size getBufferCPUMemoryUsage();
|
||||||
static uint32_t getBufferGPUCount();
|
static uint32_t getBufferGPUCount();
|
||||||
static Size getBufferGPUMemoryUsage();
|
static Size getBufferGPUMemoryUsage();
|
||||||
|
|
||||||
Buffer();
|
Buffer(Size pageSize = DEFAULT_PAGE_SIZE);
|
||||||
Buffer(Size size, const Byte* bytes);
|
Buffer(Size size, const Byte* bytes, Size pageSize = DEFAULT_PAGE_SIZE);
|
||||||
Buffer(const Buffer& buf); // deep copy of the sysmem buffer
|
Buffer(const Buffer& buf); // deep copy of the sysmem buffer
|
||||||
Buffer& operator=(const Buffer& buf); // deep copy of the sysmem buffer
|
Buffer& operator=(const Buffer& buf); // deep copy of the sysmem buffer
|
||||||
~Buffer();
|
~Buffer();
|
||||||
|
|
||||||
// The size in bytes of data stored in the buffer
|
// The size in bytes of data stored in the buffer
|
||||||
Size getSize() const { return getSysmem().getSize(); }
|
Size getSize() const;
|
||||||
const Byte* getData() const { return getSysmem().readData(); }
|
const Byte* getData() const { return getSysmem().readData(); }
|
||||||
Byte* editData() { return editSysmem().editData(); }
|
|
||||||
|
|
||||||
// Resize the buffer
|
// Resize the buffer
|
||||||
// Keep previous data [0 to min(pSize, mSize)]
|
// Keep previous data [0 to min(pSize, mSize)]
|
||||||
|
@ -143,6 +149,23 @@ public:
|
||||||
// \return the number of bytes copied
|
// \return the number of bytes copied
|
||||||
Size setSubData(Size offset, Size size, const Byte* data);
|
Size setSubData(Size offset, Size size, const Byte* data);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Size setSubData(Size index, const T& t) {
|
||||||
|
Size offset = index * sizeof(T);
|
||||||
|
Size size = sizeof(T);
|
||||||
|
return setSubData(offset, size, reinterpret_cast<const Byte*>(&t));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Size setSubData(Size index, const std::vector<T>& t) {
|
||||||
|
if (t.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Size offset = index * sizeof(T);
|
||||||
|
Size size = t.size() * sizeof(T);
|
||||||
|
return setSubData(offset, size, reinterpret_cast<const Byte*>(&t[0]));
|
||||||
|
}
|
||||||
|
|
||||||
// Append new data at the end of the current buffer
|
// Append new data at the end of the current buffer
|
||||||
// do a resize( size + getSize) and copy the new data
|
// do a resize( size + getSize) and copy the new data
|
||||||
// \return the number of bytes copied
|
// \return the number of bytes copied
|
||||||
|
@ -155,18 +178,38 @@ public:
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Size append(const std::vector<T>& t) {
|
Size append(const std::vector<T>& t) {
|
||||||
|
if (t.empty()) {
|
||||||
|
return _end;
|
||||||
|
}
|
||||||
return append(sizeof(T) * t.size(), reinterpret_cast<const Byte*>(&t[0]));
|
return append(sizeof(T) * t.size(), reinterpret_cast<const Byte*>(&t[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access the sysmem object.
|
|
||||||
const Sysmem& getSysmem() const { assert(_sysmem); return (*_sysmem); }
|
|
||||||
Sysmem& editSysmem() { assert(_sysmem); return (*_sysmem); }
|
|
||||||
|
|
||||||
const GPUObjectPointer gpuObject {};
|
const GPUObjectPointer gpuObject {};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void markDirty(Size offset, Size bytes);
|
||||||
|
|
||||||
Sysmem* _sysmem = NULL;
|
template <typename T>
|
||||||
|
void markDirty(Size index, Size count = 1) {
|
||||||
|
markDirty(sizeof(T) * index, sizeof(T) * count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access the sysmem object, limited to ourselves and GPUObject derived classes
|
||||||
|
const Sysmem& getSysmem() const { return _sysmem; }
|
||||||
|
Sysmem& editSysmem() { return _sysmem; }
|
||||||
|
Byte* editData() { return editSysmem().editData(); }
|
||||||
|
|
||||||
|
Size getRequiredPageCount() const;
|
||||||
|
|
||||||
|
Size _end { 0 };
|
||||||
|
mutable uint8_t _flags;
|
||||||
|
mutable PageFlags _pages;
|
||||||
|
const Size _pageSize;
|
||||||
|
Sysmem _sysmem;
|
||||||
|
|
||||||
|
// FIXME find a more generic way to do this.
|
||||||
|
friend class GLBackend;
|
||||||
|
friend class BufferView;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Buffer> BufferPointer;
|
typedef std::shared_ptr<Buffer> BufferPointer;
|
||||||
|
@ -290,8 +333,14 @@ public:
|
||||||
int _stride;
|
int _stride;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Direct memory access to the buffer contents is incompatible with the paging memory scheme
|
||||||
template <typename T> Iterator<T> begin() { return Iterator<T>(&edit<T>(0), _stride); }
|
template <typename T> Iterator<T> begin() { return Iterator<T>(&edit<T>(0), _stride); }
|
||||||
template <typename T> Iterator<T> end() { return Iterator<T>(&edit<T>(getNum<T>()), _stride); }
|
template <typename T> Iterator<T> end() { return Iterator<T>(&edit<T>(getNum<T>()), _stride); }
|
||||||
|
#else
|
||||||
|
template <typename T> Iterator<const T> begin() const { return Iterator<const T>(&get<T>(), _stride); }
|
||||||
|
template <typename T> Iterator<const T> end() const { return Iterator<const T>(&get<T>(getNum<T>()), _stride); }
|
||||||
|
#endif
|
||||||
template <typename T> Iterator<const T> cbegin() const { return Iterator<const T>(&get<T>(), _stride); }
|
template <typename T> Iterator<const T> cbegin() const { return Iterator<const T>(&get<T>(), _stride); }
|
||||||
template <typename T> Iterator<const T> cend() const { return Iterator<const T>(&get<T>(getNum<T>()), _stride); }
|
template <typename T> Iterator<const T> cend() const { return Iterator<const T>(&get<T>(getNum<T>()), _stride); }
|
||||||
|
|
||||||
|
@ -328,6 +377,7 @@ public:
|
||||||
qDebug() << "Accessing buffer outside the BufferView range, element size = " << sizeof(T) << " when bufferView size = " << _size;
|
qDebug() << "Accessing buffer outside the BufferView range, element size = " << sizeof(T) << " when bufferView size = " << _size;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
_buffer->markDirty(_offset, sizeof(T));
|
||||||
T* t = (reinterpret_cast<T*> (_buffer->editData() + _offset));
|
T* t = (reinterpret_cast<T*> (_buffer->editData() + _offset));
|
||||||
return *(t);
|
return *(t);
|
||||||
}
|
}
|
||||||
|
@ -361,6 +411,7 @@ public:
|
||||||
qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum<T>();
|
qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum<T>();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
_buffer->markDirty(elementOffset, sizeof(T));
|
||||||
return *(reinterpret_cast<T*> (_buffer->editData() + elementOffset));
|
return *(reinterpret_cast<T*> (_buffer->editData() + elementOffset));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -74,6 +74,11 @@ void Material::setOpacity(float opacity) {
|
||||||
_schemaBuffer.edit<Schema>()._opacity = opacity;
|
_schemaBuffer.edit<Schema>()._opacity = opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Material::setUnlit(bool value) {
|
||||||
|
_key.setUnlit(value);
|
||||||
|
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||||
|
}
|
||||||
|
|
||||||
void Material::setAlbedo(const Color& albedo, bool isSRGB) {
|
void Material::setAlbedo(const Color& albedo, bool isSRGB) {
|
||||||
_key.setAlbedo(glm::any(glm::greaterThan(albedo, Color(0.0f))));
|
_key.setAlbedo(glm::any(glm::greaterThan(albedo, Color(0.0f))));
|
||||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||||
|
@ -93,6 +98,7 @@ void Material::setFresnel(const Color& fresnel, bool isSRGB) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::setMetallic(float metallic) {
|
void Material::setMetallic(float metallic) {
|
||||||
|
metallic = glm::clamp(metallic, 0.0f, 1.0f);
|
||||||
_key.setMetallic(metallic > 0.0f);
|
_key.setMetallic(metallic > 0.0f);
|
||||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||||
_schemaBuffer.edit<Schema>()._metallic = metallic;
|
_schemaBuffer.edit<Schema>()._metallic = metallic;
|
||||||
|
|
|
@ -28,14 +28,15 @@ class MaterialKey {
|
||||||
public:
|
public:
|
||||||
enum FlagBit {
|
enum FlagBit {
|
||||||
EMISSIVE_VAL_BIT = 0,
|
EMISSIVE_VAL_BIT = 0,
|
||||||
|
UNLIT_VAL_BIT,
|
||||||
ALBEDO_VAL_BIT,
|
ALBEDO_VAL_BIT,
|
||||||
METALLIC_VAL_BIT,
|
METALLIC_VAL_BIT,
|
||||||
GLOSSY_VAL_BIT,
|
GLOSSY_VAL_BIT,
|
||||||
OPACITY_VAL_BIT,
|
OPACITY_VAL_BIT,
|
||||||
OPACITY_MASK_MAP_BIT, // OPacity Map and Opacity MASK map are mutually exclusive
|
OPACITY_MASK_MAP_BIT, // Opacity Map and Opacity MASK map are mutually exclusive
|
||||||
OPACITY_TRANSLUCENT_MAP_BIT,
|
OPACITY_TRANSLUCENT_MAP_BIT,
|
||||||
|
|
||||||
// THe map bits must be in the smae sequence as the enum names for the map channels
|
// THe map bits must be in the same sequence as the enum names for the map channels
|
||||||
EMISSIVE_MAP_BIT,
|
EMISSIVE_MAP_BIT,
|
||||||
ALBEDO_MAP_BIT,
|
ALBEDO_MAP_BIT,
|
||||||
METALLIC_MAP_BIT,
|
METALLIC_MAP_BIT,
|
||||||
|
@ -74,9 +75,12 @@ public:
|
||||||
MaterialKey build() const { return MaterialKey(_flags); }
|
MaterialKey build() const { return MaterialKey(_flags); }
|
||||||
|
|
||||||
Builder& withEmissive() { _flags.set(EMISSIVE_VAL_BIT); return (*this); }
|
Builder& withEmissive() { _flags.set(EMISSIVE_VAL_BIT); return (*this); }
|
||||||
|
Builder& withUnlit() { _flags.set(UNLIT_VAL_BIT); return (*this); }
|
||||||
|
|
||||||
Builder& withAlbedo() { _flags.set(ALBEDO_VAL_BIT); return (*this); }
|
Builder& withAlbedo() { _flags.set(ALBEDO_VAL_BIT); return (*this); }
|
||||||
Builder& withMetallic() { _flags.set(METALLIC_VAL_BIT); return (*this); }
|
Builder& withMetallic() { _flags.set(METALLIC_VAL_BIT); return (*this); }
|
||||||
Builder& withGlossy() { _flags.set(GLOSSY_VAL_BIT); return (*this); }
|
Builder& withGlossy() { _flags.set(GLOSSY_VAL_BIT); return (*this); }
|
||||||
|
|
||||||
Builder& withTranslucentFactor() { _flags.set(OPACITY_VAL_BIT); return (*this); }
|
Builder& withTranslucentFactor() { _flags.set(OPACITY_VAL_BIT); return (*this); }
|
||||||
|
|
||||||
Builder& withEmissiveMap() { _flags.set(EMISSIVE_MAP_BIT); return (*this); }
|
Builder& withEmissiveMap() { _flags.set(EMISSIVE_MAP_BIT); return (*this); }
|
||||||
|
@ -98,6 +102,9 @@ public:
|
||||||
void setEmissive(bool value) { _flags.set(EMISSIVE_VAL_BIT, value); }
|
void setEmissive(bool value) { _flags.set(EMISSIVE_VAL_BIT, value); }
|
||||||
bool isEmissive() const { return _flags[EMISSIVE_VAL_BIT]; }
|
bool isEmissive() const { return _flags[EMISSIVE_VAL_BIT]; }
|
||||||
|
|
||||||
|
void setUnlit(bool value) { _flags.set(UNLIT_VAL_BIT, value); }
|
||||||
|
bool isUnlit() const { return _flags[UNLIT_VAL_BIT]; }
|
||||||
|
|
||||||
void setEmissiveMap(bool value) { _flags.set(EMISSIVE_MAP_BIT, value); }
|
void setEmissiveMap(bool value) { _flags.set(EMISSIVE_MAP_BIT, value); }
|
||||||
bool isEmissiveMap() const { return _flags[EMISSIVE_MAP_BIT]; }
|
bool isEmissiveMap() const { return _flags[EMISSIVE_MAP_BIT]; }
|
||||||
|
|
||||||
|
@ -172,6 +179,9 @@ public:
|
||||||
Builder& withoutEmissiveMap() { _value.reset(MaterialKey::EMISSIVE_MAP_BIT); _mask.set(MaterialKey::EMISSIVE_MAP_BIT); return (*this); }
|
Builder& withoutEmissiveMap() { _value.reset(MaterialKey::EMISSIVE_MAP_BIT); _mask.set(MaterialKey::EMISSIVE_MAP_BIT); return (*this); }
|
||||||
Builder& withEmissiveMap() { _value.set(MaterialKey::EMISSIVE_MAP_BIT); _mask.set(MaterialKey::EMISSIVE_MAP_BIT); return (*this); }
|
Builder& withEmissiveMap() { _value.set(MaterialKey::EMISSIVE_MAP_BIT); _mask.set(MaterialKey::EMISSIVE_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
|
Builder& withoutUnlit() { _value.reset(MaterialKey::UNLIT_VAL_BIT); _mask.set(MaterialKey::UNLIT_VAL_BIT); return (*this); }
|
||||||
|
Builder& withUnlit() { _value.set(MaterialKey::UNLIT_VAL_BIT); _mask.set(MaterialKey::UNLIT_VAL_BIT); return (*this); }
|
||||||
|
|
||||||
Builder& withoutAlbedo() { _value.reset(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
Builder& withoutAlbedo() { _value.reset(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
||||||
Builder& withAlbedo() { _value.set(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
Builder& withAlbedo() { _value.set(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
||||||
|
|
||||||
|
@ -250,6 +260,9 @@ public:
|
||||||
void setOpacity(float opacity);
|
void setOpacity(float opacity);
|
||||||
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
|
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
|
||||||
|
|
||||||
|
void setUnlit(bool value);
|
||||||
|
bool isUnlit() const { return _key.isUnlit(); }
|
||||||
|
|
||||||
void setAlbedo(const Color& albedo, bool isSRGB = true);
|
void setAlbedo(const Color& albedo, bool isSRGB = true);
|
||||||
Color getAlbedo(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_schemaBuffer.get<Schema>()._albedo) : _schemaBuffer.get<Schema>()._albedo); }
|
Color getAlbedo(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_schemaBuffer.get<Schema>()._albedo) : _schemaBuffer.get<Schema>()._albedo); }
|
||||||
|
|
||||||
|
|
|
@ -40,20 +40,21 @@ float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); }
|
||||||
int getMaterialKey(Material m) { return floatBitsToInt(m._spareKey.w); }
|
int getMaterialKey(Material m) { return floatBitsToInt(m._spareKey.w); }
|
||||||
|
|
||||||
const int EMISSIVE_VAL_BIT = 0x00000001;
|
const int EMISSIVE_VAL_BIT = 0x00000001;
|
||||||
const int ALBEDO_VAL_BIT = 0x00000002;
|
const int UNLIT_VAL_BIT = 0x00000002;
|
||||||
const int METALLIC_VAL_BIT = 0x00000004;
|
const int ALBEDO_VAL_BIT = 0x00000004;
|
||||||
const int GLOSSY_VAL_BIT = 0x00000008;
|
const int METALLIC_VAL_BIT = 0x00000008;
|
||||||
const int OPACITY_VAL_BIT = 0x00000010;
|
const int GLOSSY_VAL_BIT = 0x00000010;
|
||||||
const int OPACITY_MASK_MAP_BIT = 0x00000020;
|
const int OPACITY_VAL_BIT = 0x00000020;
|
||||||
const int OPACITY_TRANSLUCENT_MAP_BIT = 0x00000040;
|
const int OPACITY_MASK_MAP_BIT = 0x00000040;
|
||||||
|
const int OPACITY_TRANSLUCENT_MAP_BIT = 0x00000080;
|
||||||
|
|
||||||
const int EMISSIVE_MAP_BIT = 0x00000080;
|
const int EMISSIVE_MAP_BIT = 0x00000100;
|
||||||
const int ALBEDO_MAP_BIT = 0x00000100;
|
const int ALBEDO_MAP_BIT = 0x00000200;
|
||||||
const int METALLIC_MAP_BIT = 0x00000200;
|
const int METALLIC_MAP_BIT = 0x00000400;
|
||||||
const int ROUGHNESS_MAP_BIT = 0x00000400;
|
const int ROUGHNESS_MAP_BIT = 0x00000800;
|
||||||
const int NORMAL_MAP_BIT = 0x00000800;
|
const int NORMAL_MAP_BIT = 0x00001000;
|
||||||
const int OCCLUSION_MAP_BIT = 0x00001000;
|
const int OCCLUSION_MAP_BIT = 0x00002000;
|
||||||
const int LIGHTMAP_MAP_BIT = 0x00002000;
|
const int LIGHTMAP_MAP_BIT = 0x00004000;
|
||||||
|
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -118,29 +118,18 @@ AnimDebugDraw::AnimDebugDraw() :
|
||||||
|
|
||||||
// HACK: add red, green and blue axis at (1,1,1)
|
// HACK: add red, green and blue axis at (1,1,1)
|
||||||
_animDebugDrawData->_vertexBuffer->resize(sizeof(Vertex) * 6);
|
_animDebugDrawData->_vertexBuffer->resize(sizeof(Vertex) * 6);
|
||||||
Vertex* data = (Vertex*)_animDebugDrawData->_vertexBuffer->editData();
|
|
||||||
|
|
||||||
data[0].pos = glm::vec3(1.0, 1.0f, 1.0f);
|
|
||||||
data[0].rgba = toRGBA(255, 0, 0, 255);
|
|
||||||
data[1].pos = glm::vec3(2.0, 1.0f, 1.0f);
|
|
||||||
data[1].rgba = toRGBA(255, 0, 0, 255);
|
|
||||||
|
|
||||||
data[2].pos = glm::vec3(1.0, 1.0f, 1.0f);
|
|
||||||
data[2].rgba = toRGBA(0, 255, 0, 255);
|
|
||||||
data[3].pos = glm::vec3(1.0, 2.0f, 1.0f);
|
|
||||||
data[3].rgba = toRGBA(0, 255, 0, 255);
|
|
||||||
|
|
||||||
data[4].pos = glm::vec3(1.0, 1.0f, 1.0f);
|
|
||||||
data[4].rgba = toRGBA(0, 0, 255, 255);
|
|
||||||
data[5].pos = glm::vec3(1.0, 1.0f, 2.0f);
|
|
||||||
data[5].rgba = toRGBA(0, 0, 255, 255);
|
|
||||||
|
|
||||||
_animDebugDrawData->_indexBuffer->resize(sizeof(uint16_t) * 6);
|
|
||||||
uint16_t* indices = (uint16_t*)_animDebugDrawData->_indexBuffer->editData();
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
indices[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static std::vector<Vertex> vertices({
|
||||||
|
Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(255, 0, 0, 255) },
|
||||||
|
Vertex { glm::vec3(2.0, 1.0f, 1.0f), toRGBA(255, 0, 0, 255) },
|
||||||
|
Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(0, 255, 0, 255) },
|
||||||
|
Vertex { glm::vec3(1.0, 2.0f, 1.0f), toRGBA(0, 255, 0, 255) },
|
||||||
|
Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(0, 0, 255, 255) },
|
||||||
|
Vertex { glm::vec3(1.0, 1.0f, 2.0f), toRGBA(0, 0, 255, 255) },
|
||||||
|
});
|
||||||
|
static std::vector<uint16_t> indices({ 0, 1, 2, 3, 4, 5 });
|
||||||
|
_animDebugDrawData->_vertexBuffer->setSubData<Vertex>(0, vertices);
|
||||||
|
_animDebugDrawData->_indexBuffer->setSubData<uint16_t>(0, indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimDebugDraw::~AnimDebugDraw() {
|
AnimDebugDraw::~AnimDebugDraw() {
|
||||||
|
@ -356,9 +345,13 @@ void AnimDebugDraw::update() {
|
||||||
numVerts += (int)DebugDraw::getInstance().getRays().size() * VERTICES_PER_RAY;
|
numVerts += (int)DebugDraw::getInstance().getRays().size() * VERTICES_PER_RAY;
|
||||||
|
|
||||||
// allocate verts!
|
// allocate verts!
|
||||||
data._vertexBuffer->resize(sizeof(Vertex) * numVerts);
|
std::vector<Vertex> vertices;
|
||||||
Vertex* verts = (Vertex*)data._vertexBuffer->editData();
|
vertices.resize(numVerts);
|
||||||
Vertex* v = verts;
|
//Vertex* verts = (Vertex*)data._vertexBuffer->editData();
|
||||||
|
Vertex* v = nullptr;
|
||||||
|
if (numVerts) {
|
||||||
|
v = &vertices[0];
|
||||||
|
}
|
||||||
|
|
||||||
// draw absolute poses
|
// draw absolute poses
|
||||||
for (auto& iter : _absolutePoses) {
|
for (auto& iter : _absolutePoses) {
|
||||||
|
@ -381,6 +374,8 @@ void AnimDebugDraw::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
data._vertexBuffer->resize(sizeof(Vertex) * numVerts);
|
||||||
|
data._vertexBuffer->setSubData<Vertex>(0, vertices);
|
||||||
|
|
||||||
// draw markers from shared DebugDraw singleton
|
// draw markers from shared DebugDraw singleton
|
||||||
for (auto& iter : markerMap) {
|
for (auto& iter : markerMap) {
|
||||||
|
@ -408,20 +403,19 @@ void AnimDebugDraw::update() {
|
||||||
}
|
}
|
||||||
DebugDraw::getInstance().clearRays();
|
DebugDraw::getInstance().clearRays();
|
||||||
|
|
||||||
assert(numVerts == (v - verts));
|
assert((!numVerts && !v) || (numVerts == (v - &vertices[0])));
|
||||||
|
|
||||||
render::Item::Bound theBound;
|
render::Item::Bound theBound;
|
||||||
for (int i = 0; i < numVerts; i++) {
|
for (int i = 0; i < numVerts; i++) {
|
||||||
theBound += verts[i].pos;
|
theBound += vertices[i].pos;
|
||||||
}
|
}
|
||||||
data._bound = theBound;
|
data._bound = theBound;
|
||||||
|
|
||||||
data._isVisible = (numVerts > 0);
|
data._isVisible = (numVerts > 0);
|
||||||
|
|
||||||
data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
|
data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
|
||||||
uint16_t* indices = (uint16_t*)data._indexBuffer->editData();
|
|
||||||
for (int i = 0; i < numVerts; i++) {
|
for (int i = 0; i < numVerts; i++) {
|
||||||
indices[i] = i;
|
data._indexBuffer->setSubData<uint16_t>(i, (uint16_t)i);;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
scene->enqueuePendingChanges(pendingChanges);
|
scene->enqueuePendingChanges(pendingChanges);
|
||||||
|
|
|
@ -90,14 +90,21 @@ static const std::string DEFAULT_OCCLUSION_SHADER{
|
||||||
static const std::string DEFAULT_EMISSIVE_SHADER{
|
static const std::string DEFAULT_EMISSIVE_SHADER{
|
||||||
"vec4 getFragmentColor() {"
|
"vec4 getFragmentColor() {"
|
||||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||||
" return (frag.mode != LIGHT_MAPPED ? vec4(pow(frag.emissive, vec3(1.0 / 2.2)), 1.0) : vec4(vec3(0.0), 1.0));"
|
" return (frag.mode == FRAG_MODE_SHADED ? vec4(pow(frag.emissive, vec3(1.0 / 2.2)), 1.0) : vec4(vec3(0.0), 1.0));"
|
||||||
|
" }"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::string DEFAULT_UNLIT_SHADER{
|
||||||
|
"vec4 getFragmentColor() {"
|
||||||
|
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||||
|
" return (frag.mode == FRAG_MODE_UNLIT ? vec4(pow(frag.diffuse, vec3(1.0 / 2.2)), 1.0) : vec4(vec3(0.0), 1.0));"
|
||||||
" }"
|
" }"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::string DEFAULT_LIGHTMAP_SHADER{
|
static const std::string DEFAULT_LIGHTMAP_SHADER{
|
||||||
"vec4 getFragmentColor() {"
|
"vec4 getFragmentColor() {"
|
||||||
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
|
||||||
" return (frag.mode == LIGHT_MAPPED ? vec4(frag.emissive, 1.0) : vec4(vec3(0.0), 1.0));"
|
" return (frag.mode == FRAG_MODE_LIGHTMAPPED ? vec4(pow(frag.emissive, vec3(1.0 / 2.2)), 1.0) : vec4(vec3(0.0), 1.0));"
|
||||||
" }"
|
" }"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -184,6 +191,8 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust
|
||||||
return DEFAULT_DEPTH_SHADER;
|
return DEFAULT_DEPTH_SHADER;
|
||||||
case EmissiveMode:
|
case EmissiveMode:
|
||||||
return DEFAULT_EMISSIVE_SHADER;
|
return DEFAULT_EMISSIVE_SHADER;
|
||||||
|
case UnlitMode:
|
||||||
|
return DEFAULT_UNLIT_SHADER;
|
||||||
case OcclusionMode:
|
case OcclusionMode:
|
||||||
return DEFAULT_OCCLUSION_SHADER;
|
return DEFAULT_OCCLUSION_SHADER;
|
||||||
case LightmapMode:
|
case LightmapMode:
|
||||||
|
|
|
@ -53,6 +53,7 @@ protected:
|
||||||
RoughnessMode,
|
RoughnessMode,
|
||||||
MetallicMode,
|
MetallicMode,
|
||||||
EmissiveMode,
|
EmissiveMode,
|
||||||
|
UnlitMode,
|
||||||
OcclusionMode,
|
OcclusionMode,
|
||||||
LightmapMode,
|
LightmapMode,
|
||||||
LightingMode,
|
LightingMode,
|
||||||
|
|
|
@ -11,135 +11,44 @@
|
||||||
<@if not DEFERRED_BUFFER_SLH@>
|
<@if not DEFERRED_BUFFER_SLH@>
|
||||||
<@def DEFERRED_BUFFER_SLH@>
|
<@def DEFERRED_BUFFER_SLH@>
|
||||||
|
|
||||||
|
// Unpack the metallic-mode value
|
||||||
|
const float FRAG_PACK_SHADED_NON_METALLIC = 0.0;
|
||||||
|
const float FRAG_PACK_SHADED_METALLIC = 0.1;
|
||||||
|
const float FRAG_PACK_SHADED_RANGE_INV = 1.0 / (FRAG_PACK_SHADED_METALLIC - FRAG_PACK_SHADED_NON_METALLIC);
|
||||||
|
|
||||||
// the albedo texture
|
const float FRAG_PACK_LIGHTMAPPED_NON_METALLIC = 0.2;
|
||||||
uniform sampler2D albedoMap;
|
const float FRAG_PACK_LIGHTMAPPED_METALLIC = 0.3;
|
||||||
|
const float FRAG_PACK_LIGHTMAPPED_RANGE_INV = 1.0 / (FRAG_PACK_LIGHTMAPPED_METALLIC - FRAG_PACK_LIGHTMAPPED_NON_METALLIC);
|
||||||
|
|
||||||
// the normal texture
|
const float FRAG_PACK_UNLIT = 0.5;
|
||||||
uniform sampler2D normalMap;
|
|
||||||
|
|
||||||
// the specular texture
|
const int FRAG_MODE_UNLIT = 0;
|
||||||
uniform sampler2D specularMap;
|
const int FRAG_MODE_SHADED = 1;
|
||||||
|
const int FRAG_MODE_LIGHTMAPPED = 2;
|
||||||
|
|
||||||
// the depth texture
|
void unpackModeMetallic(float rawValue, out int mode, out float metallic) {
|
||||||
uniform sampler2D depthMap;
|
if (rawValue <= FRAG_PACK_SHADED_METALLIC) {
|
||||||
|
mode = FRAG_MODE_SHADED;
|
||||||
// the obscurance texture
|
metallic = clamp((rawValue - FRAG_PACK_SHADED_NON_METALLIC) * FRAG_PACK_SHADED_RANGE_INV, 0.0, 1.0);
|
||||||
uniform sampler2D obscuranceMap;
|
} else if (rawValue <= FRAG_PACK_LIGHTMAPPED_METALLIC) {
|
||||||
|
mode = FRAG_MODE_LIGHTMAPPED;
|
||||||
// the lighting texture
|
metallic = clamp((rawValue - FRAG_PACK_LIGHTMAPPED_NON_METALLIC) * FRAG_PACK_SHADED_RANGE_INV, 0.0, 1.0);
|
||||||
uniform sampler2D lightingMap;
|
} else if (rawValue >= FRAG_PACK_UNLIT) {
|
||||||
|
mode = FRAG_MODE_UNLIT;
|
||||||
|
metallic = 0.0;
|
||||||
struct DeferredTransform {
|
|
||||||
mat4 projection;
|
|
||||||
mat4 viewInverse;
|
|
||||||
float stereoSide;
|
|
||||||
vec3 _spareABC;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std140) uniform deferredTransformBuffer {
|
|
||||||
DeferredTransform _deferredTransform;
|
|
||||||
};
|
|
||||||
DeferredTransform getDeferredTransform() {
|
|
||||||
return _deferredTransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getStereoMode(DeferredTransform deferredTransform) {
|
|
||||||
return (deferredTransform.stereoSide != 0.0);
|
|
||||||
}
|
|
||||||
float getStereoSide(DeferredTransform deferredTransform) {
|
|
||||||
return (deferredTransform.stereoSide);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) {
|
|
||||||
vec3 nPos = vec3(texcoord.xy * 2.0f - 1.0f, depthVal * 2.0f - 1.0f);
|
|
||||||
|
|
||||||
// compute the view space position using the depth
|
|
||||||
// basically manually pick the proj matrix components to do the inverse
|
|
||||||
float Ze = -deferredTransform.projection[3][2] / (nPos.z + deferredTransform.projection[2][2]);
|
|
||||||
float Xe = (-Ze * nPos.x - Ze * deferredTransform.projection[2][0] - deferredTransform.projection[3][0]) / deferredTransform.projection[0][0];
|
|
||||||
float Ye = (-Ze * nPos.y - Ze * deferredTransform.projection[2][1] - deferredTransform.projection[3][1]) / deferredTransform.projection[1][1];
|
|
||||||
return vec4(Xe, Ye, Ze, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DeferredFragment {
|
|
||||||
vec4 normalVal;
|
|
||||||
vec4 diffuseVal;
|
|
||||||
vec4 specularVal;
|
|
||||||
vec4 position;
|
|
||||||
vec3 normal;
|
|
||||||
float metallic;
|
|
||||||
vec3 diffuse;
|
|
||||||
float obscurance;
|
|
||||||
vec3 specular;
|
|
||||||
float roughness;
|
|
||||||
vec3 emissive;
|
|
||||||
int mode;
|
|
||||||
float depthVal;
|
|
||||||
};
|
|
||||||
|
|
||||||
const int LIGHT_MAPPED = 1;
|
|
||||||
|
|
||||||
vec4 unpackDeferredPosition(DeferredTransform deferredTransform, float depthValue, vec2 texcoord) {
|
|
||||||
if (getStereoMode(deferredTransform)) {
|
|
||||||
if (texcoord.x > 0.5) {
|
|
||||||
texcoord.x -= 0.5;
|
|
||||||
}
|
|
||||||
texcoord.x *= 2.0;
|
|
||||||
}
|
}
|
||||||
return evalEyePositionFromZ(deferredTransform, depthValue, texcoord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) {
|
float packShadedMetallic(float metallic) {
|
||||||
|
return mix(FRAG_PACK_SHADED_NON_METALLIC, FRAG_PACK_SHADED_METALLIC, metallic);
|
||||||
DeferredFragment frag;
|
|
||||||
frag.depthVal = -1;
|
|
||||||
frag.normalVal = texture(normalMap, texcoord);
|
|
||||||
frag.diffuseVal = texture(albedoMap, texcoord);
|
|
||||||
frag.specularVal = texture(specularMap, texcoord);
|
|
||||||
frag.obscurance = texture(obscuranceMap, texcoord).x;
|
|
||||||
|
|
||||||
// Unpack the normal from the map
|
|
||||||
frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0));
|
|
||||||
|
|
||||||
frag.mode = 0;
|
|
||||||
frag.emissive = frag.specularVal.xyz;
|
|
||||||
if (frag.normalVal.a < 0.5) {
|
|
||||||
frag.mode = 0;
|
|
||||||
frag.roughness = 2.0 * frag.normalVal.a;
|
|
||||||
} else {
|
|
||||||
frag.mode = LIGHT_MAPPED;
|
|
||||||
frag.roughness = 2.0 * frag.normalVal.a - 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
frag.metallic = frag.diffuseVal.a;
|
|
||||||
frag.diffuse = frag.diffuseVal.xyz;
|
|
||||||
if (frag.metallic <= 0.5) {
|
|
||||||
frag.metallic = 0.0;
|
|
||||||
frag.specular = vec3(0.03); // Default Di-electric fresnel value
|
|
||||||
} else {
|
|
||||||
frag.specular = vec3(frag.diffuseVal.xyz);
|
|
||||||
frag.metallic = 1.0;
|
|
||||||
}
|
|
||||||
frag.obscurance = min(frag.specularVal.w, frag.obscurance);
|
|
||||||
|
|
||||||
return frag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec2 texcoord) {
|
float packLightmappedMetallic(float metallic) {
|
||||||
|
return mix(FRAG_PACK_LIGHTMAPPED_NON_METALLIC, FRAG_PACK_LIGHTMAPPED_METALLIC, metallic);
|
||||||
float depthValue = texture(depthMap, texcoord).r;
|
|
||||||
|
|
||||||
DeferredFragment frag = unpackDeferredFragmentNoPosition(texcoord);
|
|
||||||
|
|
||||||
frag.depthVal = depthValue;
|
|
||||||
frag.position = unpackDeferredPosition(deferredTransform, frag.depthVal, texcoord);
|
|
||||||
|
|
||||||
return frag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float packUnlit() {
|
||||||
|
return FRAG_PACK_UNLIT;
|
||||||
|
}
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
140
libraries/render-utils/src/DeferredBufferRead.slh
Normal file
140
libraries/render-utils/src/DeferredBufferRead.slh
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
<!
|
||||||
|
// DeferredBufferRead.slh
|
||||||
|
// libraries/render-utils/src
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 5/4/16.
|
||||||
|
// Copyright 2013 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
|
||||||
|
!>
|
||||||
|
<@if not DEFERRED_BUFFER_READ_SLH@>
|
||||||
|
<@def DEFERRED_BUFFER_READ_SLH@>
|
||||||
|
|
||||||
|
<@include DeferredBuffer.slh@>
|
||||||
|
|
||||||
|
// the albedo texture
|
||||||
|
uniform sampler2D albedoMap;
|
||||||
|
|
||||||
|
// the normal texture
|
||||||
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
// the specular texture
|
||||||
|
uniform sampler2D specularMap;
|
||||||
|
|
||||||
|
// the depth texture
|
||||||
|
uniform sampler2D depthMap;
|
||||||
|
|
||||||
|
// the obscurance texture
|
||||||
|
uniform sampler2D obscuranceMap;
|
||||||
|
|
||||||
|
// the lighting texture
|
||||||
|
uniform sampler2D lightingMap;
|
||||||
|
|
||||||
|
|
||||||
|
struct DeferredTransform {
|
||||||
|
mat4 projection;
|
||||||
|
mat4 viewInverse;
|
||||||
|
float stereoSide;
|
||||||
|
vec3 _spareABC;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform deferredTransformBuffer {
|
||||||
|
DeferredTransform _deferredTransform;
|
||||||
|
};
|
||||||
|
DeferredTransform getDeferredTransform() {
|
||||||
|
return _deferredTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getStereoMode(DeferredTransform deferredTransform) {
|
||||||
|
return (deferredTransform.stereoSide != 0.0);
|
||||||
|
}
|
||||||
|
float getStereoSide(DeferredTransform deferredTransform) {
|
||||||
|
return (deferredTransform.stereoSide);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) {
|
||||||
|
vec3 nPos = vec3(texcoord.xy * 2.0f - 1.0f, depthVal * 2.0f - 1.0f);
|
||||||
|
|
||||||
|
// compute the view space position using the depth
|
||||||
|
// basically manually pick the proj matrix components to do the inverse
|
||||||
|
float Ze = -deferredTransform.projection[3][2] / (nPos.z + deferredTransform.projection[2][2]);
|
||||||
|
float Xe = (-Ze * nPos.x - Ze * deferredTransform.projection[2][0] - deferredTransform.projection[3][0]) / deferredTransform.projection[0][0];
|
||||||
|
float Ye = (-Ze * nPos.y - Ze * deferredTransform.projection[2][1] - deferredTransform.projection[3][1]) / deferredTransform.projection[1][1];
|
||||||
|
return vec4(Xe, Ye, Ze, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DeferredFragment {
|
||||||
|
vec4 normalVal;
|
||||||
|
vec4 diffuseVal;
|
||||||
|
vec4 specularVal;
|
||||||
|
vec4 position;
|
||||||
|
vec3 normal;
|
||||||
|
float metallic;
|
||||||
|
vec3 diffuse;
|
||||||
|
float obscurance;
|
||||||
|
vec3 specular;
|
||||||
|
float roughness;
|
||||||
|
vec3 emissive;
|
||||||
|
int mode;
|
||||||
|
float depthVal;
|
||||||
|
};
|
||||||
|
|
||||||
|
vec4 unpackDeferredPosition(DeferredTransform deferredTransform, float depthValue, vec2 texcoord) {
|
||||||
|
if (getStereoMode(deferredTransform)) {
|
||||||
|
if (texcoord.x > 0.5) {
|
||||||
|
texcoord.x -= 0.5;
|
||||||
|
}
|
||||||
|
texcoord.x *= 2.0;
|
||||||
|
}
|
||||||
|
return evalEyePositionFromZ(deferredTransform, depthValue, texcoord);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) {
|
||||||
|
|
||||||
|
DeferredFragment frag;
|
||||||
|
frag.depthVal = -1;
|
||||||
|
frag.normalVal = texture(normalMap, texcoord);
|
||||||
|
frag.diffuseVal = texture(albedoMap, texcoord);
|
||||||
|
frag.specularVal = texture(specularMap, texcoord);
|
||||||
|
frag.obscurance = texture(obscuranceMap, texcoord).x;
|
||||||
|
|
||||||
|
// Unpack the normal from the map
|
||||||
|
frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0));
|
||||||
|
frag.roughness = 2.0 * frag.normalVal.a;
|
||||||
|
|
||||||
|
// Diffuse color and unpack the mode and the metallicness
|
||||||
|
frag.diffuse = frag.diffuseVal.xyz;
|
||||||
|
unpackModeMetallic(frag.diffuseVal.w, frag.mode, frag.metallic);
|
||||||
|
|
||||||
|
|
||||||
|
if (frag.metallic <= 0.5) {
|
||||||
|
frag.metallic = 0.0;
|
||||||
|
frag.specular = vec3(0.03); // Default Di-electric fresnel value
|
||||||
|
} else {
|
||||||
|
frag.specular = vec3(frag.diffuseVal.xyz);
|
||||||
|
frag.metallic = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
frag.emissive = frag.specularVal.xyz;
|
||||||
|
frag.obscurance = min(frag.specularVal.w, frag.obscurance);
|
||||||
|
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec2 texcoord) {
|
||||||
|
|
||||||
|
float depthValue = texture(depthMap, texcoord).r;
|
||||||
|
|
||||||
|
DeferredFragment frag = unpackDeferredFragmentNoPosition(texcoord);
|
||||||
|
|
||||||
|
frag.depthVal = depthValue;
|
||||||
|
frag.position = unpackDeferredPosition(deferredTransform, frag.depthVal, texcoord);
|
||||||
|
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<@endif@>
|
|
@ -11,6 +11,8 @@
|
||||||
<@if not DEFERRED_BUFFER_WRITE_SLH@>
|
<@if not DEFERRED_BUFFER_WRITE_SLH@>
|
||||||
<@def DEFERRED_BUFFER_WRITE_SLH@>
|
<@def DEFERRED_BUFFER_WRITE_SLH@>
|
||||||
|
|
||||||
|
<@include DeferredBuffer.slh@>
|
||||||
|
|
||||||
layout(location = 0) out vec4 _fragColor0;
|
layout(location = 0) out vec4 _fragColor0;
|
||||||
layout(location = 1) out vec4 _fragColor1;
|
layout(location = 1) out vec4 _fragColor1;
|
||||||
layout(location = 2) out vec4 _fragColor2;
|
layout(location = 2) out vec4 _fragColor2;
|
||||||
|
@ -48,13 +50,12 @@ const vec3 DEFAULT_EMISSIVE = vec3(0.0);
|
||||||
const float DEFAULT_OCCLUSION = 1.0;
|
const float DEFAULT_OCCLUSION = 1.0;
|
||||||
const vec3 DEFAULT_FRESNEL = DEFAULT_EMISSIVE;
|
const vec3 DEFAULT_FRESNEL = DEFAULT_EMISSIVE;
|
||||||
|
|
||||||
|
|
||||||
void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 emissive, float occlusion) {
|
void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 emissive, float occlusion) {
|
||||||
if (alpha != 1.0) {
|
if (alpha != 1.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
_fragColor0 = vec4(albedo, metallic);
|
_fragColor0 = vec4(albedo, packShadedMetallic(metallic));
|
||||||
_fragColor1 = vec4(bestFitNormal(normal), 0.5 * clamp(roughness, 0.0, 1.0));
|
_fragColor1 = vec4(bestFitNormal(normal), clamp(roughness, 0.0, 1.0));
|
||||||
_fragColor2 = vec4(emissive, occlusion);
|
_fragColor2 = vec4(emissive, occlusion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,19 +64,25 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float r
|
||||||
if (alpha != 1.0) {
|
if (alpha != 1.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
_fragColor0 = vec4(albedo, metallic);
|
_fragColor0 = vec4(albedo, packLightmappedMetallic(metallic));
|
||||||
_fragColor1 = vec4(bestFitNormal(normal), 0.5 + 0.5 * clamp(roughness, 0.0, 1.0));
|
_fragColor1 = vec4(bestFitNormal(normal), clamp(roughness, 0.0, 1.0));
|
||||||
_fragColor2 = vec4(emissive, 1.0);
|
_fragColor2 = vec4(emissive, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) {
|
||||||
|
if (alpha != 1.0) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
_fragColor0 = vec4(color, packUnlit());
|
||||||
|
_fragColor1 = vec4(bestFitNormal(normal), 1.0);
|
||||||
|
//_fragColor2 = vec4(vec3(0.0), 1.0); // If unlit, do not worry about the emissive color target
|
||||||
|
}
|
||||||
|
|
||||||
void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 albedo, vec3 fresnel, float roughness) {
|
void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 albedo, vec3 fresnel, float roughness) {
|
||||||
if (alpha <= 0.0) {
|
if (alpha <= 0.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
_fragColor0 = vec4(albedo.rgb, alpha);
|
_fragColor0 = vec4(albedo.rgb, alpha);
|
||||||
// _fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
|
||||||
// _fragColor2 = vec4(fresnel, roughness);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -59,7 +59,8 @@ void FramebufferCache::createPrimaryFramebuffer() {
|
||||||
_deferredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
_deferredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||||
_deferredFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
_deferredFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||||
|
|
||||||
auto colorFormat = gpu::Element::COLOR_RGBA_32;
|
// auto colorFormat = gpu::Element::COLOR_RGBA_32;
|
||||||
|
auto colorFormat = gpu::Element::COLOR_SRGBA_32;
|
||||||
auto width = _frameBufferSize.width();
|
auto width = _frameBufferSize.width();
|
||||||
auto height = _frameBufferSize.height();
|
auto height = _frameBufferSize.height();
|
||||||
|
|
||||||
|
@ -95,10 +96,7 @@ void FramebufferCache::createPrimaryFramebuffer() {
|
||||||
|
|
||||||
auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR);
|
auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR);
|
||||||
|
|
||||||
// FIXME: Decide on the proper one, let s stick to R11G11B10 for now
|
|
||||||
//_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, defaultSampler));
|
|
||||||
_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, defaultSampler));
|
_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, defaultSampler));
|
||||||
//_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::HALF, gpu::RGBA), width, height, defaultSampler));
|
|
||||||
_lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
_lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||||
_lightingFramebuffer->setRenderBuffer(0, _lightingTexture);
|
_lightingFramebuffer->setRenderBuffer(0, _lightingTexture);
|
||||||
_lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
_lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
||||||
|
@ -212,7 +210,7 @@ gpu::TexturePointer FramebufferCache::getLightingTexture() {
|
||||||
|
|
||||||
gpu::FramebufferPointer FramebufferCache::getFramebuffer() {
|
gpu::FramebufferPointer FramebufferCache::getFramebuffer() {
|
||||||
if (_cachedFramebuffers.isEmpty()) {
|
if (_cachedFramebuffers.isEmpty()) {
|
||||||
_cachedFramebuffers.push_back(gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height())));
|
_cachedFramebuffers.push_back(gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_SRGBA_32, _frameBufferSize.width(), _frameBufferSize.height())));
|
||||||
}
|
}
|
||||||
gpu::FramebufferPointer result = _cachedFramebuffers.front();
|
gpu::FramebufferPointer result = _cachedFramebuffers.front();
|
||||||
_cachedFramebuffers.pop_front();
|
_cachedFramebuffers.pop_front();
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include "simple_vert.h"
|
#include "simple_vert.h"
|
||||||
#include "simple_textured_frag.h"
|
#include "simple_textured_frag.h"
|
||||||
#include "simple_textured_emisive_frag.h"
|
#include "simple_textured_unlit_frag.h"
|
||||||
|
|
||||||
#include "grid_frag.h"
|
#include "grid_frag.h"
|
||||||
|
|
||||||
|
@ -1687,7 +1687,7 @@ public:
|
||||||
enum FlagBit {
|
enum FlagBit {
|
||||||
IS_TEXTURED_FLAG = 0,
|
IS_TEXTURED_FLAG = 0,
|
||||||
IS_CULLED_FLAG,
|
IS_CULLED_FLAG,
|
||||||
IS_EMISSIVE_FLAG,
|
IS_UNLIT_FLAG,
|
||||||
HAS_DEPTH_BIAS_FLAG,
|
HAS_DEPTH_BIAS_FLAG,
|
||||||
|
|
||||||
NUM_FLAGS,
|
NUM_FLAGS,
|
||||||
|
@ -1696,7 +1696,7 @@ public:
|
||||||
enum Flag {
|
enum Flag {
|
||||||
IS_TEXTURED = (1 << IS_TEXTURED_FLAG),
|
IS_TEXTURED = (1 << IS_TEXTURED_FLAG),
|
||||||
IS_CULLED = (1 << IS_CULLED_FLAG),
|
IS_CULLED = (1 << IS_CULLED_FLAG),
|
||||||
IS_EMISSIVE = (1 << IS_EMISSIVE_FLAG),
|
IS_UNLIT = (1 << IS_UNLIT_FLAG),
|
||||||
HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG),
|
HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG),
|
||||||
};
|
};
|
||||||
typedef unsigned short Flags;
|
typedef unsigned short Flags;
|
||||||
|
@ -1705,7 +1705,7 @@ public:
|
||||||
|
|
||||||
bool isTextured() const { return isFlag(IS_TEXTURED); }
|
bool isTextured() const { return isFlag(IS_TEXTURED); }
|
||||||
bool isCulled() const { return isFlag(IS_CULLED); }
|
bool isCulled() const { return isFlag(IS_CULLED); }
|
||||||
bool isEmissive() const { return isFlag(IS_EMISSIVE); }
|
bool isUnlit() const { return isFlag(IS_UNLIT); }
|
||||||
bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); }
|
bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); }
|
||||||
|
|
||||||
Flags _flags = 0;
|
Flags _flags = 0;
|
||||||
|
@ -1715,9 +1715,9 @@ public:
|
||||||
|
|
||||||
|
|
||||||
SimpleProgramKey(bool textured = false, bool culled = true,
|
SimpleProgramKey(bool textured = false, bool culled = true,
|
||||||
bool emissive = false, bool depthBias = false) {
|
bool unlit = false, bool depthBias = false) {
|
||||||
_flags = (textured ? IS_TEXTURED : 0) | (culled ? IS_CULLED : 0) |
|
_flags = (textured ? IS_TEXTURED : 0) | (culled ? IS_CULLED : 0) |
|
||||||
(emissive ? IS_EMISSIVE : 0) | (depthBias ? HAS_DEPTH_BIAS : 0);
|
(unlit ? IS_UNLIT : 0) | (depthBias ? HAS_DEPTH_BIAS : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleProgramKey(int bitmask) : _flags(bitmask) {}
|
SimpleProgramKey(int bitmask) : _flags(bitmask) {}
|
||||||
|
@ -1731,8 +1731,8 @@ inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) {
|
||||||
return a.getRaw() == b.getRaw();
|
return a.getRaw() == b.getRaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, bool emissive, bool depthBiased) {
|
void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, bool unlit, bool depthBiased) {
|
||||||
batch.setPipeline(getSimplePipeline(textured, culled, emissive, depthBiased));
|
batch.setPipeline(getSimplePipeline(textured, culled, unlit, depthBiased));
|
||||||
|
|
||||||
// If not textured, set a default albedo map
|
// If not textured, set a default albedo map
|
||||||
if (!textured) {
|
if (!textured) {
|
||||||
|
@ -1744,23 +1744,23 @@ void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool cul
|
||||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool culled, bool emissive, bool depthBiased) {
|
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool culled, bool unlit, bool depthBiased) {
|
||||||
SimpleProgramKey config{textured, culled, emissive, depthBiased};
|
SimpleProgramKey config{ textured, culled, unlit, depthBiased };
|
||||||
|
|
||||||
// Compile the shaders
|
// Compile the shaders
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
std::call_once(once, [&]() {
|
std::call_once(once, [&]() {
|
||||||
auto VS = gpu::Shader::createVertex(std::string(simple_vert));
|
auto VS = gpu::Shader::createVertex(std::string(simple_vert));
|
||||||
auto PS = gpu::Shader::createPixel(std::string(simple_textured_frag));
|
auto PS = gpu::Shader::createPixel(std::string(simple_textured_frag));
|
||||||
auto PSEmissive = gpu::Shader::createPixel(std::string(simple_textured_emisive_frag));
|
auto PSUnlit = gpu::Shader::createPixel(std::string(simple_textured_unlit_frag));
|
||||||
|
|
||||||
_simpleShader = gpu::Shader::createProgram(VS, PS);
|
_simpleShader = gpu::Shader::createProgram(VS, PS);
|
||||||
_emissiveShader = gpu::Shader::createProgram(VS, PSEmissive);
|
_unlitShader = gpu::Shader::createProgram(VS, PSUnlit);
|
||||||
|
|
||||||
gpu::Shader::BindingSet slotBindings;
|
gpu::Shader::BindingSet slotBindings;
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::MAP::NORMAL_FITTING));
|
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::MAP::NORMAL_FITTING));
|
||||||
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
|
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
|
||||||
gpu::Shader::makeProgram(*_emissiveShader, slotBindings);
|
gpu::Shader::makeProgram(*_unlitShader, slotBindings);
|
||||||
});
|
});
|
||||||
|
|
||||||
// If the pipeline already exists, return it
|
// If the pipeline already exists, return it
|
||||||
|
@ -1785,7 +1785,7 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool culled
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
|
||||||
gpu::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader;
|
gpu::ShaderPointer program = (config.isUnlit()) ? _unlitShader : _simpleShader;
|
||||||
gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state);
|
gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state);
|
||||||
_simplePrograms.insert(config, pipeline);
|
_simplePrograms.insert(config, pipeline);
|
||||||
return pipeline;
|
return pipeline;
|
||||||
|
|
|
@ -153,10 +153,10 @@ public:
|
||||||
|
|
||||||
// Bind the pipeline and get the state to render static geometry
|
// Bind the pipeline and get the state to render static geometry
|
||||||
void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true,
|
void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true,
|
||||||
bool emissive = false, bool depthBias = false);
|
bool unlit = false, bool depthBias = false);
|
||||||
// Get the pipeline to render static geometry
|
// Get the pipeline to render static geometry
|
||||||
gpu::PipelinePointer getSimplePipeline(bool textured = false, bool culled = true,
|
gpu::PipelinePointer getSimplePipeline(bool textured = false, bool culled = true,
|
||||||
bool emissive = false, bool depthBias = false);
|
bool unlit = false, bool depthBias = false);
|
||||||
render::ShapePipelinePointer getShapePipeline() { return GeometryCache::_simplePipeline; }
|
render::ShapePipelinePointer getShapePipeline() { return GeometryCache::_simplePipeline; }
|
||||||
|
|
||||||
// Static (instanced) geometry
|
// Static (instanced) geometry
|
||||||
|
@ -393,7 +393,7 @@ private:
|
||||||
QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry;
|
QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry;
|
||||||
|
|
||||||
gpu::ShaderPointer _simpleShader;
|
gpu::ShaderPointer _simpleShader;
|
||||||
gpu::ShaderPointer _emissiveShader;
|
gpu::ShaderPointer _unlitShader;
|
||||||
static render::ShapePipelinePointer _simplePipeline;
|
static render::ShapePipelinePointer _simplePipeline;
|
||||||
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
||||||
};
|
};
|
||||||
|
|
|
@ -157,7 +157,7 @@ vec3 fetchLightmapMap(vec2 uv) {
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func $discardTransparent(opacity)@>
|
<@func discardTransparent(opacity)@>
|
||||||
{
|
{
|
||||||
if (<$opacity$> < 1.0) {
|
if (<$opacity$> < 1.0) {
|
||||||
discard;
|
discard;
|
||||||
|
|
|
@ -144,6 +144,11 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
||||||
auto materialKey = _drawMaterial->getKey();
|
auto materialKey = _drawMaterial->getKey();
|
||||||
auto textureMaps = _drawMaterial->getTextureMaps();
|
auto textureMaps = _drawMaterial->getTextureMaps();
|
||||||
|
|
||||||
|
int numUnlit = 0;
|
||||||
|
if (materialKey.isUnlit()) {
|
||||||
|
numUnlit++;
|
||||||
|
}
|
||||||
|
|
||||||
// Albedo
|
// Albedo
|
||||||
if (materialKey.isAlbedoMap()) {
|
if (materialKey.isAlbedoMap()) {
|
||||||
auto albedoMap = textureMaps[model::MaterialKey::ALBEDO_MAP];
|
auto albedoMap = textureMaps[model::MaterialKey::ALBEDO_MAP];
|
||||||
|
@ -414,6 +419,7 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
||||||
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
||||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||||
|
bool isUnlit = drawMaterialKey.isUnlit();
|
||||||
|
|
||||||
bool isSkinned = _isSkinned;
|
bool isSkinned = _isSkinned;
|
||||||
bool wireframe = _model->isWireframe();
|
bool wireframe = _model->isWireframe();
|
||||||
|
@ -435,6 +441,9 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
if (hasLightmap) {
|
if (hasLightmap) {
|
||||||
builder.withLightmap();
|
builder.withLightmap();
|
||||||
}
|
}
|
||||||
|
if (isUnlit) {
|
||||||
|
builder.withUnlit();
|
||||||
|
}
|
||||||
if (isSkinned) {
|
if (isSkinned) {
|
||||||
builder.withSkinned();
|
builder.withSkinned();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "skin_model_normal_map_vert.h"
|
#include "skin_model_normal_map_vert.h"
|
||||||
|
|
||||||
#include "model_frag.h"
|
#include "model_frag.h"
|
||||||
#include "model_emissive_frag.h"
|
#include "model_unlit_frag.h"
|
||||||
#include "model_shadow_frag.h"
|
#include "model_shadow_frag.h"
|
||||||
#include "model_normal_map_frag.h"
|
#include "model_normal_map_frag.h"
|
||||||
#include "model_normal_specular_map_frag.h"
|
#include "model_normal_specular_map_frag.h"
|
||||||
|
@ -37,13 +37,13 @@
|
||||||
#include "model_lightmap_normal_specular_map_frag.h"
|
#include "model_lightmap_normal_specular_map_frag.h"
|
||||||
#include "model_lightmap_specular_map_frag.h"
|
#include "model_lightmap_specular_map_frag.h"
|
||||||
#include "model_translucent_frag.h"
|
#include "model_translucent_frag.h"
|
||||||
#include "model_translucent_emissive_frag.h"
|
#include "model_translucent_unlit_frag.h"
|
||||||
|
|
||||||
#include "overlay3D_vert.h"
|
#include "overlay3D_vert.h"
|
||||||
#include "overlay3D_frag.h"
|
#include "overlay3D_frag.h"
|
||||||
#include "overlay3D_translucent_frag.h"
|
#include "overlay3D_translucent_frag.h"
|
||||||
#include "overlay3D_emissive_frag.h"
|
#include "overlay3D_unlit_frag.h"
|
||||||
#include "overlay3D_translucent_emissive_frag.h"
|
#include "overlay3D_translucent_unlit_frag.h"
|
||||||
|
|
||||||
#include "drawOpaqueStencil_frag.h"
|
#include "drawOpaqueStencil_frag.h"
|
||||||
|
|
||||||
|
@ -102,13 +102,13 @@ void initOverlay3DPipelines(ShapePlumber& plumber) {
|
||||||
auto vertex = gpu::Shader::createVertex(std::string(overlay3D_vert));
|
auto vertex = gpu::Shader::createVertex(std::string(overlay3D_vert));
|
||||||
auto pixel = gpu::Shader::createPixel(std::string(overlay3D_frag));
|
auto pixel = gpu::Shader::createPixel(std::string(overlay3D_frag));
|
||||||
auto pixelTranslucent = gpu::Shader::createPixel(std::string(overlay3D_translucent_frag));
|
auto pixelTranslucent = gpu::Shader::createPixel(std::string(overlay3D_translucent_frag));
|
||||||
auto pixelEmissive = gpu::Shader::createPixel(std::string(overlay3D_emissive_frag));
|
auto pixelUnlit = gpu::Shader::createPixel(std::string(overlay3D_unlit_frag));
|
||||||
auto pixelTranslucentEmissive = gpu::Shader::createPixel(std::string(overlay3D_translucent_emissive_frag));
|
auto pixelTranslucentUnlit = gpu::Shader::createPixel(std::string(overlay3D_translucent_unlit_frag));
|
||||||
|
|
||||||
auto opaqueProgram = gpu::Shader::createProgram(vertex, pixel);
|
auto opaqueProgram = gpu::Shader::createProgram(vertex, pixel);
|
||||||
auto translucentProgram = gpu::Shader::createProgram(vertex, pixelTranslucent);
|
auto translucentProgram = gpu::Shader::createProgram(vertex, pixelTranslucent);
|
||||||
auto emissiveOpaqueProgram = gpu::Shader::createProgram(vertex, pixelEmissive);
|
auto unlitOpaqueProgram = gpu::Shader::createProgram(vertex, pixelUnlit);
|
||||||
auto emissiveTranslucentProgram = gpu::Shader::createProgram(vertex, pixelTranslucentEmissive);
|
auto unlitTranslucentProgram = gpu::Shader::createProgram(vertex, pixelTranslucentUnlit);
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
bool isCulled = (i & 1);
|
bool isCulled = (i & 1);
|
||||||
|
@ -138,9 +138,9 @@ void initOverlay3DPipelines(ShapePlumber& plumber) {
|
||||||
isOpaque ? builder.withOpaque() : builder.withTranslucent();
|
isOpaque ? builder.withOpaque() : builder.withTranslucent();
|
||||||
|
|
||||||
auto simpleProgram = isOpaque ? opaqueProgram : translucentProgram;
|
auto simpleProgram = isOpaque ? opaqueProgram : translucentProgram;
|
||||||
auto emissiveProgram = isOpaque ? emissiveOpaqueProgram : emissiveTranslucentProgram;
|
auto unlitProgram = isOpaque ? unlitOpaqueProgram : unlitTranslucentProgram;
|
||||||
plumber.addPipeline(builder.withoutEmissive().build(), simpleProgram, state, &lightBatchSetter);
|
plumber.addPipeline(builder.withoutUnlit().build(), simpleProgram, state, &lightBatchSetter);
|
||||||
plumber.addPipeline(builder.withEmissive().build(), emissiveProgram, state, &batchSetter);
|
plumber.addPipeline(builder.withUnlit().build(), unlitProgram, state, &batchSetter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,12 +201,12 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||||
|
|
||||||
// Pixel shaders
|
// Pixel shaders
|
||||||
auto modelPixel = gpu::Shader::createPixel(std::string(model_frag));
|
auto modelPixel = gpu::Shader::createPixel(std::string(model_frag));
|
||||||
auto modelEmissivePixel = gpu::Shader::createPixel(std::string(model_emissive_frag));
|
auto modelUnlitPixel = gpu::Shader::createPixel(std::string(model_unlit_frag));
|
||||||
auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag));
|
auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag));
|
||||||
auto modelSpecularMapPixel = gpu::Shader::createPixel(std::string(model_specular_map_frag));
|
auto modelSpecularMapPixel = gpu::Shader::createPixel(std::string(model_specular_map_frag));
|
||||||
auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_normal_specular_map_frag));
|
auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_normal_specular_map_frag));
|
||||||
auto modelTranslucentPixel = gpu::Shader::createPixel(std::string(model_translucent_frag));
|
auto modelTranslucentPixel = gpu::Shader::createPixel(std::string(model_translucent_frag));
|
||||||
auto modelTranslucentEmissivePixel = gpu::Shader::createPixel(std::string(model_translucent_emissive_frag));
|
auto modelTranslucentUnlitPixel = gpu::Shader::createPixel(std::string(model_translucent_unlit_frag));
|
||||||
auto modelShadowPixel = gpu::Shader::createPixel(std::string(model_shadow_frag));
|
auto modelShadowPixel = gpu::Shader::createPixel(std::string(model_shadow_frag));
|
||||||
auto modelLightmapPixel = gpu::Shader::createPixel(std::string(model_lightmap_frag));
|
auto modelLightmapPixel = gpu::Shader::createPixel(std::string(model_lightmap_frag));
|
||||||
auto modelLightmapNormalMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_map_frag));
|
auto modelLightmapNormalMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_map_frag));
|
||||||
|
@ -219,8 +219,8 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||||
Key::Builder(),
|
Key::Builder(),
|
||||||
modelVertex, modelPixel);
|
modelVertex, modelPixel);
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withEmissive(),
|
Key::Builder().withUnlit(),
|
||||||
modelVertex, modelEmissivePixel);
|
modelVertex, modelUnlitPixel);
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withTangents(),
|
Key::Builder().withTangents(),
|
||||||
modelNormalMapVertex, modelNormalMapPixel);
|
modelNormalMapVertex, modelNormalMapPixel);
|
||||||
|
@ -235,8 +235,8 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||||
Key::Builder().withTranslucent(),
|
Key::Builder().withTranslucent(),
|
||||||
modelVertex, modelTranslucentPixel);
|
modelVertex, modelTranslucentPixel);
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withTranslucent().withEmissive(),
|
Key::Builder().withTranslucent().withUnlit(),
|
||||||
modelVertex, modelTranslucentEmissivePixel);
|
modelVertex, modelTranslucentUnlitPixel);
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withTranslucent().withTangents(),
|
Key::Builder().withTranslucent().withTangents(),
|
||||||
modelNormalMapVertex, modelTranslucentPixel);
|
modelNormalMapVertex, modelTranslucentPixel);
|
||||||
|
@ -296,4 +296,5 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withDepthOnly(),
|
Key::Builder().withSkinned().withDepthOnly(),
|
||||||
skinModelShadowVertex, modelShadowPixel);
|
skinModelShadowVertex, modelShadowPixel);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include DeferredBuffer.slh@>
|
<@include DeferredBufferRead.slh@>
|
||||||
|
|
||||||
uniform sampler2D pyramidMap;
|
uniform sampler2D pyramidMap;
|
||||||
uniform sampler2D occlusionMap;
|
uniform sampler2D occlusionMap;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include DeferredBuffer.slh@>
|
<@include DeferredBufferRead.slh@>
|
||||||
<@include DeferredGlobalLight.slh@>
|
<@include DeferredGlobalLight.slh@>
|
||||||
|
|
||||||
<$declareEvalLightmappedColor()$>
|
<$declareEvalLightmappedColor()$>
|
||||||
|
@ -27,7 +27,9 @@ void main(void) {
|
||||||
|
|
||||||
float shadowAttenuation = 1.0;
|
float shadowAttenuation = 1.0;
|
||||||
|
|
||||||
if (frag.mode == LIGHT_MAPPED) {
|
if (frag.mode == FRAG_MODE_UNLIT) {
|
||||||
|
_fragColor = vec4(frag.diffuse, 1.0);
|
||||||
|
} else if (frag.mode == FRAG_MODE_LIGHTMAPPED) {
|
||||||
vec3 color = evalLightmappedColor(
|
vec3 color = evalLightmappedColor(
|
||||||
deferredTransform.viewInverse,
|
deferredTransform.viewInverse,
|
||||||
shadowAttenuation,
|
shadowAttenuation,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include Shadow.slh@>
|
<@include Shadow.slh@>
|
||||||
<@include DeferredBuffer.slh@>
|
<@include DeferredBufferRead.slh@>
|
||||||
<@include DeferredGlobalLight.slh@>
|
<@include DeferredGlobalLight.slh@>
|
||||||
|
|
||||||
<$declareEvalLightmappedColor()$>
|
<$declareEvalLightmappedColor()$>
|
||||||
|
@ -29,7 +29,9 @@ void main(void) {
|
||||||
vec4 worldPos = deferredTransform.viewInverse * vec4(frag.position.xyz, 1.0);
|
vec4 worldPos = deferredTransform.viewInverse * vec4(frag.position.xyz, 1.0);
|
||||||
float shadowAttenuation = evalShadowAttenuation(worldPos);
|
float shadowAttenuation = evalShadowAttenuation(worldPos);
|
||||||
|
|
||||||
if (frag.mode == LIGHT_MAPPED) {
|
if (frag.mode == FRAG_MODE_UNLIT) {
|
||||||
|
_fragColor = vec4(frag.diffuse, 1.0);
|
||||||
|
} else if (frag.mode == FRAG_MODE_LIGHTMAPPED) {
|
||||||
vec3 color = evalLightmappedColor(
|
vec3 color = evalLightmappedColor(
|
||||||
deferredTransform.viewInverse,
|
deferredTransform.viewInverse,
|
||||||
shadowAttenuation,
|
shadowAttenuation,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include DeferredBuffer.slh@>
|
<@include DeferredBufferRead.slh@>
|
||||||
<@include DeferredGlobalLight.slh@>
|
<@include DeferredGlobalLight.slh@>
|
||||||
|
|
||||||
<$declareEvalLightmappedColor()$>
|
<$declareEvalLightmappedColor()$>
|
||||||
|
@ -28,7 +28,9 @@ void main(void) {
|
||||||
float shadowAttenuation = 1.0;
|
float shadowAttenuation = 1.0;
|
||||||
|
|
||||||
// Light mapped or not ?
|
// Light mapped or not ?
|
||||||
if (frag.mode == LIGHT_MAPPED) {
|
if (frag.mode == FRAG_MODE_UNLIT) {
|
||||||
|
_fragColor = vec4(frag.diffuse, 1.0);
|
||||||
|
} else if (frag.mode == FRAG_MODE_LIGHTMAPPED) {
|
||||||
vec3 color = evalLightmappedColor(
|
vec3 color = evalLightmappedColor(
|
||||||
deferredTransform.viewInverse,
|
deferredTransform.viewInverse,
|
||||||
shadowAttenuation,
|
shadowAttenuation,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include Shadow.slh@>
|
<@include Shadow.slh@>
|
||||||
<@include DeferredBuffer.slh@>
|
<@include DeferredBufferRead.slh@>
|
||||||
<@include DeferredGlobalLight.slh@>
|
<@include DeferredGlobalLight.slh@>
|
||||||
|
|
||||||
<$declareEvalLightmappedColor()$>
|
<$declareEvalLightmappedColor()$>
|
||||||
|
@ -30,7 +30,9 @@ void main(void) {
|
||||||
float shadowAttenuation = evalShadowAttenuation(worldPos);
|
float shadowAttenuation = evalShadowAttenuation(worldPos);
|
||||||
|
|
||||||
// Light mapped or not ?
|
// Light mapped or not ?
|
||||||
if (frag.mode == LIGHT_MAPPED) {
|
if (frag.mode == FRAG_MODE_UNLIT) {
|
||||||
|
_fragColor = vec4(frag.diffuse, 1.0);
|
||||||
|
} else if (frag.mode == FRAG_MODE_LIGHTMAPPED) {
|
||||||
vec3 color = evalLightmappedColor(
|
vec3 color = evalLightmappedColor(
|
||||||
deferredTransform.viewInverse,
|
deferredTransform.viewInverse,
|
||||||
shadowAttenuation,
|
shadowAttenuation,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include DeferredBuffer.slh@>
|
<@include DeferredBufferRead.slh@>
|
||||||
<@include DeferredGlobalLight.slh@>
|
<@include DeferredGlobalLight.slh@>
|
||||||
|
|
||||||
<$declareEvalLightmappedColor()$>
|
<$declareEvalLightmappedColor()$>
|
||||||
|
@ -28,7 +28,9 @@ void main(void) {
|
||||||
float shadowAttenuation = 1.0;
|
float shadowAttenuation = 1.0;
|
||||||
|
|
||||||
// Light mapped or not ?
|
// Light mapped or not ?
|
||||||
if (frag.mode == LIGHT_MAPPED) {
|
if (frag.mode == FRAG_MODE_UNLIT) {
|
||||||
|
_fragColor = vec4(frag.diffuse, 1.0);
|
||||||
|
} else if (frag.mode == FRAG_MODE_LIGHTMAPPED) {
|
||||||
vec3 color = evalLightmappedColor(
|
vec3 color = evalLightmappedColor(
|
||||||
deferredTransform.viewInverse,
|
deferredTransform.viewInverse,
|
||||||
shadowAttenuation,
|
shadowAttenuation,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//!>
|
//!>
|
||||||
|
|
||||||
<@include Shadow.slh@>
|
<@include Shadow.slh@>
|
||||||
<@include DeferredBuffer.slh@>
|
<@include DeferredBufferRead.slh@>
|
||||||
<@include DeferredGlobalLight.slh@>
|
<@include DeferredGlobalLight.slh@>
|
||||||
|
|
||||||
<$declareEvalLightmappedColor()$>
|
<$declareEvalLightmappedColor()$>
|
||||||
|
@ -30,7 +30,9 @@ void main(void) {
|
||||||
float shadowAttenuation = evalShadowAttenuation(worldPos);
|
float shadowAttenuation = evalShadowAttenuation(worldPos);
|
||||||
|
|
||||||
// Light mapped or not ?
|
// Light mapped or not ?
|
||||||
if (frag.mode == LIGHT_MAPPED) {
|
if (frag.mode == FRAG_MODE_UNLIT) {
|
||||||
|
_fragColor = vec4(frag.diffuse, 1.0);
|
||||||
|
} else if (frag.mode == FRAG_MODE_LIGHTMAPPED) {
|
||||||
vec3 color = evalLightmappedColor(
|
vec3 color = evalLightmappedColor(
|
||||||
deferredTransform.viewInverse,
|
deferredTransform.viewInverse,
|
||||||
shadowAttenuation,
|
shadowAttenuation,
|
||||||
|
|
|
@ -30,7 +30,7 @@ void main(void) {
|
||||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
||||||
|
|
||||||
float opacity = 1.0;
|
float opacity = 1.0;
|
||||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>;
|
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||||
<$discardTransparent(opacity)$>;
|
<$discardTransparent(opacity)$>;
|
||||||
|
|
||||||
vec3 albedo = getMaterialAlbedo(mat);
|
vec3 albedo = getMaterialAlbedo(mat);
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
<@include gpu/Config.slh@>
|
|
||||||
<$VERSION_HEADER$>
|
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
|
||||||
//
|
|
||||||
// model_emissive.frag
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
// Created by Zach Pomerantz on 2/3/2016.
|
|
||||||
// Copyright 2016 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
<@include DeferredBufferWrite.slh@>
|
|
||||||
<@include model/Material.slh@>
|
|
||||||
|
|
||||||
uniform sampler2D albedoMap;
|
|
||||||
|
|
||||||
in vec2 _texCoord0;
|
|
||||||
in vec3 _normal;
|
|
||||||
in vec3 _color;
|
|
||||||
in float _alpha;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
vec4 texel = texture(albedoMap, _texCoord0);
|
|
||||||
|
|
||||||
Material mat = getMaterial();
|
|
||||||
vec3 fragColor = getMaterialAlbedo(mat) * texel.rgb * _color;
|
|
||||||
|
|
||||||
packDeferredFragmentLightmap(
|
|
||||||
normalize(_normal),
|
|
||||||
texel.a,
|
|
||||||
vec3(1.0),
|
|
||||||
getMaterialRoughness(mat),
|
|
||||||
getMaterialMetallic(mat),
|
|
||||||
getMaterialFresnel(mat),
|
|
||||||
fragColor);
|
|
||||||
}
|
|
|
@ -31,7 +31,7 @@ void main(void) {
|
||||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
||||||
|
|
||||||
float opacity = 1.0;
|
float opacity = 1.0;
|
||||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>;
|
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||||
<$discardTransparent(opacity)$>;
|
<$discardTransparent(opacity)$>;
|
||||||
|
|
||||||
vec3 albedo = getMaterialAlbedo(mat);
|
vec3 albedo = getMaterialAlbedo(mat);
|
||||||
|
|
|
@ -31,7 +31,7 @@ void main(void) {
|
||||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, occlusionTex)$>
|
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, occlusionTex)$>
|
||||||
|
|
||||||
float opacity = 1.0;
|
float opacity = 1.0;
|
||||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>;
|
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||||
<$discardTransparent(opacity)$>;
|
<$discardTransparent(opacity)$>;
|
||||||
|
|
||||||
vec3 albedo = getMaterialAlbedo(mat);
|
vec3 albedo = getMaterialAlbedo(mat);
|
||||||
|
|
|
@ -38,8 +38,7 @@ void main(void) {
|
||||||
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex, occlusionTex)$>
|
||||||
|
|
||||||
float opacity = getMaterialOpacity(mat) * _alpha;
|
float opacity = getMaterialOpacity(mat) * _alpha;
|
||||||
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>;
|
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||||
<$discardTransparent(opacity)$>;
|
|
||||||
|
|
||||||
vec3 albedo = getMaterialAlbedo(mat);
|
vec3 albedo = getMaterialAlbedo(mat);
|
||||||
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
<@include gpu/Config.slh@>
|
|
||||||
<$VERSION_HEADER$>
|
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
|
||||||
//
|
|
||||||
// model_translucent_emissive.frag
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
// Created by Zach Pomerantz on 2/3/2016.
|
|
||||||
// Copyright 2016 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
<@include model/Material.slh@>
|
|
||||||
|
|
||||||
uniform sampler2D albedoMap;
|
|
||||||
|
|
||||||
in vec2 _texCoord0;
|
|
||||||
in vec3 _color;
|
|
||||||
in float _alpha;
|
|
||||||
|
|
||||||
out vec4 _fragColor;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
vec4 albedo = texture(albedoMap, _texCoord0);
|
|
||||||
|
|
||||||
Material mat = getMaterial();
|
|
||||||
vec3 fragColor = getMaterialAlbedo(mat) * albedo.rgb * _color;
|
|
||||||
float fragOpacity = getMaterialOpacity(mat) * albedo.a * _alpha;
|
|
||||||
|
|
||||||
_fragColor = vec4(fragColor, fragOpacity);
|
|
||||||
}
|
|
39
libraries/render-utils/src/model_translucent_unlit.slf
Normal file
39
libraries/render-utils/src/model_translucent_unlit.slf
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// model_translucent_unlit.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Zach Pomerantz on 2/3/2016.
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
|
<@include MaterialTextures.slh@>
|
||||||
|
<$declareMaterialTextures(ALBEDO, ROUGHNESS, _SCRIBE_NULL, _SCRIBE_NULL, EMISSIVE, OCCLUSION)$>
|
||||||
|
|
||||||
|
in vec2 _texCoord0;
|
||||||
|
in vec3 _color;
|
||||||
|
in float _alpha;
|
||||||
|
|
||||||
|
out vec4 _fragColor;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
Material mat = getMaterial();
|
||||||
|
int matKey = getMaterialKey(mat);
|
||||||
|
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$>
|
||||||
|
|
||||||
|
float opacity = getMaterialOpacity(mat) * _alpha;
|
||||||
|
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||||
|
|
||||||
|
vec3 albedo = getMaterialAlbedo(mat);
|
||||||
|
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||||
|
albedo *= _color;
|
||||||
|
|
||||||
|
_fragColor = vec4(albedo, opacity);
|
||||||
|
}
|
44
libraries/render-utils/src/model_unlit.slf
Normal file
44
libraries/render-utils/src/model_unlit.slf
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// material_opaque_unlit.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 5/5/2016.
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
<@include DeferredBufferWrite.slh@>
|
||||||
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
|
<@include MaterialTextures.slh@>
|
||||||
|
<$declareMaterialTextures(ALBEDO, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$>
|
||||||
|
|
||||||
|
in vec2 _texCoord0;
|
||||||
|
in vec3 _normal;
|
||||||
|
in vec3 _color;
|
||||||
|
in float _alpha;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
|
||||||
|
Material mat = getMaterial();
|
||||||
|
int matKey = getMaterialKey(mat);
|
||||||
|
<$fetchMaterialTextures(matKey, _texCoord0, albedoTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL)$>
|
||||||
|
|
||||||
|
float opacity = 1.0;
|
||||||
|
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
|
||||||
|
<$discardTransparent(opacity)$>;
|
||||||
|
|
||||||
|
vec3 albedo = getMaterialAlbedo(mat);
|
||||||
|
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
|
||||||
|
albedo *= _color;
|
||||||
|
|
||||||
|
packDeferredFragmentUnlit(
|
||||||
|
normalize(_normal),
|
||||||
|
opacity,
|
||||||
|
albedo);
|
||||||
|
}
|
|
@ -71,6 +71,7 @@ void main(void) {
|
||||||
fragRoughness,
|
fragRoughness,
|
||||||
fragOpacity);
|
fragOpacity);
|
||||||
|
|
||||||
|
|
||||||
// Apply standard tone mapping
|
// Apply standard tone mapping
|
||||||
_fragColor = vec4(pow(color.xyz, vec3(1.0 / 2.2)), color.w);
|
_fragColor = vec4(pow(color.xyz, vec3(1.0 / 2.2)), color.w);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<$VERSION_HEADER$>
|
<$VERSION_HEADER$>
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
//
|
//
|
||||||
// overlay3D_translucent_emissive.frag
|
// overlay3D_translucent_unlit.frag
|
||||||
// fragment shader
|
// fragment shader
|
||||||
//
|
//
|
||||||
// Created by Zach Pomerantz on 2/2/2016.
|
// Created by Zach Pomerantz on 2/2/2016.
|
|
@ -2,7 +2,7 @@
|
||||||
<$VERSION_HEADER$>
|
<$VERSION_HEADER$>
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
//
|
//
|
||||||
// overlay3D_emissive.frag
|
// overlay3D_unlit.frag
|
||||||
// fragment shader
|
// fragment shader
|
||||||
//
|
//
|
||||||
// Created by Zach Pomerantz on 2/2/2016.
|
// Created by Zach Pomerantz on 2/2/2016.
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
// Everything about deferred buffer
|
// Everything about deferred buffer
|
||||||
<@include DeferredBuffer.slh@>
|
<@include DeferredBufferRead.slh@>
|
||||||
|
|
||||||
//Everything about deferred lighting
|
//Everything about deferred lighting
|
||||||
<@include DeferredLighting.slh@>
|
<@include DeferredLighting.slh@>
|
||||||
|
@ -32,6 +32,10 @@ void main(void) {
|
||||||
vec2 texCoord = _texCoord0.st / _texCoord0.q;
|
vec2 texCoord = _texCoord0.st / _texCoord0.q;
|
||||||
DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord);
|
DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord);
|
||||||
|
|
||||||
|
if (frag.mode == FRAG_MODE_UNLIT) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
mat4 invViewMat = deferredTransform.viewInverse;
|
mat4 invViewMat = deferredTransform.viewInverse;
|
||||||
|
|
||||||
// Kill if in front of the light volume
|
// Kill if in front of the light volume
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
in vec3 _normal;
|
in vec3 _normal;
|
||||||
in vec3 _modelNormal;
|
in vec3 _modelNormal;
|
||||||
in vec3 _color;
|
in vec4 _color;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
in vec4 _position;
|
in vec4 _position;
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,12 @@
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
out vec3 _normal;
|
out vec3 _normal;
|
||||||
out vec3 _modelNormal;
|
out vec3 _modelNormal;
|
||||||
out vec3 _color;
|
out vec4 _color;
|
||||||
out vec2 _texCoord0;
|
out vec2 _texCoord0;
|
||||||
out vec4 _position;
|
out vec4 _position;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
_color = colorToLinearRGB(inColor.rgb);
|
_color = colorToLinearRGBA(inColor);
|
||||||
_texCoord0 = inTexCoord0.st;
|
_texCoord0 = inTexCoord0.st;
|
||||||
_position = inPosition;
|
_position = inPosition;
|
||||||
_modelNormal = inNormal.xyz;
|
_modelNormal = inNormal.xyz;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
<@include gpu/Color.slh@>
|
||||||
<@include DeferredBufferWrite.slh@>
|
<@include DeferredBufferWrite.slh@>
|
||||||
<@include model/Material.slh@>
|
<@include model/Material.slh@>
|
||||||
|
|
||||||
|
@ -20,13 +21,14 @@ uniform sampler2D originalTexture;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
in vec3 _normal;
|
in vec3 _normal;
|
||||||
in vec3 _color;
|
in vec4 _color;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
Material material = getMaterial();
|
|
||||||
vec4 texel = texture(originalTexture, _texCoord0);
|
vec4 texel = texture(originalTexture, _texCoord0);
|
||||||
|
if (_color.a <= 0.0) {
|
||||||
|
texel = colorToLinearRGBA(texel);
|
||||||
|
}
|
||||||
packDeferredFragment(
|
packDeferredFragment(
|
||||||
normalize(_normal.xyz),
|
normalize(_normal.xyz),
|
||||||
texel.a,
|
texel.a,
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
<@include gpu/Color.slh@>
|
||||||
<@include DeferredBufferWrite.slh@>
|
<@include DeferredBufferWrite.slh@>
|
||||||
|
|
||||||
// the albedo texture
|
// the albedo texture
|
||||||
|
@ -19,18 +20,17 @@ uniform sampler2D originalTexture;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
in vec3 _normal;
|
in vec3 _normal;
|
||||||
in vec3 _color;
|
in vec4 _color;
|
||||||
in vec2 _texCoord0;
|
in vec2 _texCoord0;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 texel = texture(originalTexture, _texCoord0.st);
|
vec4 texel = texture(originalTexture, _texCoord0.st);
|
||||||
|
if (_color.a <= 0.0) {
|
||||||
|
texel = colorToLinearRGBA(texel);
|
||||||
|
}
|
||||||
|
|
||||||
packDeferredFragmentLightmap(
|
packDeferredFragmentUnlit(
|
||||||
normalize(_normal),
|
normalize(_normal),
|
||||||
texel.a,
|
texel.a,
|
||||||
_color.rgb,
|
_color.rgb * texel.rgb);
|
||||||
DEFAULT_ROUGHNESS,
|
|
||||||
DEFAULT_METALLIC,
|
|
||||||
DEFAULT_SPECULAR,
|
|
||||||
texel.rgb);
|
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
// Everything about deferred buffer
|
// Everything about deferred buffer
|
||||||
<@include DeferredBuffer.slh@>
|
<@include DeferredBufferRead.slh@>
|
||||||
|
|
||||||
//Everything about deferred lighting
|
//Everything about deferred lighting
|
||||||
<@include DeferredLighting.slh@>
|
<@include DeferredLighting.slh@>
|
||||||
|
@ -32,6 +32,10 @@ void main(void) {
|
||||||
vec2 texCoord = _texCoord0.st / _texCoord0.q;
|
vec2 texCoord = _texCoord0.st / _texCoord0.q;
|
||||||
DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord);
|
DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord);
|
||||||
|
|
||||||
|
if (frag.mode == FRAG_MODE_UNLIT) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
mat4 invViewMat = deferredTransform.viewInverse;
|
mat4 invViewMat = deferredTransform.viewInverse;
|
||||||
|
|
||||||
// Kill if in front of the light volume
|
// Kill if in front of the light volume
|
||||||
|
|
|
@ -116,35 +116,25 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
||||||
// FIrst thing, we collect the bound and the status for all the items we want to render
|
// FIrst thing, we collect the bound and the status for all the items we want to render
|
||||||
int nbItems = 0;
|
int nbItems = 0;
|
||||||
{
|
{
|
||||||
if (!_itemBounds) {
|
_itemBounds.resize(inItems.size());
|
||||||
_itemBounds = std::make_shared<gpu::Buffer>();
|
_itemStatus.resize(inItems.size());
|
||||||
}
|
_itemCells.resize(inItems.size());
|
||||||
if (!_itemStatus) {
|
|
||||||
_itemStatus = std::make_shared<gpu::Buffer>();;
|
|
||||||
}
|
|
||||||
if (!_itemCells) {
|
|
||||||
_itemCells = std::make_shared<gpu::Buffer>();;
|
|
||||||
}
|
|
||||||
|
|
||||||
_itemBounds->resize((inItems.size() * sizeof(AABox)));
|
// AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
||||||
_itemStatus->resize((inItems.size() * NUM_STATUS_VEC4_PER_ITEM * sizeof(glm::vec4)));
|
// glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
||||||
_itemCells->resize((inItems.size() * sizeof(Octree::Location)));
|
// Octree::Location* itemCell = reinterpret_cast<Octree::Location*> (_itemCells->editData());
|
||||||
|
for (size_t i = 0; i < inItems.size(); ++i) {
|
||||||
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
const auto& item = inItems[i];
|
||||||
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
|
||||||
Octree::Location* itemCell = reinterpret_cast<Octree::Location*> (_itemCells->editData());
|
|
||||||
for (auto& item : inItems) {
|
|
||||||
if (!item.bound.isInvalid()) {
|
if (!item.bound.isInvalid()) {
|
||||||
if (!item.bound.isNull()) {
|
if (!item.bound.isNull()) {
|
||||||
(*itemAABox) = item.bound;
|
_itemBounds[i] = item.bound;
|
||||||
} else {
|
} else {
|
||||||
(*itemAABox).setBox(item.bound.getCorner(), 0.1f);
|
_itemBounds[i].setBox(item.bound.getCorner(), 0.1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto& itemScene = scene->getItem(item.id);
|
auto& itemScene = scene->getItem(item.id);
|
||||||
|
_itemCells[i] = scene->getSpatialTree().getCellLocation(itemScene.getCell());
|
||||||
(*itemCell) = scene->getSpatialTree().getCellLocation(itemScene.getCell());
|
|
||||||
|
|
||||||
auto itemStatusPointer = itemScene.getStatus();
|
auto itemStatusPointer = itemScene.getStatus();
|
||||||
if (itemStatusPointer) {
|
if (itemStatusPointer) {
|
||||||
|
@ -152,25 +142,19 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
||||||
auto&& currentStatusValues = itemStatusPointer->getCurrentValues();
|
auto&& currentStatusValues = itemStatusPointer->getCurrentValues();
|
||||||
int valueNum = 0;
|
int valueNum = 0;
|
||||||
for (int vec4Num = 0; vec4Num < NUM_STATUS_VEC4_PER_ITEM; vec4Num++) {
|
for (int vec4Num = 0; vec4Num < NUM_STATUS_VEC4_PER_ITEM; vec4Num++) {
|
||||||
(*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData());
|
auto& value = (vec4Num ? _itemStatus[i].first : _itemStatus[i].second);
|
||||||
|
value = glm::ivec4(Item::Status::Value::INVALID.getPackedData());
|
||||||
for (int component = 0; component < VEC4_LENGTH; component++) {
|
for (int component = 0; component < VEC4_LENGTH; component++) {
|
||||||
valueNum = vec4Num * VEC4_LENGTH + component;
|
valueNum = vec4Num * VEC4_LENGTH + component;
|
||||||
if (valueNum < (int)currentStatusValues.size()) {
|
if (valueNum < (int)currentStatusValues.size()) {
|
||||||
(*itemStatus)[component] = currentStatusValues[valueNum].getPackedData();
|
value[component] = currentStatusValues[valueNum].getPackedData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemStatus++;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData());
|
_itemStatus[i].first = _itemStatus[i].second = glm::ivec4(Item::Status::Value::INVALID.getPackedData());
|
||||||
itemStatus++;
|
|
||||||
(*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData());
|
|
||||||
itemStatus++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nbItems++;
|
nbItems++;
|
||||||
itemAABox++;
|
|
||||||
itemCell++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,25 +178,20 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
||||||
// bind the one gpu::Pipeline we need
|
// bind the one gpu::Pipeline we need
|
||||||
batch.setPipeline(getDrawItemBoundsPipeline());
|
batch.setPipeline(getDrawItemBoundsPipeline());
|
||||||
|
|
||||||
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
//AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
||||||
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
//glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
||||||
Octree::Location* itemCell = reinterpret_cast<Octree::Location*> (_itemCells->editData());
|
//Octree::Location* itemCell = reinterpret_cast<Octree::Location*> (_itemCells->editData());
|
||||||
|
|
||||||
const unsigned int VEC3_ADRESS_OFFSET = 3;
|
const unsigned int VEC3_ADRESS_OFFSET = 3;
|
||||||
|
|
||||||
if (_showDisplay) {
|
if (_showDisplay) {
|
||||||
for (int i = 0; i < nbItems; i++) {
|
for (int i = 0; i < nbItems; i++) {
|
||||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
|
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)&(_itemBounds[i]));
|
||||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*)&(_itemBounds[i])) + VEC3_ADRESS_OFFSET);
|
||||||
|
|
||||||
|
|
||||||
glm::ivec4 cellLocation(itemCell->pos.x, itemCell->pos.y, itemCell->pos.z, itemCell->depth);
|
|
||||||
|
|
||||||
|
glm::ivec4 cellLocation(_itemCells[i].pos, _itemCells[i].depth);
|
||||||
batch._glUniform4iv(_drawItemCellLocLoc, 1, ((const int*)(&cellLocation)));
|
batch._glUniform4iv(_drawItemCellLocLoc, 1, ((const int*)(&cellLocation)));
|
||||||
|
|
||||||
|
|
||||||
batch.draw(gpu::LINES, 24, 0);
|
batch.draw(gpu::LINES, 24, 0);
|
||||||
itemCell++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,10 +201,10 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
||||||
|
|
||||||
if (_showNetwork) {
|
if (_showNetwork) {
|
||||||
for (int i = 0; i < nbItems; i++) {
|
for (int i = 0; i < nbItems; i++) {
|
||||||
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i));
|
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*)&(_itemBounds[i]));
|
||||||
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*)&(_itemBounds[i])) + VEC3_ADRESS_OFFSET);
|
||||||
batch._glUniform4iv(_drawItemStatusValue0Loc, 1, (const int*)(itemStatus + NUM_STATUS_VEC4_PER_ITEM * i));
|
batch._glUniform4iv(_drawItemStatusValue0Loc, 1, (const int*)&(_itemStatus[i].first));
|
||||||
batch._glUniform4iv(_drawItemStatusValue1Loc, 1, (const int*)(itemStatus + NUM_STATUS_VEC4_PER_ITEM * i + 1));
|
batch._glUniform4iv(_drawItemStatusValue1Loc, 1, (const int*)&(_itemStatus[i].second));
|
||||||
batch.draw(gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM, 0);
|
batch.draw(gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,9 +68,13 @@ namespace render {
|
||||||
gpu::Stream::FormatPointer _drawItemFormat;
|
gpu::Stream::FormatPointer _drawItemFormat;
|
||||||
gpu::PipelinePointer _drawItemBoundsPipeline;
|
gpu::PipelinePointer _drawItemBoundsPipeline;
|
||||||
gpu::PipelinePointer _drawItemStatusPipeline;
|
gpu::PipelinePointer _drawItemStatusPipeline;
|
||||||
gpu::BufferPointer _itemBounds;
|
|
||||||
gpu::BufferPointer _itemCells;
|
std::vector<AABox> _itemBounds;
|
||||||
gpu::BufferPointer _itemStatus;
|
std::vector<std::pair<glm::ivec4, glm::ivec4>> _itemStatus;
|
||||||
|
std::vector<Octree::Location> _itemCells;
|
||||||
|
//gpu::BufferPointer _itemBounds;
|
||||||
|
//gpu::BufferPointer _itemCells;
|
||||||
|
//gpu::BufferPointer _itemStatus;
|
||||||
gpu::TexturePointer _statusIconMap;
|
gpu::TexturePointer _statusIconMap;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
LIGHTMAP,
|
LIGHTMAP,
|
||||||
TANGENTS,
|
TANGENTS,
|
||||||
SPECULAR,
|
SPECULAR,
|
||||||
EMISSIVE,
|
UNLIT,
|
||||||
SKINNED,
|
SKINNED,
|
||||||
STEREO,
|
STEREO,
|
||||||
DEPTH_ONLY,
|
DEPTH_ONLY,
|
||||||
|
@ -57,7 +57,7 @@ public:
|
||||||
Builder& withLightmap() { _flags.set(LIGHTMAP); return (*this); }
|
Builder& withLightmap() { _flags.set(LIGHTMAP); return (*this); }
|
||||||
Builder& withTangents() { _flags.set(TANGENTS); return (*this); }
|
Builder& withTangents() { _flags.set(TANGENTS); return (*this); }
|
||||||
Builder& withSpecular() { _flags.set(SPECULAR); return (*this); }
|
Builder& withSpecular() { _flags.set(SPECULAR); return (*this); }
|
||||||
Builder& withEmissive() { _flags.set(EMISSIVE); return (*this); }
|
Builder& withUnlit() { _flags.set(UNLIT); return (*this); }
|
||||||
Builder& withSkinned() { _flags.set(SKINNED); return (*this); }
|
Builder& withSkinned() { _flags.set(SKINNED); return (*this); }
|
||||||
Builder& withStereo() { _flags.set(STEREO); return (*this); }
|
Builder& withStereo() { _flags.set(STEREO); return (*this); }
|
||||||
Builder& withDepthOnly() { _flags.set(DEPTH_ONLY); return (*this); }
|
Builder& withDepthOnly() { _flags.set(DEPTH_ONLY); return (*this); }
|
||||||
|
@ -101,8 +101,8 @@ public:
|
||||||
Builder& withSpecular() { _flags.set(SPECULAR); _mask.set(SPECULAR); return (*this); }
|
Builder& withSpecular() { _flags.set(SPECULAR); _mask.set(SPECULAR); return (*this); }
|
||||||
Builder& withoutSpecular() { _flags.reset(SPECULAR); _mask.set(SPECULAR); return (*this); }
|
Builder& withoutSpecular() { _flags.reset(SPECULAR); _mask.set(SPECULAR); return (*this); }
|
||||||
|
|
||||||
Builder& withEmissive() { _flags.set(EMISSIVE); _mask.set(EMISSIVE); return (*this); }
|
Builder& withUnlit() { _flags.set(UNLIT); _mask.set(UNLIT); return (*this); }
|
||||||
Builder& withoutEmissive() { _flags.reset(EMISSIVE); _mask.set(EMISSIVE); return (*this); }
|
Builder& withoutUnlit() { _flags.reset(UNLIT); _mask.set(UNLIT); return (*this); }
|
||||||
|
|
||||||
Builder& withSkinned() { _flags.set(SKINNED); _mask.set(SKINNED); return (*this); }
|
Builder& withSkinned() { _flags.set(SKINNED); _mask.set(SKINNED); return (*this); }
|
||||||
Builder& withoutSkinned() { _flags.reset(SKINNED); _mask.set(SKINNED); return (*this); }
|
Builder& withoutSkinned() { _flags.reset(SKINNED); _mask.set(SKINNED); return (*this); }
|
||||||
|
@ -137,7 +137,7 @@ public:
|
||||||
bool hasLightmap() const { return _flags[LIGHTMAP]; }
|
bool hasLightmap() const { return _flags[LIGHTMAP]; }
|
||||||
bool hasTangents() const { return _flags[TANGENTS]; }
|
bool hasTangents() const { return _flags[TANGENTS]; }
|
||||||
bool hasSpecular() const { return _flags[SPECULAR]; }
|
bool hasSpecular() const { return _flags[SPECULAR]; }
|
||||||
bool hasEmissive() const { return _flags[EMISSIVE]; }
|
bool isUnlit() const { return _flags[UNLIT]; }
|
||||||
bool isTranslucent() const { return _flags[TRANSLUCENT]; }
|
bool isTranslucent() const { return _flags[TRANSLUCENT]; }
|
||||||
bool isSkinned() const { return _flags[SKINNED]; }
|
bool isSkinned() const { return _flags[SKINNED]; }
|
||||||
bool isStereo() const { return _flags[STEREO]; }
|
bool isStereo() const { return _flags[STEREO]; }
|
||||||
|
@ -173,7 +173,7 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& key) {
|
||||||
<< "hasLightmap:" << key.hasLightmap()
|
<< "hasLightmap:" << key.hasLightmap()
|
||||||
<< "hasTangents:" << key.hasTangents()
|
<< "hasTangents:" << key.hasTangents()
|
||||||
<< "hasSpecular:" << key.hasSpecular()
|
<< "hasSpecular:" << key.hasSpecular()
|
||||||
<< "hasEmissive:" << key.hasEmissive()
|
<< "isUnlit:" << key.isUnlit()
|
||||||
<< "isTranslucent:" << key.isTranslucent()
|
<< "isTranslucent:" << key.isTranslucent()
|
||||||
<< "isSkinned:" << key.isSkinned()
|
<< "isSkinned:" << key.isSkinned()
|
||||||
<< "isStereo:" << key.isStereo()
|
<< "isStereo:" << key.isStereo()
|
||||||
|
|
|
@ -62,8 +62,6 @@
|
||||||
|
|
||||||
#include "MIDIEvent.h"
|
#include "MIDIEvent.h"
|
||||||
|
|
||||||
std::atomic<bool> ScriptEngine::_stoppingAllScripts { false };
|
|
||||||
|
|
||||||
static const QString SCRIPT_EXCEPTION_FORMAT = "[UncaughtException] %1 in %2:%3";
|
static const QString SCRIPT_EXCEPTION_FORMAT = "[UncaughtException] %1 in %2:%3";
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QScriptEngine::FunctionSignature)
|
Q_DECLARE_METATYPE(QScriptEngine::FunctionSignature)
|
||||||
|
@ -762,7 +760,7 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString&
|
||||||
|
|
||||||
|
|
||||||
QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fileName, int lineNumber) {
|
QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fileName, int lineNumber) {
|
||||||
if (_stoppingAllScripts) {
|
if (DependencyManager::get<ScriptEngines>()->isStopped()) {
|
||||||
return QScriptValue(); // bail early
|
return QScriptValue(); // bail early
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,7 +794,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::run() {
|
void ScriptEngine::run() {
|
||||||
if (_stoppingAllScripts) {
|
if (DependencyManager::get<ScriptEngines>()->isStopped()) {
|
||||||
return; // bail early - avoid setting state in init(), as evaluate() will bail too
|
return; // bail early - avoid setting state in init(), as evaluate() will bail too
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,7 +1013,7 @@ QObject* ScriptEngine::setupTimerWithInterval(const QScriptValue& function, int
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) {
|
QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) {
|
||||||
if (_stoppingAllScripts) {
|
if (DependencyManager::get<ScriptEngines>()->isStopped()) {
|
||||||
qCDebug(scriptengine) << "Script.setInterval() while shutting down is ignored... parent script:" << getFilename();
|
qCDebug(scriptengine) << "Script.setInterval() while shutting down is ignored... parent script:" << getFilename();
|
||||||
return NULL; // bail early
|
return NULL; // bail early
|
||||||
}
|
}
|
||||||
|
@ -1024,7 +1022,7 @@ QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS)
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject* ScriptEngine::setTimeout(const QScriptValue& function, int timeoutMS) {
|
QObject* ScriptEngine::setTimeout(const QScriptValue& function, int timeoutMS) {
|
||||||
if (_stoppingAllScripts) {
|
if (DependencyManager::get<ScriptEngines>()->isStopped()) {
|
||||||
qCDebug(scriptengine) << "Script.setTimeout() while shutting down is ignored... parent script:" << getFilename();
|
qCDebug(scriptengine) << "Script.setTimeout() while shutting down is ignored... parent script:" << getFilename();
|
||||||
return NULL; // bail early
|
return NULL; // bail early
|
||||||
}
|
}
|
||||||
|
@ -1074,7 +1072,7 @@ void ScriptEngine::print(const QString& message) {
|
||||||
// If no callback is specified, the included files will be loaded synchronously and will block execution until
|
// If no callback is specified, the included files will be loaded synchronously and will block execution until
|
||||||
// all of the files have finished loading.
|
// all of the files have finished loading.
|
||||||
void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callback) {
|
void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callback) {
|
||||||
if (_stoppingAllScripts) {
|
if (DependencyManager::get<ScriptEngines>()->isStopped()) {
|
||||||
qCDebug(scriptengine) << "Script.include() while shutting down is ignored..."
|
qCDebug(scriptengine) << "Script.include() while shutting down is ignored..."
|
||||||
<< "includeFiles:" << includeFiles << "parent script:" << getFilename();
|
<< "includeFiles:" << includeFiles << "parent script:" << getFilename();
|
||||||
return; // bail early
|
return; // bail early
|
||||||
|
@ -1172,7 +1170,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::include(const QString& includeFile, QScriptValue callback) {
|
void ScriptEngine::include(const QString& includeFile, QScriptValue callback) {
|
||||||
if (_stoppingAllScripts) {
|
if (DependencyManager::get<ScriptEngines>()->isStopped()) {
|
||||||
qCDebug(scriptengine) << "Script.include() while shutting down is ignored... "
|
qCDebug(scriptengine) << "Script.include() while shutting down is ignored... "
|
||||||
<< "includeFile:" << includeFile << "parent script:" << getFilename();
|
<< "includeFile:" << includeFile << "parent script:" << getFilename();
|
||||||
return; // bail early
|
return; // bail early
|
||||||
|
@ -1187,7 +1185,7 @@ void ScriptEngine::include(const QString& includeFile, QScriptValue callback) {
|
||||||
// as a stand-alone script. To accomplish this, the ScriptEngine class just emits a signal which
|
// as a stand-alone script. To accomplish this, the ScriptEngine class just emits a signal which
|
||||||
// the Application or other context will connect to in order to know to actually load the script
|
// the Application or other context will connect to in order to know to actually load the script
|
||||||
void ScriptEngine::load(const QString& loadFile) {
|
void ScriptEngine::load(const QString& loadFile) {
|
||||||
if (_stoppingAllScripts) {
|
if (DependencyManager::get<ScriptEngines>()->isStopped()) {
|
||||||
qCDebug(scriptengine) << "Script.load() while shutting down is ignored... "
|
qCDebug(scriptengine) << "Script.load() while shutting down is ignored... "
|
||||||
<< "loadFile:" << loadFile << "parent script:" << getFilename();
|
<< "loadFile:" << loadFile << "parent script:" << getFilename();
|
||||||
return; // bail early
|
return; // bail early
|
||||||
|
|
|
@ -80,6 +80,8 @@ public:
|
||||||
/// run the script in the callers thread, exit when stop() is called.
|
/// run the script in the callers thread, exit when stop() is called.
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
QString getFilename() const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts
|
// NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts
|
||||||
Q_INVOKABLE void stop();
|
Q_INVOKABLE void stop();
|
||||||
|
@ -198,7 +200,6 @@ protected:
|
||||||
qint64 _lastUpdate;
|
qint64 _lastUpdate;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
QString getFilename() const;
|
|
||||||
|
|
||||||
bool evaluatePending() const { return _evaluatesPending > 0; }
|
bool evaluatePending() const { return _evaluatesPending > 0; }
|
||||||
void timerFired();
|
void timerFired();
|
||||||
|
@ -231,9 +232,6 @@ protected:
|
||||||
QUrl currentSandboxURL {}; // The toplevel url string for the entity script that loaded the code being executed, else empty.
|
QUrl currentSandboxURL {}; // The toplevel url string for the entity script that loaded the code being executed, else empty.
|
||||||
void doWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, std::function<void()> operation);
|
void doWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, std::function<void()> operation);
|
||||||
void callWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, QScriptValue function, QScriptValue thisObject, QScriptValueList args);
|
void callWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, QScriptValue function, QScriptValue thisObject, QScriptValueList args);
|
||||||
|
|
||||||
friend class ScriptEngines;
|
|
||||||
static std::atomic<bool> _stoppingAllScripts;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ScriptEngine_h
|
#endif // hifi_ScriptEngine_h
|
||||||
|
|
|
@ -119,26 +119,27 @@ void ScriptEngines::registerScriptInitializer(ScriptInitializer initializer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngines::addScriptEngine(ScriptEngine* engine) {
|
void ScriptEngines::addScriptEngine(ScriptEngine* engine) {
|
||||||
_allScriptsMutex.lock();
|
if (_isStopped) {
|
||||||
_allKnownScriptEngines.insert(engine);
|
engine->deleteLater();
|
||||||
_allScriptsMutex.unlock();
|
} else {
|
||||||
|
QMutexLocker locker(&_allScriptsMutex);
|
||||||
|
_allKnownScriptEngines.insert(engine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngines::removeScriptEngine(ScriptEngine* engine) {
|
void ScriptEngines::removeScriptEngine(ScriptEngine* engine) {
|
||||||
// If we're not already in the middle of stopping all scripts, then we should remove ourselves
|
// If we're not already in the middle of stopping all scripts, then we should remove ourselves
|
||||||
// from the list of running scripts. We don't do this if we're in the process of stopping all scripts
|
// from the list of running scripts. We don't do this if we're in the process of stopping all scripts
|
||||||
// because that method removes scripts from its list as it iterates them
|
// because that method removes scripts from its list as it iterates them
|
||||||
if (!_stoppingAllScripts) {
|
if (!_isStopped) {
|
||||||
_allScriptsMutex.lock();
|
QMutexLocker locker(&_allScriptsMutex);
|
||||||
_allKnownScriptEngines.remove(engine);
|
_allKnownScriptEngines.remove(engine);
|
||||||
_allScriptsMutex.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngines::shutdownScripting() {
|
void ScriptEngines::shutdownScripting() {
|
||||||
_allScriptsMutex.lock();
|
_isStopped = true;
|
||||||
_stoppingAllScripts = true;
|
QMutexLocker locker(&_allScriptsMutex);
|
||||||
ScriptEngine::_stoppingAllScripts = true;
|
|
||||||
qCDebug(scriptengine) << "Stopping all scripts.... currently known scripts:" << _allKnownScriptEngines.size();
|
qCDebug(scriptengine) << "Stopping all scripts.... currently known scripts:" << _allKnownScriptEngines.size();
|
||||||
|
|
||||||
QMutableSetIterator<ScriptEngine*> i(_allKnownScriptEngines);
|
QMutableSetIterator<ScriptEngine*> i(_allKnownScriptEngines);
|
||||||
|
@ -174,8 +175,6 @@ void ScriptEngines::shutdownScripting() {
|
||||||
i.remove();
|
i.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_stoppingAllScripts = false;
|
|
||||||
_allScriptsMutex.unlock();
|
|
||||||
qCDebug(scriptengine) << "DONE Stopping all scripts....";
|
qCDebug(scriptengine) << "DONE Stopping all scripts....";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +498,6 @@ void ScriptEngines::launchScriptEngine(ScriptEngine* scriptEngine) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScriptEngines::onScriptFinished(const QString& rawScriptURL, ScriptEngine* engine) {
|
void ScriptEngines::onScriptFinished(const QString& rawScriptURL, ScriptEngine* engine) {
|
||||||
bool removed = false;
|
bool removed = false;
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,16 +86,17 @@ protected:
|
||||||
void onScriptEngineLoaded(const QString& scriptFilename);
|
void onScriptEngineLoaded(const QString& scriptFilename);
|
||||||
void onScriptEngineError(const QString& scriptFilename);
|
void onScriptEngineError(const QString& scriptFilename);
|
||||||
void launchScriptEngine(ScriptEngine* engine);
|
void launchScriptEngine(ScriptEngine* engine);
|
||||||
|
bool isStopped() const { return _isStopped; }
|
||||||
|
|
||||||
QReadWriteLock _scriptEnginesHashLock;
|
QReadWriteLock _scriptEnginesHashLock;
|
||||||
QHash<QUrl, ScriptEngine*> _scriptEnginesHash;
|
QHash<QUrl, ScriptEngine*> _scriptEnginesHash;
|
||||||
QSet<ScriptEngine*> _allKnownScriptEngines;
|
QSet<ScriptEngine*> _allKnownScriptEngines;
|
||||||
QMutex _allScriptsMutex;
|
QMutex _allScriptsMutex;
|
||||||
std::atomic<bool> _stoppingAllScripts { false };
|
|
||||||
std::list<ScriptInitializer> _scriptInitializers;
|
std::list<ScriptInitializer> _scriptInitializers;
|
||||||
mutable Setting::Handle<QString> _scriptsLocationHandle;
|
mutable Setting::Handle<QString> _scriptsLocationHandle;
|
||||||
ScriptsModel _scriptsModel;
|
ScriptsModel _scriptsModel;
|
||||||
ScriptsModelFilter _scriptsModelFilter;
|
ScriptsModelFilter _scriptsModelFilter;
|
||||||
|
std::atomic<bool> _isStopped { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
QUrl normalizeScriptURL(const QUrl& rawScriptURL);
|
QUrl normalizeScriptURL(const QUrl& rawScriptURL);
|
||||||
|
|
|
@ -33,6 +33,7 @@ Column {
|
||||||
"Roughness",
|
"Roughness",
|
||||||
"Metallic",
|
"Metallic",
|
||||||
"Emissive",
|
"Emissive",
|
||||||
|
"Shaded/Lightmapped/Unlit",
|
||||||
"Occlusion",
|
"Occlusion",
|
||||||
"Lightmap",
|
"Lightmap",
|
||||||
"Lighting",
|
"Lighting",
|
||||||
|
|
|
@ -262,6 +262,14 @@ eventMapping.from(Controller.Standard.LeftPrimaryThumb).peek().to(goActive);
|
||||||
eventMapping.from(Controller.Standard.RightPrimaryThumb).peek().to(goActive);
|
eventMapping.from(Controller.Standard.RightPrimaryThumb).peek().to(goActive);
|
||||||
eventMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(goActive);
|
eventMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(goActive);
|
||||||
eventMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(goActive);
|
eventMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(goActive);
|
||||||
|
eventMapping.from(Controller.Standard.LT).peek().to(goActive);
|
||||||
|
eventMapping.from(Controller.Standard.LB).peek().to(goActive);
|
||||||
|
eventMapping.from(Controller.Standard.LS).peek().to(goActive);
|
||||||
|
eventMapping.from(Controller.Standard.RT).peek().to(goActive);
|
||||||
|
eventMapping.from(Controller.Standard.RB).peek().to(goActive);
|
||||||
|
eventMapping.from(Controller.Standard.RS).peek().to(goActive);
|
||||||
|
eventMapping.from(Controller.Standard.Back).peek().to(goActive);
|
||||||
|
eventMapping.from(Controller.Standard.Start).peek().to(goActive);
|
||||||
Controller.enableMapping(eventMappingName);
|
Controller.enableMapping(eventMappingName);
|
||||||
|
|
||||||
Script.scriptEnding.connect(function () {
|
Script.scriptEnding.connect(function () {
|
||||||
|
|
|
@ -739,6 +739,9 @@ function MyController(hand) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.propsArePhysical = function(props) {
|
this.propsArePhysical = function(props) {
|
||||||
|
if (!props.dynamic) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
var isPhysical = (props.shapeType && props.shapeType != 'none');
|
var isPhysical = (props.shapeType && props.shapeType != 'none');
|
||||||
return isPhysical;
|
return isPhysical;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
var PopUpMenu = function(properties) {
|
var PopUpMenu = function (properties) {
|
||||||
var value = properties.value,
|
var value = properties.value,
|
||||||
promptOverlay,
|
promptOverlay,
|
||||||
valueOverlay,
|
valueOverlay,
|
||||||
|
@ -21,9 +21,8 @@ var PopUpMenu = function(properties) {
|
||||||
MIN_MAX_BUTTON_SVG_WIDTH = 17.1,
|
MIN_MAX_BUTTON_SVG_WIDTH = 17.1,
|
||||||
MIN_MAX_BUTTON_SVG_HEIGHT = 32.5,
|
MIN_MAX_BUTTON_SVG_HEIGHT = 32.5,
|
||||||
MIN_MAX_BUTTON_WIDTH = 14,
|
MIN_MAX_BUTTON_WIDTH = 14,
|
||||||
MIN_MAX_BUTTON_HEIGHT = MIN_MAX_BUTTON_WIDTH;
|
MIN_MAX_BUTTON_HEIGHT = MIN_MAX_BUTTON_WIDTH,
|
||||||
|
MIN_MAX_BUTTON_SVG = Script.resolvePath("assets/images/tools/min-max-toggle.svg");
|
||||||
MIN_MAX_BUTTON_SVG = Script.resolvePath("assets/images/tools/min-max-toggle.svg");
|
|
||||||
|
|
||||||
function positionDisplayOptions() {
|
function positionDisplayOptions() {
|
||||||
var y,
|
var y,
|
||||||
|
@ -203,7 +202,7 @@ var PopUpMenu = function(properties) {
|
||||||
width: MIN_MAX_BUTTON_SVG_WIDTH,
|
width: MIN_MAX_BUTTON_SVG_WIDTH,
|
||||||
height: MIN_MAX_BUTTON_SVG_HEIGHT / 2
|
height: MIN_MAX_BUTTON_SVG_HEIGHT / 2
|
||||||
},
|
},
|
||||||
color: properties.buttonColor,
|
//color: properties.buttonColor,
|
||||||
alpha: properties.buttonAlpha,
|
alpha: properties.buttonAlpha,
|
||||||
visible: properties.visible
|
visible: properties.visible
|
||||||
});
|
});
|
||||||
|
@ -218,11 +217,10 @@ var PopUpMenu = function(properties) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var usersWindow = (function() {
|
var usersWindow = (function () {
|
||||||
|
|
||||||
var baseURL = Script.resolvePath("assets/images/tools/");
|
var baseURL = Script.resolvePath("assets/images/tools/"),
|
||||||
|
WINDOW_WIDTH = 260,
|
||||||
var WINDOW_WIDTH = 260,
|
|
||||||
WINDOW_MARGIN = 12,
|
WINDOW_MARGIN = 12,
|
||||||
WINDOW_BASE_MARGIN = 6, // A little less is needed in order look correct
|
WINDOW_BASE_MARGIN = 6, // A little less is needed in order look correct
|
||||||
WINDOW_FONT = {
|
WINDOW_FONT = {
|
||||||
|
@ -248,6 +246,17 @@ var usersWindow = (function() {
|
||||||
WINDOW_BACKGROUND_ALPHA = 0.8,
|
WINDOW_BACKGROUND_ALPHA = 0.8,
|
||||||
windowPane,
|
windowPane,
|
||||||
windowHeading,
|
windowHeading,
|
||||||
|
|
||||||
|
// Window border is similar to that of edit.js.
|
||||||
|
WINDOW_BORDER_WIDTH = WINDOW_WIDTH + 2 * WINDOW_BASE_MARGIN,
|
||||||
|
WINDOW_BORDER_TOP_MARGIN = 2 * WINDOW_BASE_MARGIN,
|
||||||
|
WINDOW_BORDER_BOTTOM_MARGIN = WINDOW_BASE_MARGIN,
|
||||||
|
WINDOW_BORDER_LEFT_MARGIN = WINDOW_BASE_MARGIN,
|
||||||
|
WINDOW_BORDER_RADIUS = 4,
|
||||||
|
WINDOW_BORDER_COLOR = { red: 255, green: 255, blue: 255 },
|
||||||
|
WINDOW_BORDER_ALPHA = 0.5,
|
||||||
|
windowBorder,
|
||||||
|
|
||||||
MIN_MAX_BUTTON_SVG = baseURL + "min-max-toggle.svg",
|
MIN_MAX_BUTTON_SVG = baseURL + "min-max-toggle.svg",
|
||||||
MIN_MAX_BUTTON_SVG_WIDTH = 17.1,
|
MIN_MAX_BUTTON_SVG_WIDTH = 17.1,
|
||||||
MIN_MAX_BUTTON_SVG_HEIGHT = 32.5,
|
MIN_MAX_BUTTON_SVG_HEIGHT = 32.5,
|
||||||
|
@ -331,6 +340,7 @@ var usersWindow = (function() {
|
||||||
visibilityControl,
|
visibilityControl,
|
||||||
|
|
||||||
windowHeight,
|
windowHeight,
|
||||||
|
windowBorderHeight,
|
||||||
windowTextHeight,
|
windowTextHeight,
|
||||||
windowLineSpacing,
|
windowLineSpacing,
|
||||||
windowLineHeight, // = windowTextHeight + windowLineSpacing
|
windowLineHeight, // = windowTextHeight + windowLineSpacing
|
||||||
|
@ -356,14 +366,21 @@ var usersWindow = (function() {
|
||||||
MENU_ITEM_AFTER = "Chat...",
|
MENU_ITEM_AFTER = "Chat...",
|
||||||
|
|
||||||
SETTING_USERS_WINDOW_MINIMIZED = "UsersWindow.Minimized",
|
SETTING_USERS_WINDOW_MINIMIZED = "UsersWindow.Minimized",
|
||||||
|
SETINGS_USERS_WINDOW_OFFSET = "UsersWindow.Offset",
|
||||||
|
// +ve x, y values are offset from left, top of screen; -ve from right, bottom.
|
||||||
|
|
||||||
isVisible = true,
|
isVisible = true,
|
||||||
isMinimized = false,
|
isMinimized = false,
|
||||||
|
isBorderVisible = false,
|
||||||
|
|
||||||
viewportHeight,
|
viewport,
|
||||||
isMirrorDisplay = false,
|
isMirrorDisplay = false,
|
||||||
isFullscreenMirror = false,
|
isFullscreenMirror = false,
|
||||||
|
|
||||||
|
windowPosition = { }, // Bottom left corner of window pane.
|
||||||
|
isMovingWindow = false,
|
||||||
|
movingClickOffset = { x: 0, y: 0 },
|
||||||
|
|
||||||
isUsingScrollbars = false,
|
isUsingScrollbars = false,
|
||||||
isMovingScrollbar = false,
|
isMovingScrollbar = false,
|
||||||
scrollbarBackgroundPosition = {},
|
scrollbarBackgroundPosition = {},
|
||||||
|
@ -379,19 +396,23 @@ var usersWindow = (function() {
|
||||||
|
|
||||||
if (isMinimized) {
|
if (isMinimized) {
|
||||||
windowHeight = windowTextHeight + WINDOW_MARGIN + WINDOW_BASE_MARGIN;
|
windowHeight = windowTextHeight + WINDOW_MARGIN + WINDOW_BASE_MARGIN;
|
||||||
|
windowBorderHeight = windowHeight + WINDOW_BORDER_TOP_MARGIN + WINDOW_BORDER_BOTTOM_MARGIN;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve space for title, friends button, and option controls
|
// Reserve space for title, friends button, and option controls
|
||||||
nonUsersHeight = WINDOW_MARGIN + windowLineHeight + FRIENDS_BUTTON_SPACER + FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER + windowLineHeight + VISIBILITY_SPACER + windowLineHeight + WINDOW_BASE_MARGIN;
|
nonUsersHeight = WINDOW_MARGIN + windowLineHeight + FRIENDS_BUTTON_SPACER + FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER
|
||||||
|
+ windowLineHeight + VISIBILITY_SPACER
|
||||||
|
+ windowLineHeight + WINDOW_BASE_MARGIN;
|
||||||
|
|
||||||
// Limit window to height of viewport minus VU meter and mirror if displayed
|
// Limit window to height of viewport above window position minus VU meter and mirror if displayed
|
||||||
windowHeight = linesOfUsers.length * windowLineHeight - windowLineSpacing + nonUsersHeight;
|
windowHeight = linesOfUsers.length * windowLineHeight - windowLineSpacing + nonUsersHeight;
|
||||||
maxWindowHeight = viewportHeight - AUDIO_METER_HEIGHT;
|
maxWindowHeight = windowPosition.y - AUDIO_METER_HEIGHT;
|
||||||
if (isMirrorDisplay && !isFullscreenMirror) {
|
if (isMirrorDisplay && !isFullscreenMirror) {
|
||||||
maxWindowHeight -= MIRROR_HEIGHT;
|
maxWindowHeight -= MIRROR_HEIGHT;
|
||||||
}
|
}
|
||||||
windowHeight = Math.max(Math.min(windowHeight, maxWindowHeight), nonUsersHeight);
|
windowHeight = Math.max(Math.min(windowHeight, maxWindowHeight), nonUsersHeight);
|
||||||
|
windowBorderHeight = windowHeight + WINDOW_BORDER_TOP_MARGIN + WINDOW_BORDER_BOTTOM_MARGIN;
|
||||||
|
|
||||||
// Corresponding number of users to actually display
|
// Corresponding number of users to actually display
|
||||||
numUsersToDisplay = Math.max(Math.round((windowHeight - nonUsersHeight) / windowLineHeight), 0);
|
numUsersToDisplay = Math.max(Math.round((windowHeight - nonUsersHeight) / windowLineHeight), 0);
|
||||||
|
@ -405,38 +426,57 @@ var usersWindow = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateOverlayPositions() {
|
function updateOverlayPositions() {
|
||||||
var y;
|
// Overlay positions are all relative to windowPosition; windowPosition is the position of the windowPane overlay.
|
||||||
|
var windowLeft = windowPosition.x,
|
||||||
|
windowTop = windowPosition.y - windowHeight,
|
||||||
|
x,
|
||||||
|
y;
|
||||||
|
|
||||||
|
Overlays.editOverlay(windowBorder, {
|
||||||
|
x: windowPosition.x - WINDOW_BORDER_LEFT_MARGIN,
|
||||||
|
y: windowTop - WINDOW_BORDER_TOP_MARGIN
|
||||||
|
});
|
||||||
Overlays.editOverlay(windowPane, {
|
Overlays.editOverlay(windowPane, {
|
||||||
y: viewportHeight - windowHeight
|
x: windowLeft,
|
||||||
|
y: windowTop
|
||||||
});
|
});
|
||||||
Overlays.editOverlay(windowHeading, {
|
Overlays.editOverlay(windowHeading, {
|
||||||
y: viewportHeight - windowHeight + WINDOW_MARGIN
|
x: windowLeft + WINDOW_MARGIN,
|
||||||
|
y: windowTop + WINDOW_MARGIN
|
||||||
});
|
});
|
||||||
|
|
||||||
Overlays.editOverlay(minimizeButton, {
|
Overlays.editOverlay(minimizeButton, {
|
||||||
y: viewportHeight - windowHeight + WINDOW_MARGIN / 2
|
x: windowLeft + WINDOW_WIDTH - WINDOW_MARGIN / 2 - MIN_MAX_BUTTON_WIDTH,
|
||||||
|
y: windowTop + WINDOW_MARGIN / 2
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollbarBackgroundPosition.y = viewportHeight - windowHeight + WINDOW_MARGIN + windowTextHeight;
|
scrollbarBackgroundPosition.x = windowLeft + WINDOW_WIDTH - 0.5 * WINDOW_MARGIN - SCROLLBAR_BACKGROUND_WIDTH;
|
||||||
|
scrollbarBackgroundPosition.y = windowTop + WINDOW_MARGIN + windowTextHeight;
|
||||||
Overlays.editOverlay(scrollbarBackground, {
|
Overlays.editOverlay(scrollbarBackground, {
|
||||||
|
x: scrollbarBackgroundPosition.x,
|
||||||
y: scrollbarBackgroundPosition.y
|
y: scrollbarBackgroundPosition.y
|
||||||
});
|
});
|
||||||
scrollbarBarPosition.y = scrollbarBackgroundPosition.y + 1 + scrollbarValue * (scrollbarBackgroundHeight - scrollbarBarHeight - 2);
|
scrollbarBarPosition.y = scrollbarBackgroundPosition.y + 1
|
||||||
|
+ scrollbarValue * (scrollbarBackgroundHeight - scrollbarBarHeight - 2);
|
||||||
Overlays.editOverlay(scrollbarBar, {
|
Overlays.editOverlay(scrollbarBar, {
|
||||||
|
x: scrollbarBackgroundPosition.x + 1,
|
||||||
y: scrollbarBarPosition.y
|
y: scrollbarBarPosition.y
|
||||||
});
|
});
|
||||||
|
|
||||||
y = viewportHeight - FRIENDS_BUTTON_HEIGHT - DISPLAY_SPACER - windowLineHeight - VISIBILITY_SPACER - windowLineHeight - WINDOW_BASE_MARGIN;
|
x = windowLeft + WINDOW_MARGIN;
|
||||||
|
y = windowPosition.y - FRIENDS_BUTTON_HEIGHT - DISPLAY_SPACER
|
||||||
|
- windowLineHeight - VISIBILITY_SPACER
|
||||||
|
- windowLineHeight - WINDOW_BASE_MARGIN;
|
||||||
Overlays.editOverlay(friendsButton, {
|
Overlays.editOverlay(friendsButton, {
|
||||||
|
x: x,
|
||||||
y: y
|
y: y
|
||||||
});
|
});
|
||||||
|
|
||||||
y += FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER;
|
y += FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER;
|
||||||
displayControl.updatePosition(WINDOW_MARGIN, y);
|
displayControl.updatePosition(x, y);
|
||||||
|
|
||||||
y += windowLineHeight + VISIBILITY_SPACER;
|
y += windowLineHeight + VISIBILITY_SPACER;
|
||||||
visibilityControl.updatePosition(WINDOW_MARGIN, y);
|
visibilityControl.updatePosition(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateUsersDisplay() {
|
function updateUsersDisplay() {
|
||||||
|
@ -487,6 +527,10 @@ var usersWindow = (function() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Overlays.editOverlay(windowBorder, {
|
||||||
|
height: windowBorderHeight
|
||||||
|
});
|
||||||
|
|
||||||
Overlays.editOverlay(windowPane, {
|
Overlays.editOverlay(windowPane, {
|
||||||
height: windowHeight,
|
height: windowHeight,
|
||||||
text: displayText
|
text: displayText
|
||||||
|
@ -512,7 +556,7 @@ var usersWindow = (function() {
|
||||||
usersRequest.send();
|
usersRequest.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
processUsers = function() {
|
processUsers = function () {
|
||||||
var response,
|
var response,
|
||||||
myUsername,
|
myUsername,
|
||||||
user,
|
user,
|
||||||
|
@ -565,12 +609,15 @@ var usersWindow = (function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pollUsersTimedOut = function() {
|
pollUsersTimedOut = function () {
|
||||||
print("Error: Request for users status timed out");
|
print("Error: Request for users status timed out");
|
||||||
usersTimer = Script.setTimeout(pollUsers, HTTP_GET_TIMEOUT); // Try again after a longer delay.
|
usersTimer = Script.setTimeout(pollUsers, HTTP_GET_TIMEOUT); // Try again after a longer delay.
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateOverlayVisibility() {
|
function updateOverlayVisibility() {
|
||||||
|
Overlays.editOverlay(windowBorder, {
|
||||||
|
visible: isVisible && isBorderVisible
|
||||||
|
});
|
||||||
Overlays.editOverlay(windowPane, {
|
Overlays.editOverlay(windowPane, {
|
||||||
visible: isVisible
|
visible: isVisible
|
||||||
});
|
});
|
||||||
|
@ -670,7 +717,7 @@ var usersWindow = (function() {
|
||||||
if (clickedOverlay === windowPane) {
|
if (clickedOverlay === windowPane) {
|
||||||
|
|
||||||
overlayX = event.x - WINDOW_MARGIN;
|
overlayX = event.x - WINDOW_MARGIN;
|
||||||
overlayY = event.y - viewportHeight + windowHeight - WINDOW_MARGIN - windowLineHeight;
|
overlayY = event.y - windowPosition.y + windowHeight - WINDOW_MARGIN - windowLineHeight;
|
||||||
|
|
||||||
numLinesBefore = Math.round(overlayY / windowLineHeight);
|
numLinesBefore = Math.round(overlayY / windowLineHeight);
|
||||||
minY = numLinesBefore * windowLineHeight;
|
minY = numLinesBefore * windowLineHeight;
|
||||||
|
@ -683,7 +730,8 @@ var usersWindow = (function() {
|
||||||
|
|
||||||
userClicked = firstUserToDisplay + lineClicked;
|
userClicked = firstUserToDisplay + lineClicked;
|
||||||
|
|
||||||
if (0 <= userClicked && userClicked < linesOfUsers.length && 0 <= overlayX && overlayX <= usersOnline[linesOfUsers[userClicked]].textWidth) {
|
if (0 <= userClicked && userClicked < linesOfUsers.length && 0 <= overlayX
|
||||||
|
&& overlayX <= usersOnline[linesOfUsers[userClicked]].textWidth) {
|
||||||
//print("Go to " + usersOnline[linesOfUsers[userClicked]].username);
|
//print("Go to " + usersOnline[linesOfUsers[userClicked]].username);
|
||||||
location.goToUser(usersOnline[linesOfUsers[userClicked]].username);
|
location.goToUser(usersOnline[linesOfUsers[userClicked]].username);
|
||||||
}
|
}
|
||||||
|
@ -735,13 +783,29 @@ var usersWindow = (function() {
|
||||||
friendsWindow.setURL(FRIENDS_WINDOW_URL);
|
friendsWindow.setURL(FRIENDS_WINDOW_URL);
|
||||||
friendsWindow.setVisible(true);
|
friendsWindow.setVisible(true);
|
||||||
friendsWindow.raise();
|
friendsWindow.raise();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clickedOverlay === windowBorder) {
|
||||||
|
movingClickOffset = {
|
||||||
|
x: event.x - windowPosition.x,
|
||||||
|
y: event.y - windowPosition.y
|
||||||
|
};
|
||||||
|
|
||||||
|
isMovingWindow = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMouseMoveEvent(event) {
|
function onMouseMoveEvent(event) {
|
||||||
|
var isVisible;
|
||||||
|
|
||||||
if (isMovingScrollbar) {
|
if (isMovingScrollbar) {
|
||||||
if (scrollbarBackgroundPosition.x - WINDOW_MARGIN <= event.x && event.x <= scrollbarBackgroundPosition.x + SCROLLBAR_BACKGROUND_WIDTH + WINDOW_MARGIN && scrollbarBackgroundPosition.y - WINDOW_MARGIN <= event.y && event.y <= scrollbarBackgroundPosition.y + scrollbarBackgroundHeight + WINDOW_MARGIN) {
|
if (scrollbarBackgroundPosition.x - WINDOW_MARGIN <= event.x
|
||||||
scrollbarValue = (event.y - scrollbarBarClickedAt * scrollbarBarHeight - scrollbarBackgroundPosition.y) / (scrollbarBackgroundHeight - scrollbarBarHeight - 2);
|
&& event.x <= scrollbarBackgroundPosition.x + SCROLLBAR_BACKGROUND_WIDTH + WINDOW_MARGIN
|
||||||
|
&& scrollbarBackgroundPosition.y - WINDOW_MARGIN <= event.y
|
||||||
|
&& event.y <= scrollbarBackgroundPosition.y + scrollbarBackgroundHeight + WINDOW_MARGIN) {
|
||||||
|
scrollbarValue = (event.y - scrollbarBarClickedAt * scrollbarBarHeight - scrollbarBackgroundPosition.y)
|
||||||
|
/ (scrollbarBackgroundHeight - scrollbarBarHeight - 2);
|
||||||
scrollbarValue = Math.min(Math.max(scrollbarValue, 0.0), 1.0);
|
scrollbarValue = Math.min(Math.max(scrollbarValue, 0.0), 1.0);
|
||||||
firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay));
|
firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay));
|
||||||
updateOverlayPositions();
|
updateOverlayPositions();
|
||||||
|
@ -753,35 +817,95 @@ var usersWindow = (function() {
|
||||||
isMovingScrollbar = false;
|
isMovingScrollbar = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isMovingWindow) {
|
||||||
|
windowPosition = {
|
||||||
|
x: event.x - movingClickOffset.x,
|
||||||
|
y: event.y - movingClickOffset.y
|
||||||
|
};
|
||||||
|
calculateWindowHeight();
|
||||||
|
updateOverlayPositions();
|
||||||
|
updateUsersDisplay();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
isVisible = isBorderVisible;
|
||||||
|
if (isVisible) {
|
||||||
|
isVisible = windowPosition.x - WINDOW_BORDER_LEFT_MARGIN <= event.x
|
||||||
|
&& event.x <= windowPosition.x - WINDOW_BORDER_LEFT_MARGIN + WINDOW_BORDER_WIDTH
|
||||||
|
&& windowPosition.y - windowHeight - WINDOW_BORDER_TOP_MARGIN <= event.y
|
||||||
|
&& event.y <= windowPosition.y + WINDOW_BORDER_BOTTOM_MARGIN;
|
||||||
|
} else {
|
||||||
|
isVisible = windowPosition.x <= event.x && event.x <= windowPosition.x + WINDOW_WIDTH
|
||||||
|
&& windowPosition.y - windowHeight <= event.y && event.y <= windowPosition.y;
|
||||||
|
}
|
||||||
|
if (isVisible !== isBorderVisible) {
|
||||||
|
isBorderVisible = isVisible;
|
||||||
|
Overlays.editOverlay(windowBorder, {
|
||||||
|
visible: isBorderVisible
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMouseReleaseEvent() {
|
function onMouseReleaseEvent() {
|
||||||
Overlays.editOverlay(scrollbarBar, {
|
var offset = {};
|
||||||
backgroundAlpha: SCROLLBAR_BAR_ALPHA
|
|
||||||
});
|
if (isMovingScrollbar) {
|
||||||
isMovingScrollbar = false;
|
Overlays.editOverlay(scrollbarBar, {
|
||||||
|
backgroundAlpha: SCROLLBAR_BAR_ALPHA
|
||||||
|
});
|
||||||
|
isMovingScrollbar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMovingWindow) {
|
||||||
|
// Save offset of bottom of window to nearest edge of the window.
|
||||||
|
offset.x = (windowPosition.x + WINDOW_WIDTH / 2 < viewport.x / 2) ? windowPosition.x : windowPosition.x - viewport.x;
|
||||||
|
offset.y = (windowPosition.y < viewport.y / 2) ? windowPosition.y : windowPosition.y - viewport.y;
|
||||||
|
Settings.setValue(SETINGS_USERS_WINDOW_OFFSET, JSON.stringify(offset));
|
||||||
|
isMovingWindow = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onScriptUpdate() {
|
function onScriptUpdate() {
|
||||||
var oldViewportHeight = viewportHeight,
|
var oldViewport = viewport,
|
||||||
oldIsMirrorDisplay = isMirrorDisplay,
|
oldIsMirrorDisplay = isMirrorDisplay,
|
||||||
oldIsFullscreenMirror = isFullscreenMirror,
|
oldIsFullscreenMirror = isFullscreenMirror,
|
||||||
MIRROR_MENU_ITEM = "Mirror",
|
MIRROR_MENU_ITEM = "Mirror",
|
||||||
FULLSCREEN_MIRROR_MENU_ITEM = "Fullscreen Mirror";
|
FULLSCREEN_MIRROR_MENU_ITEM = "Fullscreen Mirror";
|
||||||
|
|
||||||
viewportHeight = Controller.getViewportDimensions().y;
|
viewport = Controller.getViewportDimensions();
|
||||||
isMirrorDisplay = Menu.isOptionChecked(MIRROR_MENU_ITEM);
|
isMirrorDisplay = Menu.isOptionChecked(MIRROR_MENU_ITEM);
|
||||||
isFullscreenMirror = Menu.isOptionChecked(FULLSCREEN_MIRROR_MENU_ITEM);
|
isFullscreenMirror = Menu.isOptionChecked(FULLSCREEN_MIRROR_MENU_ITEM);
|
||||||
|
|
||||||
if (viewportHeight !== oldViewportHeight || isMirrorDisplay !== oldIsMirrorDisplay || isFullscreenMirror !== oldIsFullscreenMirror) {
|
if (viewport.y !== oldViewport.y || isMirrorDisplay !== oldIsMirrorDisplay
|
||||||
|
|| isFullscreenMirror !== oldIsFullscreenMirror) {
|
||||||
calculateWindowHeight();
|
calculateWindowHeight();
|
||||||
updateUsersDisplay();
|
updateUsersDisplay();
|
||||||
updateOverlayPositions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (viewport.y !== oldViewport.y) {
|
||||||
|
if (windowPosition.y > oldViewport.y / 2) {
|
||||||
|
// Maintain position w.r.t. bottom of window.
|
||||||
|
windowPosition.y = viewport.y - (oldViewport.y - windowPosition.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewport.x !== oldViewport.x) {
|
||||||
|
if (windowPosition.x + (WINDOW_WIDTH / 2) > oldViewport.x / 2) {
|
||||||
|
// Maintain position w.r.t. right of window.
|
||||||
|
windowPosition.x = viewport.x - (oldViewport.x - windowPosition.x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOverlayPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUp() {
|
function setUp() {
|
||||||
var textSizeOverlay;
|
var textSizeOverlay,
|
||||||
|
offsetSetting,
|
||||||
|
offset = {},
|
||||||
|
hmdViewport;
|
||||||
|
|
||||||
textSizeOverlay = Overlays.addOverlay("text", {
|
textSizeOverlay = Overlays.addOverlay("text", {
|
||||||
font: WINDOW_FONT,
|
font: WINDOW_FONT,
|
||||||
|
@ -792,13 +916,40 @@ var usersWindow = (function() {
|
||||||
windowLineHeight = windowTextHeight + windowLineSpacing;
|
windowLineHeight = windowTextHeight + windowLineSpacing;
|
||||||
Overlays.deleteOverlay(textSizeOverlay);
|
Overlays.deleteOverlay(textSizeOverlay);
|
||||||
|
|
||||||
viewportHeight = Controller.getViewportDimensions().y;
|
viewport = Controller.getViewportDimensions();
|
||||||
|
|
||||||
|
offsetSetting = Settings.getValue(SETINGS_USERS_WINDOW_OFFSET);
|
||||||
|
if (offsetSetting !== "") {
|
||||||
|
offset = JSON.parse(Settings.getValue(SETINGS_USERS_WINDOW_OFFSET));
|
||||||
|
}
|
||||||
|
if (offset.hasOwnProperty("x") && offset.hasOwnProperty("y")) {
|
||||||
|
windowPosition.x = offset.x < 0 ? viewport.x + offset.x : offset.x;
|
||||||
|
windowPosition.y = offset.y <= 0 ? viewport.y + offset.y : offset.y;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
hmdViewport = Controller.getRecommendedOverlayRect();
|
||||||
|
windowPosition = {
|
||||||
|
x: (viewport.x - hmdViewport.width) / 2, // HMD viewport is narrower than screen.
|
||||||
|
y: hmdViewport.height // HMD viewport starts at top of screen but only extends down so far.
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
calculateWindowHeight();
|
calculateWindowHeight();
|
||||||
|
|
||||||
|
windowBorder = Overlays.addOverlay("rectangle", {
|
||||||
|
x: 0,
|
||||||
|
y: viewport.y, // Start up off-screen
|
||||||
|
width: WINDOW_BORDER_WIDTH,
|
||||||
|
height: windowBorderHeight,
|
||||||
|
radius: WINDOW_BORDER_RADIUS,
|
||||||
|
color: WINDOW_BORDER_COLOR,
|
||||||
|
alpha: WINDOW_BORDER_ALPHA,
|
||||||
|
visible: isVisible && isBorderVisible
|
||||||
|
});
|
||||||
|
|
||||||
windowPane = Overlays.addOverlay("text", {
|
windowPane = Overlays.addOverlay("text", {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: viewportHeight, // Start up off-screen
|
y: viewport.y,
|
||||||
width: WINDOW_WIDTH,
|
width: WINDOW_WIDTH,
|
||||||
height: windowHeight,
|
height: windowHeight,
|
||||||
topMargin: WINDOW_MARGIN + windowLineHeight,
|
topMargin: WINDOW_MARGIN + windowLineHeight,
|
||||||
|
@ -813,8 +964,8 @@ var usersWindow = (function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHeading = Overlays.addOverlay("text", {
|
windowHeading = Overlays.addOverlay("text", {
|
||||||
x: WINDOW_MARGIN,
|
x: 0,
|
||||||
y: viewportHeight,
|
y: viewport.y,
|
||||||
width: WINDOW_WIDTH - 2 * WINDOW_MARGIN,
|
width: WINDOW_WIDTH - 2 * WINDOW_MARGIN,
|
||||||
height: windowTextHeight,
|
height: windowTextHeight,
|
||||||
topMargin: 0,
|
topMargin: 0,
|
||||||
|
@ -828,8 +979,8 @@ var usersWindow = (function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
minimizeButton = Overlays.addOverlay("image", {
|
minimizeButton = Overlays.addOverlay("image", {
|
||||||
x: WINDOW_WIDTH - WINDOW_MARGIN / 2 - MIN_MAX_BUTTON_WIDTH,
|
x: 0,
|
||||||
y: viewportHeight,
|
y: viewport.y,
|
||||||
width: MIN_MAX_BUTTON_WIDTH,
|
width: MIN_MAX_BUTTON_WIDTH,
|
||||||
height: MIN_MAX_BUTTON_HEIGHT,
|
height: MIN_MAX_BUTTON_HEIGHT,
|
||||||
imageURL: MIN_MAX_BUTTON_SVG,
|
imageURL: MIN_MAX_BUTTON_SVG,
|
||||||
|
@ -845,11 +996,11 @@ var usersWindow = (function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollbarBackgroundPosition = {
|
scrollbarBackgroundPosition = {
|
||||||
x: WINDOW_WIDTH - 0.5 * WINDOW_MARGIN - SCROLLBAR_BACKGROUND_WIDTH,
|
x: 0,
|
||||||
y: viewportHeight
|
y: viewport.y
|
||||||
};
|
};
|
||||||
scrollbarBackground = Overlays.addOverlay("text", {
|
scrollbarBackground = Overlays.addOverlay("text", {
|
||||||
x: scrollbarBackgroundPosition.x,
|
x: 0,
|
||||||
y: scrollbarBackgroundPosition.y,
|
y: scrollbarBackgroundPosition.y,
|
||||||
width: SCROLLBAR_BACKGROUND_WIDTH,
|
width: SCROLLBAR_BACKGROUND_WIDTH,
|
||||||
height: windowTextHeight,
|
height: windowTextHeight,
|
||||||
|
@ -860,11 +1011,11 @@ var usersWindow = (function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollbarBarPosition = {
|
scrollbarBarPosition = {
|
||||||
x: WINDOW_WIDTH - 0.5 * WINDOW_MARGIN - SCROLLBAR_BACKGROUND_WIDTH + 1,
|
x: 0,
|
||||||
y: viewportHeight
|
y: viewport.y
|
||||||
};
|
};
|
||||||
scrollbarBar = Overlays.addOverlay("text", {
|
scrollbarBar = Overlays.addOverlay("text", {
|
||||||
x: scrollbarBarPosition.x,
|
x: 0,
|
||||||
y: scrollbarBarPosition.y,
|
y: scrollbarBarPosition.y,
|
||||||
width: SCROLLBAR_BACKGROUND_WIDTH - 2,
|
width: SCROLLBAR_BACKGROUND_WIDTH - 2,
|
||||||
height: windowTextHeight,
|
height: windowTextHeight,
|
||||||
|
@ -875,8 +1026,8 @@ var usersWindow = (function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
friendsButton = Overlays.addOverlay("image", {
|
friendsButton = Overlays.addOverlay("image", {
|
||||||
x: WINDOW_MARGIN,
|
x: 0,
|
||||||
y: viewportHeight,
|
y: viewport.y,
|
||||||
width: FRIENDS_BUTTON_WIDTH,
|
width: FRIENDS_BUTTON_WIDTH,
|
||||||
height: FRIENDS_BUTTON_HEIGHT,
|
height: FRIENDS_BUTTON_HEIGHT,
|
||||||
imageURL: FRIENDS_BUTTON_SVG,
|
imageURL: FRIENDS_BUTTON_SVG,
|
||||||
|
@ -895,8 +1046,8 @@ var usersWindow = (function() {
|
||||||
value: DISPLAY_VALUES[0],
|
value: DISPLAY_VALUES[0],
|
||||||
values: DISPLAY_VALUES,
|
values: DISPLAY_VALUES,
|
||||||
displayValues: DISPLAY_DISPLAY_VALUES,
|
displayValues: DISPLAY_DISPLAY_VALUES,
|
||||||
x: WINDOW_MARGIN,
|
x: 0,
|
||||||
y: viewportHeight,
|
y: viewport.y,
|
||||||
width: WINDOW_WIDTH - 1.5 * WINDOW_MARGIN,
|
width: WINDOW_WIDTH - 1.5 * WINDOW_MARGIN,
|
||||||
promptWidth: DISPLAY_PROMPT_WIDTH,
|
promptWidth: DISPLAY_PROMPT_WIDTH,
|
||||||
lineHeight: windowLineHeight,
|
lineHeight: windowLineHeight,
|
||||||
|
@ -928,8 +1079,8 @@ var usersWindow = (function() {
|
||||||
value: myVisibility,
|
value: myVisibility,
|
||||||
values: VISIBILITY_VALUES,
|
values: VISIBILITY_VALUES,
|
||||||
displayValues: VISIBILITY_DISPLAY_VALUES,
|
displayValues: VISIBILITY_DISPLAY_VALUES,
|
||||||
x: WINDOW_MARGIN,
|
x: 0,
|
||||||
y: viewportHeight,
|
y: viewport.y,
|
||||||
width: WINDOW_WIDTH - 1.5 * WINDOW_MARGIN,
|
width: WINDOW_WIDTH - 1.5 * WINDOW_MARGIN,
|
||||||
promptWidth: VISIBILITY_PROMPT_WIDTH,
|
promptWidth: VISIBILITY_PROMPT_WIDTH,
|
||||||
lineHeight: windowLineHeight,
|
lineHeight: windowLineHeight,
|
||||||
|
@ -979,6 +1130,7 @@ var usersWindow = (function() {
|
||||||
Menu.removeMenuItem(MENU_NAME, MENU_ITEM);
|
Menu.removeMenuItem(MENU_NAME, MENU_ITEM);
|
||||||
|
|
||||||
Script.clearTimeout(usersTimer);
|
Script.clearTimeout(usersTimer);
|
||||||
|
Overlays.deleteOverlay(windowBorder);
|
||||||
Overlays.deleteOverlay(windowPane);
|
Overlays.deleteOverlay(windowPane);
|
||||||
Overlays.deleteOverlay(windowHeading);
|
Overlays.deleteOverlay(windowHeading);
|
||||||
Overlays.deleteOverlay(minimizeButton);
|
Overlays.deleteOverlay(minimizeButton);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <render-utils/simple_vert.h>
|
#include <render-utils/simple_vert.h>
|
||||||
#include <render-utils/simple_frag.h>
|
#include <render-utils/simple_frag.h>
|
||||||
#include <render-utils/simple_textured_frag.h>
|
#include <render-utils/simple_textured_frag.h>
|
||||||
#include <render-utils/simple_textured_emisive_frag.h>
|
#include <render-utils/simple_textured_unlit_frag.h>
|
||||||
|
|
||||||
#include <render-utils/deferred_light_vert.h>
|
#include <render-utils/deferred_light_vert.h>
|
||||||
#include <render-utils/deferred_light_limited_vert.h>
|
#include <render-utils/deferred_light_limited_vert.h>
|
||||||
|
@ -160,7 +160,7 @@ void QTestWindow::draw() {
|
||||||
testShaderBuild(skybox_vert, skybox_frag);
|
testShaderBuild(skybox_vert, skybox_frag);
|
||||||
testShaderBuild(simple_vert, simple_frag);
|
testShaderBuild(simple_vert, simple_frag);
|
||||||
testShaderBuild(simple_vert, simple_textured_frag);
|
testShaderBuild(simple_vert, simple_textured_frag);
|
||||||
testShaderBuild(simple_vert, simple_textured_emisive_frag);
|
testShaderBuild(simple_vert, simple_textured_unlit_frag);
|
||||||
testShaderBuild(deferred_light_vert, directional_light_frag);
|
testShaderBuild(deferred_light_vert, directional_light_frag);
|
||||||
testShaderBuild(deferred_light_vert, directional_ambient_light_frag);
|
testShaderBuild(deferred_light_vert, directional_ambient_light_frag);
|
||||||
testShaderBuild(deferred_light_vert, directional_skybox_light_frag);
|
testShaderBuild(deferred_light_vert, directional_skybox_light_frag);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "TextTemplate.h"
|
#include "TextTemplate.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
@ -168,7 +169,7 @@ int main (int argc, char** argv) {
|
||||||
auto scribe = std::make_shared<TextTemplate>(srcFilename, config);
|
auto scribe = std::make_shared<TextTemplate>(srcFilename, config);
|
||||||
|
|
||||||
// ready to parse and generate
|
// ready to parse and generate
|
||||||
std::ostringstream destStringStream;
|
std::stringstream destStringStream;
|
||||||
int numErrors = scribe->scribe(destStringStream, srcStream, vars);
|
int numErrors = scribe->scribe(destStringStream, srcStream, vars);
|
||||||
if (numErrors) {
|
if (numErrors) {
|
||||||
cerr << "Scribe " << srcFilename << "> failed: " << numErrors << " errors." << endl;
|
cerr << "Scribe " << srcFilename << "> failed: " << numErrors << " errors." << endl;
|
||||||
|
@ -187,14 +188,38 @@ int main (int argc, char** argv) {
|
||||||
|
|
||||||
std::ostringstream targetStringStream;
|
std::ostringstream targetStringStream;
|
||||||
if (makeCPlusPlus) {
|
if (makeCPlusPlus) {
|
||||||
|
// Because there is a maximum size for literal strings declared in source we need to partition the
|
||||||
|
// full source string stream into pages that seems to be around that value...
|
||||||
|
const int MAX_STRING_LITERAL = 10000;
|
||||||
|
std::string lineToken;
|
||||||
|
auto pageSize = lineToken.length();
|
||||||
|
std::vector<std::shared_ptr<std::stringstream>> pages(1, std::make_shared<std::stringstream>());
|
||||||
|
while (!destStringStream.eof()) {
|
||||||
|
std::getline(destStringStream, lineToken);
|
||||||
|
auto lineSize = lineToken.length() + 1;
|
||||||
|
|
||||||
|
if (pageSize + lineSize > MAX_STRING_LITERAL) {
|
||||||
|
pages.push_back(std::make_shared<std::stringstream>());
|
||||||
|
// reset pageStringStream
|
||||||
|
pageSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*pages.back()) << lineToken << std::endl;
|
||||||
|
pageSize += lineSize;
|
||||||
|
}
|
||||||
|
|
||||||
targetStringStream << "// File generated by Scribe " << vars["_SCRIBE_DATE"] << std::endl;
|
targetStringStream << "// File generated by Scribe " << vars["_SCRIBE_DATE"] << std::endl;
|
||||||
targetStringStream << "#ifndef scribe_" << targetName << "_h" << std::endl;
|
targetStringStream << "#ifndef scribe_" << targetName << "_h" << std::endl;
|
||||||
targetStringStream << "#define scribe_" << targetName << "_h" << std::endl << std::endl;
|
targetStringStream << "#define scribe_" << targetName << "_h" << std::endl << std::endl;
|
||||||
|
|
||||||
// targetStringStream << "const char " << targetName << "[] = R\"XXXX(" << destStringStream.str() << ")XXXX\";";
|
targetStringStream << "const char " << targetName << "[] = \n";
|
||||||
targetStringStream << "const char " << targetName << "[] = R\"SCRIBE(";
|
|
||||||
targetStringStream << destStringStream.str();
|
// Write the pages content
|
||||||
targetStringStream << "\n)SCRIBE\";\n\n";
|
for (auto page : pages) {
|
||||||
|
targetStringStream << "R\"SCRIBE(\n" << page->str() << "\n)SCRIBE\"\n";
|
||||||
|
}
|
||||||
|
targetStringStream << ";\n" << std::endl << std::endl;
|
||||||
|
|
||||||
targetStringStream << "#endif" << std::endl;
|
targetStringStream << "#endif" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
targetStringStream << destStringStream.str();
|
targetStringStream << destStringStream.str();
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
var MINUTE_HAND_CLOCK_SCRIPT_URL = Script.resolvePath("cuckooClockMinuteHandEntityScript.js" )
|
var MINUTE_HAND_CLOCK_SCRIPT_URL = Script.resolvePath("cuckooClockMinuteHandEntityScript.js")
|
||||||
var CLOCK_BODY_URL = "atp:/cuckooClock/cuckoo2_BODY.fbx";
|
var CLOCK_BODY_URL = "atp:/cuckooClock/cuckoo2_BODY.fbx";
|
||||||
var CLOCK_BODY_COLLISION_HULL_URL = "atp:/cuckooClock/clockHull.obj";
|
var CLOCK_BODY_COLLISION_HULL_URL = "atp:/cuckooClock/clockHull.obj";
|
||||||
var CLOCK_FACE_URL = "atp:/cuckooClock/cuckooClock2_FACE.fbx";
|
var CLOCK_FACE_URL = "atp:/cuckooClock/cuckooClock2_FACE.fbx";
|
||||||
|
@ -38,11 +38,11 @@ MyCuckooClock = function(spawnPosition, spawnRotation) {
|
||||||
},
|
},
|
||||||
position: spawnPosition,
|
position: spawnPosition,
|
||||||
rotation: clockRotation,
|
rotation: clockRotation,
|
||||||
dimensions: {
|
dimensions: Vec3.multiply(0.5, {
|
||||||
x: 0.8181,
|
x: 0.8181,
|
||||||
y: 1.3662,
|
y: 1.3662,
|
||||||
z: 0.8181
|
z: 0.8181
|
||||||
},
|
}),
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
hifiHomeKey: {
|
hifiHomeKey: {
|
||||||
reset: true
|
reset: true
|
||||||
|
@ -50,9 +50,9 @@ MyCuckooClock = function(spawnPosition, spawnRotation) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
var forwardOffset = -0.13
|
var forwardOffset = 0.5 * -0.13;
|
||||||
var upOffset = 0.255;
|
var upOffset = 0.5 * 0.255;
|
||||||
var sideOffset = -0.03;
|
var sideOffset = 0.5 * -0.03;
|
||||||
var clockFacePosition = spawnPosition;
|
var clockFacePosition = spawnPosition;
|
||||||
clockFacePosition = Vec3.sum(clockFacePosition, Vec3.multiply(Quat.getFront(clockRotation), forwardOffset));
|
clockFacePosition = Vec3.sum(clockFacePosition, Vec3.multiply(Quat.getFront(clockRotation), forwardOffset));
|
||||||
clockFacePosition = Vec3.sum(clockFacePosition, Vec3.multiply(Quat.getUp(clockRotation), upOffset));
|
clockFacePosition = Vec3.sum(clockFacePosition, Vec3.multiply(Quat.getUp(clockRotation), upOffset));
|
||||||
|
@ -65,11 +65,11 @@ MyCuckooClock = function(spawnPosition, spawnRotation) {
|
||||||
name: "home_model_clockFace",
|
name: "home_model_clockFace",
|
||||||
modelURL: CLOCK_FACE_URL,
|
modelURL: CLOCK_FACE_URL,
|
||||||
position: clockFacePosition,
|
position: clockFacePosition,
|
||||||
dimensions: {
|
dimensions: Vec3.multiply(0.5, {
|
||||||
x: 0.2397,
|
x: 0.2397,
|
||||||
y: 0.2402,
|
y: 0.2402,
|
||||||
z: 0.0212
|
z: 0.0212
|
||||||
},
|
}),
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
hifiHomeKey: {
|
hifiHomeKey: {
|
||||||
reset: true
|
reset: true
|
||||||
|
@ -86,7 +86,7 @@ MyCuckooClock = function(spawnPosition, spawnRotation) {
|
||||||
|
|
||||||
var myDate = new Date()
|
var myDate = new Date()
|
||||||
// HOUR HAND *************************
|
// HOUR HAND *************************
|
||||||
var clockHandForwardOffset = -0.017;
|
var clockHandForwardOffset = (0.5 * -0.017);
|
||||||
|
|
||||||
|
|
||||||
var hourHandPosition = Vec3.sum(clockFacePosition, Vec3.multiply(Quat.getFront(clockRotation), clockHandForwardOffset));
|
var hourHandPosition = Vec3.sum(clockFacePosition, Vec3.multiply(Quat.getFront(clockRotation), clockHandForwardOffset));
|
||||||
|
@ -118,11 +118,11 @@ MyCuckooClock = function(spawnPosition, spawnRotation) {
|
||||||
rotation: worldClockHandRotation,
|
rotation: worldClockHandRotation,
|
||||||
angularDamping: 0,
|
angularDamping: 0,
|
||||||
angularVelocity: worldAngularVelocity,
|
angularVelocity: worldAngularVelocity,
|
||||||
dimensions: {
|
dimensions: Vec3.multiply(0.5, {
|
||||||
x: 0.0263,
|
x: 0.0263,
|
||||||
y: 0.0982,
|
y: 0.0982,
|
||||||
z: 0.0024
|
z: 0.0024
|
||||||
},
|
}),
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
hifiHomeKey: {
|
hifiHomeKey: {
|
||||||
reset: true
|
reset: true
|
||||||
|
@ -150,11 +150,11 @@ MyCuckooClock = function(spawnPosition, spawnRotation) {
|
||||||
modelURL: CLOCK_SECOND_HAND_URL,
|
modelURL: CLOCK_SECOND_HAND_URL,
|
||||||
name: "home_model_clockSecondHand",
|
name: "home_model_clockSecondHand",
|
||||||
position: hourHandPosition,
|
position: hourHandPosition,
|
||||||
dimensions: {
|
dimensions: Vec3.multiply(0.5, {
|
||||||
x: 0.0043,
|
x: 0.0043,
|
||||||
y: 0.1117,
|
y: 0.1117,
|
||||||
z: 0.0008
|
z: 0.0008
|
||||||
},
|
}),
|
||||||
color: {
|
color: {
|
||||||
red: 200,
|
red: 200,
|
||||||
green: 10,
|
green: 10,
|
||||||
|
@ -202,14 +202,14 @@ MyCuckooClock = function(spawnPosition, spawnRotation) {
|
||||||
y: 0.05,
|
y: 0.05,
|
||||||
z: 0.5
|
z: 0.5
|
||||||
},
|
},
|
||||||
rotation:worldClockHandRotation,
|
rotation: worldClockHandRotation,
|
||||||
angularDamping: 0,
|
angularDamping: 0,
|
||||||
angularVelocity: worldAngularVelocity,
|
angularVelocity: worldAngularVelocity,
|
||||||
dimensions: {
|
dimensions: Vec3.multiply(0.5, {
|
||||||
x: 0.0251,
|
x: 0.0251,
|
||||||
y: 0.1179,
|
y: 0.1179,
|
||||||
z: 0.0032
|
z: 0.0032
|
||||||
},
|
}),
|
||||||
script: MINUTE_HAND_CLOCK_SCRIPT_URL,
|
script: MINUTE_HAND_CLOCK_SCRIPT_URL,
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
clockBody: clockBody,
|
clockBody: clockBody,
|
||||||
|
|
165
unpublishedScripts/DomainContent/Home/firePit/fire.js
Normal file
165
unpublishedScripts/DomainContent/Home/firePit/fire.js
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
// this script turns an entity into an exploder -- anything that collides with it will be vaporized!
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
function Fire() {
|
||||||
|
_this = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
var RED = {
|
||||||
|
red: 255,
|
||||||
|
green: 0,
|
||||||
|
blue: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
var ORANGE = {
|
||||||
|
red: 255,
|
||||||
|
green: 165,
|
||||||
|
blue: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
var YELLOW = {
|
||||||
|
red: 255,
|
||||||
|
green: 255,
|
||||||
|
blue: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
var GREEN = {
|
||||||
|
red: 0,
|
||||||
|
green: 255,
|
||||||
|
blue: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
var BLUE = {
|
||||||
|
red: 0,
|
||||||
|
green: 0,
|
||||||
|
blue: 255
|
||||||
|
};
|
||||||
|
|
||||||
|
var INDIGO = {
|
||||||
|
red: 128,
|
||||||
|
green: 0,
|
||||||
|
blue: 128
|
||||||
|
};
|
||||||
|
|
||||||
|
var VIOLET = {
|
||||||
|
red: 75,
|
||||||
|
green: 0,
|
||||||
|
blue: 130
|
||||||
|
};
|
||||||
|
|
||||||
|
var colors = [RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET];
|
||||||
|
|
||||||
|
Fire.prototype = {
|
||||||
|
preload: function(entityID) {
|
||||||
|
this.entityID = entityID;
|
||||||
|
this.EXPLOSION_SOUND = SoundCache.getSound("atp:/firepit/fire_burst.wav");
|
||||||
|
|
||||||
|
},
|
||||||
|
collisionWithEntity: function(myID, otherID, collisionInfo) {
|
||||||
|
var otherProps = Entities.getEntityProperties(otherID);
|
||||||
|
var data = null;
|
||||||
|
try {
|
||||||
|
data = JSON.parse(otherProps.userData)
|
||||||
|
} catch (err) {
|
||||||
|
print('ERROR GETTING USERDATA!');
|
||||||
|
}
|
||||||
|
if (data === null || "") {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (data.hasOwnProperty('hifiHomeKey')) {
|
||||||
|
if (data.hifiHomeKey.reset === true) {
|
||||||
|
print('FLAMMABLE THING, EXPLODE IT!');
|
||||||
|
_this.playSoundAtCurrentPosition();
|
||||||
|
_this.explodeWithColor();
|
||||||
|
_this.smokePuff();
|
||||||
|
Entities.deleteEntity(otherID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
explodeWithColor: function() {
|
||||||
|
print('EXPLODE!')
|
||||||
|
var myProps = Entities.getEntityProperties(this.entityID);
|
||||||
|
var color = colors[Math.floor(Math.random() * colors.length)];
|
||||||
|
var explosionParticleProperties = {
|
||||||
|
"color": color,
|
||||||
|
"isEmitting": 1,
|
||||||
|
"maxParticles": 1000,
|
||||||
|
"lifespan": 0.25,
|
||||||
|
"emitRate": 1,
|
||||||
|
"emitSpeed": 0.1,
|
||||||
|
"speedSpread": 1,
|
||||||
|
"emitOrientation": Quat.getUp(myProps.rotation),
|
||||||
|
"emitDimensions": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"polarStart": 0,
|
||||||
|
"polarFinish": 0,
|
||||||
|
"azimuthStart": 0,
|
||||||
|
"azimuthFinish": 0,
|
||||||
|
"emitAcceleration": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"accelerationSpread": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"particleRadius": 0.829,
|
||||||
|
"radiusSpread": 0,
|
||||||
|
"radiusStart": 0.361,
|
||||||
|
"radiusFinish": 0.294,
|
||||||
|
"colorSpread": {
|
||||||
|
"red": 0,
|
||||||
|
"green": 0,
|
||||||
|
"blue": 0
|
||||||
|
},
|
||||||
|
"colorStart": {
|
||||||
|
"red": 255,
|
||||||
|
"green": 255,
|
||||||
|
"blue": 255
|
||||||
|
},
|
||||||
|
"colorFinish": {
|
||||||
|
"red": 255,
|
||||||
|
"green": 255,
|
||||||
|
"blue": 255
|
||||||
|
},
|
||||||
|
"alpha": 1,
|
||||||
|
"alphaSpread": 0,
|
||||||
|
"alphaStart": -0.2,
|
||||||
|
"alphaFinish": 0.5,
|
||||||
|
"emitterShouldTrail": 0,
|
||||||
|
"textures": "atp:/firepit/explode.png",
|
||||||
|
"type": "ParticleEffect",
|
||||||
|
lifetime: 1,
|
||||||
|
position: myProps.position
|
||||||
|
};
|
||||||
|
|
||||||
|
var explosion = Entities.addEntity(explosionParticleProperties);
|
||||||
|
print('explosion is: ' + explosion)
|
||||||
|
},
|
||||||
|
smokePuff: function() {
|
||||||
|
//smoke puff here
|
||||||
|
},
|
||||||
|
playSoundAtCurrentPosition: function() {
|
||||||
|
|
||||||
|
var audioProperties = {
|
||||||
|
volume: 0.5,
|
||||||
|
position: Entities.getEntityProperties(this.entityID).position
|
||||||
|
};
|
||||||
|
|
||||||
|
Audio.playSound(this.EXPLOSION_SOUND, audioProperties);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Fire();
|
||||||
|
});
|
51
unpublishedScripts/DomainContent/Home/firePit/flicker.js
Normal file
51
unpublishedScripts/DomainContent/Home/firePit/flicker.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
var MINIMUM_LIGHT_INTENSITY = 50.0;
|
||||||
|
var MAXIMUM_LIGHT_INTENSITY = 200.0;
|
||||||
|
var LIGHT_FALLOFF_RADIUS = 0.1;
|
||||||
|
var LIGHT_INTENSITY_RANDOMNESS = 0.1;
|
||||||
|
|
||||||
|
function randFloat(low, high) {
|
||||||
|
return low + Math.random() * (high - low);
|
||||||
|
}
|
||||||
|
|
||||||
|
var _this;
|
||||||
|
|
||||||
|
function FlickeringFlame() {
|
||||||
|
_this = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalTime = 0;
|
||||||
|
var spacer = 2;
|
||||||
|
FlickeringFlame.prototype = {
|
||||||
|
preload: function(entityID) {
|
||||||
|
this.entityID = entityID;
|
||||||
|
Script.update.connect(this.update);
|
||||||
|
},
|
||||||
|
update: function(deltaTime) {
|
||||||
|
|
||||||
|
totalTime += deltaTime;
|
||||||
|
if (totalTime > spacer) {
|
||||||
|
var howManyAvatars = AvatarList.getAvatarIdentifiers().length;
|
||||||
|
var intensity = (MINIMUM_LIGHT_INTENSITY + (MAXIMUM_LIGHT_INTENSITY + (Math.sin(totalTime) * MAXIMUM_LIGHT_INTENSITY)));
|
||||||
|
intensity += randFloat(-LIGHT_INTENSITY_RANDOMNESS, LIGHT_INTENSITY_RANDOMNESS);
|
||||||
|
|
||||||
|
Entities.editEntity(_this.entityID, {
|
||||||
|
intensity: intensity
|
||||||
|
});
|
||||||
|
|
||||||
|
spacer = Math.random(0, 100) * (2 / howManyAvatars);
|
||||||
|
totalTime = 0;
|
||||||
|
} else {
|
||||||
|
//just keep counting
|
||||||
|
}
|
||||||
|
},
|
||||||
|
unload: function() {
|
||||||
|
Script.update.disconnect(this.update)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FlickeringFlame
|
||||||
|
|
||||||
|
|
||||||
|
});
|
|
@ -37,14 +37,10 @@
|
||||||
|
|
||||||
var whiteboardPath = Script.resolvePath("atp:/whiteboard/wrapper.js");
|
var whiteboardPath = Script.resolvePath("atp:/whiteboard/wrapper.js");
|
||||||
|
|
||||||
var plantPath = Script.resolvePath("atp:/growingPlant/wrapper.js");
|
|
||||||
|
|
||||||
var cuckooClockPath = Script.resolvePath("atp:/cuckooClock/wrapper.js");
|
var cuckooClockPath = Script.resolvePath("atp:/cuckooClock/wrapper.js");
|
||||||
|
|
||||||
var pingPongGunPath = Script.resolvePath("atp:/pingPongGun/wrapper.js");
|
var pingPongGunPath = Script.resolvePath("atp:/pingPongGun/wrapper.js");
|
||||||
|
|
||||||
var musicBoxPath = Script.resolvePath("musicBox/wrapper.js?" + Math.random());
|
|
||||||
|
|
||||||
var transformerPath = Script.resolvePath("atp:/dressingRoom/wrapper.js");
|
var transformerPath = Script.resolvePath("atp:/dressingRoom/wrapper.js");
|
||||||
|
|
||||||
Script.include(utilsPath);
|
Script.include(utilsPath);
|
||||||
|
@ -54,10 +50,8 @@
|
||||||
Script.include(fishTankPath);
|
Script.include(fishTankPath);
|
||||||
Script.include(tiltMazePath);
|
Script.include(tiltMazePath);
|
||||||
Script.include(whiteboardPath);
|
Script.include(whiteboardPath);
|
||||||
Script.include(plantPath);
|
|
||||||
Script.include(cuckooClockPath);
|
Script.include(cuckooClockPath);
|
||||||
Script.include(pingPongGunPath);
|
Script.include(pingPongGunPath);
|
||||||
// Script.include(musicBoxPath);
|
|
||||||
Script.include(transformerPath);
|
Script.include(transformerPath);
|
||||||
|
|
||||||
var TRANSFORMER_URL_ROBOT = 'atp:/dressingRoom/simple_robot.fbx';
|
var TRANSFORMER_URL_ROBOT = 'atp:/dressingRoom/simple_robot.fbx';
|
||||||
|
@ -204,23 +198,13 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var whiteboard = new Whiteboard({
|
var whiteboard = new Whiteboard({
|
||||||
x: 1104,
|
x: 1105.0955,
|
||||||
y: 460.5,
|
y: 460.5000,
|
||||||
z: -77
|
z: -77.4409
|
||||||
}, {
|
}, {
|
||||||
x: 0,
|
x: -0.0013,
|
||||||
y: -133,
|
y: -133.0056,
|
||||||
z: 0
|
z: -0.0013
|
||||||
});
|
|
||||||
|
|
||||||
var myPlant = new Plant({
|
|
||||||
x: 1099.8785,
|
|
||||||
y: 460.3115,
|
|
||||||
z: -84.7736
|
|
||||||
}, {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var pingPongGun = new HomePingPongGun({
|
var pingPongGun = new HomePingPongGun({
|
||||||
|
@ -234,16 +218,15 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var cuckooClock = new MyCuckooClock({
|
var cuckooClock = new MyCuckooClock({
|
||||||
x: 1105.267,
|
x: 1105.5237,
|
||||||
y: 461.44,
|
y: 461.4826,
|
||||||
z: -81.9495
|
z: -81.7524
|
||||||
}, {
|
}, {
|
||||||
x: 0,
|
x: -0.0013,
|
||||||
y: -57,
|
y: -57.0089,
|
||||||
z: 0
|
z: -0.0013
|
||||||
});
|
});
|
||||||
|
|
||||||
// var musicBox = new MusicBox();
|
|
||||||
print('HOME after creating scripted entities')
|
print('HOME after creating scripted entities')
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue