mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 14:52:46 +02:00
Merge pull request #5041 from ZappoMan/team-teaching-all-entities
TEAM TEACHING - overlays and entities, fix to shrunken avatars
This commit is contained in:
commit
7ffe7b31a6
25 changed files with 193 additions and 440 deletions
|
@ -581,9 +581,11 @@ void Avatar::simulateAttachments(float deltaTime) {
|
||||||
void Avatar::renderAttachments(RenderArgs* args) {
|
void Avatar::renderAttachments(RenderArgs* args) {
|
||||||
// RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
// RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||||
// RenderArgs::SHADOW_RENDER_MODE : RenderArgs::DEFAULT_RENDER_MODE;
|
// RenderArgs::SHADOW_RENDER_MODE : RenderArgs::DEFAULT_RENDER_MODE;
|
||||||
|
/*
|
||||||
foreach (Model* model, _attachmentModels) {
|
foreach (Model* model, _attachmentModels) {
|
||||||
model->render(args, 1.0f);
|
model->render(args, 1.0f);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::updateJointMappings() {
|
void Avatar::updateJointMappings() {
|
||||||
|
|
|
@ -1580,12 +1580,16 @@ void MyAvatar::renderAttachments(RenderArgs* args) {
|
||||||
QString headJointName = (geometry.headJointIndex == -1) ? QString() : geometry.joints.at(geometry.headJointIndex).name;
|
QString headJointName = (geometry.headJointIndex == -1) ? QString() : geometry.joints.at(geometry.headJointIndex).name;
|
||||||
// RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
// RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||||
// RenderArgs::SHADOW_RENDER_MODE : RenderArgs::DEFAULT_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++) {
|
for (int i = 0; i < _attachmentData.size(); i++) {
|
||||||
const QString& jointName = _attachmentData.at(i).jointName;
|
const QString& jointName = _attachmentData.at(i).jointName;
|
||||||
if (jointName != headJointName && jointName != "Head") {
|
if (jointName != headJointName && jointName != "Head") {
|
||||||
_attachmentModels.at(i)->render(args, 1.0f);
|
_attachmentModels.at(i)->render(args, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//Renders sixense laser pointers for UI selection with controllers
|
//Renders sixense laser pointers for UI selection with controllers
|
||||||
|
|
|
@ -9,6 +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
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
#include <GlowEffect.h>
|
#include <GlowEffect.h>
|
||||||
|
|
||||||
#include "ModelOverlay.h"
|
#include "ModelOverlay.h"
|
||||||
|
@ -54,11 +55,34 @@ void ModelOverlay::update(float deltatime) {
|
||||||
_isLoaded = _model.isActive();
|
_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) {
|
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) {
|
if (!_visible) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (_model.isActive()) {
|
if (_model.isActive()) {
|
||||||
if (_model.isRenderable()) {
|
if (_model.isRenderable()) {
|
||||||
float glowLevel = getGlowLevel();
|
float glowLevel = getGlowLevel();
|
||||||
|
@ -72,6 +96,7 @@ void ModelOverlay::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelOverlay::setProperties(const QScriptValue &properties) {
|
void ModelOverlay::setProperties(const QScriptValue &properties) {
|
||||||
|
|
|
@ -32,6 +32,9 @@ public:
|
||||||
|
|
||||||
virtual ModelOverlay* createClone() const;
|
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:
|
private:
|
||||||
|
|
||||||
Model _model;
|
Model _model;
|
||||||
|
|
|
@ -228,3 +228,15 @@ float Overlay::updatePulse() {
|
||||||
return _pulse;
|
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 update(float deltatime) {}
|
||||||
virtual void render(RenderArgs* args) = 0;
|
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
|
// getters
|
||||||
virtual bool is3D() const = 0;
|
virtual bool is3D() const = 0;
|
||||||
bool isLoaded() { return _isLoaded; }
|
bool isLoaded() { return _isLoaded; }
|
||||||
|
@ -117,5 +120,11 @@ protected:
|
||||||
QScriptEngine* _scriptEngine;
|
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
|
#endif // hifi_Overlay_h
|
||||||
|
|
|
@ -33,49 +33,6 @@
|
||||||
#include "Text3DOverlay.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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Overlays::Overlays() : _nextOverlayID(1) {
|
Overlays::Overlays() : _nextOverlayID(1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +75,7 @@ void Overlays::update(float deltatime) {
|
||||||
|
|
||||||
void Overlays::cleanupOverlaysToDelete() {
|
void Overlays::cleanupOverlaysToDelete() {
|
||||||
if (!_overlaysToDelete.isEmpty()) {
|
if (!_overlaysToDelete.isEmpty()) {
|
||||||
|
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||||
render::PendingChanges pendingChanges;
|
render::PendingChanges pendingChanges;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -128,13 +86,12 @@ void Overlays::cleanupOverlaysToDelete() {
|
||||||
|
|
||||||
auto itemID = overlay->getRenderItemID();
|
auto itemID = overlay->getRenderItemID();
|
||||||
if (itemID != render::Item::INVALID_ITEM_ID) {
|
if (itemID != render::Item::INVALID_ITEM_ID) {
|
||||||
pendingChanges.removeItem(itemID);
|
overlay->removeFromScene(overlay, scene, pendingChanges);
|
||||||
}
|
}
|
||||||
} while (!_overlaysToDelete.isEmpty());
|
} while (!_overlaysToDelete.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pendingChanges._removedItems.size() > 0) {
|
if (pendingChanges._removedItems.size() > 0) {
|
||||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
|
||||||
scene->enqueuePendingChanges(pendingChanges);
|
scene->enqueuePendingChanges(pendingChanges);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,13 +173,9 @@ unsigned int Overlays::addOverlay(Overlay* overlay) {
|
||||||
_overlaysWorld[thisID] = overlayPointer;
|
_overlaysWorld[thisID] = overlayPointer;
|
||||||
|
|
||||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
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;
|
render::PendingChanges pendingChanges;
|
||||||
pendingChanges.resetItem(itemID, overlayPayloadPointer);
|
|
||||||
|
overlayPointer->addToScene(overlayPointer, scene, pendingChanges);
|
||||||
|
|
||||||
scene->enqueuePendingChanges(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) {
|
if (_tree && !_shuttingDown) {
|
||||||
renderArgs->_renderer = this;
|
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();
|
_tree->lockForRead();
|
||||||
|
|
||||||
// Whenever you're in an intersection between zones, we will always choose the smallest zone.
|
// Whenever you're in an intersection between zones, we will always choose the smallest zone.
|
||||||
_bestZone = NULL; // NOTE: Is this what we want?
|
_bestZone = NULL; // NOTE: Is this what we want?
|
||||||
_bestZoneVolume = std::numeric_limits<float>::max();
|
_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);
|
_tree->recurseTreeWithOperation(renderOperation, renderArgs);
|
||||||
|
|
||||||
applyZonePropertiesToScene(_bestZone);
|
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();
|
_tree->unlock();
|
||||||
|
|
||||||
// FIX ME - this is very suspicious!
|
|
||||||
// glPushMatrix();
|
|
||||||
// renderArgs->_context->render(batch);
|
|
||||||
// glPopMatrix();
|
|
||||||
|
|
||||||
renderArgs->_batch = nullptr;
|
|
||||||
|
|
||||||
// stats...
|
// stats...
|
||||||
_meshesConsidered = renderArgs->_meshesConsidered;
|
_meshesConsidered = renderArgs->_meshesConsidered;
|
||||||
_meshesRendered = renderArgs->_meshesRendered;
|
_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) {
|
void EntityTreeRenderer::addEntityToScene(EntityItemPointer entity) {
|
||||||
// here's where we add the entity payload to the scene
|
// here's where we add the entity payload to the scene
|
||||||
if (entity && entity->canRenderInScene()) {
|
render::PendingChanges pendingChanges;
|
||||||
if (entity->readyToAddToScene()) {
|
auto scene = _viewState->getMain3DScene();
|
||||||
render::PendingChanges pendingChanges;
|
if (entity->addToScene(entity, scene, pendingChanges)) {
|
||||||
auto scene = _viewState->getMain3DScene();
|
_entitiesInScene.insert(entity);
|
||||||
if (entity->addToScene(entity, scene, pendingChanges)) {
|
|
||||||
_entitiesInScene.insert(entity);
|
|
||||||
}
|
|
||||||
scene->enqueuePendingChanges(pendingChanges);
|
|
||||||
} else {
|
|
||||||
if (!_pendingAddToScene.contains(entity)) {
|
|
||||||
_pendingAddToScene << 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) {
|
void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) {
|
||||||
if (_tree && !_shuttingDown) {
|
if (_tree && !_shuttingDown) {
|
||||||
|
|
|
@ -123,9 +123,7 @@ protected:
|
||||||
virtual Octree* createTree() { return new EntityTree(true); }
|
virtual Octree* createTree() { return new EntityTree(true); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkPendingAddToScene(RenderArgs* renderArgs);
|
|
||||||
void addEntityToScene(EntityItemPointer entity);
|
void addEntityToScene(EntityItemPointer entity);
|
||||||
QSet<EntityItemPointer> _pendingAddToScene;
|
|
||||||
|
|
||||||
void applyZonePropertiesToScene(std::shared_ptr<ZoneEntityItem> zone);
|
void applyZonePropertiesToScene(std::shared_ptr<ZoneEntityItem> zone);
|
||||||
void renderElementProxy(EntityTreeElement* entityTreeElement, RenderArgs* args);
|
void renderElementProxy(EntityTreeElement* entityTreeElement, RenderArgs* args);
|
||||||
|
|
|
@ -32,9 +32,7 @@ namespace render {
|
||||||
if (args) {
|
if (args) {
|
||||||
args->_elementsTouched++;
|
args->_elementsTouched++;
|
||||||
if (payload && payload->entity) {
|
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() \
|
#define SIMPLE_RENDERABLE() \
|
||||||
public: \
|
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 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); } \
|
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) { _renderHelper.removeFromScene(self, scene, pendingChanges); } \
|
||||||
private: \
|
private: \
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define hifi_RenderableLightEntityItem_h
|
#define hifi_RenderableLightEntityItem_h
|
||||||
|
|
||||||
#include <LightEntityItem.h>
|
#include <LightEntityItem.h>
|
||||||
|
#include "RenderableEntityItem.h"
|
||||||
|
|
||||||
class RenderableLightEntityItem : public LightEntityItem {
|
class RenderableLightEntityItem : public LightEntityItem {
|
||||||
public:
|
public:
|
||||||
|
@ -22,12 +23,13 @@ public:
|
||||||
LightEntityItem(entityItemID, properties)
|
LightEntityItem(entityItemID, properties)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual bool canRenderInScene() { return false; } // we don't yet play well with others
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||||
void** intersectedObject, bool precisionPicking) const;
|
void** intersectedObject, bool precisionPicking) const;
|
||||||
|
|
||||||
|
SIMPLE_RENDERABLE();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
|
|
||||||
SIMPLE_RENDERABLE()
|
SIMPLE_RENDERABLE();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateGeometry();
|
void updateGeometry();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
#include <AbstractViewStateInterface.h>
|
||||||
#include <DeferredLightingEffect.h>
|
#include <DeferredLightingEffect.h>
|
||||||
#include <Model.h>
|
#include <Model.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
@ -210,6 +211,19 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasModel()) {
|
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();
|
remapTextures();
|
||||||
{
|
{
|
||||||
float alpha = getLocalRenderAlpha();
|
float alpha = getLocalRenderAlpha();
|
||||||
|
|
|
@ -43,7 +43,6 @@ public:
|
||||||
|
|
||||||
virtual void somethingChangedNotification() { _needsInitialSimulation = true; }
|
virtual void somethingChangedNotification() { _needsInitialSimulation = true; }
|
||||||
|
|
||||||
virtual bool canRenderInScene() { return true; }
|
|
||||||
virtual bool readyToAddToScene(RenderArgs* renderArgs = nullptr);
|
virtual bool readyToAddToScene(RenderArgs* renderArgs = nullptr);
|
||||||
virtual bool addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
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);
|
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);
|
void updateQuads(RenderArgs* args, bool textured);
|
||||||
|
|
||||||
SIMPLE_RENDERABLE()
|
SIMPLE_RENDERABLE();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "PolyVoxEntityItem.h"
|
#include "PolyVoxEntityItem.h"
|
||||||
#include "RenderableDebugableEntityItem.h"
|
#include "RenderableDebugableEntityItem.h"
|
||||||
|
#include "RenderableEntityItem.h"
|
||||||
|
|
||||||
class RenderablePolyVoxEntityItem : public PolyVoxEntityItem {
|
class RenderablePolyVoxEntityItem : public PolyVoxEntityItem {
|
||||||
public:
|
public:
|
||||||
|
@ -70,6 +71,8 @@ public:
|
||||||
virtual void setAll(uint8_t toValue);
|
virtual void setAll(uint8_t toValue);
|
||||||
|
|
||||||
virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue);
|
virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue);
|
||||||
|
|
||||||
|
SIMPLE_RENDERABLE();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
|
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
|
|
||||||
SIMPLE_RENDERABLE()
|
SIMPLE_RENDERABLE();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include <TextEntityItem.h>
|
#include <TextEntityItem.h>
|
||||||
#include <TextRenderer3D.h>
|
#include <TextRenderer3D.h>
|
||||||
|
|
||||||
|
#include "RenderableEntityItem.h"
|
||||||
|
|
||||||
const int FIXED_FONT_POINT_SIZE = 40;
|
const int FIXED_FONT_POINT_SIZE = 40;
|
||||||
|
|
||||||
class RenderableTextEntityItem : public TextEntityItem {
|
class RenderableTextEntityItem : public TextEntityItem {
|
||||||
|
@ -27,7 +29,8 @@ public:
|
||||||
~RenderableTextEntityItem() { delete _textRenderer; }
|
~RenderableTextEntityItem() { delete _textRenderer; }
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
virtual bool canRenderInScene() { return false; } // we don't yet play well with others
|
|
||||||
|
SIMPLE_RENDERABLE();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextRenderer3D* _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE / 2.0f);
|
TextRenderer3D* _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE / 2.0f);
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#include <WebEntityItem.h>
|
#include <WebEntityItem.h>
|
||||||
|
|
||||||
|
#include "RenderableEntityItem.h"
|
||||||
|
|
||||||
class OffscreenQmlSurface;
|
class OffscreenQmlSurface;
|
||||||
|
|
||||||
class RenderableWebEntityItem : public WebEntityItem {
|
class RenderableWebEntityItem : public WebEntityItem {
|
||||||
|
@ -24,7 +26,8 @@ public:
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
virtual void setSourceUrl(const QString& value);
|
virtual void setSourceUrl(const QString& value);
|
||||||
virtual bool canRenderInScene() { return false; } // we don't yet play well with others
|
|
||||||
|
SIMPLE_RENDERABLE();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OffscreenQmlSurface* _webSurface{ nullptr };
|
OffscreenQmlSurface* _webSurface{ nullptr };
|
||||||
|
|
|
@ -102,7 +102,8 @@ void RenderableZoneEntityItem::render(RenderArgs* args) {
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
|
|
||||||
if (_model && _model->isActive()) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,8 +157,6 @@ public:
|
||||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData)
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData)
|
||||||
{ return 0; }
|
{ 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,
|
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
|
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,
|
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene,
|
||||||
|
|
|
@ -925,6 +925,7 @@ void Model::removeFromScene(std::shared_ptr<render::Scene> scene, render::Pendin
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::render(RenderArgs* renderArgs, float alpha) {
|
bool Model::render(RenderArgs* renderArgs, float alpha) {
|
||||||
|
return true; //
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
|
|
||||||
// render the attachments
|
// render the attachments
|
||||||
|
@ -1994,15 +1995,6 @@ void Model::deleteGeometry() {
|
||||||
_blendedBlendshapeCoefficients.clear();
|
_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) {
|
void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) {
|
||||||
|
|
||||||
// Capture the view matrix once for the rendering of this model
|
// 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]);
|
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) {
|
AABox Model::getPartBounds(int meshIndex, int partIndex) {
|
||||||
if (!_calculatedMeshPartBoxesValid) {
|
if (!_calculatedMeshPartBoxesValid) {
|
||||||
|
@ -2329,21 +2096,17 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
|
||||||
return; // FIXME!
|
return; // FIXME!
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.clusterMatrices.size() > 1) {
|
if (isSkinned) {
|
||||||
GLBATCH(glUniformMatrix4fv)(locations->clusterMatrices, state.clusterMatrices.size(), false,
|
GLBATCH(glUniformMatrix4fv)(locations->clusterMatrices, state.clusterMatrices.size(), false,
|
||||||
(const float*)state.clusterMatrices.constData());
|
(const float*)state.clusterMatrices.constData());
|
||||||
// batch.setModelTransform(Transform());
|
_transforms[0] = Transform();
|
||||||
_transforms[0].setTranslation(_translation);
|
_transforms[0].preTranslate(_translation);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_transforms[0] = Transform(state.clusterMatrices[0]);
|
_transforms[0] = Transform(state.clusterMatrices[0]);
|
||||||
_transforms[0].preTranslate(_translation);
|
_transforms[0].preTranslate(_translation);
|
||||||
|
|
||||||
//batch.setModelTransform(Transform(state.clusterMatrices[0]));
|
|
||||||
}
|
}
|
||||||
batch.setModelTransform(_transforms[0]);
|
batch.setModelTransform(_transforms[0]);
|
||||||
|
|
||||||
|
|
||||||
if (mesh.blendshapes.isEmpty()) {
|
if (mesh.blendshapes.isEmpty()) {
|
||||||
batch.setInputFormat(networkMesh._vertexFormat);
|
batch.setInputFormat(networkMesh._vertexFormat);
|
||||||
batch.setInputStream(0, *networkMesh._vertexStream);
|
batch.setInputStream(0, *networkMesh._vertexStream);
|
||||||
|
@ -2588,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,
|
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 hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
|
||||||
bool forceRenderSomeMeshes) {
|
bool forceRenderSomeMeshes) {
|
||||||
|
|
|
@ -114,14 +114,8 @@ public:
|
||||||
void reset();
|
void reset();
|
||||||
virtual void simulate(float deltaTime, bool fullUpdate = true);
|
virtual void simulate(float deltaTime, bool fullUpdate = true);
|
||||||
|
|
||||||
bool render(RenderArgs* renderArgs, float alpha = 1.0f);
|
|
||||||
void renderSetup(RenderArgs* args);
|
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
|
// new Scene/Engine rendering support
|
||||||
bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); }
|
bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); }
|
||||||
bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return isRenderable() && isActive() && isLoadedWithTextures(); }
|
bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return isRenderable() && isActive() && isLoadedWithTextures(); }
|
||||||
|
@ -393,13 +387,6 @@ private:
|
||||||
void renderDebugMeshBoxes();
|
void renderDebugMeshBoxes();
|
||||||
int _debugMeshBoxesID = GeometryCache::UNKNOWN_ID;
|
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()
|
// helper functions used by render() or renderInScene()
|
||||||
bool renderCore(RenderArgs* args, float alpha);
|
bool renderCore(RenderArgs* args, float alpha);
|
||||||
int renderMeshes(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
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,
|
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
|
||||||
Locations*& locations);
|
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;
|
static AbstractViewStateInterface* _viewState;
|
||||||
|
|
||||||
class RenderKey {
|
class RenderKey {
|
||||||
|
@ -547,6 +530,14 @@ private:
|
||||||
QSet<std::shared_ptr<OpaqueMeshPart>> _opaqueRenderItems;
|
QSet<std::shared_ptr<OpaqueMeshPart>> _opaqueRenderItems;
|
||||||
QSet<render::ItemID> _renderItems;
|
QSet<render::ItemID> _renderItems;
|
||||||
bool _readyWhenAdded = false;
|
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>)
|
Q_DECLARE_METATYPE(QPointer<Model>)
|
||||||
|
|
Loading…
Reference in a new issue