Keep iterating on the zones

This commit is contained in:
samcake 2017-05-05 18:07:21 -07:00
parent bc1e5101ac
commit b6c966ef39
6 changed files with 142 additions and 83 deletions

View file

@ -24,6 +24,8 @@
#include "RenderableEntityItem.h"
#include <LightPayload.h>
#include "DeferredLightingEffect.h"
// Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1
@ -73,6 +75,7 @@ void RenderableZoneEntityItem::somethingChangedNotification() {
// If graphics elements are changed, we need to update the render items
if (_keyLightPropertiesChanged || _backgroundPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged) {
notifyChangedRenderItem();
}
@ -120,6 +123,52 @@ void RenderableZoneEntityItem::updateGeometry() {
}
}
void RenderableZoneEntityItem::updateTextures() {
auto textureCache = DependencyManager::get<TextureCache>();
bool isAmbientSet = false;
if (_pendingAmbientTexture && !_ambientTexture) {
_ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::CUBE_TEXTURE);
}
if (_ambientTexture && _ambientTexture->isLoaded()) {
_pendingAmbientTexture = false;
auto texture = _ambientTexture->getGPUTexture();
if (texture) {
isAmbientSet = true;
} else {
qCDebug(entitiesrenderer) << "Failed to load ambient texture:" << _ambientTexture->getURL();
}
}
if (_pendingSkyboxTexture &&
(!_skyboxTexture || (_skyboxTexture->getURL() != _skyboxTextureURL))) {
_skyboxTexture = textureCache->getTexture(_skyboxTextureURL, image::TextureUsage::CUBE_TEXTURE);
}
if (_skyboxTexture && _skyboxTexture->isLoaded()) {
_pendingSkyboxTexture = false;
auto texture = _skyboxTexture->getGPUTexture();
if (texture) {
// skybox->setCubemap(texture);
if (!isAmbientSet) {
// sceneKeyLight->setAmbientSphere(texture->getIrradiance());
// sceneKeyLight->setAmbientMap(texture);
isAmbientSet = true;
}
} else {
qCDebug(entitiesrenderer) << "Failed to load skybox texture:" << _skyboxTexture->getURL();
}
} else {
// skybox->setCubemap(nullptr);
}
if (!isAmbientSet) {
// sceneKeyLight->resetAmbientSphere();
// sceneKeyLight->setAmbientMap(nullptr);
}
}
void RenderableZoneEntityItem::render(RenderArgs* args) {
Q_ASSERT(getType() == EntityTypes::Zone);
@ -235,6 +284,23 @@ public:
typedef Payload::DataPointer Pointer;
EntityItemPointer entity;
void render(RenderArgs* args);
model::LightPointer editLight() { _needUpdate = true; return _light; }
render::Item::Bound& editBound() { _needUpdate = true; return _bound; }
void setVisible(bool visible) { _isVisible = visible; }
bool isVisible() const { return _isVisible; }
model::LightPointer _light;
render::Item::Bound _bound;
LightStagePointer _stage;
LightStage::Index _index { LightStage::INVALID_INDEX };
bool _needUpdate { true };
bool _isVisible { true };
};
namespace render {
@ -254,11 +320,7 @@ namespace render {
return render::Item::Bound();
}
template <> void payloadRender(const RenderableZoneEntityItemMeta::Pointer& payload, RenderArgs* args) {
if (args) {
if (payload && payload->entity) {
payload->entity->render(args);
}
}
payload->render(args);
}
}
@ -318,19 +380,20 @@ void RenderableZoneEntityItem::notifyBoundChanged() {
}
}
void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) {
void RenderableZoneEntityItem::updateKeyZoneItemFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) {
auto entity = this;
keylightPayload.setVisible(entity->getVisible());
keyZonePayload.setVisible(entity->getVisible());
auto light = keylightPayload.editLight();
auto light = keyZonePayload.editLight();
light->setPosition(entity->getPosition());
light->setOrientation(entity->getRotation());
bool success;
keylightPayload.editBound() = entity->getAABox(success);
keyZonePayload.editBound() = entity->getAABox(success);
if (!success) {
keylightPayload.editBound() = render::Item::Bound();
keyZonePayload.editBound() = render::Item::Bound();
}
// Set the keylight
@ -340,8 +403,14 @@ void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& key
light->setDirection(this->getKeyLightProperties().getDirection());
light->setType(model::Light::SUN);
}
void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) {
}
void RenderableZoneEntityItem::sceneUpdateRenderItemFromEntity(render::Transaction& transaction) {
if (!render::Item::isValidID(_myKeyLightItem)) {
return;
@ -361,4 +430,35 @@ void RenderableZoneEntityItem::notifyChangedRenderItem() {
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
sceneUpdateRenderItemFromEntity(transaction);
scene->enqueueTransaction(transaction);
}
}
void RenderableZoneEntityItemMeta::render(RenderArgs* args) {
entity->render(args);
if (!_stage) {
_stage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
}
// Do we need to allocate the light in the stage ?
if (LightStage::isIndexInvalid(_index)) {
_index = _stage->addLight(_light);
_needUpdate = false;
}
// Need an update ?
if (_needUpdate) {
_stage->updateLightArrayBuffer(_index);
_needUpdate = false;
}
if (isVisible()) {
// FInally, push the light visible in the frame
_stage->_currentFrame.pushLight(_index, _light->getType());
#ifdef WANT_DEBUG
Q_ASSERT(args->_batch);
gpu::Batch& batch = *args->_batch;
batch.setModelTransform(getTransformToCenter());
DependencyManager::get<GeometryCache>()->renderWireSphere(batch, 0.5f, 15, 15, glm::vec4(color, 1.0f));
#endif
}
}

View file

@ -18,6 +18,8 @@
class NetworkGeometry;
class KeyLightPayload;
class RenderableZoneEntityItemMeta;
class RenderableZoneEntityItem : public ZoneEntityItem {
public:
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
@ -52,21 +54,34 @@ private:
Model* getModel();
void initialSimulation();
void updateGeometry();
void updateTextures();
template<typename Lambda>
void changeProperties(Lambda functor);
void notifyChangedRenderItem();
void sceneUpdateRenderItemFromEntity(render::Transaction& transaction);
void updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload);
void updateKeyZoneItemFromEntity(RenderableZoneEntityItemMeta& keyZonePayload);
void updateKeyLightItemFromEntity(KeyLightPayload& keyLightPayload);
Model* _model;
bool _needsInitialSimulation;
render::ItemID _myMetaItem{ render::Item::INVALID_ITEM_ID };
render::ItemID _myKeyLightItem { render::Item::INVALID_ITEM_ID };
// More attributes used for rendering:
NetworkTexturePointer _ambientTexture;
NetworkTexturePointer _skyboxTexture;
QString _ambientTextureURL;
QString _skyboxTextureURL;
bool _pendingAmbientTexture { false };
bool _pendingSkyboxTexture { false };
bool _validAmbientTextureURL { false };
bool _validSkyboxTextureURL { false };
};
#endif // hifi_RenderableZoneEntityItem_h

