mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Merging the day after the flight back to france, getting all the fixes
This commit is contained in:
commit
3a93409080
38 changed files with 354 additions and 586 deletions
|
@ -1714,12 +1714,9 @@ bool Application::acceptSnapshot(const QString& urlString) {
|
|||
|
||||
SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(snapshotPath);
|
||||
if (snapshotData) {
|
||||
if (!snapshotData->getDomain().isEmpty()) {
|
||||
DependencyManager::get<NodeList>()->getDomainHandler().setHostnameAndPort(snapshotData->getDomain());
|
||||
if (!snapshotData->getURL().toString().isEmpty()) {
|
||||
DependencyManager::get<AddressManager>()->handleLookupString(snapshotData->getURL().toString());
|
||||
}
|
||||
|
||||
_myAvatar->setPosition(snapshotData->getLocation());
|
||||
_myAvatar->setOrientation(snapshotData->getOrientation());
|
||||
} else {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("No location details were found in the file "
|
||||
|
@ -3188,17 +3185,12 @@ namespace render {
|
|||
template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); }
|
||||
template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); }
|
||||
template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) {
|
||||
if (args->_renderMode != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
||||
if (args->_renderMode != RenderArgs::MIRROR_RENDER_MODE && Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
||||
PerformanceTimer perfTimer("worldBox");
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram((*args->_batch));
|
||||
|
||||
renderWorldBox(args);
|
||||
|
||||
// FIXME: there's currently a bug in the new render engine, if this origin dot is rendered out of view it will
|
||||
// screw up the state of textures on models so they all end up rendering in the incorrect tint/color/texture
|
||||
float originSphereRadius = 0.05f;
|
||||
DependencyManager::get<GeometryCache>()->renderSphere((*args->_batch), originSphereRadius, 15, 15, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
auto& batch = *args->_batch;
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch);
|
||||
renderWorldBox(batch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#include <QShowEvent>
|
||||
#include <QHideEvent>
|
||||
#include <QWindowStateChangeEvent>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QDropEvent>
|
||||
#include <QMimeData>
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "Menu.h"
|
||||
|
@ -27,6 +30,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||
_windowGeometry("WindowGeometry"),
|
||||
_windowState("WindowState", 0)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
|
||||
void MainWindow::restoreGeometry() {
|
||||
|
@ -87,13 +91,13 @@ void MainWindow::changeEvent(QEvent* event) {
|
|||
if (event->type() == QEvent::WindowStateChange) {
|
||||
QWindowStateChangeEvent* stateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
|
||||
if ((stateChangeEvent->oldState() == Qt::WindowNoState ||
|
||||
stateChangeEvent->oldState() == Qt::WindowMaximized) &&
|
||||
windowState() == Qt::WindowMinimized) {
|
||||
stateChangeEvent->oldState() == Qt::WindowMaximized) &&
|
||||
windowState() == Qt::WindowMinimized) {
|
||||
emit windowShown(false);
|
||||
} else {
|
||||
emit windowShown(true);
|
||||
}
|
||||
|
||||
|
||||
if (isFullScreen() != Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) {
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::Fullscreen, isFullScreen());
|
||||
}
|
||||
|
@ -106,3 +110,13 @@ void MainWindow::changeEvent(QEvent* event) {
|
|||
}
|
||||
QMainWindow::changeEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::dragEnterEvent(QDragEnterEvent* event) {
|
||||
if (event->mimeData()) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::dropEvent(QDropEvent* event) {
|
||||
QCoreApplication::sendEvent(QCoreApplication::instance(), event);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ protected:
|
|||
virtual void showEvent(QShowEvent* event);
|
||||
virtual void hideEvent(QHideEvent* event);
|
||||
virtual void changeEvent(QEvent* event);
|
||||
virtual void dragEnterEvent(QDragEnterEvent *e);
|
||||
virtual void dropEvent(QDropEvent *e);
|
||||
|
||||
private:
|
||||
Setting::Handle<QRect> _windowGeometry;
|
||||
|
|
|
@ -33,42 +33,44 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
void renderWorldBox(RenderArgs* renderArgs) {
|
||||
void renderWorldBox(gpu::Batch& batch) {
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto batch = renderArgs->_batch;
|
||||
|
||||
// Show edge of world
|
||||
glm::vec3 red(1.0f, 0.0f, 0.0f);
|
||||
glm::vec3 green(0.0f, 1.0f, 0.0f);
|
||||
glm::vec3 blue(0.0f, 0.0f, 1.0f);
|
||||
glm::vec3 grey(0.5f, 0.5f, 0.5f);
|
||||
|
||||
geometryCache->renderLine(*batch, glm::vec3(0, 0, 0), glm::vec3(TREE_SCALE, 0, 0), red);
|
||||
geometryCache->renderLine(*batch, glm::vec3(0, 0, 0), glm::vec3(0, TREE_SCALE, 0), green);
|
||||
geometryCache->renderLine(*batch, glm::vec3(0, 0, 0), glm::vec3(0, 0, TREE_SCALE), blue);
|
||||
geometryCache->renderLine(*batch, glm::vec3(0, 0, TREE_SCALE), glm::vec3(TREE_SCALE, 0, TREE_SCALE), grey);
|
||||
geometryCache->renderLine(*batch, glm::vec3(TREE_SCALE, 0, TREE_SCALE), glm::vec3(TREE_SCALE, 0, 0), grey);
|
||||
|
||||
auto transform = Transform{};
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(TREE_SCALE, 0.0f, 0.0f), red);
|
||||
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, TREE_SCALE, 0.0f), green);
|
||||
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, TREE_SCALE), blue);
|
||||
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, TREE_SCALE), glm::vec3(TREE_SCALE, 0.0f, TREE_SCALE), grey);
|
||||
geometryCache->renderLine(batch, glm::vec3(TREE_SCALE, 0.0f, TREE_SCALE), glm::vec3(TREE_SCALE, 0.0f, 0.0f), grey);
|
||||
|
||||
// Draw meter markers along the 3 axis to help with measuring things
|
||||
const float MARKER_DISTANCE = 1.0f;
|
||||
const float MARKER_RADIUS = 0.05f;
|
||||
|
||||
geometryCache->renderSphere(batch, MARKER_RADIUS, 10, 10, red);
|
||||
|
||||
transform.setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f));
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderSphere(batch, MARKER_RADIUS, 10, 10, red);
|
||||
|
||||
Transform transform;
|
||||
transform.setTranslation(glm::vec3(MARKER_DISTANCE, 0, 0));
|
||||
batch->setModelTransform(transform);
|
||||
geometryCache->renderSphere(*batch, MARKER_RADIUS, 10, 10, red);
|
||||
transform.setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f));
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderSphere(batch, MARKER_RADIUS, 10, 10, green);
|
||||
|
||||
transform.setTranslation(glm::vec3(0, MARKER_DISTANCE, 0));
|
||||
batch->setModelTransform(transform);
|
||||
geometryCache->renderSphere(*batch, MARKER_RADIUS, 10, 10, green);
|
||||
transform.setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE));
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderSphere(batch, MARKER_RADIUS, 10, 10, blue);
|
||||
|
||||
transform.setTranslation(glm::vec3(0, 0, MARKER_DISTANCE));
|
||||
batch->setModelTransform(transform);
|
||||
geometryCache->renderSphere(*batch, MARKER_RADIUS, 10, 10, blue);
|
||||
|
||||
transform.setTranslation(glm::vec3(MARKER_DISTANCE, 0, MARKER_DISTANCE));
|
||||
batch->setModelTransform(transform);
|
||||
geometryCache->renderSphere(*batch, MARKER_RADIUS, 10, 10, grey);
|
||||
transform.setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE));
|
||||
batch.setModelTransform(transform);
|
||||
geometryCache->renderSphere(batch, MARKER_RADIUS, 10, 10, grey);
|
||||
}
|
||||
|
||||
// Return a random vector of average length 1
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
float randFloat();
|
||||
const glm::vec3 randVector();
|
||||
|
||||
void renderWorldBox(RenderArgs* renderArgs);
|
||||
void renderWorldBox(gpu::Batch& batch);
|
||||
int widthText(float scale, int mono, char const* string);
|
||||
|
||||
void drawText(int x, int y, float scale, float radians, int mono,
|
||||
|
|
|
@ -581,9 +581,11 @@ void Avatar::simulateAttachments(float deltaTime) {
|
|||
void Avatar::renderAttachments(RenderArgs* args) {
|
||||
// RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||
// RenderArgs::SHADOW_RENDER_MODE : RenderArgs::DEFAULT_RENDER_MODE;
|
||||
/*
|
||||
foreach (Model* model, _attachmentModels) {
|
||||
model->render(args, 1.0f);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void Avatar::updateJointMappings() {
|
||||
|
|
|
@ -1580,12 +1580,16 @@ void MyAvatar::renderAttachments(RenderArgs* args) {
|
|||
QString headJointName = (geometry.headJointIndex == -1) ? QString() : geometry.joints.at(geometry.headJointIndex).name;
|
||||
// RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||
// RenderArgs::SHADOW_RENDER_MODE : RenderArgs::DEFAULT_RENDER_MODE;
|
||||
|
||||
// FIX ME - attachments need to be added to scene too...
|
||||
/*
|
||||
for (int i = 0; i < _attachmentData.size(); i++) {
|
||||
const QString& jointName = _attachmentData.at(i).jointName;
|
||||
if (jointName != headJointName && jointName != "Head") {
|
||||
_attachmentModels.at(i)->render(args, 1.0f);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//Renders sixense laser pointers for UI selection with controllers
|
||||
|
|
|
@ -15,8 +15,10 @@
|
|||
#include <QFileInfo>
|
||||
#include <QImage>
|
||||
#include <QTemporaryFile>
|
||||
#include <QUrl>
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <AddressManager.h>
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <avatar/MyAvatar.h>
|
||||
#include <FileUtils.h>
|
||||
|
@ -28,131 +30,101 @@
|
|||
|
||||
// filename format: hifi-snap-by-%username%-on-%date%_%time%_@-%location%.jpg
|
||||
// %1 <= username, %2 <= date and time, %3 <= current location
|
||||
const QString FILENAME_PATH_FORMAT = "hifi-snap-by-%1-on-%2@%3.jpg";
|
||||
const QString FILENAME_PATH_FORMAT = "hifi-snap-by-%1-on-%2.jpg";
|
||||
|
||||
const QString DATETIME_FORMAT = "yyyy-MM-dd_hh-mm-ss";
|
||||
const QString SNAPSHOTS_DIRECTORY = "Snapshots";
|
||||
|
||||
const QString LOCATION_X = "location-x";
|
||||
const QString LOCATION_Y = "location-y";
|
||||
const QString LOCATION_Z = "location-z";
|
||||
|
||||
const QString ORIENTATION_X = "orientation-x";
|
||||
const QString ORIENTATION_Y = "orientation-y";
|
||||
const QString ORIENTATION_Z = "orientation-z";
|
||||
const QString ORIENTATION_W = "orientation-w";
|
||||
|
||||
const QString DOMAIN_KEY = "domain";
|
||||
const QString URL = "highfidelity_url";
|
||||
|
||||
Setting::Handle<QString> Snapshot::snapshotsLocation("snapshotsLocation",
|
||||
QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
|
||||
QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
|
||||
|
||||
SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) {
|
||||
|
||||
|
||||
if (!QFile(snapshotPath).exists()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
QImage shot(snapshotPath);
|
||||
|
||||
|
||||
// no location data stored
|
||||
if (shot.text(LOCATION_X).isEmpty() || shot.text(LOCATION_Y).isEmpty() || shot.text(LOCATION_Z).isEmpty()) {
|
||||
if (shot.text(URL).isEmpty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// parsing URL
|
||||
QUrl url = QUrl(shot.text(URL), QUrl::ParsingMode::StrictMode);
|
||||
|
||||
SnapshotMetaData* data = new SnapshotMetaData();
|
||||
data->setLocation(glm::vec3(shot.text(LOCATION_X).toFloat(),
|
||||
shot.text(LOCATION_Y).toFloat(),
|
||||
shot.text(LOCATION_Z).toFloat()));
|
||||
|
||||
data->setOrientation(glm::quat(shot.text(ORIENTATION_W).toFloat(),
|
||||
shot.text(ORIENTATION_X).toFloat(),
|
||||
shot.text(ORIENTATION_Y).toFloat(),
|
||||
shot.text(ORIENTATION_Z).toFloat()));
|
||||
|
||||
data->setDomain(shot.text(DOMAIN_KEY));
|
||||
|
||||
data->setURL(url);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
QString Snapshot::saveSnapshot(QImage image) {
|
||||
|
||||
QFile* snapshotFile = savedFileForSnapshot(image, false);
|
||||
|
||||
|
||||
// we don't need the snapshot file, so close it, grab its filename and delete it
|
||||
snapshotFile->close();
|
||||
|
||||
|
||||
QString snapshotPath = QFileInfo(*snapshotFile).absoluteFilePath();
|
||||
|
||||
|
||||
delete snapshotFile;
|
||||
|
||||
|
||||
return snapshotPath;
|
||||
}
|
||||
|
||||
QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) {
|
||||
// return whatever we get back from saved file for snapshot
|
||||
return static_cast<QTemporaryFile*>(savedFileForSnapshot(image, true));;
|
||||
return static_cast<QTemporaryFile*>(savedFileForSnapshot(image, true));
|
||||
}
|
||||
|
||||
QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary) {
|
||||
|
||||
Avatar* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
|
||||
glm::vec3 location = avatar->getPosition();
|
||||
glm::quat orientation = avatar->getHead()->getOrientation();
|
||||
|
||||
// add metadata
|
||||
shot.setText(LOCATION_X, QString::number(location.x));
|
||||
shot.setText(LOCATION_Y, QString::number(location.y));
|
||||
shot.setText(LOCATION_Z, QString::number(location.z));
|
||||
|
||||
shot.setText(ORIENTATION_X, QString::number(orientation.x));
|
||||
shot.setText(ORIENTATION_Y, QString::number(orientation.y));
|
||||
shot.setText(ORIENTATION_Z, QString::number(orientation.z));
|
||||
shot.setText(ORIENTATION_W, QString::number(orientation.w));
|
||||
|
||||
shot.setText(DOMAIN_KEY, DependencyManager::get<NodeList>()->getDomainHandler().getHostname());
|
||||
|
||||
QString formattedLocation = QString("%1_%2_%3").arg(location.x).arg(location.y).arg(location.z);
|
||||
// replace decimal . with '-'
|
||||
formattedLocation.replace('.', '-');
|
||||
|
||||
// adding URL to snapshot
|
||||
QUrl currentURL = DependencyManager::get<AddressManager>()->currentAddress();
|
||||
shot.setText(URL, currentURL.toString());
|
||||
|
||||
QString username = AccountManager::getInstance().getAccountInfo().getUsername();
|
||||
// normalize username, replace all non alphanumeric with '-'
|
||||
username.replace(QRegExp("[^A-Za-z0-9_]"), "-");
|
||||
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
QString filename = FILENAME_PATH_FORMAT.arg(username, now.toString(DATETIME_FORMAT), formattedLocation);
|
||||
|
||||
|
||||
QString filename = FILENAME_PATH_FORMAT.arg(username, now.toString(DATETIME_FORMAT));
|
||||
|
||||
const int IMAGE_QUALITY = 100;
|
||||
|
||||
|
||||
if (!isTemporary) {
|
||||
QString snapshotFullPath = snapshotsLocation.get();
|
||||
|
||||
|
||||
if (!snapshotFullPath.endsWith(QDir::separator())) {
|
||||
snapshotFullPath.append(QDir::separator());
|
||||
}
|
||||
|
||||
|
||||
snapshotFullPath.append(filename);
|
||||
|
||||
|
||||
QFile* imageFile = new QFile(snapshotFullPath);
|
||||
imageFile->open(QIODevice::WriteOnly);
|
||||
|
||||
|
||||
shot.save(imageFile, 0, IMAGE_QUALITY);
|
||||
imageFile->close();
|
||||
|
||||
|
||||
return imageFile;
|
||||
|
||||
} else {
|
||||
QTemporaryFile* imageTempFile = new QTemporaryFile(QDir::tempPath() + "/XXXXXX-" + filename);
|
||||
|
||||
|
||||
if (!imageTempFile->open()) {
|
||||
qDebug() << "Unable to open QTemporaryFile for temp snapshot. Will not save.";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
shot.save(imageTempFile, 0, IMAGE_QUALITY);
|
||||
imageTempFile->close();
|
||||
|
||||
|
||||
return imageTempFile;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,20 +24,12 @@ class QTemporaryFile;
|
|||
|
||||
class SnapshotMetaData {
|
||||
public:
|
||||
|
||||
QString getDomain() { return _domain; }
|
||||
void setDomain(QString domain) { _domain = domain; }
|
||||
|
||||
glm::vec3 getLocation() { return _location; }
|
||||
void setLocation(glm::vec3 location) { _location = location; }
|
||||
|
||||
glm::quat getOrientation() { return _orientation; }
|
||||
void setOrientation(glm::quat orientation) { _orientation = orientation; }
|
||||
|
||||
|
||||
QUrl getURL() { return _URL; }
|
||||
void setURL(QUrl URL) { _URL = URL; }
|
||||
|
||||
private:
|
||||
QString _domain;
|
||||
glm::vec3 _location;
|
||||
glm::quat _orientation;;
|
||||
QUrl _URL;
|
||||
};
|
||||
|
||||
class Snapshot {
|
||||
|
@ -45,7 +37,7 @@ public:
|
|||
static QString saveSnapshot(QImage image);
|
||||
static QTemporaryFile* saveTempSnapshot(QImage image);
|
||||
static SnapshotMetaData* parseSnapshotData(QString snapshotPath);
|
||||
|
||||
|
||||
static Setting::Handle<QString> snapshotsLocation;
|
||||
private:
|
||||
static QFile* savedFileForSnapshot(QImage & image, bool isTemporary);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <Application.h>
|
||||
#include <GlowEffect.h>
|
||||
|
||||
#include "ModelOverlay.h"
|
||||
|
@ -54,11 +55,34 @@ void ModelOverlay::update(float deltatime) {
|
|||
_isLoaded = _model.isActive();
|
||||
}
|
||||
|
||||
bool ModelOverlay::addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
|
||||
Base3DOverlay::addToScene(overlay, scene, pendingChanges);
|
||||
_model.addToScene(scene, pendingChanges);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModelOverlay::removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
|
||||
Base3DOverlay::removeFromScene(overlay, scene, pendingChanges);
|
||||
_model.removeFromScene(scene, pendingChanges);
|
||||
}
|
||||
|
||||
void ModelOverlay::render(RenderArgs* args) {
|
||||
|
||||
// check to see if when we added our model to the scene they were ready, if they were not ready, then
|
||||
// fix them up in the scene
|
||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||
render::PendingChanges pendingChanges;
|
||||
if (_model.needsFixupInScene()) {
|
||||
_model.removeFromScene(scene, pendingChanges);
|
||||
_model.addToScene(scene, pendingChanges);
|
||||
}
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
|
||||
if (!_visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if (_model.isActive()) {
|
||||
if (_model.isRenderable()) {
|
||||
float glowLevel = getGlowLevel();
|
||||
|
@ -72,6 +96,7 @@ void ModelOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void ModelOverlay::setProperties(const QScriptValue &properties) {
|
||||
|
|
|
@ -32,6 +32,9 @@ public:
|
|||
|
||||
virtual ModelOverlay* createClone() const;
|
||||
|
||||
virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
|
||||
private:
|
||||
|
||||
Model _model;
|
||||
|
|
|
@ -228,3 +228,15 @@ float Overlay::updatePulse() {
|
|||
return _pulse;
|
||||
}
|
||||
|
||||
bool Overlay::addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
|
||||
auto overlayPayload = new Overlay::Payload(overlay);
|
||||
auto overlayPayloadPointer = Overlay::PayloadPointer(overlayPayload);
|
||||
_renderItemID = scene->allocateID();
|
||||
pendingChanges.resetItem(_renderItemID, overlayPayloadPointer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Overlay::removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
|
||||
pendingChanges.removeItem(_renderItemID);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ public:
|
|||
virtual void update(float deltatime) {}
|
||||
virtual void render(RenderArgs* args) = 0;
|
||||
|
||||
virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
|
||||
// getters
|
||||
virtual bool is3D() const = 0;
|
||||
bool isLoaded() { return _isLoaded; }
|
||||
|
@ -117,5 +120,11 @@ protected:
|
|||
QScriptEngine* _scriptEngine;
|
||||
};
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay);
|
||||
template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay);
|
||||
template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args);
|
||||
}
|
||||
|
||||
|
||||
#endif // hifi_Overlay_h
|
||||
|
|
|
@ -33,49 +33,6 @@
|
|||
#include "Text3DOverlay.h"
|
||||
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) {
|
||||
if (overlay->is3D() && !static_cast<Base3DOverlay*>(overlay.get())->getDrawOnHUD()) {
|
||||
if (static_cast<Base3DOverlay*>(overlay.get())->getDrawInFront()) {
|
||||
return ItemKey::Builder().withTypeShape().withNoDepthSort().build();
|
||||
} else {
|
||||
return ItemKey::Builder::opaqueShape();
|
||||
}
|
||||
} else {
|
||||
return ItemKey::Builder().withTypeShape().withViewSpace().build();
|
||||
}
|
||||
}
|
||||
template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay) {
|
||||
if (overlay->is3D()) {
|
||||
return static_cast<Base3DOverlay*>(overlay.get())->getBounds();
|
||||
} else {
|
||||
QRect bounds = static_cast<Overlay2D*>(overlay.get())->getBounds();
|
||||
return AABox(glm::vec3(bounds.x(), bounds.y(), 0.0f), glm::vec3(bounds.width(), bounds.height(), 0.1f));
|
||||
}
|
||||
}
|
||||
template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) {
|
||||
if (args) {
|
||||
args->_elementsTouched++;
|
||||
|
||||
glPushMatrix();
|
||||
if (overlay->getAnchor() == Overlay::MY_AVATAR) {
|
||||
MyAvatar* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
glm::quat myAvatarRotation = avatar->getOrientation();
|
||||
glm::vec3 myAvatarPosition = avatar->getPosition();
|
||||
float angle = glm::degrees(glm::angle(myAvatarRotation));
|
||||
glm::vec3 axis = glm::axis(myAvatarRotation);
|
||||
float myAvatarScale = avatar->getScale();
|
||||
|
||||
glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z);
|
||||
glRotatef(angle, axis.x, axis.y, axis.z);
|
||||
glScalef(myAvatarScale, myAvatarScale, myAvatarScale);
|
||||
}
|
||||
overlay->render(args);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Overlays::Overlays() : _nextOverlayID(1) {
|
||||
}
|
||||
|
||||
|
@ -118,6 +75,7 @@ void Overlays::update(float deltatime) {
|
|||
|
||||
void Overlays::cleanupOverlaysToDelete() {
|
||||
if (!_overlaysToDelete.isEmpty()) {
|
||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||
render::PendingChanges pendingChanges;
|
||||
|
||||
{
|
||||
|
@ -128,13 +86,12 @@ void Overlays::cleanupOverlaysToDelete() {
|
|||
|
||||
auto itemID = overlay->getRenderItemID();
|
||||
if (itemID != render::Item::INVALID_ITEM_ID) {
|
||||
pendingChanges.removeItem(itemID);
|
||||
overlay->removeFromScene(overlay, scene, pendingChanges);
|
||||
}
|
||||
} while (!_overlaysToDelete.isEmpty());
|
||||
}
|
||||
|
||||
if (pendingChanges._removedItems.size() > 0) {
|
||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
}
|
||||
|
@ -216,13 +173,9 @@ unsigned int Overlays::addOverlay(Overlay* overlay) {
|
|||
_overlaysWorld[thisID] = overlayPointer;
|
||||
|
||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||
auto overlayPayload = new Overlay::Payload(overlayPointer);
|
||||
auto overlayPayloadPointer = Overlay::PayloadPointer(overlayPayload);
|
||||
render::ItemID itemID = scene->allocateID();
|
||||
overlay->setRenderItemID(itemID);
|
||||
|
||||
render::PendingChanges pendingChanges;
|
||||
pendingChanges.resetItem(itemID, overlayPayloadPointer);
|
||||
|
||||
overlayPointer->addToScene(overlayPointer, scene, pendingChanges);
|
||||
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
|
77
interface/src/ui/overlays/OverlaysPayload.cpp
Normal file
77
interface/src/ui/overlays/OverlaysPayload.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// OverlaysPayload.cpp
|
||||
// interface/src/ui/overlays
|
||||
//
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QScriptValueIterator>
|
||||
|
||||
#include <limits>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <Application.h>
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <LODManager.h>
|
||||
#include <render/Scene.h>
|
||||
|
||||
#include "BillboardOverlay.h"
|
||||
#include "Circle3DOverlay.h"
|
||||
#include "Cube3DOverlay.h"
|
||||
#include "ImageOverlay.h"
|
||||
#include "Line3DOverlay.h"
|
||||
#include "LocalModelsOverlay.h"
|
||||
#include "ModelOverlay.h"
|
||||
#include "Overlays.h"
|
||||
#include "Rectangle3DOverlay.h"
|
||||
#include "Sphere3DOverlay.h"
|
||||
#include "Grid3DOverlay.h"
|
||||
#include "TextOverlay.h"
|
||||
#include "Text3DOverlay.h"
|
||||
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) {
|
||||
if (overlay->is3D() && !static_cast<Base3DOverlay*>(overlay.get())->getDrawOnHUD()) {
|
||||
if (static_cast<Base3DOverlay*>(overlay.get())->getDrawInFront()) {
|
||||
return ItemKey::Builder().withTypeShape().withNoDepthSort().build();
|
||||
} else {
|
||||
return ItemKey::Builder::opaqueShape();
|
||||
}
|
||||
} else {
|
||||
return ItemKey::Builder().withTypeShape().withViewSpace().build();
|
||||
}
|
||||
}
|
||||
template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay) {
|
||||
if (overlay->is3D()) {
|
||||
return static_cast<Base3DOverlay*>(overlay.get())->getBounds();
|
||||
} else {
|
||||
QRect bounds = static_cast<Overlay2D*>(overlay.get())->getBounds();
|
||||
return AABox(glm::vec3(bounds.x(), bounds.y(), 0.0f), glm::vec3(bounds.width(), bounds.height(), 0.1f));
|
||||
}
|
||||
}
|
||||
template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) {
|
||||
if (args) {
|
||||
args->_elementsTouched++;
|
||||
|
||||
glPushMatrix();
|
||||
if (overlay->getAnchor() == Overlay::MY_AVATAR) {
|
||||
MyAvatar* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
glm::quat myAvatarRotation = avatar->getOrientation();
|
||||
glm::vec3 myAvatarPosition = avatar->getPosition();
|
||||
float angle = glm::degrees(glm::angle(myAvatarRotation));
|
||||
glm::vec3 axis = glm::axis(myAvatarRotation);
|
||||
float myAvatarScale = avatar->getScale();
|
||||
|
||||
glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z);
|
||||
glRotatef(angle, axis.x, axis.y, axis.z);
|
||||
glScalef(myAvatarScale, myAvatarScale, myAvatarScale);
|
||||
}
|
||||
overlay->render(args);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -493,45 +493,22 @@ void EntityTreeRenderer::render(RenderArgs* renderArgs) {
|
|||
if (_tree && !_shuttingDown) {
|
||||
renderArgs->_renderer = this;
|
||||
|
||||
checkPendingAddToScene(renderArgs);
|
||||
|
||||
Model::startScene(renderArgs->_renderSide);
|
||||
|
||||
ViewFrustum* frustum = (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||
_viewState->getShadowViewFrustum() : _viewState->getCurrentViewFrustum();
|
||||
|
||||
// Setup batch transform matrices
|
||||
gpu::Batch batch; // FIX ME - this is very suspicious!
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
frustum->evalProjectionMatrix(projMat);
|
||||
frustum->evalViewTransform(viewMat);
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
||||
renderArgs->_batch = &batch; // FIX ME - this is very suspicious!
|
||||
|
||||
_tree->lockForRead();
|
||||
|
||||
// Whenever you're in an intersection between zones, we will always choose the smallest zone.
|
||||
_bestZone = NULL; // NOTE: Is this what we want?
|
||||
_bestZoneVolume = std::numeric_limits<float>::max();
|
||||
|
||||
// FIX ME: right now the renderOperation does the following:
|
||||
// 1) determining the best zone (not really rendering)
|
||||
// 2) render the debug cell details
|
||||
// we should clean this up
|
||||
_tree->recurseTreeWithOperation(renderOperation, renderArgs);
|
||||
|
||||
applyZonePropertiesToScene(_bestZone);
|
||||
|
||||
// we must call endScene while we still have the tree locked so that no one deletes a model
|
||||
// on us while rendering the scene
|
||||
Model::endScene(renderArgs);
|
||||
_tree->unlock();
|
||||
|
||||
// FIX ME - this is very suspicious!
|
||||
// glPushMatrix();
|
||||
// renderArgs->_context->render(batch);
|
||||
// glPopMatrix();
|
||||
|
||||
renderArgs->_batch = nullptr;
|
||||
|
||||
// stats...
|
||||
_meshesConsidered = renderArgs->_meshesConsidered;
|
||||
_meshesRendered = renderArgs->_meshesRendered;
|
||||
|
@ -715,39 +692,6 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hack for models and other entities that don't yet play well with others. :(
|
||||
if (!entityItem->canRenderInScene()) {
|
||||
// render entityItem
|
||||
AABox entityBox = entityItem->getAABox();
|
||||
|
||||
// TODO: some entity types (like lights) might want to be rendered even
|
||||
// when they are outside of the view frustum...
|
||||
float distance = args->_viewFrustum->distanceToCamera(entityBox.calcCenter());
|
||||
|
||||
bool outOfView = args->_viewFrustum->boxInFrustum(entityBox) == ViewFrustum::OUTSIDE;
|
||||
if (!outOfView) {
|
||||
bool bigEnoughToRender = _viewState->shouldRenderMesh(entityBox.getLargestDimension(), distance);
|
||||
|
||||
if (bigEnoughToRender) {
|
||||
renderProxies(entityItem, args);
|
||||
|
||||
Glower* glower = NULL;
|
||||
if (entityItem->getGlowLevel() > 0.0f) {
|
||||
glower = new Glower(args, entityItem->getGlowLevel());
|
||||
}
|
||||
entityItem->render(args);
|
||||
args->_itemsRendered++;
|
||||
if (glower) {
|
||||
delete glower;
|
||||
}
|
||||
} else {
|
||||
args->_itemsTooSmall++;
|
||||
}
|
||||
} else {
|
||||
args->_itemsOutOfView++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1093,34 +1037,14 @@ void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
|
|||
|
||||
void EntityTreeRenderer::addEntityToScene(EntityItemPointer entity) {
|
||||
// here's where we add the entity payload to the scene
|
||||
if (entity && entity->canRenderInScene()) {
|
||||
if (entity->readyToAddToScene()) {
|
||||
render::PendingChanges pendingChanges;
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
if (entity->addToScene(entity, scene, pendingChanges)) {
|
||||
_entitiesInScene.insert(entity);
|
||||
}
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
} else {
|
||||
if (!_pendingAddToScene.contains(entity)) {
|
||||
_pendingAddToScene << entity;
|
||||
}
|
||||
}
|
||||
render::PendingChanges pendingChanges;
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
if (entity->addToScene(entity, scene, pendingChanges)) {
|
||||
_entitiesInScene.insert(entity);
|
||||
}
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::checkPendingAddToScene(RenderArgs* renderArgs) {
|
||||
QSet<EntityItemPointer> addedToScene;
|
||||
foreach (auto entity, _pendingAddToScene) {
|
||||
if (entity->readyToAddToScene(renderArgs)) {
|
||||
addEntityToScene(entity);
|
||||
addedToScene << entity;
|
||||
}
|
||||
}
|
||||
foreach (auto addedEntity, addedToScene) {
|
||||
_pendingAddToScene.remove(addedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) {
|
||||
if (_tree && !_shuttingDown) {
|
||||
|
|
|
@ -123,9 +123,7 @@ protected:
|
|||
virtual Octree* createTree() { return new EntityTree(true); }
|
||||
|
||||
private:
|
||||
void checkPendingAddToScene(RenderArgs* renderArgs);
|
||||
void addEntityToScene(EntityItemPointer entity);
|
||||
QSet<EntityItemPointer> _pendingAddToScene;
|
||||
|
||||
void applyZonePropertiesToScene(std::shared_ptr<ZoneEntityItem> zone);
|
||||
void renderElementProxy(EntityTreeElement* entityTreeElement, RenderArgs* args);
|
||||
|
|
|
@ -32,9 +32,7 @@ namespace render {
|
|||
if (args) {
|
||||
args->_elementsTouched++;
|
||||
if (payload && payload->entity) {
|
||||
if (payload->entity->getType() != EntityTypes::Model) {
|
||||
payload->entity->render(args);
|
||||
}
|
||||
payload->entity->render(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ private:
|
|||
|
||||
#define SIMPLE_RENDERABLE() \
|
||||
public: \
|
||||
virtual bool canRenderInScene() { return true; } \
|
||||
virtual bool addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) { return _renderHelper.addToScene(self, scene, pendingChanges); } \
|
||||
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) { _renderHelper.removeFromScene(self, scene, pendingChanges); } \
|
||||
private: \
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define hifi_RenderableLightEntityItem_h
|
||||
|
||||
#include <LightEntityItem.h>
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
class RenderableLightEntityItem : public LightEntityItem {
|
||||
public:
|
||||
|
@ -22,12 +23,13 @@ public:
|
|||
LightEntityItem(entityItemID, properties)
|
||||
{ }
|
||||
|
||||
virtual bool canRenderInScene() { return false; } // we don't yet play well with others
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject, bool precisionPicking) const;
|
||||
|
||||
SIMPLE_RENDERABLE();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,32 +24,32 @@ EntityItemPointer RenderableLineEntityItem::factory(const EntityItemID& entityID
|
|||
return EntityItemPointer(new RenderableLineEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
void RenderableLineEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
||||
Q_ASSERT(getType() == EntityTypes::Line);
|
||||
glm::vec3 p1 = ENTITY_ITEM_ZERO_VEC3;
|
||||
glm::vec3 p2 = getDimensions();
|
||||
glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||
|
||||
Q_ASSERT(args->_batch);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
batch.setModelTransform(getTransformToCenter());
|
||||
|
||||
glLineWidth(getLineWidth());
|
||||
void RenderableLineEntityItem::updateGeometry() {
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {
|
||||
_lineVerticesID = geometryCache ->allocateID();
|
||||
}
|
||||
|
||||
//TODO: Figure out clean , efficient way to do relative line positioning. For now we'll just use absolute positioning.
|
||||
//glTranslatef(position.x, position.y, position.z);
|
||||
//glm::vec3 axis = glm::axis(rotation);
|
||||
//glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
if (_pointsChanged) {
|
||||
geometryCache->updateVertices(_lineVerticesID, getLinePoints(), lineColor);
|
||||
glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||
geometryCache->updateVertices(_lineVerticesID, getLinePoints(), lineColor);
|
||||
_pointsChanged = false;
|
||||
}
|
||||
geometryCache->renderVertices(gpu::LINE_STRIP, _lineVerticesID);
|
||||
}
|
||||
|
||||
void RenderableLineEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
||||
Q_ASSERT(getType() == EntityTypes::Line);
|
||||
updateGeometry();
|
||||
|
||||
Q_ASSERT(args->_batch);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
// TODO: Figure out clean , efficient way to do relative line positioning. For now we'll just use absolute positioning.
|
||||
//batch.setModelTransform(getTransformToCenter());
|
||||
batch.setModelTransform(Transform());
|
||||
|
||||
batch._glLineWidth(getLineWidth());
|
||||
DependencyManager::get<GeometryCache>()->renderVertices(batch, gpu::LINE_STRIP, _lineVerticesID);
|
||||
batch._glLineWidth(1.0f);
|
||||
|
||||
RenderableDebugableEntityItem::render(this, args);
|
||||
};
|
||||
|
|
|
@ -28,9 +28,11 @@ public:
|
|||
|
||||
virtual void render(RenderArgs* args);
|
||||
|
||||
SIMPLE_RENDERABLE()
|
||||
SIMPLE_RENDERABLE();
|
||||
|
||||
protected:
|
||||
void updateGeometry();
|
||||
|
||||
int _lineVerticesID;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <AbstractViewStateInterface.h>
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <Model.h>
|
||||
#include <PerfStat.h>
|
||||
|
@ -210,6 +211,19 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
if (hasModel()) {
|
||||
if (_model) {
|
||||
// check to see if when we added our models to the scene they were ready, if they were not ready, then
|
||||
// fix them up in the scene
|
||||
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||
render::PendingChanges pendingChanges;
|
||||
if (_model->needsFixupInScene()) {
|
||||
_model->removeFromScene(scene, pendingChanges);
|
||||
_model->addToScene(scene, pendingChanges);
|
||||
}
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
||||
|
||||
remapTextures();
|
||||
{
|
||||
float alpha = getLocalRenderAlpha();
|
||||
|
|
|
@ -43,7 +43,6 @@ public:
|
|||
|
||||
virtual void somethingChangedNotification() { _needsInitialSimulation = true; }
|
||||
|
||||
virtual bool canRenderInScene() { return true; }
|
||||
virtual bool readyToAddToScene(RenderArgs* renderArgs = nullptr);
|
||||
virtual bool addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
|
||||
void updateQuads(RenderArgs* args, bool textured);
|
||||
|
||||
SIMPLE_RENDERABLE()
|
||||
SIMPLE_RENDERABLE();
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "PolyVoxEntityItem.h"
|
||||
#include "RenderableDebugableEntityItem.h"
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
class RenderablePolyVoxEntityItem : public PolyVoxEntityItem {
|
||||
public:
|
||||
|
@ -70,6 +71,8 @@ public:
|
|||
virtual void setAll(uint8_t toValue);
|
||||
|
||||
virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue);
|
||||
|
||||
SIMPLE_RENDERABLE();
|
||||
|
||||
private:
|
||||
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
|
||||
virtual void render(RenderArgs* args);
|
||||
|
||||
SIMPLE_RENDERABLE()
|
||||
SIMPLE_RENDERABLE();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <TextEntityItem.h>
|
||||
#include <TextRenderer3D.h>
|
||||
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
const int FIXED_FONT_POINT_SIZE = 40;
|
||||
|
||||
class RenderableTextEntityItem : public TextEntityItem {
|
||||
|
@ -27,7 +29,8 @@ public:
|
|||
~RenderableTextEntityItem() { delete _textRenderer; }
|
||||
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual bool canRenderInScene() { return false; } // we don't yet play well with others
|
||||
|
||||
SIMPLE_RENDERABLE();
|
||||
|
||||
private:
|
||||
TextRenderer3D* _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE / 2.0f);
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include <WebEntityItem.h>
|
||||
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
class OffscreenQmlSurface;
|
||||
|
||||
class RenderableWebEntityItem : public WebEntityItem {
|
||||
|
@ -24,7 +26,8 @@ public:
|
|||
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual void setSourceUrl(const QString& value);
|
||||
virtual bool canRenderInScene() { return false; } // we don't yet play well with others
|
||||
|
||||
SIMPLE_RENDERABLE();
|
||||
|
||||
private:
|
||||
OffscreenQmlSurface* _webSurface{ nullptr };
|
||||
|
|
|
@ -102,7 +102,8 @@ void RenderableZoneEntityItem::render(RenderArgs* args) {
|
|||
updateGeometry();
|
||||
|
||||
if (_model && _model->isActive()) {
|
||||
_model->renderInScene(getLocalRenderAlpha(), args);
|
||||
// FIX ME: this is no longer available... we need to switch to payloads
|
||||
//_model->renderInScene(getLocalRenderAlpha(), args);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -157,8 +157,6 @@ public:
|
|||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData)
|
||||
{ return 0; }
|
||||
|
||||
virtual bool canRenderInScene() { return false; } // does your entity property render using Render Items and Payloads
|
||||
virtual bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return true; } // we assume you're ready to add
|
||||
virtual bool addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene,
|
||||
render::PendingChanges& pendingChanges) { return false; } // by default entity items don't add to scene
|
||||
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene,
|
||||
|
|
|
@ -157,6 +157,7 @@ public:
|
|||
void _glDisableVertexAttribArray(GLint location);
|
||||
|
||||
void _glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
void _glLineWidth(GLfloat width);
|
||||
|
||||
enum Command {
|
||||
COMMAND_draw = 0,
|
||||
|
@ -216,6 +217,7 @@ public:
|
|||
COMMAND_glDisableVertexAttribArray,
|
||||
|
||||
COMMAND_glColor4f,
|
||||
COMMAND_glLineWidth,
|
||||
|
||||
NUM_COMMANDS,
|
||||
};
|
||||
|
|
|
@ -66,8 +66,9 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
|
||||
(&::gpu::GLBackend::do_glEnableVertexAttribArray),
|
||||
(&::gpu::GLBackend::do_glDisableVertexAttribArray),
|
||||
|
||||
|
||||
(&::gpu::GLBackend::do_glColor4f),
|
||||
(&::gpu::GLBackend::do_glLineWidth),
|
||||
};
|
||||
|
||||
GLBackend::GLBackend() :
|
||||
|
@ -566,6 +567,18 @@ void GLBackend::do_glColor4f(Batch& batch, uint32 paramOffset) {
|
|||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glLineWidth(GLfloat width) {
|
||||
ADD_COMMAND_GL(glLineWidth);
|
||||
|
||||
_params.push_back(width);
|
||||
|
||||
DO_IT_NOW(_glLineWidth, 1);
|
||||
}
|
||||
void GLBackend::do_glLineWidth(Batch& batch, uint32 paramOffset) {
|
||||
glLineWidth(batch._params[paramOffset]._float);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GLBackend::loadMatrix(GLenum target, const glm::mat4 & m) {
|
||||
glMatrixMode(target);
|
||||
glLoadMatrixf(glm::value_ptr(m));
|
||||
|
|
|
@ -370,8 +370,9 @@ protected:
|
|||
|
||||
void do_glEnableVertexAttribArray(Batch& batch, uint32 paramOffset);
|
||||
void do_glDisableVertexAttribArray(Batch& batch, uint32 paramOffset);
|
||||
|
||||
|
||||
void do_glColor4f(Batch& batch, uint32 paramOffset);
|
||||
void do_glLineWidth(Batch& batch, uint32 paramOffset);
|
||||
|
||||
typedef void (GLBackend::*CommandCall)(Batch&, uint32);
|
||||
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
|
||||
|
|
|
@ -925,6 +925,7 @@ void Model::removeFromScene(std::shared_ptr<render::Scene> scene, render::Pendin
|
|||
}
|
||||
|
||||
bool Model::render(RenderArgs* renderArgs, float alpha) {
|
||||
return true; //
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
// render the attachments
|
||||
|
@ -1994,15 +1995,6 @@ void Model::deleteGeometry() {
|
|||
_blendedBlendshapeCoefficients.clear();
|
||||
}
|
||||
|
||||
// Scene rendering support
|
||||
QVector<Model*> Model::_modelsInScene;
|
||||
gpu::Batch Model::_sceneRenderBatch;
|
||||
void Model::startScene(RenderArgs::RenderSide renderSide) {
|
||||
if (renderSide != RenderArgs::STEREO_RIGHT) {
|
||||
_modelsInScene.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) {
|
||||
|
||||
// Capture the view matrix once for the rendering of this model
|
||||
|
@ -2019,231 +2011,6 @@ void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) {
|
|||
batch.setViewTransform(_transforms[0]);
|
||||
}
|
||||
|
||||
void Model::endScene(RenderArgs* args) {
|
||||
// Now that we migrated everything to the new RENDER/SCENE no more work to do!
|
||||
return;
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
|
||||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_LEGACY)
|
||||
// with legacy transform profile, we still to protect that transform stack...
|
||||
glPushMatrix();
|
||||
#endif
|
||||
|
||||
auto mode = args->_renderMode;
|
||||
|
||||
RenderArgs::RenderSide renderSide = RenderArgs::MONO;
|
||||
if (args) {
|
||||
renderSide = args->_renderSide;
|
||||
}
|
||||
|
||||
|
||||
gpu::GLBackend backend;
|
||||
backend.syncCache(); // force sync with gl state here
|
||||
|
||||
if (args) {
|
||||
glm::mat4 proj;
|
||||
// If for easier debug depending on the pass
|
||||
if (mode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||
args->_viewFrustum->evalProjectionMatrix(proj);
|
||||
} else {
|
||||
args->_viewFrustum->evalProjectionMatrix(proj);
|
||||
}
|
||||
gpu::Batch batch;
|
||||
batch.setProjectionTransform(proj);
|
||||
backend.render(batch);
|
||||
}
|
||||
|
||||
// Do the rendering batch creation for mono or left eye, not for right eye
|
||||
if (renderSide != RenderArgs::STEREO_RIGHT) {
|
||||
// Let's introduce a gpu::Batch to capture all the calls to the graphics api
|
||||
_sceneRenderBatch.clear();
|
||||
gpu::Batch& batch = _sceneRenderBatch;
|
||||
|
||||
/*DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(
|
||||
mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE,
|
||||
mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE,
|
||||
mode == RenderArgs::DEFAULT_RENDER_MODE);
|
||||
*/
|
||||
|
||||
/* if (mode != RenderArgs::SHADOW_RENDER_MODE) */{
|
||||
GLenum buffers[3];
|
||||
|
||||
int bufferCount = 0;
|
||||
// if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE) {
|
||||
if (mode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
|
||||
}
|
||||
//if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE) {
|
||||
if (mode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
|
||||
}
|
||||
// if (mode == RenderArgs::DEFAULT_RENDER_MODE) {
|
||||
if (mode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
|
||||
}
|
||||
GLBATCH(glDrawBuffers)(bufferCount, buffers);
|
||||
|
||||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryOpaqueFramebuffer());
|
||||
}
|
||||
|
||||
const float DEFAULT_ALPHA_THRESHOLD = 0.5f;
|
||||
|
||||
int opaqueMeshPartsRendered = 0;
|
||||
|
||||
// now, for each model in the scene, render the mesh portions
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, false, args);
|
||||
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, false, args);
|
||||
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, true, args);
|
||||
|
||||
// render translucent meshes afterwards
|
||||
{
|
||||
GLenum buffers[2];
|
||||
int bufferCount = 0;
|
||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
|
||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
|
||||
GLBATCH(glDrawBuffers)(bufferCount, buffers);
|
||||
}
|
||||
|
||||
int translucentParts = 0;
|
||||
const float MOSTLY_OPAQUE_THRESHOLD = 0.75f;
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, false, args);
|
||||
|
||||
|
||||
{
|
||||
GLenum buffers[1];
|
||||
int bufferCount = 0;
|
||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
|
||||
GLBATCH(glDrawBuffers)(bufferCount, buffers);
|
||||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryTransparentFramebuffer());
|
||||
}
|
||||
|
||||
// if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE) {
|
||||
if (mode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryTransparentFramebuffer());
|
||||
|
||||
const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f;
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, false, args);
|
||||
|
||||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryOpaqueFramebuffer());
|
||||
}
|
||||
|
||||
GLBATCH(glDepthMask)(true);
|
||||
GLBATCH(glDepthFunc)(GL_LESS);
|
||||
GLBATCH(glDisable)(GL_CULL_FACE);
|
||||
|
||||
if (mode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||
GLBATCH(glCullFace)(GL_BACK);
|
||||
}
|
||||
|
||||
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0 + 1);
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0 + 2);
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0 + 3);
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
|
||||
|
||||
|
||||
// deactivate vertex arrays after drawing
|
||||
GLBATCH(glDisableClientState)(GL_NORMAL_ARRAY);
|
||||
GLBATCH(glDisableClientState)(GL_VERTEX_ARRAY);
|
||||
GLBATCH(glDisableClientState)(GL_TEXTURE_COORD_ARRAY);
|
||||
GLBATCH(glDisableClientState)(GL_COLOR_ARRAY);
|
||||
GLBATCH(glDisableVertexAttribArray)(gpu::Stream::TANGENT);
|
||||
GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_INDEX);
|
||||
GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_WEIGHT);
|
||||
|
||||
// bind with 0 to switch back to normal operation
|
||||
GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, 0);
|
||||
GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Back to no program
|
||||
GLBATCH(glUseProgram)(0);
|
||||
|
||||
if (args) {
|
||||
args->_translucentMeshPartsRendered = translucentParts;
|
||||
args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Render!
|
||||
{
|
||||
PROFILE_RANGE("render Batch");
|
||||
backend.render(_sceneRenderBatch);
|
||||
}
|
||||
|
||||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_LEGACY)
|
||||
// with legacy transform profile, we still to protect that transform stack...
|
||||
glPopMatrix();
|
||||
#endif
|
||||
|
||||
// restore all the default material settings
|
||||
_viewState->setupWorldLight();
|
||||
|
||||
}
|
||||
|
||||
bool Model::renderInScene(float alpha, RenderArgs* args) {
|
||||
// render the attachments
|
||||
foreach (Model* attachment, _attachments) {
|
||||
attachment->renderInScene(alpha);
|
||||
}
|
||||
if (_meshStates.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args->_debugFlags == RenderArgs::RENDER_DEBUG_HULLS && _renderCollisionHull == false) {
|
||||
// turning collision hull rendering on
|
||||
_renderCollisionHull = true;
|
||||
_nextGeometry = _collisionGeometry;
|
||||
_saveNonCollisionGeometry = _geometry;
|
||||
updateGeometry();
|
||||
simulate(0.0, true);
|
||||
} else if (args->_debugFlags != RenderArgs::RENDER_DEBUG_HULLS && _renderCollisionHull == true) {
|
||||
// turning collision hull rendering off
|
||||
_renderCollisionHull = false;
|
||||
_nextGeometry = _saveNonCollisionGeometry;
|
||||
_saveNonCollisionGeometry.clear();
|
||||
updateGeometry();
|
||||
simulate(0.0, true);
|
||||
}
|
||||
|
||||
renderSetup(args);
|
||||
_modelsInScene.push_back(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
AABox Model::getPartBounds(int meshIndex, int partIndex) {
|
||||
if (!_calculatedMeshPartBoxesValid) {
|
||||
|
@ -2320,19 +2087,14 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
|
|||
if (isSkinned) {
|
||||
GLBATCH(glUniformMatrix4fv)(locations->clusterMatrices, state.clusterMatrices.size(), false,
|
||||
(const float*)state.clusterMatrices.constData());
|
||||
|
||||
_transforms[0].setIdentity();
|
||||
_transforms[0].setTranslation(_translation);
|
||||
batch.setModelTransform(_transforms[0]);
|
||||
_transforms[0] = Transform();
|
||||
_transforms[0].preTranslate(_translation);
|
||||
} else {
|
||||
_transforms[0] = Transform(state.clusterMatrices[0]);
|
||||
_transforms[0].preTranslate(_translation);
|
||||
|
||||
//batch.setModelTransform(Transform(state.clusterMatrices[0]));
|
||||
batch.setModelTransform(_transforms[0]);
|
||||
}
|
||||
|
||||
// Input stage
|
||||
batch.setModelTransform(_transforms[0]);
|
||||
|
||||
if (mesh.blendshapes.isEmpty()) {
|
||||
batch.setInputFormat(networkMesh._vertexFormat);
|
||||
batch.setInputStream(0, *networkMesh._vertexStream);
|
||||
|
@ -2347,8 +2109,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
|
|||
GLBATCH(glColor4f)(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
qint64 offset = 0;
|
||||
|
||||
// guard against partially loaded meshes
|
||||
if (partIndex >= networkMesh.parts.size() || partIndex >= mesh.parts.size()) {
|
||||
return;
|
||||
|
@ -2439,6 +2199,20 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
|
|||
|
||||
meshPartsRendered++;
|
||||
|
||||
// FIX ME This is very unefficient
|
||||
qint64 offset = 0;
|
||||
for (int j = 0; j < partIndex; j++) {
|
||||
const NetworkMeshPart& networkPart = networkMesh.parts.at(j);
|
||||
const FBXMeshPart& part = mesh.parts.at(j);
|
||||
if ((networkPart.isTranslucent() || part.opacity != 1.0f) != translucent) {
|
||||
offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int);
|
||||
continue;
|
||||
}
|
||||
|
||||
offset += part.quadIndices.size() * sizeof(int);
|
||||
offset += part.triangleIndices.size() * sizeof(int);
|
||||
}
|
||||
|
||||
if (part.quadIndices.size() > 0) {
|
||||
batch.drawIndexed(gpu::QUADS, part.quadIndices.size(), offset);
|
||||
offset += part.quadIndices.size() * sizeof(int);
|
||||
|
@ -2577,34 +2351,6 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
|||
}
|
||||
}
|
||||
|
||||
int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args) {
|
||||
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
int meshPartsRendered = 0;
|
||||
|
||||
bool pickProgramsNeeded = true;
|
||||
Locations* locations = nullptr;
|
||||
|
||||
foreach(Model* model, _modelsInScene) {
|
||||
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
|
||||
if (whichList) {
|
||||
QVector<int>& list = *whichList;
|
||||
if (list.size() > 0) {
|
||||
if (pickProgramsNeeded) {
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe, args, locations);
|
||||
pickProgramsNeeded = false;
|
||||
}
|
||||
|
||||
model->setupBatchTransform(batch, args);
|
||||
meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return meshPartsRendered;
|
||||
}
|
||||
|
||||
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
|
||||
bool forceRenderSomeMeshes) {
|
||||
|
|
|
@ -114,14 +114,8 @@ public:
|
|||
void reset();
|
||||
virtual void simulate(float deltaTime, bool fullUpdate = true);
|
||||
|
||||
bool render(RenderArgs* renderArgs, float alpha = 1.0f);
|
||||
void renderSetup(RenderArgs* args);
|
||||
|
||||
// Scene rendering support
|
||||
static void startScene(RenderArgs::RenderSide renderSide);
|
||||
bool renderInScene(float alpha = 1.0f, RenderArgs* args = NULL);
|
||||
static void endScene(RenderArgs* args);
|
||||
|
||||
// new Scene/Engine rendering support
|
||||
bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); }
|
||||
bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return isRenderable() && isActive() && isLoadedWithTextures(); }
|
||||
|
@ -393,13 +387,6 @@ private:
|
|||
void renderDebugMeshBoxes();
|
||||
int _debugMeshBoxesID = GeometryCache::UNKNOWN_ID;
|
||||
|
||||
// Scene rendering support
|
||||
static QVector<Model*> _modelsInScene;
|
||||
static gpu::Batch _sceneRenderBatch;
|
||||
|
||||
static void endSceneSimple(RenderArgs::RenderMode mode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs* args = NULL);
|
||||
static void endSceneSplitPass(RenderArgs::RenderMode mode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs* args = NULL);
|
||||
|
||||
// helper functions used by render() or renderInScene()
|
||||
bool renderCore(RenderArgs* args, float alpha);
|
||||
int renderMeshes(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
|
@ -417,10 +404,6 @@ private:
|
|||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
|
||||
Locations*& locations);
|
||||
|
||||
static int renderMeshesForModelsInScene(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args);
|
||||
|
||||
|
||||
static AbstractViewStateInterface* _viewState;
|
||||
|
||||
class RenderKey {
|
||||
|
@ -547,6 +530,14 @@ private:
|
|||
QSet<std::shared_ptr<OpaqueMeshPart>> _opaqueRenderItems;
|
||||
QSet<render::ItemID> _renderItems;
|
||||
bool _readyWhenAdded = false;
|
||||
|
||||
|
||||
private:
|
||||
// FIX ME - We want to get rid of this interface for rendering...
|
||||
// right now the only remaining user are Avatar attachments.
|
||||
// that usage has been temporarily disabled...
|
||||
bool render(RenderArgs* renderArgs, float alpha = 1.0f);
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QPointer<Model>)
|
||||
|
|
|
@ -16,6 +16,17 @@
|
|||
OffscreenGlCanvas::OffscreenGlCanvas() {
|
||||
}
|
||||
|
||||
OffscreenGlCanvas::~OffscreenGlCanvas() {
|
||||
#ifdef DEBUG
|
||||
if (_logger) {
|
||||
makeCurrent();
|
||||
delete _logger;
|
||||
_logger = nullptr;
|
||||
}
|
||||
#endif
|
||||
_context.doneCurrent();
|
||||
}
|
||||
|
||||
void OffscreenGlCanvas::create(QOpenGLContext* sharedContext) {
|
||||
if (nullptr != sharedContext) {
|
||||
sharedContext->doneCurrent();
|
||||
|
|
|
@ -20,6 +20,7 @@ class QOpenGLDebugLogger;
|
|||
class OffscreenGlCanvas : public QObject {
|
||||
public:
|
||||
OffscreenGlCanvas();
|
||||
~OffscreenGlCanvas();
|
||||
void create(QOpenGLContext* sharedContext = nullptr);
|
||||
bool makeCurrent();
|
||||
void doneCurrent();
|
||||
|
|
Loading…
Reference in a new issue