From 653d2e72b1f5387f64f682848d6670f91601225c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 7 May 2015 11:23:11 -0700 Subject: [PATCH] Skybox kind of working --- interface/src/Application.cpp | 6 +++ libraries/gpu/src/gpu/GLBackendState.cpp | 1 + libraries/gpu/src/gpu/GLBackendTexture.cpp | 3 +- libraries/gpu/src/gpu/Texture.h | 4 +- libraries/model/src/model/Material.cpp | 12 ----- libraries/model/src/model/Material.h | 21 -------- libraries/model/src/model/Skybox.cpp | 6 +-- libraries/model/src/model/Stage.cpp | 16 ++++++- libraries/model/src/model/Stage.h | 4 +- libraries/model/src/model/TextureStorage.cpp | 29 +++++++++++ libraries/model/src/model/TextureStorage.h | 48 +++++++++++++++++++ libraries/render-utils/src/TextureCache.cpp | 42 +++++++++++----- libraries/render-utils/src/TextureCache.h | 4 +- .../src/SceneScriptingInterface.cpp | 26 ++++++++++ .../src/SceneScriptingInterface.h | 3 +- 15 files changed, 167 insertions(+), 58 deletions(-) create mode 100755 libraries/model/src/model/TextureStorage.cpp create mode 100755 libraries/model/src/model/TextureStorage.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 021981a80e..bac2aceb75 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3212,6 +3212,12 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { auto skybox = skyStage->getSkybox(); if (skybox) { + if (!skybox->getCubemap()) { + auto texture = DependencyManager::get()-> + getTexture(QUrl("https://hifi-public.s3.amazonaws.com/ryan/CloudyDay.png"), CUBE_TEXTURE); + skybox->setCubemap(texture->getGPUTexture()); + } + gpu::Batch batch; model::Skybox::render(batch, _viewFrustum, *skybox); diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index 2d3eacd37f..5670fddb08 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -464,6 +464,7 @@ void GLBackend::getCurrentGLState(State::Data& state) { void GLBackend::syncPipelineStateCache() { State::Data state; + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); getCurrentGLState(state); State::Signature signature = State::evalSignature(state); diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 4387821cfd..df275e16ad 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -370,7 +370,8 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { glBindTexture(GL_TEXTURE_CUBE_MAP, object->_texture); const int NUM_FACES = 6; const GLenum FACE_LAYOUT[] = { - GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + // GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 883b7c7098..19add9a47e 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -68,11 +68,11 @@ public: uint8 _maxMip = MAX_MIP_LEVEL; Desc() {} - Desc(const Filter filter) : _filter(filter) {} + Desc(const Filter filter, const WrapMode wrap = WRAP_REPEAT) : _filter(filter), _wrapModeU(wrap), _wrapModeV(wrap), _wrapModeW(wrap) {} }; Sampler() {} - Sampler(const Filter filter) : _desc(filter) {} + Sampler(const Filter filter, const WrapMode wrap = WRAP_REPEAT) : _desc(filter, wrap) {} Sampler(const Desc& desc) : _desc(desc) {} ~Sampler() {} diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index d27bdd4372..55572a5122 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -92,15 +92,3 @@ void Material::setTextureView(MapChannel channel, const gpu::TextureView& view) _textureMap[channel] = view; } -// TextureStorage -TextureStorage::TextureStorage(const QUrl& url) : gpu::Texture::Storage(), _url(url) { - init(); -} - -TextureStorage::~TextureStorage() { -} - -void TextureStorage::init() { - _gpuTexture = TexturePointer(Texture::createFromStorage(this)); -} - diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index 7e4417b55b..cd4c6d0373 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -23,27 +23,6 @@ namespace model { -typedef glm::vec3 Color; - -// TextureStorage is a specialized version of the gpu::Texture::Storage -// It adds the URL and the notion that it owns the gpu::Texture -class TextureStorage : public gpu::Texture::Storage { -public: - TextureStorage(const QUrl& url); - ~TextureStorage(); - - const QUrl& getUrl() const { return _url; } - const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; } - -protected: - gpu::TexturePointer _gpuTexture; - QUrl _url; - void init(); -}; -typedef std::shared_ptr< TextureStorage > TextureStoragePointer; - - - class Material { public: typedef gpu::BufferView UniformBufferView; diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 8495baf600..b80d5fcb36 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -21,7 +21,7 @@ using namespace model; Skybox::Skybox() { - _cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1)); +/* _cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1)); unsigned char texels[] = { 255, 0, 0, 255, 0, 255, 255, 255, @@ -30,7 +30,7 @@ Skybox::Skybox() { 0, 255, 0, 255, 255, 0, 255, 255, }; - _cubemap->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, sizeof(texels), texels); + _cubemap->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, sizeof(texels), texels); */ } void Skybox::setColor(const Color& color) { @@ -43,7 +43,7 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { - if (skybox.getCubemap()) { + if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { static gpu::PipelinePointer thePipeline; static gpu::BufferPointer theBuffer; diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index c29ebfe83e..e5d23e9191 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -190,7 +190,8 @@ const float NUM_HOURS_PER_DAY = 24.0f; const float NUM_HOURS_PER_HALF_DAY = NUM_HOURS_PER_DAY * 0.5f; SunSkyStage::SunSkyStage() : - _sunLight(new Light()) + _sunLight(new Light()), + _skybox(new Skybox()) { _sunLight->setType(Light::SUN); @@ -290,6 +291,19 @@ void SunSkyStage::updateGraphicsObject() const { _sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f)); } + // Background + switch (getBackgroundMode()) { + case NO_BACKGROUND: { + break; + } + case SKY_DOME: { + break; + } + case SKY_BOX: { + break; + } + }; + static int firstTime = 0; if (firstTime == 0) { firstTime++; diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index b6a19b49cd..a5f39cb825 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -223,11 +223,11 @@ public: const SkyboxPointer& getSkybox() const { valid(); return _skybox; } protected: - BackgroundMode _backgroundMode = SKY_DOME; + BackgroundMode _backgroundMode = SKY_BOX; LightPointer _sunLight; AtmospherePointer _atmosphere; - SkyboxPointer _skybox; + mutable SkyboxPointer _skybox; gpu::PipelinePointer _skyPipeline; diff --git a/libraries/model/src/model/TextureStorage.cpp b/libraries/model/src/model/TextureStorage.cpp new file mode 100755 index 0000000000..cc01941424 --- /dev/null +++ b/libraries/model/src/model/TextureStorage.cpp @@ -0,0 +1,29 @@ +// +// TextureStorage.cpp +// libraries/model/src/model +// +// Created by Sam Gateau on 5/6/2015. +// 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 "TextureStorage.h" + +using namespace model; +using namespace gpu; + +// TextureStorage +TextureStorage::TextureStorage(const QUrl& url, Texture::Type type ) : Texture::Storage(), + _url(url), + _type(type) { + init(); +} + +TextureStorage::~TextureStorage() { +} + +void TextureStorage::init() { + _gpuTexture = TexturePointer(Texture::createFromStorage(this)); +} + diff --git a/libraries/model/src/model/TextureStorage.h b/libraries/model/src/model/TextureStorage.h new file mode 100755 index 0000000000..ec56438bf3 --- /dev/null +++ b/libraries/model/src/model/TextureStorage.h @@ -0,0 +1,48 @@ +// +// TextureStorage.h +// libraries/model/src/model +// +// Created by Sam Gateau on 5/6/2015. +// 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 +// +#ifndef hifi_model_TextureStorage_h +#define hifi_model_TextureStorage_h + +#include "gpu/Texture.h" + +#include "Material.h" + +#include + +namespace model { + +typedef glm::vec3 Color; + +// TextureStorage is a specialized version of the gpu::Texture::Storage +// It provides the mechanism to create a texture from a Url and the intended usage +// that guides the internal format used +class TextureStorage : public gpu::Texture::Storage { +public: + TextureStorage(const QUrl& url, gpu::Texture::Type type = gpu::Texture::TEX_2D); + ~TextureStorage(); + + const QUrl& getUrl() const { return _url; } + const gpu::Texture::Type getType() const { return _type; } + const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; } + +protected: + gpu::TexturePointer _gpuTexture; + QUrl _url; + gpu::Texture::Type _type; + + void init(); +}; +typedef std::shared_ptr< TextureStorage > TextureStoragePointer; + +}; + +#endif // hifi_model_TextureStorage_h + diff --git a/libraries/render-utils/src/TextureCache.cpp b/libraries/render-utils/src/TextureCache.cpp index 2f9960355f..ded6673683 100644 --- a/libraries/render-utils/src/TextureCache.cpp +++ b/libraries/render-utils/src/TextureCache.cpp @@ -417,17 +417,23 @@ void ImageReader::run() { return; } - // enforce a fixed maximum area (1024 * 2048) - const int MAXIMUM_AREA_SIZE = 2097152; int imageArea = image.width() * image.height(); - if (imageArea > MAXIMUM_AREA_SIZE) { - float scaleRatio = sqrtf((float)MAXIMUM_AREA_SIZE) / sqrtf((float)imageArea); - int resizeWidth = static_cast(std::floor(scaleRatio * static_cast(image.width()))); - int resizeHeight = static_cast(std::floor(scaleRatio * static_cast(image.height()))); - qCDebug(renderutils) << "Image greater than maximum size:" << _url << image.width() << image.height() << - " scaled to:" << resizeWidth << resizeHeight; - image = image.scaled(resizeWidth, resizeHeight, Qt::IgnoreAspectRatio); - imageArea = image.width() * image.height(); + auto ntex = dynamic_cast(&*texture); + if (ntex && (ntex->getType() == CUBE_TEXTURE)) { + qCDebug(renderutils) << "Cube map size:" << _url << image.width() << image.height(); + } else { + + // enforce a fixed maximum area (1024 * 2048) + const int MAXIMUM_AREA_SIZE = 2097152; + if (imageArea > MAXIMUM_AREA_SIZE) { + float scaleRatio = sqrtf((float)MAXIMUM_AREA_SIZE) / sqrtf((float)imageArea); + int resizeWidth = static_cast(std::floor(scaleRatio * static_cast(image.width()))); + int resizeHeight = static_cast(std::floor(scaleRatio * static_cast(image.height()))); + qCDebug(renderutils) << "Image greater than maximum size:" << _url << image.width() << image.height() << + " scaled to:" << resizeWidth << resizeHeight; + image = image.scaled(resizeWidth, resizeHeight, Qt::IgnoreAspectRatio); + imageArea = image.width() * image.height(); + } } const int EIGHT_BIT_MAXIMUM = 255; @@ -507,6 +513,7 @@ void NetworkTexture::setImage(const QImage& image, bool translucent, const QColo imageLoaded(image); if ((_width > 0) && (_height > 0)) { + bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE); gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB)); @@ -515,9 +522,18 @@ void NetworkTexture::setImage(const QImage& image, bool translucent, const QColo formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA)); formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA)); } - _gpuTexture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); - _gpuTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); - _gpuTexture->autoGenerateMips(-1); + + if (_type == CUBE_TEXTURE) { + if (_height >= (6 * _width)) { + _gpuTexture = gpu::TexturePointer(gpu::Texture::createCube(formatGPU, image.width(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT, gpu::Sampler::WRAP_CLAMP))); + _gpuTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); + _gpuTexture->autoGenerateMips(-1); + } + } else { + _gpuTexture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + _gpuTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); + _gpuTexture->autoGenerateMips(-1); + } } } diff --git a/libraries/render-utils/src/TextureCache.h b/libraries/render-utils/src/TextureCache.h index e25a640ae7..3ff184c621 100644 --- a/libraries/render-utils/src/TextureCache.h +++ b/libraries/render-utils/src/TextureCache.h @@ -27,7 +27,7 @@ class NetworkTexture; typedef QSharedPointer NetworkTexturePointer; -enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, SPLAT_TEXTURE }; +enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, SPLAT_TEXTURE, CUBE_TEXTURE }; /// Stores cached textures, including render-to-texture targets. class TextureCache : public ResourceCache, public Dependency { @@ -164,7 +164,7 @@ public: int getOriginalHeight() const { return _originalHeight; } int getWidth() const { return _width; } int getHeight() const { return _height; } - + TextureType getType() const { return _type; } protected: virtual void downloadFinished(QNetworkReply* reply); diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index 2461487414..ad76dbcc38 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -13,6 +13,9 @@ #include "SceneScriptingInterface.h" +#include "SceneScriptingInterface.h" + + void SceneScriptingInterface::setStageOrientation(const glm::quat& orientation) { _skyStage->setOriginOrientation(orientation); } @@ -86,6 +89,29 @@ bool SceneScriptingInterface::isStageSunModelEnabled() const { return _skyStage->isSunModelEnabled(); } +void SceneScriptingInterface::setBackgroundMode(const QString& mode) { + if (mode == QString("inherit")) { + _skyStage->setBackgroundMode(model::SunSkyStage::NO_BACKGROUND); + } else if (mode == QString("atmosphere")) { + _skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME); + } else if (mode == QString("skybox")) { + _skyStage->setBackgroundMode(model::SunSkyStage::SKY_BOX); + } +} + +QString SceneScriptingInterface::getBackgroundMode() const { + switch (_skyStage->getBackgroundMode()) { + case model::SunSkyStage::NO_BACKGROUND: + return QString("inherit"); + case model::SunSkyStage::SKY_DOME: + return QString("atmosphere"); + case model::SunSkyStage::SKY_BOX: + return QString("skybox"); + default: + return QString("inherit"); + }; +} + model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { return _skyStage; } diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index c384153a0f..50aaae83ff 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -57,7 +57,8 @@ public: Q_INVOKABLE glm::vec3 getKeyLightDirection() const; - + Q_INVOKABLE void setBackgroundMode(const QString& mode); + Q_INVOKABLE QString getBackgroundMode() const; model::SunSkyStagePointer getSkyStage() const;