mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
commit
12c26f9c3c
15 changed files with 339 additions and 185 deletions
|
@ -35,6 +35,7 @@ ZoneOverlayManager = function(isEntityFunc, entityAddedFunc, entityRemovedFunc,
|
|||
this.setVisible = function(isVisible) {
|
||||
if (visible != isVisible) {
|
||||
visible = isVisible;
|
||||
Entities.setDrawZoneBoundaries(visible);
|
||||
for (var id in entityOverlays) {
|
||||
Overlays.editOverlay(entityOverlays[id].solid, { visible: visible });
|
||||
Overlays.editOverlay(entityOverlays[id].outline, { visible: visible });
|
||||
|
|
|
@ -3254,6 +3254,11 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||
}
|
||||
_entities.render(renderMode, renderSide, renderDebugFlags);
|
||||
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
||||
// Restaure polygon mode
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
}
|
||||
|
||||
// render JS/scriptable overlays
|
||||
|
|
|
@ -685,7 +685,7 @@ void ApplicationOverlay::renderControllerPointers() {
|
|||
}
|
||||
|
||||
//If the cursor is out of the screen then don't render it
|
||||
if (mouseX < 0 || mouseX >= canvasSize.x || mouseY < 0 || mouseY >= canvasSize.y) {
|
||||
if (mouseX < 0 || mouseX >= (int)canvasSize.x || mouseY < 0 || mouseY >= (int)canvasSize.y) {
|
||||
_reticleActive[index] = false;
|
||||
continue;
|
||||
}
|
||||
|
@ -998,7 +998,7 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() {
|
|||
if (nodeList && !nodeList->getDomainHandler().isConnected()) {
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto canvasSize = qApp->getCanvasSize();
|
||||
if (canvasSize.x != _previousBorderWidth || canvasSize.y != _previousBorderHeight) {
|
||||
if ((int)canvasSize.x != _previousBorderWidth || (int)canvasSize.y != _previousBorderHeight) {
|
||||
glm::vec4 color(CONNECTION_STATUS_BORDER_COLOR[0],
|
||||
CONNECTION_STATUS_BORDER_COLOR[1],
|
||||
CONNECTION_STATUS_BORDER_COLOR[2], 1.0f);
|
||||
|
|
|
@ -87,11 +87,10 @@ void Overlays::renderHUD() {
|
|||
QReadLocker lock(&_lock);
|
||||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(),
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
RenderArgs args(NULL, Application::getInstance()->getViewFrustum(),
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
||||
|
||||
foreach(Overlay* thisOverlay, _overlaysHUD) {
|
||||
if (thisOverlay->is3D()) {
|
||||
|
@ -125,11 +124,10 @@ void Overlays::renderWorld(bool drawFront,
|
|||
float myAvatarScale = 1.0f;
|
||||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
RenderArgs args = { NULL, Application::getInstance()->getDisplayViewFrustum(),
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide, renderDebugFlags,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
RenderArgs args(NULL, Application::getInstance()->getDisplayViewFrustum(),
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide, renderDebugFlags);
|
||||
|
||||
|
||||
foreach(Overlay* thisOverlay, _overlaysWorld) {
|
||||
|
|
|
@ -392,8 +392,8 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
|
|||
ViewFrustum* frustum = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||
_viewState->getShadowViewFrustum() : _viewState->getCurrentViewFrustum();
|
||||
|
||||
RenderArgs args = { this, frustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide,
|
||||
renderDebugFlags, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
RenderArgs args(this, frustum, getSizeScale(), getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide, renderDebugFlags);
|
||||
|
||||
_tree->lockForRead();
|
||||
|
||||
|
@ -677,8 +677,7 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
|
||||
if (entityItem->isVisible()) {
|
||||
|
||||
// NOTE: Zone Entities are a special case we handle here... Zones don't render
|
||||
// like other entity types. So we will skip the normal rendering tests
|
||||
// NOTE: Zone Entities are a special case we handle here...
|
||||
if (entityItem->getType() == EntityTypes::Zone) {
|
||||
if (entityItem->contains(_viewState->getAvatarPosition())) {
|
||||
float entityVolumeEstimate = entityItem->getVolumeEstimate();
|
||||
|
@ -699,42 +698,42 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 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);
|
||||
// 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(entityItem->getGlowLevel());
|
||||
}
|
||||
entityItem->render(args);
|
||||
args->_itemsRendered++;
|
||||
if (glower) {
|
||||
delete glower;
|
||||
}
|
||||
} else {
|
||||
args->_itemsTooSmall++;
|
||||
if (bigEnoughToRender) {
|
||||
renderProxies(entityItem, args);
|
||||
|
||||
Glower* glower = NULL;
|
||||
if (entityItem->getGlowLevel() > 0.0f) {
|
||||
glower = new Glower(entityItem->getGlowLevel());
|
||||
}
|
||||
entityItem->render(args);
|
||||
args->_itemsRendered++;
|
||||
if (glower) {
|
||||
delete glower;
|
||||
}
|
||||
} else {
|
||||
args->_itemsOutOfView++;
|
||||
args->_itemsTooSmall++;
|
||||
}
|
||||
} else {
|
||||
args->_itemsOutOfView++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float EntityTreeRenderer::getSizeScale() const {
|
||||
float EntityTreeRenderer::getSizeScale() const {
|
||||
return _viewState->getSizeScale();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
|
||||
#include "RenderableZoneEntityItem.h"
|
||||
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
EntityItem* RenderableZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableZoneEntityItem(entityID, properties);
|
||||
|
@ -27,10 +29,12 @@ void RenderableZoneEntityItem::changeProperties(Lambda setNewProperties) {
|
|||
setNewProperties();
|
||||
|
||||
if (oldShapeURL != getCompoundShapeURL()) {
|
||||
if (!_model) {
|
||||
_model = getModel();
|
||||
_needsInitialSimulation = true;
|
||||
if (_model) {
|
||||
delete _model;
|
||||
}
|
||||
|
||||
_model = getModel();
|
||||
_needsInitialSimulation = true;
|
||||
_model->setURL(getCompoundShapeURL(), QUrl(), true, true);
|
||||
}
|
||||
if (oldPosition != getPosition() ||
|
||||
|
@ -61,6 +65,7 @@ int RenderableZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
|
|||
|
||||
Model* RenderableZoneEntityItem::getModel() {
|
||||
Model* model = new Model();
|
||||
model->setIsWireframe(true);
|
||||
model->init();
|
||||
return model;
|
||||
}
|
||||
|
@ -74,9 +79,66 @@ void RenderableZoneEntityItem::initialSimulation() {
|
|||
_needsInitialSimulation = false;
|
||||
}
|
||||
|
||||
void RenderableZoneEntityItem::updateGeometry() {
|
||||
if (_model && !_model->isActive() && hasCompoundShapeURL()) {
|
||||
// Since we have a delayload, we need to update the geometry if it has been downloaded
|
||||
_model->setURL(getCompoundShapeURL(), QUrl(), true);
|
||||
}
|
||||
if (_model && _model->isActive() && _needsInitialSimulation) {
|
||||
initialSimulation();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableZoneEntityItem::render(RenderArgs* args) {
|
||||
if (_drawZoneBoundaries) {
|
||||
// TODO: Draw the zone boundaries...
|
||||
switch (getShapeType()) {
|
||||
case SHAPE_TYPE_COMPOUND: {
|
||||
updateGeometry();
|
||||
|
||||
if (_model && _model->isActive()) {
|
||||
PerformanceTimer perfTimer("zone->renderCompound");
|
||||
glPushMatrix();
|
||||
_model->renderInScene(getLocalRenderAlpha(), args);
|
||||
glPopMatrix();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SHAPE_TYPE_BOX:
|
||||
case SHAPE_TYPE_SPHERE: {
|
||||
PerformanceTimer perfTimer("zone->renderPrimitive");
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 center = getCenter();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
glm::vec4 DEFAULT_COLOR(1.0f, 1.0f, 1.0f, getLocalRenderAlpha());
|
||||
|
||||
glPushMatrix(); {
|
||||
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);
|
||||
glPushMatrix(); {
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
|
||||
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
||||
|
||||
if (getShapeType() == SHAPE_TYPE_SPHERE) {
|
||||
const int SLICES = 15;
|
||||
const int STACKS = 15;
|
||||
deferredLightingEffect->renderWireSphere(0.5f, SLICES, STACKS, DEFAULT_COLOR);
|
||||
} else {
|
||||
deferredLightingEffect->renderWireCube(1.0f, DEFAULT_COLOR);
|
||||
}
|
||||
} glPopMatrix();
|
||||
} glPopMatrix();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Not handled
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,16 +146,9 @@ bool RenderableZoneEntityItem::contains(const glm::vec3& point) const {
|
|||
if (getShapeType() != SHAPE_TYPE_COMPOUND) {
|
||||
return EntityItem::contains(point);
|
||||
}
|
||||
|
||||
if (_model && !_model->isActive() && hasCompoundShapeURL()) {
|
||||
// Since we have a delayload, we need to update the geometry if it has been downloaded
|
||||
_model->setURL(getCompoundShapeURL(), QUrl(), true);
|
||||
}
|
||||
const_cast<RenderableZoneEntityItem*>(this)->updateGeometry();
|
||||
|
||||
if (_model && _model->isActive() && EntityItem::contains(point)) {
|
||||
if (_needsInitialSimulation) {
|
||||
const_cast<RenderableZoneEntityItem*>(this)->initialSimulation();
|
||||
}
|
||||
return _model->convexHullContains(point);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
private:
|
||||
Model* getModel();
|
||||
void initialSimulation();
|
||||
void updateGeometry();
|
||||
|
||||
template<typename Lambda>
|
||||
void changeProperties(Lambda functor);
|
||||
|
|
|
@ -263,17 +263,15 @@ void ZoneEntityItem::debugDump() const {
|
|||
ShapeType ZoneEntityItem::getShapeType() const {
|
||||
// Zones are not allowed to have a SHAPE_TYPE_NONE... they are always at least a SHAPE_TYPE_BOX
|
||||
if (_shapeType == SHAPE_TYPE_COMPOUND) {
|
||||
return hasCompoundShapeURL() ? SHAPE_TYPE_COMPOUND : SHAPE_TYPE_BOX;
|
||||
return hasCompoundShapeURL() ? SHAPE_TYPE_COMPOUND : DEFAULT_SHAPE_TYPE;
|
||||
} else {
|
||||
return _shapeType == SHAPE_TYPE_NONE ? SHAPE_TYPE_BOX : _shapeType;
|
||||
return _shapeType == SHAPE_TYPE_NONE ? DEFAULT_SHAPE_TYPE : _shapeType;
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setCompoundShapeURL(const QString& url) {
|
||||
_compoundShapeURL = url;
|
||||
if (!_compoundShapeURL.isEmpty()) {
|
||||
updateShapeType(SHAPE_TYPE_COMPOUND);
|
||||
} else if (_shapeType == SHAPE_TYPE_COMPOUND) {
|
||||
if (_compoundShapeURL.isEmpty() && _shapeType == SHAPE_TYPE_COMPOUND) {
|
||||
_shapeType = DEFAULT_SHAPE_TYPE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,11 +44,6 @@ public:
|
|||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);
|
||||
|
||||
// NOTE: Apparently if you begin to return a shape type, then the physics system will prevent an avatar
|
||||
// from penetrating the walls of the entity. This fact will likely be important to Clement as he works
|
||||
// on better defining the shape/volume of a zone.
|
||||
//virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; }
|
||||
|
||||
xColor getKeyLightColor() const { xColor color = { _keyLightColor[RED_INDEX], _keyLightColor[GREEN_INDEX], _keyLightColor[BLUE_INDEX] }; return color; }
|
||||
void setKeyLightColor(const xColor& value) {
|
||||
_keyLightColor[RED_INDEX] = value.red;
|
||||
|
@ -146,7 +141,7 @@ protected:
|
|||
uint16_t _stageDay;
|
||||
float _stageHour;
|
||||
|
||||
ShapeType _shapeType = SHAPE_TYPE_NONE;
|
||||
ShapeType _shapeType = DEFAULT_SHAPE_TYPE;
|
||||
QString _compoundShapeURL;
|
||||
|
||||
BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT;
|
||||
|
|
|
@ -31,36 +31,51 @@ typedef GLBackend::GLState::Command1<State::DepthTest> CommandDepthTest;
|
|||
typedef GLBackend::GLState::Command3<State::StencilActivation, State::StencilTest, State::StencilTest> CommandStencil;
|
||||
typedef GLBackend::GLState::Command1<State::BlendFunction> CommandBlend;
|
||||
|
||||
// The state commands to reset to default,
|
||||
// WARNING depending on the order of the State::Field enum
|
||||
const GLBackend::GLState::Commands GLBackend::GLState::_resetStateCommands = {
|
||||
CommandPointer(new Command1I(&GLBackend::do_setStateFillMode, State::DEFAULT.fillMode)),
|
||||
CommandPointer(new Command1I(&GLBackend::do_setStateCullMode, State::DEFAULT.cullMode)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateFrontFaceClockwise, State::DEFAULT.frontFaceClockwise)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateDepthClipEnable, State::DEFAULT.depthClipEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateScissorEnable, State::DEFAULT.scissorEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateMultisampleEnable, State::DEFAULT.multisampleEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateAntialiasedLineEnable, State::DEFAULT.antialisedLineEnable)),
|
||||
const GLBackend::GLState::Commands makeResetStateCommands();
|
||||
const GLBackend::GLState::Commands GLBackend::GLState::_resetStateCommands = makeResetStateCommands();
|
||||
|
||||
// Depth bias has 2 fields in State but really one call in GLBackend
|
||||
CommandPointer(new CommandDepthBias(&GLBackend::do_setStateDepthBias, Vec2(State::DEFAULT.depthBias, State::DEFAULT.depthBiasSlopeScale))),
|
||||
CommandPointer(new CommandDepthBias(&GLBackend::do_setStateDepthBias, Vec2(State::DEFAULT.depthBias, State::DEFAULT.depthBiasSlopeScale))),
|
||||
|
||||
CommandPointer(new CommandDepthTest(&GLBackend::do_setStateDepthTest, State::DEFAULT.depthTest)),
|
||||
|
||||
// Depth bias has 3 fields in State but really one call in GLBackend
|
||||
CommandPointer(new CommandStencil(&GLBackend::do_setStateStencil, State::DEFAULT.stencilActivation, State::DEFAULT.stencilTestFront, State::DEFAULT.stencilTestBack)),
|
||||
CommandPointer(new CommandStencil(&GLBackend::do_setStateStencil, State::DEFAULT.stencilActivation, State::DEFAULT.stencilTestFront, State::DEFAULT.stencilTestBack)),
|
||||
CommandPointer(new CommandStencil(&GLBackend::do_setStateStencil, State::DEFAULT.stencilActivation, State::DEFAULT.stencilTestFront, State::DEFAULT.stencilTestBack)),
|
||||
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateAlphaToCoverageEnable, State::DEFAULT.alphaToCoverageEnable)),
|
||||
|
||||
CommandPointer(new Command1U(&GLBackend::do_setStateSampleMask, State::DEFAULT.sampleMask)),
|
||||
|
||||
CommandPointer(new CommandBlend(&GLBackend::do_setStateBlend, State::DEFAULT.blendFunction)),
|
||||
|
||||
CommandPointer(new Command1U(&GLBackend::do_setStateColorWriteMask, State::DEFAULT.colorWriteMask))
|
||||
};
|
||||
const GLBackend::GLState::Commands makeResetStateCommands() {
|
||||
// Since State::DEFAULT is a static defined in another .cpp the initialisation order is random
|
||||
// and we have a 50/50 chance that State::DEFAULT is not yet initialized.
|
||||
// Since State::DEFAULT = State::Data() it is much easier to not use the actual State::DEFAULT
|
||||
// but another State::Data object with a default initialization.
|
||||
State::Data DEFAULT = State::Data();
|
||||
|
||||
CommandPointer depthBiasCommand = CommandPointer(new CommandDepthBias(&GLBackend::do_setStateDepthBias, Vec2(DEFAULT.depthBias, DEFAULT.depthBiasSlopeScale)));
|
||||
CommandPointer stencilCommand = CommandPointer(new CommandStencil(&GLBackend::do_setStateStencil, DEFAULT.stencilActivation, DEFAULT.stencilTestFront, DEFAULT.stencilTestBack));
|
||||
|
||||
// The state commands to reset to default,
|
||||
// WARNING depending on the order of the State::Field enum
|
||||
return {
|
||||
CommandPointer(new Command1I(&GLBackend::do_setStateFillMode, DEFAULT.fillMode)),
|
||||
CommandPointer(new Command1I(&GLBackend::do_setStateCullMode, DEFAULT.cullMode)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateFrontFaceClockwise, DEFAULT.frontFaceClockwise)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateDepthClipEnable, DEFAULT.depthClipEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateScissorEnable, DEFAULT.scissorEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateMultisampleEnable, DEFAULT.multisampleEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateAntialiasedLineEnable, DEFAULT.antialisedLineEnable)),
|
||||
|
||||
// Depth bias has 2 fields in State but really one call in GLBackend
|
||||
CommandPointer(depthBiasCommand),
|
||||
CommandPointer(depthBiasCommand),
|
||||
|
||||
CommandPointer(new CommandDepthTest(&GLBackend::do_setStateDepthTest, DEFAULT.depthTest)),
|
||||
|
||||
// Depth bias has 3 fields in State but really one call in GLBackend
|
||||
CommandPointer(stencilCommand),
|
||||
CommandPointer(stencilCommand),
|
||||
CommandPointer(stencilCommand),
|
||||
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateAlphaToCoverageEnable, DEFAULT.alphaToCoverageEnable)),
|
||||
|
||||
CommandPointer(new Command1U(&GLBackend::do_setStateSampleMask, DEFAULT.sampleMask)),
|
||||
|
||||
CommandPointer(new CommandBlend(&GLBackend::do_setStateBlend, DEFAULT.blendFunction)),
|
||||
|
||||
CommandPointer(new Command1U(&GLBackend::do_setStateColorWriteMask, DEFAULT.colorWriteMask))
|
||||
};
|
||||
}
|
||||
|
||||
void generateFillMode(GLBackend::GLState::Commands& commands, State::FillMode fillMode) {
|
||||
commands.push_back(CommandPointer(new Command1I(&GLBackend::do_setStateFillMode, int32(fillMode))));
|
||||
|
|
|
@ -20,6 +20,8 @@ State::State() {
|
|||
State::~State() {
|
||||
}
|
||||
|
||||
// WARNING: GLBackend::GLState::_resetStateCommands heavily relies on the fact that State::DEFAULT = State::Data()
|
||||
// Please make sure to go check makeResetStateCommands() before modifying this value
|
||||
const State::Data State::DEFAULT = State::Data();
|
||||
|
||||
State::Signature State::evalSignature(const Data& state) {
|
||||
|
|
|
@ -167,8 +167,8 @@ bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) {
|
|||
void OctreeRenderer::render(RenderArgs::RenderMode renderMode,
|
||||
RenderArgs::RenderSide renderSide,
|
||||
RenderArgs::DebugFlags renderDebugFlags) {
|
||||
RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide,
|
||||
renderDebugFlags, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
RenderArgs args(this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide, renderDebugFlags);
|
||||
if (_tree) {
|
||||
_tree->lockForRead();
|
||||
_tree->recurseTreeWithOperation(renderOperation, &args);
|
||||
|
|
|
@ -84,6 +84,7 @@ Model::Model(QObject* parent) :
|
|||
_calculatedMeshBoxesValid(false),
|
||||
_calculatedMeshTrianglesValid(false),
|
||||
_meshGroupsKnown(false),
|
||||
_isWireframe(false),
|
||||
_renderCollisionHull(false) {
|
||||
|
||||
// we may have been created in the network thread, but we live in the main thread
|
||||
|
@ -100,8 +101,8 @@ Model::RenderPipelineLib Model::_renderPipelineLib;
|
|||
const GLint MATERIAL_GPU_SLOT = 3;
|
||||
|
||||
void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
||||
gpu::ShaderPointer& vertexShader,
|
||||
gpu::ShaderPointer& pixelShader ) {
|
||||
gpu::ShaderPointer& vertexShader,
|
||||
gpu::ShaderPointer& pixelShader ) {
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
|
||||
|
@ -119,7 +120,7 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
|||
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
|
||||
// Backface on shadow
|
||||
if (key.isShadow()) {
|
||||
state->setCullMode(gpu::State::CULL_FRONT);
|
||||
|
@ -140,7 +141,20 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
|||
// Good to go add the brand new pipeline
|
||||
auto pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
insert(value_type(key.getRaw(), RenderPipeline(pipeline, locations)));
|
||||
|
||||
|
||||
|
||||
if (!key.isWireFrame()) {
|
||||
|
||||
RenderKey wireframeKey(key.getRaw() | RenderKey::IS_WIREFRAME);
|
||||
gpu::StatePointer wireframeState = gpu::StatePointer(new gpu::State(state->getValues()));
|
||||
|
||||
wireframeState->setFillMode(gpu::State::FILL_LINE);
|
||||
|
||||
// create a new RenderPipeline with the same shader side and the mirrorState
|
||||
auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState));
|
||||
insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations)));
|
||||
}
|
||||
|
||||
// If not a shadow pass, create the mirror version from the same state, just change the FrontFace
|
||||
if (!key.isShadow()) {
|
||||
|
||||
|
@ -152,6 +166,17 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
|||
// create a new RenderPipeline with the same shader side and the mirrorState
|
||||
auto mirrorPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, mirrorState));
|
||||
insert(value_type(mirrorKey.getRaw(), RenderPipeline(mirrorPipeline, locations)));
|
||||
|
||||
if (!key.isWireFrame()) {
|
||||
RenderKey wireframeKey(key.getRaw() | RenderKey::IS_MIRROR | RenderKey::IS_WIREFRAME);
|
||||
gpu::StatePointer wireframeState = gpu::StatePointer(new gpu::State(state->getValues()));;
|
||||
|
||||
wireframeState->setFillMode(gpu::State::FILL_LINE);
|
||||
|
||||
// create a new RenderPipeline with the same shader side and the mirrorState
|
||||
auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState));
|
||||
insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,19 +833,19 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
|
||||
//renderMeshes(batch, mode, translucent, alphaThreshold, hasTangents, hasSpecular, isSkinned, args, forceRenderMeshes);
|
||||
int opaqueMeshPartsRendered = 0;
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, false, args, true);
|
||||
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, false, args, true);
|
||||
|
||||
// render translucent meshes afterwards
|
||||
//DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(false, true, true);
|
||||
|
@ -834,14 +859,14 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
|
||||
int translucentMeshPartsRendered = 0;
|
||||
const float MOSTLY_OPAQUE_THRESHOLD = 0.75f;
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, false, args, true);
|
||||
|
||||
{
|
||||
GLenum buffers[1];
|
||||
|
@ -855,14 +880,14 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryTransparentFramebuffer());
|
||||
|
||||
const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f;
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, false, args, true);
|
||||
|
||||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryOpaqueFramebuffer());
|
||||
}
|
||||
|
@ -1110,7 +1135,7 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
|
|||
// if so instructed, keep the current geometry until the new one is loaded
|
||||
_nextBaseGeometry = _nextGeometry = DependencyManager::get<GeometryCache>()->getGeometry(url, fallback, delayLoad);
|
||||
_nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS;
|
||||
if (!retainCurrent || !isActive() || _nextGeometry->isLoaded()) {
|
||||
if (!retainCurrent || !isActive() || (_nextGeometry && _nextGeometry->isLoaded())) {
|
||||
applyNextGeometry();
|
||||
}
|
||||
}
|
||||
|
@ -1873,19 +1898,21 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
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, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, args);
|
||||
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args);
|
||||
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
|
||||
{
|
||||
|
@ -1898,14 +1925,14 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
|
||||
int translucentParts = 0;
|
||||
const float MOSTLY_OPAQUE_THRESHOLD = 0.75f;
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, args);
|
||||
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);
|
||||
|
||||
|
||||
{
|
||||
|
@ -1921,14 +1948,14 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
// 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, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, args);
|
||||
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());
|
||||
}
|
||||
|
@ -2017,7 +2044,7 @@ bool Model::renderInScene(float alpha, RenderArgs* args) {
|
|||
updateGeometry();
|
||||
simulate(0.0, true);
|
||||
}
|
||||
|
||||
|
||||
renderSetup(args);
|
||||
_modelsInScene.push_back(this);
|
||||
return true;
|
||||
|
@ -2057,8 +2084,8 @@ void Model::segregateMeshGroups() {
|
|||
if (wantDebug) {
|
||||
qCDebug(renderutils) << "materialID:" << materialID << "parts:" << mesh.parts.size();
|
||||
}
|
||||
|
||||
RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
|
||||
RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe());
|
||||
|
||||
// reuse or create the bucket corresponding to that key and insert the mesh as unsorted
|
||||
_renderBuckets[key.getRaw()]._unsortedMeshes.insertMulti(materialID, i);
|
||||
|
@ -2067,20 +2094,20 @@ void Model::segregateMeshGroups() {
|
|||
for(auto& b : _renderBuckets) {
|
||||
foreach(auto i, b.second._unsortedMeshes) {
|
||||
b.second._meshes.append(i);
|
||||
b.second._unsortedMeshes.clear();
|
||||
}
|
||||
b.second._unsortedMeshes.clear();
|
||||
}
|
||||
|
||||
_meshGroupsKnown = true;
|
||||
}
|
||||
}
|
||||
|
||||
QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned) {
|
||||
QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
// depending on which parameters we were called with, pick the correct mesh group to render
|
||||
QVector<int>* whichList = NULL;
|
||||
|
||||
RenderKey key(translucent, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
RenderKey key(translucent, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
|
||||
|
||||
auto bucket = _renderBuckets.find(key.getRaw());
|
||||
if (bucket != _renderBuckets.end()) {
|
||||
|
@ -2091,10 +2118,10 @@ QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool h
|
|||
}
|
||||
|
||||
void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
|
||||
Locations*& locations) {
|
||||
|
||||
RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
|
||||
auto pipeline = _renderPipelineLib.find(key.getRaw());
|
||||
if (pipeline == _renderPipelineLib.end()) {
|
||||
qDebug() << "No good, couldn't find a pipeline from the key ?" << key.getRaw();
|
||||
|
@ -2119,7 +2146,7 @@ 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, RenderArgs* args) {
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args) {
|
||||
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
int meshPartsRendered = 0;
|
||||
|
@ -2128,12 +2155,12 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
|||
Locations* locations = nullptr;
|
||||
|
||||
foreach(Model* model, _modelsInScene) {
|
||||
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
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, args, locations);
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe, args, locations);
|
||||
pickProgramsNeeded = false;
|
||||
}
|
||||
|
||||
|
@ -2147,14 +2174,14 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
|||
}
|
||||
|
||||
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
|
||||
bool forceRenderSomeMeshes) {
|
||||
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
int meshPartsRendered = 0;
|
||||
|
||||
//Pick the mesh list with the requested render flags
|
||||
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
|
||||
if (!whichList) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -2166,9 +2193,9 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
|||
}
|
||||
|
||||
Locations* locations = nullptr;
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe,
|
||||
args, locations);
|
||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
||||
args, locations, forceRenderSomeMeshes);
|
||||
|
||||
return meshPartsRendered;
|
||||
|
|
|
@ -116,6 +116,9 @@ public:
|
|||
Q_INVOKABLE void setCollisionModelURL(const QUrl& url);
|
||||
const QUrl& getCollisionURL() const { return _collisionUrl; }
|
||||
|
||||
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
|
||||
bool isWireframe() const { return _isWireframe; }
|
||||
|
||||
/// Sets the distance parameter used for LOD computations.
|
||||
void setLODDistance(float distance) { _lodDistance = distance; }
|
||||
|
||||
|
@ -350,6 +353,7 @@ private:
|
|||
void segregateMeshGroups(); // used to calculate our list of translucent vs opaque meshes
|
||||
|
||||
bool _meshGroupsKnown;
|
||||
bool _isWireframe;
|
||||
|
||||
|
||||
// debug rendering support
|
||||
|
@ -366,23 +370,23 @@ private:
|
|||
// helper functions used by render() or renderInScene()
|
||||
void renderSetup(RenderArgs* args);
|
||||
bool renderCore(float alpha, RenderArgs::RenderMode mode, RenderArgs* args);
|
||||
int renderMeshes(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL,
|
||||
int renderMeshes(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args = NULL,
|
||||
bool forceRenderMeshes = false);
|
||||
|
||||
void setupBatchTransform(gpu::Batch& batch, RenderArgs* args);
|
||||
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
|
||||
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe);
|
||||
|
||||
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
RenderArgs* args, Locations* locations,
|
||||
bool forceRenderSomeMeshes = false);
|
||||
|
||||
static void pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
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, RenderArgs* args);
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args);
|
||||
|
||||
|
||||
static AbstractViewStateInterface* _viewState;
|
||||
|
@ -400,7 +404,8 @@ private:
|
|||
IS_DEPTH_ONLY_FLAG,
|
||||
IS_SHADOW_FLAG,
|
||||
IS_MIRROR_FLAG, //THis means that the mesh is rendered mirrored, not the same as "Rear view mirror"
|
||||
|
||||
IS_WIREFRAME_FLAG,
|
||||
|
||||
NUM_FLAGS,
|
||||
};
|
||||
|
||||
|
@ -415,7 +420,7 @@ private:
|
|||
IS_DEPTH_ONLY = (1 << IS_DEPTH_ONLY_FLAG),
|
||||
IS_SHADOW = (1 << IS_SHADOW_FLAG),
|
||||
IS_MIRROR = (1 << IS_MIRROR_FLAG),
|
||||
|
||||
IS_WIREFRAME = (1 << IS_WIREFRAME_FLAG),
|
||||
};
|
||||
typedef unsigned short Flags;
|
||||
|
||||
|
@ -433,6 +438,7 @@ private:
|
|||
bool isDepthOnly() const { return isFlag(IS_DEPTH_ONLY); }
|
||||
bool isShadow() const { return isFlag(IS_SHADOW); } // = depth only but with back facing
|
||||
bool isMirror() const { return isFlag(IS_MIRROR); }
|
||||
bool isWireFrame() const { return isFlag(IS_WIREFRAME); }
|
||||
|
||||
Flags _flags = 0;
|
||||
short _spare = 0;
|
||||
|
@ -442,22 +448,24 @@ private:
|
|||
|
||||
RenderKey(
|
||||
bool translucent, bool hasLightmap,
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned) :
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) :
|
||||
RenderKey( (translucent ? IS_TRANSLUCENT : 0)
|
||||
| (hasLightmap ? HAS_LIGHTMAP : 0)
|
||||
| (hasTangents ? HAS_TANGENTS : 0)
|
||||
| (hasSpecular ? HAS_SPECULAR : 0)
|
||||
| (isSkinned ? IS_SKINNED : 0)
|
||||
| (isWireframe ? IS_WIREFRAME : 0)
|
||||
) {}
|
||||
|
||||
RenderKey(RenderArgs::RenderMode mode,
|
||||
bool translucent, float alphaThreshold, bool hasLightmap,
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned) :
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) :
|
||||
RenderKey( ((translucent && (alphaThreshold == 0.0f) && (mode != RenderArgs::SHADOW_RENDER_MODE)) ? IS_TRANSLUCENT : 0)
|
||||
| (hasLightmap && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_LIGHTMAP : 0) // Lightmap, tangents and specular don't matter for depthOnly
|
||||
| (hasTangents && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_TANGENTS : 0)
|
||||
| (hasSpecular && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_SPECULAR : 0)
|
||||
| (isSkinned ? IS_SKINNED : 0)
|
||||
| (isWireframe ? IS_WIREFRAME : 0)
|
||||
| ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_DEPTH_ONLY : 0)
|
||||
| ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_SHADOW : 0)
|
||||
| ((mode == RenderArgs::MIRROR_RENDER_MODE) ? IS_MIRROR :0)
|
||||
|
|
|
@ -22,10 +22,60 @@ public:
|
|||
enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT };
|
||||
|
||||
enum DebugFlags {
|
||||
RENDER_DEBUG_NONE=0,
|
||||
RENDER_DEBUG_HULLS=1,
|
||||
RENDER_DEBUG_SIMULATION_OWNERSHIP=2
|
||||
RENDER_DEBUG_NONE = 0,
|
||||
RENDER_DEBUG_HULLS = 1,
|
||||
RENDER_DEBUG_SIMULATION_OWNERSHIP = 2,
|
||||
};
|
||||
|
||||
RenderArgs(OctreeRenderer* renderer = nullptr,
|
||||
ViewFrustum* viewFrustum = nullptr,
|
||||
float sizeScale = 1.0f,
|
||||
int boundaryLevelAdjust = 0,
|
||||
RenderMode renderMode = DEFAULT_RENDER_MODE,
|
||||
RenderSide renderSide = MONO,
|
||||
DebugFlags debugFlags = RENDER_DEBUG_NONE,
|
||||
|
||||
int elementsTouched = 0,
|
||||
int itemsRendered = 0,
|
||||
int itemsOutOfView = 0,
|
||||
int itemsTooSmall = 0,
|
||||
|
||||
int meshesConsidered = 0,
|
||||
int meshesRendered = 0,
|
||||
int meshesOutOfView = 0,
|
||||
int meshesTooSmall = 0,
|
||||
|
||||
int materialSwitches = 0,
|
||||
int trianglesRendered = 0,
|
||||
int quadsRendered = 0,
|
||||
|
||||
int translucentMeshPartsRendered = 0,
|
||||
int opaqueMeshPartsRendered = 0) :
|
||||
_renderer(renderer),
|
||||
_viewFrustum(viewFrustum),
|
||||
_sizeScale(sizeScale),
|
||||
_boundaryLevelAdjust(boundaryLevelAdjust),
|
||||
_renderMode(renderMode),
|
||||
_renderSide(renderSide),
|
||||
_debugFlags(debugFlags),
|
||||
|
||||
_elementsTouched(elementsTouched),
|
||||
_itemsRendered(itemsRendered),
|
||||
_itemsOutOfView(itemsOutOfView),
|
||||
_itemsTooSmall(itemsTooSmall),
|
||||
|
||||
_meshesConsidered(meshesConsidered),
|
||||
_meshesRendered(meshesRendered),
|
||||
_meshesOutOfView(meshesOutOfView),
|
||||
_meshesTooSmall(meshesTooSmall),
|
||||
|
||||
_materialSwitches(materialSwitches),
|
||||
_trianglesRendered(trianglesRendered),
|
||||
_quadsRendered(quadsRendered),
|
||||
|
||||
_translucentMeshPartsRendered(translucentMeshPartsRendered),
|
||||
_opaqueMeshPartsRendered(opaqueMeshPartsRendered) {
|
||||
}
|
||||
|
||||
OctreeRenderer* _renderer;
|
||||
ViewFrustum* _viewFrustum;
|
||||
|
|
Loading…
Reference in a new issue