Skybox kind of working

This commit is contained in:
Sam Gateau 2015-05-07 11:23:11 -07:00
parent 5551997cdc
commit 653d2e72b1
15 changed files with 167 additions and 58 deletions

View file

@ -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<TextureCache>()->
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);

View file

@ -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);

View file

@ -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 };

View file

@ -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() {}

View file

@ -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));
}

View file

@ -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;

View file

@ -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;

View file

@ -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++;

View file

@ -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;

View file

@ -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));
}

View file

@ -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 <qurl.h>
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

View file

@ -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<int>(std::floor(scaleRatio * static_cast<float>(image.width())));
int resizeHeight = static_cast<int>(std::floor(scaleRatio * static_cast<float>(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<NetworkTexture*>(&*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<int>(std::floor(scaleRatio * static_cast<float>(image.width())));
int resizeHeight = static_cast<int>(std::floor(scaleRatio * static_cast<float>(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);
}
}
}

View file

@ -27,7 +27,7 @@ class NetworkTexture;
typedef QSharedPointer<NetworkTexture> 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);

View file

@ -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;
}

View file

@ -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;