View file

@ -143,53 +143,12 @@ void DeferredLightingEffect::init() {
}
void DeferredLightingEffect::addLight(const model::LightPointer& light) {
assert(light);
auto lightID = _lightStage->addLight(light);
if (light->getType() == model::Light::POINT) {
_pointLights.push_back(lightID);
} else {
_spotLights.push_back(lightID);
}
}
void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color,
float intensity, float falloffRadius) {
addSpotLight(position, radius, color, intensity, falloffRadius);
}
void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color,
float intensity, float falloffRadius, const glm::quat& orientation, float exponent, float cutoff) {
unsigned int lightID = (unsigned int)(_pointLights.size() + _spotLights.size() + _globalLights.size());
if (lightID >= _allocatedLights.size()) {
_allocatedLights.push_back(std::make_shared<model::Light>());
}
model::LightPointer lp = _allocatedLights[lightID];
lp->setPosition(position);
lp->setMaximumRadius(radius);
lp->setColor(color);
lp->setIntensity(intensity);
lp->setFalloffRadius(falloffRadius);
if (exponent == 0.0f && cutoff == PI) {
lp->setType(model::Light::POINT);
_pointLights.push_back(lightID);
} else {
lp->setOrientation(orientation);
lp->setSpotAngle(cutoff);
lp->setSpotExponent(exponent);
lp->setType(model::Light::SPOT);
_spotLights.push_back(lightID);
}
}
void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) {
PerformanceTimer perfTimer("DLE->setupBatch()");
auto keyLight = _allocatedLights[_globalLights.front()];
if (_lightStage && _lightStage->_currentFrame._sunLights.size()) {
keyLight = _lightStage->getLight(_lightStage->_currentFrame._sunLights.front());
}
if (lightBufferUnit >= 0) {
batch.setUniformBuffer(lightBufferUnit, keyLight->getLightSchemaBuffer());
@ -772,16 +731,6 @@ void RenderDeferredCleanup::run(const render::RenderContextPointer& renderContex
batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, nullptr);
}
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
// End of the Lighting pass
if (!deferredLightingEffect->_pointLights.empty()) {
deferredLightingEffect->_pointLights.clear();
}
if (!deferredLightingEffect->_spotLights.empty()) {
deferredLightingEffect->_spotLights.clear();
}
}
RenderDeferred::RenderDeferred() {

View file

@ -43,18 +43,7 @@ class DeferredLightingEffect : public Dependency {
public:
void init();
void addLight(const model::LightPointer& light);
/// Adds a point light to render for the current frame.
void addPointLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(0.0f, 0.0f, 0.0f),
float intensity = 0.5f, float falloffRadius = 0.01f);
/// Adds a spot light to render for the current frame.
void addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f),
float intensity = 0.5f, float falloffRadius = 0.01f,
const glm::quat& orientation = glm::quat(), float exponent = 0.0f, float cutoff = PI);
void setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit);
void unsetKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit);
@ -113,8 +102,6 @@ private:
Lights _allocatedLights;
std::vector<int> _globalLights;
std::vector<int> _pointLights;
std::vector<int> _spotLights;
friend class LightClusteringPass;
friend class RenderDeferredSetup;

View file

@ -15,6 +15,7 @@
#include <model/Light.h>
#include <render/Item.h>
#include "LightStage.h"
#include "TextureCache.h"
class LightPayload {
public:
@ -61,6 +62,13 @@ public:
void setVisible(bool visible) { _isVisible = visible; }
bool isVisible() const { return _isVisible; }
// More attributes used for rendering:
NetworkTexturePointer _ambientTexture;
QString _ambientTextureURL;
bool _pendingAmbientTexture { false };
bool _validAmbientTextureURL { false };
protected:
model::LightPointer _light;
render::Item::Bound _bound;

View file

@ -118,7 +118,7 @@ public:
public:
Frame() {}
void clear() { _pointLights.clear(); _spotLights.clear(); }
void clear() { _pointLights.clear(); _spotLights.clear(); _sunLights.clear(); }
void pushLight(LightStage::Index index, model::Light::Type type) {
switch (type) {
case model::Light::POINT: { pushPointLight(index); break; }