From ade404a74d475c2dae5fdbf4cf2d3f335a026db9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 4 May 2015 13:43:30 -0700 Subject: [PATCH 01/13] getting rid of QSHaredPointer in favor of std::shared_ptr --- libraries/fbx/src/FBXReader.cpp | 2 +- libraries/gpu/src/gpu/Resource.h | 12 +++++------ libraries/gpu/src/gpu/Shader.h | 2 +- libraries/gpu/src/gpu/Stream.h | 4 ++-- libraries/gpu/src/gpu/Texture.h | 6 +++--- libraries/model/src/model/Geometry.h | 4 ++-- libraries/model/src/model/Light.h | 2 +- libraries/model/src/model/Material.h | 21 +++++++++++++++++++- libraries/model/src/model/Stage.h | 6 +++--- libraries/render-utils/src/GeometryCache.cpp | 14 ++++++------- libraries/render-utils/src/TextureCache.cpp | 6 +++--- 11 files changed, 49 insertions(+), 30 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 396859f3f8..6a1ecae97f 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1687,7 +1687,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, } } else if (object.name == "Material") { Material material = { glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(), 96.0f, 1.0f, - QString(""), QSharedPointer(NULL)}; + QString(""), model::MaterialPointer(NULL)}; foreach (const FBXNode& subobject, object.children) { bool properties = false; QByteArray propertyName; diff --git a/libraries/gpu/src/gpu/Resource.h b/libraries/gpu/src/gpu/Resource.h index 96b961ffd7..66c2a6e2e9 100644 --- a/libraries/gpu/src/gpu/Resource.h +++ b/libraries/gpu/src/gpu/Resource.h @@ -17,7 +17,7 @@ #include -#include +#include #ifdef _DEBUG #include #endif @@ -156,7 +156,7 @@ protected: friend class Backend; }; -typedef QSharedPointer BufferPointer; +typedef std::shared_ptr BufferPointer; typedef std::vector< BufferPointer > Buffers; @@ -317,7 +317,7 @@ public: template const T& get() const { #if _DEBUG - if (_buffer.isNull()) { + if (!_buffer) { qDebug() << "Accessing null gpu::buffer!"; } if (sizeof(T) > (_buffer->getSize() - _offset)) { @@ -333,7 +333,7 @@ public: template T& edit() { #if _DEBUG - if (_buffer.isNull()) { + if (!_buffer) { qDebug() << "Accessing null gpu::buffer!"; } if (sizeof(T) > (_buffer->getSize() - _offset)) { @@ -350,7 +350,7 @@ public: template const T& get(const Index index) const { Resource::Size elementOffset = index * sizeof(T) + _offset; #if _DEBUG - if (_buffer.isNull()) { + if (!_buffer) { qDebug() << "Accessing null gpu::buffer!"; } if (sizeof(T) > (_buffer->getSize() - elementOffset)) { @@ -366,7 +366,7 @@ public: template T& edit(const Index index) const { Resource::Size elementOffset = index * sizeof(T) + _offset; #if _DEBUG - if (_buffer.isNull()) { + if (!_buffer) { qDebug() << "Accessing null gpu::buffer!"; } if (sizeof(T) > (_buffer->getSize() - elementOffset)) { diff --git a/libraries/gpu/src/gpu/Shader.h b/libraries/gpu/src/gpu/Shader.h index c8db7cfd39..de129248ea 100755 --- a/libraries/gpu/src/gpu/Shader.h +++ b/libraries/gpu/src/gpu/Shader.h @@ -20,7 +20,7 @@ namespace gpu { class Shader { public: - typedef QSharedPointer< Shader > Pointer; + typedef std::shared_ptr< Shader > Pointer; typedef std::vector< Pointer > Shaders; class Source { diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 7cd859cbf5..27cb0ca539 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -117,7 +117,7 @@ public: void evaluateCache(); }; - typedef QSharedPointer FormatPointer; + typedef std::shared_ptr FormatPointer; }; typedef std::vector< Offset > Offsets; @@ -143,7 +143,7 @@ protected: Offsets _offsets; Strides _strides; }; -typedef QSharedPointer BufferStreamPointer; +typedef std::shared_ptr BufferStreamPointer; }; diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 7bf936958b..c7f82839a0 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -109,7 +109,7 @@ public: Element _format; bool _isGPULoaded; }; - typedef QSharedPointer< Pixels > PixelsPointer; + typedef std::shared_ptr< Pixels > PixelsPointer; class Storage { public: @@ -303,7 +303,7 @@ protected: friend class Backend; }; -typedef QSharedPointer TexturePointer; +typedef std::shared_ptr TexturePointer; typedef std::vector< TexturePointer > Textures; @@ -344,7 +344,7 @@ public: TextureView(const TextureView& view) = default; TextureView& operator=(const TextureView& view) = default; - explicit operator bool() const { return (_texture); } + explicit operator bool() const { return bool(_texture); } bool operator !() const { return (!_texture); } }; typedef std::vector TextureViews; diff --git a/libraries/model/src/model/Geometry.h b/libraries/model/src/model/Geometry.h index fbd485e6a0..31c06e6eca 100755 --- a/libraries/model/src/model/Geometry.h +++ b/libraries/model/src/model/Geometry.h @@ -47,7 +47,7 @@ public: void setVertexBuffer(const BufferView& buffer); const BufferView& getVertexBuffer() const { return _vertexBuffer; } uint getNumVertices() const { return _vertexBuffer.getNumElements(); } - bool hasVertexData() const { return !_vertexBuffer._buffer.isNull(); } + bool hasVertexData() const { return !_vertexBuffer._buffer; } // Attribute Buffers int getNumAttributes() const { return _attributeBuffers.size(); } @@ -126,7 +126,7 @@ protected: void evalVertexFormat(); }; -typedef QSharedPointer< Mesh > MeshPointer; +typedef std::shared_ptr< Mesh > MeshPointer; class Geometry { diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 30e3a8edad..18d8cc5001 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -282,7 +282,7 @@ protected: const Schema& getSchema() const { return _schemaBuffer.get(); } Schema& editSchema() { return _schemaBuffer.edit(); } }; -typedef QSharedPointer< Light > LightPointer; +typedef std::shared_ptr< Light > LightPointer; }; diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index 9262f23746..02fb7ae1f3 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -19,7 +19,26 @@ #include "gpu/Resource.h" #include "gpu/Texture.h" +#include + namespace model { + +// TextureStorage is a specialized version of the gpu::Texture::Storage +// It adds the URL and the notion that it owns the gpu::Texture +class LoadedTexture : public gpu::Texture::Storage { +public: + LoadedTexture(const QUrl& url); + ~LoadedTexture(); + + const QUrl& getUrl() const { return _url; } + const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; } + +protected: + gpu::TexturePointer _gpuTexture; + QUrl _url; +}; +typedef std::shared_ptr< LoadedTexture > LoadedTexturePointer; + typedef gpu::BufferView UniformBufferView; typedef gpu::TextureView TextureView; @@ -102,7 +121,7 @@ protected: TextureMap _textureMap; }; -typedef QSharedPointer< Material > MaterialPointer; +typedef std::shared_ptr< Material > MaterialPointer; }; diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index 237265ed12..ee7cad4176 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -158,7 +158,7 @@ protected: void updateScattering(); }; -typedef QSharedPointer< Atmosphere > AtmospherePointer; +typedef std::shared_ptr< Atmosphere > AtmospherePointer; class Skybox { @@ -173,7 +173,7 @@ public: protected: gpu::TexturePointer _cubemap; }; -typedef QSharedPointer< Skybox > SkyboxPointer; +typedef std::shared_ptr< Skybox > SkyboxPointer; // Sun sky stage generates the rendering primitives to display a scene realistically // at the specified location and time around earth @@ -244,7 +244,7 @@ protected: void updateGraphicsObject() const; }; -typedef QSharedPointer< SunSkyStage > SunSkyStagePointer; +typedef std::shared_ptr< SunSkyStage > SunSkyStagePointer; }; diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 9d71ec5cc2..77568e51e7 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -69,7 +69,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm || (!registered && !_sphereVertices.contains(radiusKey))) { if (registered && _registeredSphereVertices.contains(id)) { - _registeredSphereVertices[id].clear(); + _registeredSphereVertices[id].reset(); #ifdef WANT_DEBUG qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED VERTICES BUFFER"; #endif @@ -133,7 +133,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm || (!registered && !_sphereIndices.contains(slicesStacksKey))) { if (registered && _registeredSphereIndices.contains(id)) { - _registeredSphereIndices[id].clear(); + _registeredSphereIndices[id].reset(); #ifdef WANT_DEBUG qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED INDICES BUFFER"; #endif @@ -219,7 +219,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm || (!registered && !_sphereColors.contains(colorKey))) { if (registered && _registeredSphereColors.contains(id)) { - _registeredSphereColors[id].clear(); + _registeredSphereColors[id].reset(); #ifdef WANT_DEBUG qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED COLORS BUFFER"; #endif @@ -1581,10 +1581,10 @@ GeometryCache::BatchItemDetails::~BatchItemDetails() { void GeometryCache::BatchItemDetails::clear() { isCreated = false; - verticesBuffer.clear(); - colorBuffer.clear(); - streamFormat.clear(); - stream.clear(); + verticesBuffer.reset(); + colorBuffer.reset(); + streamFormat.reset(); + stream.reset(); } void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, diff --git a/libraries/render-utils/src/TextureCache.cpp b/libraries/render-utils/src/TextureCache.cpp index 616ff13dce..5cf26c9167 100644 --- a/libraries/render-utils/src/TextureCache.cpp +++ b/libraries/render-utils/src/TextureCache.cpp @@ -90,7 +90,7 @@ const int permutation[256] = #define USE_CHRIS_NOISE 1 const gpu::TexturePointer& TextureCache::getPermutationNormalTexture() { - if (_permutationNormalTexture.isNull()) { + if (_permutationNormalTexture) { // the first line consists of random permutation offsets unsigned char data[256 * 2 * 3]; @@ -134,7 +134,7 @@ static void loadSingleColorTexture(const unsigned char* color) { */ const gpu::TexturePointer& TextureCache::getWhiteTexture() { - if (_whiteTexture.isNull()) { + if (_whiteTexture) { _whiteTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1)); _whiteTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_WHITE); } @@ -142,7 +142,7 @@ const gpu::TexturePointer& TextureCache::getWhiteTexture() { } const gpu::TexturePointer& TextureCache::getBlueTexture() { - if (_blueTexture.isNull()) { + if (_blueTexture) { _blueTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1)); _blueTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(OPAQUE_BLUE), OPAQUE_BLUE); } From 6d02d4d25e29d354b0614b491dc663aab4f85de7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 5 May 2015 11:40:00 -0700 Subject: [PATCH 02/13] adding skybox step by step --- interface/src/Application.cpp | 68 +++++++++++-------- interface/src/devices/KeyboardMouseDevice.cpp | 6 +- libraries/model/src/model/Material.cpp | 16 ++++- libraries/model/src/model/Material.h | 16 +++-- libraries/model/src/model/Stage.cpp | 13 ++-- libraries/model/src/model/Stage.h | 28 ++++---- 6 files changed, 86 insertions(+), 61 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a63e2f2005..fa684a86f1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3071,45 +3071,53 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][2]); } - if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) { - PerformanceTimer perfTimer("stars"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... stars..."); - if (!_stars.isStarsLoaded()) { - _stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED); - } - // should be the first rendering pass - w/o depth buffer / lighting - - // compute starfield alpha based on distance from atmosphere - float alpha = 1.0f; - if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { - const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition()); - float height = glm::distance(theCamera.getPosition(), - closestData.getAtmosphereCenter(theCamera.getPosition())); - if (height < closestData.getAtmosphereInnerRadius()) { - alpha = 0.0f; - - } else if (height < closestData.getAtmosphereOuterRadius()) { - alpha = (height - closestData.getAtmosphereInnerRadius()) / - (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius()); + // Render the stars and sky only if sky dome mode + auto skyStage = DependencyManager::get()->getSkyStage(); + if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) { + } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) { + if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) { + PerformanceTimer perfTimer("stars"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::displaySide() ... stars..."); + if (!_stars.isStarsLoaded()) { + _stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED); } + // should be the first rendering pass - w/o depth buffer / lighting + + // compute starfield alpha based on distance from atmosphere + float alpha = 1.0f; + if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { + const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition()); + float height = glm::distance(theCamera.getPosition(), + closestData.getAtmosphereCenter(theCamera.getPosition())); + if (height < closestData.getAtmosphereInnerRadius()) { + alpha = 0.0f; + + } else if (height < closestData.getAtmosphereOuterRadius()) { + alpha = (height - closestData.getAtmosphereInnerRadius()) / + (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius()); + } + } + + // finally render the starfield + _stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha); } - // finally render the starfield - _stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha); + // draw the sky dome + if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { + PerformanceTimer perfTimer("atmosphere"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::displaySide() ... atmosphere..."); + _environment.renderAtmospheres(theCamera); + } + } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { + } if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } - // draw the sky dome - if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { - PerformanceTimer perfTimer("atmosphere"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... atmosphere..."); - _environment.renderAtmospheres(theCamera); - } glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); diff --git a/interface/src/devices/KeyboardMouseDevice.cpp b/interface/src/devices/KeyboardMouseDevice.cpp index 622fc4b5dc..7b0f8c056c 100755 --- a/interface/src/devices/KeyboardMouseDevice.cpp +++ b/interface/src/devices/KeyboardMouseDevice.cpp @@ -123,7 +123,11 @@ void KeyboardMouseDevice::touchUpdateEvent(const QTouchEvent* event) { } UserInputMapper::Input KeyboardMouseDevice::makeInput(Qt::Key code) { - return UserInputMapper::Input(_deviceID, code & KEYBOARD_MASK, UserInputMapper::ChannelType::BUTTON); + auto shortCode = (UserInputMapper::uint16)(code & KEYBOARD_MASK); + if (shortCode != code) { + shortCode |= 0x0800; // add this bit instead of the way Qt::Key add a bit on the 3rd byte for some keys + } + return UserInputMapper::Input(_deviceID, shortCode, UserInputMapper::ChannelType::BUTTON); } UserInputMapper::Input KeyboardMouseDevice::makeInput(Qt::MouseButton code) { diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index 1ce50174e0..ff0691442c 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -11,6 +11,7 @@ #include "Material.h" using namespace model; +using namespace gpu; Material::Material() : _flags(0), @@ -86,7 +87,20 @@ void Material::setOpacity(float opacity) { _schemaBuffer.edit()._opacity = opacity; } -void Material::setTextureView(MapChannel channel, const TextureView& view) { +void Material::setTextureView(MapChannel channel, const gpu::TextureView& view) { _flags.set(DIFFUSE_MAP_BIT + channel); _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 02fb7ae1f3..7e4417b55b 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -23,12 +23,14 @@ 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 LoadedTexture : public gpu::Texture::Storage { +class TextureStorage : public gpu::Texture::Storage { public: - LoadedTexture(const QUrl& url); - ~LoadedTexture(); + TextureStorage(const QUrl& url); + ~TextureStorage(); const QUrl& getUrl() const { return _url; } const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; } @@ -36,14 +38,16 @@ public: protected: gpu::TexturePointer _gpuTexture; QUrl _url; + void init(); }; -typedef std::shared_ptr< LoadedTexture > LoadedTexturePointer; +typedef std::shared_ptr< TextureStorage > TextureStoragePointer; + -typedef gpu::BufferView UniformBufferView; -typedef gpu::TextureView TextureView; class Material { public: + typedef gpu::BufferView UniformBufferView; + typedef gpu::TextureView TextureView; typedef glm::vec3 Color; diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 77bc3f03f0..453bc0c154 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -184,14 +184,6 @@ void Atmosphere::setInnerOuterRadiuses(float inner, float outer) { data._scales.z = data._scales.x / data._scales.y; } -Skybox::Skybox() { -} - -void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { - _cubemap = cubemap; -} - - const int NUM_DAYS_PER_YEAR = 365; const float NUM_HOURS_PER_DAY = 24.0f; @@ -301,6 +293,11 @@ void SunSkyStage::updateGraphicsObject() const { } } +void SunSkyStage::setBackgroundMode(BackgroundMode mode) { + _backgroundMode = mode; + invalidate(); +} + void SunSkyStage::setSkybox(const SkyboxPointer& skybox) { _skybox = skybox; invalidate(); diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index ee7cad4176..b28c20fc65 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -14,6 +14,7 @@ #include "gpu/Pipeline.h" #include "Light.h" +#include "Skybox.h" namespace model { @@ -160,21 +161,6 @@ protected: }; typedef std::shared_ptr< Atmosphere > AtmospherePointer; - -class Skybox { -public: - Skybox(); - Skybox& operator= (const Atmosphere& Skybox); - virtual ~Skybox() {}; - - void setCubemap(const gpu::TexturePointer& cubemap); - const gpu::TexturePointer& getCubemap() const { return _cubemap; } - -protected: - gpu::TexturePointer _cubemap; -}; -typedef std::shared_ptr< Skybox > SkyboxPointer; - // Sun sky stage generates the rendering primitives to display a scene realistically // at the specified location and time around earth class SunSkyStage { @@ -222,11 +208,23 @@ public: LightPointer getSunLight() const { valid(); return _sunLight; } AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; } + enum BackgroundMode { + NO_BACKGROUND = 0, + SKY_DOME, + SKY_BOX, + + NUM_BACKGROUND_MODES, + }; + void setBackgroundMode(BackgroundMode mode); + BackgroundMode getBackgroundMode() const { return _backgroundMode; } + // Skybox void setSkybox(const SkyboxPointer& skybox); const SkyboxPointer& getSkybox() const { valid(); return _skybox; } protected: + BackgroundMode _backgroundMode = SKY_DOME; + LightPointer _sunLight; AtmospherePointer _atmosphere; SkyboxPointer _skybox; From b1fb05e5438f6134cd1071af8b1219a0e5b7af30 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 5 May 2015 12:04:30 -0700 Subject: [PATCH 03/13] merge --- libraries/model/src/model/Skybox.cpp | 21 +++++++++++++++ libraries/model/src/model/Skybox.h | 40 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100755 libraries/model/src/model/Skybox.cpp create mode 100755 libraries/model/src/model/Skybox.h diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp new file mode 100755 index 0000000000..9a1addc9c7 --- /dev/null +++ b/libraries/model/src/model/Skybox.cpp @@ -0,0 +1,21 @@ +// +// Skybox.cpp +// libraries/model/src/model +// +// Created by Sam Gateau on 5/4/2015. +// Copyright 2015 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 "Skybox.h" + +using namespace model; + +Skybox::Skybox() { +} + +void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { + _cubemap = cubemap; +} + diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h new file mode 100755 index 0000000000..8a04265129 --- /dev/null +++ b/libraries/model/src/model/Skybox.h @@ -0,0 +1,40 @@ +// +// Skybox.h +// libraries/model/src/model +// +// Created by Sam Gateau on 5/4/2015. +// Copyright 2015 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_Skybox_h +#define hifi_model_Skybox_h + +#include "gpu/Texture.h" + +namespace model { + +typedef glm::vec3 Color; + +class Skybox { +public: + Skybox(); + Skybox& operator= (const Skybox& skybox); + virtual ~Skybox() {}; + + void setColor(const Color& color); + const Color& getColor() { return _color; } + + void setCubemap(const gpu::TexturePointer& cubemap); + const gpu::TexturePointer& getCubemap() const { return _cubemap; } + +protected: + gpu::TexturePointer _cubemap; + Color _color; +}; +typedef std::shared_ptr< Skybox > SkyboxPointer; + +}; + +#endif //hifi_model_Skybox_h From dc81a3ecc2120e075b11ec6f86ea44cce7a34bd9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 6 May 2015 09:53:36 -0700 Subject: [PATCH 04/13] Cube texture are working with the GL backend, useing it in SKybox successfullly --- interface/src/Application.cpp | 8 ++ libraries/gpu/src/gpu/Batch.cpp | 12 +++ libraries/gpu/src/gpu/Batch.h | 5 ++ libraries/gpu/src/gpu/Context.h | 1 + libraries/gpu/src/gpu/Framebuffer.h | 5 +- libraries/gpu/src/gpu/GLBackend.cpp | 36 +++++++- libraries/gpu/src/gpu/GLBackend.h | 2 + libraries/gpu/src/gpu/GLBackendPipeline.cpp | 19 ++++- libraries/gpu/src/gpu/GLBackendTexture.cpp | 88 +++++++++++++++++++- libraries/gpu/src/gpu/GLBackendTransform.cpp | 1 + libraries/gpu/src/gpu/Texture.cpp | 21 ++--- libraries/gpu/src/gpu/Texture.h | 37 ++++---- libraries/gpu/src/gpu/Transform.slh | 19 +++++ libraries/model/src/model/Skybox.cpp | 61 ++++++++++++++ libraries/model/src/model/Skybox.h | 10 ++- libraries/model/src/model/Skybox.slf | 24 ++++++ libraries/model/src/model/Skybox.slv | 42 ++++++++++ libraries/model/src/model/Stage.cpp | 4 + libraries/model/src/model/Stage.h | 2 +- libraries/octree/src/ViewFrustum.cpp | 4 + libraries/octree/src/ViewFrustum.h | 3 + 21 files changed, 363 insertions(+), 41 deletions(-) create mode 100755 libraries/model/src/model/Skybox.slf create mode 100755 libraries/model/src/model/Skybox.slv diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 19810be445..9a77cecefd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3116,6 +3116,14 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs } } } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { + auto skybox = skyStage->getSkybox(); + if (skybox) { + gpu::Batch batch; + model::Skybox::render(batch, _viewFrustum, *skybox); + + gpu::GLBackend::renderBatch(batch); + glUseProgram(0); + } } if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 4b145b55a0..bff99e7ec3 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -91,6 +91,18 @@ void Batch::drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, ui _params.push_back(nbInstances); } +void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil) { + ADD_COMMAND(clearFramebuffer); + + _params.push_back(stencil); + _params.push_back(depth); + _params.push_back(color.w); + _params.push_back(color.z); + _params.push_back(color.y); + _params.push_back(color.x); + _params.push_back(targets); +} + void Batch::setInputFormat(const Stream::FormatPointer& format) { ADD_COMMAND(setInputFormat); diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index b6bc05ab40..b369c05646 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -81,6 +81,9 @@ public: void drawInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbVertices, uint32 startVertex = 0, uint32 startInstance = 0); void drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbIndices, uint32 startIndex = 0, uint32 startInstance = 0); + // Clear framebuffer layers + void clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil); + // Input Stage // InputFormat // InputBuffers @@ -160,6 +163,8 @@ public: COMMAND_drawInstanced, COMMAND_drawIndexedInstanced, + COMMAND_clearFramebuffer, + COMMAND_setInputFormat, COMMAND_setInputBuffer, COMMAND_setIndexBuffer, diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index 022ca02d6d..7ffb22f1c8 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -43,6 +43,7 @@ public: Mat4 _viewInverse; Mat4 _projectionViewUntranslated; Mat4 _projection; + Mat4 _projectionInverse; Vec4 _viewport; }; diff --git a/libraries/gpu/src/gpu/Framebuffer.h b/libraries/gpu/src/gpu/Framebuffer.h index 69e507f824..50f42ed4fb 100755 --- a/libraries/gpu/src/gpu/Framebuffer.h +++ b/libraries/gpu/src/gpu/Framebuffer.h @@ -81,6 +81,7 @@ public: BUFFER_STENCIL = 0x80000000, BUFFER_DEPTHSTENCIL = 0xC0000000, }; + typedef uint32 Masks; ~Framebuffer(); @@ -111,7 +112,7 @@ public: // Properties - uint32 getBufferMask() const { return _bufferMask; } + Masks getBufferMask() const { return _bufferMask; } bool isEmpty() const { return (_bufferMask == 0); } bool hasColor() const { return (getBufferMask() & BUFFER_COLORS); } bool hasDepthStencil() const { return (getBufferMask() & BUFFER_DEPTHSTENCIL); } @@ -137,7 +138,7 @@ protected: TextureViews _renderBuffers; TextureView _depthStencilBuffer; - uint32 _bufferMask = 0; + Masks _bufferMask = 0; uint32 _frameCount = 0; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index a898c9042b..3c0ff4b309 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -17,7 +17,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_drawIndexed), (&::gpu::GLBackend::do_drawInstanced), (&::gpu::GLBackend::do_drawIndexedInstanced), - + (&::gpu::GLBackend::do_clearFramebuffer), + (&::gpu::GLBackend::do_setInputFormat), (&::gpu::GLBackend::do_setInputBuffer), (&::gpu::GLBackend::do_setIndexBuffer), @@ -170,6 +171,39 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } +void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) { + + uint32 masks = batch._params[paramOffset + 6]._uint; + Vec4 color; + color.x = batch._params[paramOffset + 5]._float; + color.y = batch._params[paramOffset + 4]._float; + color.z = batch._params[paramOffset + 3]._float; + color.w = batch._params[paramOffset + 2]._float; + float depth = batch._params[paramOffset + 1]._float; + int stencil = batch._params[paramOffset + 0]._float; + + GLuint glmask = 0; + if (masks & Framebuffer::BUFFER_DEPTH) { + glClearStencil(stencil); + glmask |= GL_STENCIL_BUFFER_BIT; + } + + if (masks & Framebuffer::BUFFER_DEPTH) { + glClearDepth(depth); + glmask |= GL_DEPTH_BUFFER_BIT; + } + + if (masks & Framebuffer::BUFFER_COLORS) { + glClearColor(color.x, color.y, color.z, color.w); + glmask |= GL_COLOR_BUFFER_BIT; + } + + glClear(glmask); + + (void) CHECK_GL_ERROR(); +} + + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index b725fa46d0..9943af1679 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -191,6 +191,8 @@ protected: void do_drawInstanced(Batch& batch, uint32 paramOffset); void do_drawIndexedInstanced(Batch& batch, uint32 paramOffset); + void do_clearFramebuffer(Batch& batch, uint32 paramOffset); + // Input Stage void do_setInputFormat(Batch& batch, uint32 paramOffset); void do_setInputBuffer(Batch& batch, uint32 paramOffset); diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index 48a45ce93f..938ed77730 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -171,10 +171,21 @@ void GLBackend::do_setUniformTexture(Batch& batch, uint32 paramOffset) { GLuint slot = batch._params[paramOffset + 1]._uint; TexturePointer uniformTexture = batch._textures.get(batch._params[paramOffset + 0]._uint); - GLuint to = getTextureID(uniformTexture); - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(GL_TEXTURE_2D, to); + if (!uniformTexture) { + return; + } - (void) CHECK_GL_ERROR(); + GLTexture* object = GLBackend::syncGPUObject(*uniformTexture); + if (object) { + GLuint to = object->_texture; + GLuint target = object->_target; + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(target, to); + + (void) CHECK_GL_ERROR(); + + } else { + return; + } } diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index da39ab16fa..97987a401a 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -363,6 +363,93 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { } break; } + case Texture::TEX_CUBE: { + if (texture.getNumSlices() == 1) { + GLint boundTex = -1; + glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &boundTex); + 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_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; + + if (needUpdate) { + if (texture.isStoredMipAvailable(0)) { + Texture::PixelsPointer mip = texture.accessStoredMip(0); + Element srcFormat = mip->_format; + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat); + + uint16 width = texture.getWidth(); + int faceSize = mip->_sysmem.getSize() / NUM_FACES; + + glBindTexture(GL_TEXTURE_CUBE_MAP, object->_texture); + for (int f = 0; f < NUM_FACES; f++) { + glTexSubImage2D(FACE_LAYOUT[f], 0, texelFormat.internalFormat, width, width, 0, + texelFormat.format, texelFormat.type, (GLvoid*) (mip->_sysmem.read() + f * faceSize)); + } + + if (texture.isAutogenerateMips()) { + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + } + + object->_target = GL_TEXTURE_CUBE_MAP; + + syncSampler(texture.getSampler(), texture.getType(), object); + + // At this point the mip piels have been loaded, we can notify + texture.notifyGPULoaded(0); + + object->_contentStamp = texture.getDataStamp(); + } + } else { + const gpu::Resource::Byte* bytes = 0; + Element srcFormat = texture.getTexelFormat(); + uint16 width = texture.getWidth(); + int faceSize = 0; + + if (texture.isStoredMipAvailable(0)) { + Texture::PixelsPointer mip = texture.accessStoredMip(0); + + bytes = mip->_sysmem.read(); + srcFormat = mip->_format; + faceSize = mip->_sysmem.getSize() / NUM_FACES; + + object->_contentStamp = texture.getDataStamp(); + } + + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat); + + glBindTexture(GL_TEXTURE_CUBE_MAP, object->_texture); + for (int f = 0; f < NUM_FACES; f++) { + glTexImage2D(FACE_LAYOUT[f], 0, texelFormat.internalFormat, width, width, 0, + texelFormat.format, texelFormat.type, (GLvoid*) (bytes + f * faceSize)); + } + + if (bytes && texture.isAutogenerateMips()) { + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + object->_target = GL_TEXTURE_CUBE_MAP; + + syncSampler(texture.getSampler(), texture.getType(), object); + + // At this point the mip piels have been loaded, we can notify + texture.notifyGPULoaded(0); + + object->_storageStamp = texture.getStamp(); + object->_size = texture.getSize(); + } + + glBindTexture(GL_TEXTURE_CUBE_MAP, boundTex); + } + break; + } default: qCDebug(gpulogging) << "GLBackend::syncGPUObject(const Texture&) case for Texture Type " << texture.getType() << " not supported"; } @@ -449,6 +536,5 @@ void GLBackend::syncSampler(const Sampler& sampler, Texture::Type type, GLTextur glTexParameterf(object->_target, GL_TEXTURE_MIN_LOD, (float) sampler.getMinMip()); glTexParameterf(object->_target, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); glTexParameterf(object->_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy()); - (void) CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 88c993985f..d619d0afee 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -59,6 +59,7 @@ void GLBackend::updateTransform() { // Check all the dirty flags and update the state accordingly if (_transform._invalidProj) { _transform._transformCamera._projection = _transform._projection; + _transform._transformCamera._projectionInverse = glm::inverse(_transform._projection); } if (_transform._invalidView) { diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index f73b24411b..d4891fcf7c 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -15,6 +15,8 @@ using namespace gpu; +uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = {1, 1, 1, 6}; + Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) : _sysmem(size, bytes), _format(format), @@ -131,19 +133,7 @@ Texture* Texture::createFromStorage(Storage* storage) { } Texture::Texture(): - Resource(), - _storage(), - _stamp(0), - _size(0), - _width(1), - _height(1), - _depth(1), - _numSamples(1), - _numSlices(1), - _maxMip(0), - _type(TEX_1D), - _autoGenerateMips(false), - _defined(false) + Resource() { } @@ -186,10 +176,9 @@ Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 widt _depth = depth; changed = true; } - + // Evaluate the new size with the new format - const int DIM_SIZE[] = {1, 1, 1, 6}; - uint32_t size = DIM_SIZE[_type] *_width * _height * _depth * _numSamples * texelFormat.getSize(); + uint32_t size = NUM_FACES_PER_TYPE[_type] *_width * _height * _depth * _numSamples * texelFormat.getSize(); // If size change then we need to reset if (changed || (size != getSize())) { diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index c7f82839a0..5523f7f417 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -138,6 +138,8 @@ public: TEX_2D, TEX_3D, TEX_CUBE, + + NUM_TYPES, }; static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler()); @@ -180,11 +182,19 @@ public: uint16 getDepth() const { return _depth; } uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); } - uint32 getNumTexels() const { return _width * _height * _depth; } + + // The number of faces is mostly used for cube map, and maybe for stereo ? otherwise it's 1 + // For cube maps, this means the pixels of the different faces are supposed to bepacked back to back in a mip + // as if the height was NUM_FACES time bigger. + static uint8 NUM_FACES_PER_TYPE[NUM_TYPES]; + uint8 getNumFaces() const { return NUM_FACES_PER_TYPE[getType()]; } + + uint32 getNumTexels() const { return _width * _height * _depth * getNumFaces(); } uint16 getNumSlices() const { return _numSlices; } uint16 getNumSamples() const { return _numSamples; } + // NumSamples can only have certain values based on the hw static uint16 evalNumSamplesUsed(uint16 numSamplesTried); @@ -203,7 +213,7 @@ public: uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); } uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); } uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); } - uint32 evalMipNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); } + uint32 evalMipNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getNumFaces(); } uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); } uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); } @@ -269,27 +279,26 @@ public: protected: std::unique_ptr< Storage > _storage; - Stamp _stamp; + Stamp _stamp = 0; Sampler _sampler; Stamp _samplerStamp; - - uint32 _size; + uint32 _size = 0; Element _texelFormat; - uint16 _width; - uint16 _height; - uint16 _depth; + uint16 _width = 1; + uint16 _height = 1; + uint16 _depth = 1; - uint16 _numSamples; - uint16 _numSlices; + uint16 _numSamples = 1; + uint16 _numSlices = 1; - uint16 _maxMip; + uint16 _maxMip = 0; - Type _type; - bool _autoGenerateMips; - bool _defined; + Type _type = TEX_1D; + bool _autoGenerateMips = false; + bool _defined = false; static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler); Texture(); diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 042964f0f7..a65fc7e9bd 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -21,6 +21,7 @@ struct TransformCamera { mat4 _viewInverse; mat4 _projectionViewUntranslated; mat4 _projection; + mat4 _projectionInverse; vec4 _viewport; }; @@ -120,4 +121,22 @@ TransformCamera getTransformCamera() { <@endif@> <@endfunc@> +<@func transformEyeToWorldDir(cameraTransform, eyeDir, worldDir)@> +<@if GPU_TRANSFORM_PROFILE == GPU_CORE@> + { // transformEyeToWorldDir + <$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0)); + } +<@else@> +<@endif@> +<@endfunc@> + +<@func transformClipToEyeDir(cameraTransform, clipPos, eyeDir)@> +<@if GPU_TRANSFORM_PROFILE == GPU_CORE@> + { // transformClipToEyedDir + <$eyeDir$> = vec3(<$cameraTransform$>._projectionInverse * vec4(<$clipPos$>.xyz, 1.0)); + } +<@else@> +<@endif@> +<@endfunc@> + <@endif@> diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 9a1addc9c7..c9b0d270fb 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -10,12 +10,73 @@ // #include "Skybox.h" +#include "gpu/Batch.h" +#include "gpu/Context.h" + +#include "ViewFrustum.h" +#include "skybox_vert.h" +#include "skybox_frag.h" + using namespace model; Skybox::Skybox() { + + _cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1)); + unsigned char texels[] = { + 255, 0, 0, 255, + 0, 255, 255, 255, + 0, 0, 255, 255, + 255, 255, 0, 255, + 0, 255, 0, 255, + 255, 0, 255, 255, + }; + _cubemap->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, sizeof(texels), texels); +} + +void Skybox::setColor(const Color& color) { + _color = color; } void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { _cubemap = cubemap; } +void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { + + if (skybox.getCubemap()) { + + static gpu::PipelinePointer thePipeline; + if (!thePipeline) { + auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); + auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); + auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); + + gpu::Shader::BindingSet bindings; + bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); + + if (!gpu::Shader::makeProgram(*skyShader, bindings)) { + + } + + auto skyState = gpu::StatePointer(new gpu::State()); + + thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); + } + + glm::mat4 projMat; + viewFrustum.evalProjectionMatrix(projMat); + + Transform viewTransform; + viewFrustum.evalViewTransform(viewTransform); + + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewTransform); + batch.setPipeline(thePipeline); + batch.setUniformTexture(0, skybox.getCubemap()); + batch.draw(gpu::TRIANGLE_STRIP, 4); + } else { + // skybox has no cubemap, just clear the color buffer + auto color = skybox.getColor(); + batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(skybox.getColor(),1.0f), 0.f, 0); + } +} diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h index 8a04265129..8eb910a96e 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/model/src/model/Skybox.h @@ -13,6 +13,10 @@ #include "gpu/Texture.h" +class ViewFrustum; +//class Transform; +namespace gpu { class Batch; } + namespace model { typedef glm::vec3 Color; @@ -24,14 +28,16 @@ public: virtual ~Skybox() {}; void setColor(const Color& color); - const Color& getColor() { return _color; } + const Color& getColor() const { return _color; } void setCubemap(const gpu::TexturePointer& cubemap); const gpu::TexturePointer& getCubemap() const { return _cubemap; } + static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox); + protected: gpu::TexturePointer _cubemap; - Color _color; + Color _color{1.0f, 1.0f, 1.0f}; }; typedef std::shared_ptr< Skybox > SkyboxPointer; diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf new file mode 100755 index 0000000000..da9f9401bc --- /dev/null +++ b/libraries/model/src/model/Skybox.slf @@ -0,0 +1,24 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// skybox.frag +// +// Created by Sam Gateau on 5/5/2015. +// Copyright 2015 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 +// + +uniform samplerCube cubeMap; + +varying vec3 normal; +varying vec2 texcoord; +varying vec3 color; + + +void main(void) { + vec4 texel = texture(cubeMap, normalize(normal)); + gl_FragData[0] = texel; + // gl_FragData[0] = vec4(normal, 1.0); +} diff --git a/libraries/model/src/model/Skybox.slv b/libraries/model/src/model/Skybox.slv new file mode 100755 index 0000000000..d4fe58959f --- /dev/null +++ b/libraries/model/src/model/Skybox.slv @@ -0,0 +1,42 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// skybox.vert +// vertex shader +// +// Created by Sam Gateau on 5/5/2015. +// Copyright 2015 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 gpu/Transform.slh@> + +<$declareStandardTransform()$> + +varying vec3 normal; +varying vec2 texcoord; +varying vec3 color; + +void main(void) { + const float CLIP = 1.0; + const vec2 vertices[4] = vec2[4](vec2(-CLIP, -CLIP), vec2(CLIP, -CLIP), vec2(-CLIP, CLIP), vec2(CLIP, CLIP)); + texcoord = vertices[gl_VertexID]; + + // pass along the diffuse color + color = vec3(texcoord, 0.0); + + // standard transform + TransformCamera cam = getTransformCamera(); + vec3 clipDir = vec3(texcoord.xy, 0.0); + vec3 eyeDir; + + <$transformClipToEyeDir(cam, clipDir, eyeDir)$>; + normal = normalize(eyeDir); + <$transformEyeToWorldDir(cam, eyeDir, normal)$>; + normal = normalize(normal); + + // Position is supposed to cmoe in clip space + gl_Position = vec4(texcoord.xy, 0.0, 1.0); +} diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 453bc0c154..2e579d3618 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -215,6 +215,10 @@ SunSkyStage::SunSkyStage() : _skyPipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); + + _skybox.reset(new Skybox()); + _skybox->setColor(Color(1.0f, 0.0f, 0.0f)); + } SunSkyStage::~SunSkyStage() { diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index b28c20fc65..d22269bece 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -223,7 +223,7 @@ public: const SkyboxPointer& getSkybox() const { valid(); return _skybox; } protected: - BackgroundMode _backgroundMode = SKY_DOME; + BackgroundMode _backgroundMode = SKY_BOX; LightPointer _sunLight; AtmospherePointer _atmosphere; diff --git a/libraries/octree/src/ViewFrustum.cpp b/libraries/octree/src/ViewFrustum.cpp index b18b2fcb3e..11ed24799d 100644 --- a/libraries/octree/src/ViewFrustum.cpp +++ b/libraries/octree/src/ViewFrustum.cpp @@ -862,3 +862,7 @@ void ViewFrustum::evalProjectionMatrix(glm::mat4& proj) const { } } +void ViewFrustum::evalViewTransform(Transform& view) const { + view.setTranslation(getPosition()); + view.setRotation(getOrientation()); +} diff --git a/libraries/octree/src/ViewFrustum.h b/libraries/octree/src/ViewFrustum.h index 3c8639d215..dfb0dcb308 100644 --- a/libraries/octree/src/ViewFrustum.h +++ b/libraries/octree/src/ViewFrustum.h @@ -20,6 +20,7 @@ #include #include +#include "Transform.h" #include "AABox.h" #include "AACube.h" #include "Plane.h" @@ -121,6 +122,8 @@ public: float distanceToCamera(const glm::vec3& point) const; void evalProjectionMatrix(glm::mat4& proj) const; + void evalViewTransform(Transform& view) const; + private: // Used for keyhole calculations ViewFrustum::location pointInKeyhole(const glm::vec3& point) const; From fe3b5d1867d68e02ffa89fd3cc6d01adef75844b Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 6 May 2015 10:27:31 -0700 Subject: [PATCH 05/13] preparing for PR, back to the default background mode SKy_DOME --- libraries/gpu/src/gpu/Texture.h | 2 +- libraries/model/src/model/Stage.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 5523f7f417..995196060f 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -184,7 +184,7 @@ public: uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); } // The number of faces is mostly used for cube map, and maybe for stereo ? otherwise it's 1 - // For cube maps, this means the pixels of the different faces are supposed to bepacked back to back in a mip + // For cube maps, this means the pixels of the different faces are supposed to be packed back to back in a mip // as if the height was NUM_FACES time bigger. static uint8 NUM_FACES_PER_TYPE[NUM_TYPES]; uint8 getNumFaces() const { return NUM_FACES_PER_TYPE[getType()]; } diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index d22269bece..b28c20fc65 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -223,7 +223,7 @@ public: const SkyboxPointer& getSkybox() const { valid(); return _skybox; } protected: - BackgroundMode _backgroundMode = SKY_BOX; + BackgroundMode _backgroundMode = SKY_DOME; LightPointer _sunLight; AtmospherePointer _atmosphere; From 50012ee9dea2fddb882de327e32e7672f00ed464 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 6 May 2015 11:00:37 -0700 Subject: [PATCH 06/13] fixing build issues on MAc --- libraries/gpu/src/gpu/Shader.h | 1 + libraries/gpu/src/gpu/Transform.slh | 2 ++ 2 files changed, 3 insertions(+) diff --git a/libraries/gpu/src/gpu/Shader.h b/libraries/gpu/src/gpu/Shader.h index de129248ea..9193ddb778 100755 --- a/libraries/gpu/src/gpu/Shader.h +++ b/libraries/gpu/src/gpu/Shader.h @@ -12,6 +12,7 @@ #define hifi_gpu_Shader_h #include "Resource.h" +#include #include #include diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index a65fc7e9bd..84a136d215 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -127,6 +127,7 @@ TransformCamera getTransformCamera() { <$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0)); } <@else@> + <$worldDir$> = vec3(gl_ModelViewMatrixInverseTranspose * vec4(<$eyeDir$>.xyz, 0.0)); <@endif@> <@endfunc@> @@ -136,6 +137,7 @@ TransformCamera getTransformCamera() { <$eyeDir$> = vec3(<$cameraTransform$>._projectionInverse * vec4(<$clipPos$>.xyz, 1.0)); } <@else@> + <$eyeDir$> = vec3(gl_ProjectionMatrixInverse * vec4(<$clipPos$>.xyz, 1.0)); <@endif@> <@endfunc@> From 06e1330e420de43463f43e7451987943e600f9ef Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 6 May 2015 12:12:54 -0700 Subject: [PATCH 07/13] Clean up the includes in gpu, make the skybox shader works --- libraries/gpu/src/gpu/Format.h | 26 +- libraries/gpu/src/gpu/GLBackendTexture.cpp | 10 +- libraries/gpu/src/gpu/Resource.h | 1 - libraries/gpu/src/gpu/Texture.h | 585 ++++++++++--------- libraries/gpu/src/gpu/Transform.slh | 4 +- libraries/model/src/model/Light.cpp | 2 +- libraries/model/src/model/Material.cpp | 2 +- libraries/model/src/model/Skybox.cpp | 84 +-- libraries/model/src/model/Skybox.slf | 2 +- libraries/model/src/model/Skybox.slv | 4 +- libraries/model/src/model/Stage.cpp | 6 +- libraries/model/src/model/Stage.h | 302 +++++----- libraries/render-utils/src/GeometryCache.cpp | 96 +-- libraries/render-utils/src/Model.cpp | 8 +- 14 files changed, 572 insertions(+), 560 deletions(-) diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index e43c190819..3ee32ffc56 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -27,6 +27,8 @@ typedef short int16; typedef unsigned char uint8; typedef char int8; +typedef unsigned char Byte; + typedef uint32 Offset; typedef glm::mat4 Mat4; @@ -182,18 +184,18 @@ public: uint8 _type : 4; }; - -enum ComparisonFunction { - NEVER = 0, - LESS, - EQUAL, - LESS_EQUAL, - GREATER, - NOT_EQUAL, - GREATER_EQUAL, - ALWAYS, - - NUM_COMPARISON_FUNCS, + +enum ComparisonFunction { + NEVER = 0, + LESS, + EQUAL, + LESS_EQUAL, + GREATER, + NOT_EQUAL, + GREATER_EQUAL, + ALWAYS, + + NUM_COMPARISON_FUNCS, }; }; diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 97987a401a..4387821cfd 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -297,7 +297,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { if (needUpdate) { if (texture.isStoredMipAvailable(0)) { Texture::PixelsPointer mip = texture.accessStoredMip(0); - const GLvoid* bytes = mip->_sysmem.read(); + const GLvoid* bytes = mip->_sysmem.read(); Element srcFormat = mip->_format; GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat); @@ -328,7 +328,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { if (texture.isStoredMipAvailable(0)) { Texture::PixelsPointer mip = texture.accessStoredMip(0); - bytes = mip->_sysmem.read(); + bytes = mip->_sysmem.read(); srcFormat = mip->_format; object->_contentStamp = texture.getDataStamp(); @@ -386,7 +386,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { glBindTexture(GL_TEXTURE_CUBE_MAP, object->_texture); for (int f = 0; f < NUM_FACES; f++) { glTexSubImage2D(FACE_LAYOUT[f], 0, texelFormat.internalFormat, width, width, 0, - texelFormat.format, texelFormat.type, (GLvoid*) (mip->_sysmem.read() + f * faceSize)); + texelFormat.format, texelFormat.type, (GLvoid*) (mip->_sysmem.read() + f * faceSize)); } if (texture.isAutogenerateMips()) { @@ -404,7 +404,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { object->_contentStamp = texture.getDataStamp(); } } else { - const gpu::Resource::Byte* bytes = 0; + const gpu::Byte* bytes = 0; Element srcFormat = texture.getTexelFormat(); uint16 width = texture.getWidth(); int faceSize = 0; @@ -412,7 +412,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { if (texture.isStoredMipAvailable(0)) { Texture::PixelsPointer mip = texture.accessStoredMip(0); - bytes = mip->_sysmem.read(); + bytes = mip->_sysmem.read(); srcFormat = mip->_format; faceSize = mip->_sysmem.getSize() / NUM_FACES; diff --git a/libraries/gpu/src/gpu/Resource.h b/libraries/gpu/src/gpu/Resource.h index 66c2a6e2e9..7f3f850339 100644 --- a/libraries/gpu/src/gpu/Resource.h +++ b/libraries/gpu/src/gpu/Resource.h @@ -26,7 +26,6 @@ namespace gpu { class Resource { public: - typedef unsigned char Byte; typedef unsigned int Size; static const Size NOT_ALLOCATED = -1; diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 995196060f..57b2bb0e69 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -1,24 +1,25 @@ -// -// Texture.h -// libraries/gpu/src/gpu -// -// Created by Sam Gateau on 1/16/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_gpu_Texture_h -#define hifi_gpu_Texture_h - -#include "Resource.h" -#include - -namespace gpu { - -class Sampler { -public: - +// +// Texture.h +// libraries/gpu/src/gpu +// +// Created by Sam Gateau on 1/16/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_gpu_Texture_h +#define hifi_gpu_Texture_h + +#include "Resource.h" + +#include //min max + +namespace gpu { + +class Sampler { +public: + enum Filter { FILTER_MIN_MAG_POINT, // top mip only FILTER_MIN_POINT_MAG_LINEAR, // top mip only @@ -46,7 +47,7 @@ public: WRAP_MIRROR_ONCE, NUM_WRAP_MODES - }; + }; static const uint8 MAX_MIP_LEVEL = 0xFF; @@ -92,273 +93,273 @@ public: uint8 getMaxMip() const { return _desc._maxMip; } protected: - Desc _desc; -}; - -class Texture : public Resource { -public: - - class Pixels { - public: - Pixels() {} - Pixels(const Pixels& pixels) = default; - Pixels(const Element& format, Size size, const Byte* bytes); - ~Pixels(); - - Sysmem _sysmem; - Element _format; - bool _isGPULoaded; - }; - typedef std::shared_ptr< Pixels > PixelsPointer; - - class Storage { - public: - Storage() {} - virtual ~Storage() {} - virtual void reset(); - virtual PixelsPointer editMip(uint16 level); - virtual const PixelsPointer getMip(uint16 level) const; - virtual Stamp getStamp(uint16 level) const; - virtual bool allocateMip(uint16 level); - virtual bool assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes); - virtual bool isMipAvailable(uint16 level) const; - virtual void notifyGPULoaded(uint16 level) const; - - protected: - Texture* _texture; - std::vector _mips; - - virtual void assignTexture(Texture* tex); - - friend class Texture; - }; - - enum Type { - TEX_1D = 0, - TEX_2D, - TEX_3D, - TEX_CUBE, - - NUM_TYPES, - }; - - static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler()); - static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler = Sampler()); - static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, const Sampler& sampler = Sampler()); - static Texture* createCube(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler()); - - static Texture* createFromStorage(Storage* storage); - - Texture(const Texture& buf); // deep copy of the sysmem texture - Texture& operator=(const Texture& buf); // deep copy of the sysmem texture - ~Texture(); - - Stamp getStamp() const { return _stamp; } - Stamp getDataStamp(uint16 level = 0) const { return _storage->getStamp(level); } - - // The size in bytes of data stored in the texture - Size getSize() const { return _size; } - - // Resize, unless auto mips mode would destroy all the sub mips - Size resize1D(uint16 width, uint16 numSamples); - Size resize2D(uint16 width, uint16 height, uint16 numSamples); - Size resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples); - Size resizeCube(uint16 width, uint16 numSamples); - - // Reformat, unless auto mips mode would destroy all the sub mips - Size reformat(const Element& texelFormat); - - // Size and format - Type getType() const { return _type; } - - bool isColorRenderTarget() const; - bool isDepthStencilRenderTarget() const; - - const Element& getTexelFormat() const { return _texelFormat; } - bool hasBorder() const { return false; } - - uint16 getWidth() const { return _width; } - uint16 getHeight() const { return _height; } - uint16 getDepth() const { return _depth; } - - uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); } - - // The number of faces is mostly used for cube map, and maybe for stereo ? otherwise it's 1 - // For cube maps, this means the pixels of the different faces are supposed to be packed back to back in a mip - // as if the height was NUM_FACES time bigger. - static uint8 NUM_FACES_PER_TYPE[NUM_TYPES]; - uint8 getNumFaces() const { return NUM_FACES_PER_TYPE[getType()]; } - - uint32 getNumTexels() const { return _width * _height * _depth * getNumFaces(); } - - uint16 getNumSlices() const { return _numSlices; } - uint16 getNumSamples() const { return _numSamples; } - - - // NumSamples can only have certain values based on the hw - static uint16 evalNumSamplesUsed(uint16 numSamplesTried); - - // Mips size evaluation - - // The number mips that a dimension could haves - // = 1 + log2(size) - static uint16 evalDimNumMips(uint16 size); - - // The number mips that the texture could have if all existed - // = 1 + log2(max(width, height, depth)) - uint16 evalNumMips() const; - - // Eval the size that the mips level SHOULD have - // not the one stored in the Texture - uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); } - uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); } - uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); } - uint32 evalMipNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getNumFaces(); } - uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); } - uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); } - - uint32 evalTotalSize() const { - uint32 size = 0; - uint16 minMipLevel = 0; - uint16 maxMipLevel = maxMip(); - for (uint16 l = minMipLevel; l <= maxMipLevel; l++) { - size += evalMipSize(l); - } - return size * getNumSlices(); - } - - // max mip is in the range [ 1 if no sub mips, log2(max(width, height, depth))] - // if autoGenerateMip is on => will provide the maxMIp level specified - // else provide the deepest mip level provided through assignMip - uint16 maxMip() const; - - // Generate the mips automatically - // But the sysmem version is not available - // Only works for the standard formats - // Specify the maximum Mip level available - // 0 is the default one - // 1 is the first level - // ... - // nbMips - 1 is the last mip level - // - // If -1 then all the mips are generated - // - // Return the totalnumber of mips that will be available - uint16 autoGenerateMips(uint16 maxMip); - bool isAutogenerateMips() const { return _autoGenerateMips; } - - // Managing Storage and mips - - // Manually allocate the mips down until the specified maxMip - // this is just allocating the sysmem version of it - // in case autoGen is on, this doesn't allocate - // Explicitely assign mip data for a certain level - // If Bytes is NULL then simply allocate the space so mip sysmem can be accessed - bool assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes); - - // Access the the sub mips - bool isStoredMipAvailable(uint16 level) const { return _storage->isMipAvailable(level); } - const PixelsPointer accessStoredMip(uint16 level) const { return _storage->getMip(level); } - void notifyGPULoaded(uint16 level) const { return _storage->notifyGPULoaded(level); } - - // access sizes for the stored mips - uint16 getStoredMipWidth(uint16 level) const; - uint16 getStoredMipHeight(uint16 level) const; - uint16 getStoredMipDepth(uint16 level) const; - uint32 getStoredMipNumTexels(uint16 level) const; - uint32 getStoredMipSize(uint16 level) const; - - bool isDefined() const { return _defined; } - - - // Own sampler - void setSampler(const Sampler& sampler); - const Sampler& getSampler() const { return _sampler; } - Stamp getSamplerStamp() const { return _samplerStamp; } - -protected: - std::unique_ptr< Storage > _storage; - - Stamp _stamp = 0; - - Sampler _sampler; - Stamp _samplerStamp; - - uint32 _size = 0; - Element _texelFormat; - - uint16 _width = 1; - uint16 _height = 1; - uint16 _depth = 1; - - uint16 _numSamples = 1; - uint16 _numSlices = 1; - - uint16 _maxMip = 0; - - Type _type = TEX_1D; - bool _autoGenerateMips = false; - bool _defined = false; - - static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler); - Texture(); - - Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices); - - // This shouldn't be used by anything else than the Backend class with the proper casting. - mutable GPUObject* _gpuObject = NULL; - void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; } - GPUObject* getGPUObject() const { return _gpuObject; } - friend class Backend; -}; - -typedef std::shared_ptr TexturePointer; -typedef std::vector< TexturePointer > Textures; - - - // TODO: For now TextureView works with Buffer as a place holder for the Texture. - // The overall logic should be about the same except that the Texture will be a real GL Texture under the hood -class TextureView { -public: - typedef Resource::Size Size; - - TexturePointer _texture = TexturePointer(NULL); - uint16 _subresource = 0; - Element _element = Element(gpu::VEC4, gpu::UINT8, gpu::RGBA); - - TextureView() {}; - - TextureView(const Element& element) : - _element(element) - {}; - - // create the TextureView and own the Texture - TextureView(Texture* newTexture, const Element& element) : - _texture(newTexture), - _subresource(0), - _element(element) - {}; - TextureView(const TexturePointer& texture, uint16 subresource, const Element& element) : - _texture(texture), - _subresource(subresource), - _element(element) - {}; - - TextureView(const TexturePointer& texture, uint16 subresource) : - _texture(texture), - _subresource(subresource) - {}; - - ~TextureView() {} - TextureView(const TextureView& view) = default; - TextureView& operator=(const TextureView& view) = default; - - explicit operator bool() const { return bool(_texture); } - bool operator !() const { return (!_texture); } -}; -typedef std::vector TextureViews; - -}; - - -#endif + Desc _desc; +}; + +class Texture : public Resource { +public: + + class Pixels { + public: + Pixels() {} + Pixels(const Pixels& pixels) = default; + Pixels(const Element& format, Size size, const Byte* bytes); + ~Pixels(); + + Sysmem _sysmem; + Element _format; + bool _isGPULoaded; + }; + typedef std::shared_ptr< Pixels > PixelsPointer; + + class Storage { + public: + Storage() {} + virtual ~Storage() {} + virtual void reset(); + virtual PixelsPointer editMip(uint16 level); + virtual const PixelsPointer getMip(uint16 level) const; + virtual Stamp getStamp(uint16 level) const; + virtual bool allocateMip(uint16 level); + virtual bool assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes); + virtual bool isMipAvailable(uint16 level) const; + virtual void notifyGPULoaded(uint16 level) const; + + protected: + Texture* _texture; + std::vector _mips; + + virtual void assignTexture(Texture* tex); + + friend class Texture; + }; + + enum Type { + TEX_1D = 0, + TEX_2D, + TEX_3D, + TEX_CUBE, + + NUM_TYPES, + }; + + static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler()); + static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler = Sampler()); + static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, const Sampler& sampler = Sampler()); + static Texture* createCube(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler()); + + static Texture* createFromStorage(Storage* storage); + + Texture(const Texture& buf); // deep copy of the sysmem texture + Texture& operator=(const Texture& buf); // deep copy of the sysmem texture + ~Texture(); + + Stamp getStamp() const { return _stamp; } + Stamp getDataStamp(uint16 level = 0) const { return _storage->getStamp(level); } + + // The size in bytes of data stored in the texture + Size getSize() const { return _size; } + + // Resize, unless auto mips mode would destroy all the sub mips + Size resize1D(uint16 width, uint16 numSamples); + Size resize2D(uint16 width, uint16 height, uint16 numSamples); + Size resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples); + Size resizeCube(uint16 width, uint16 numSamples); + + // Reformat, unless auto mips mode would destroy all the sub mips + Size reformat(const Element& texelFormat); + + // Size and format + Type getType() const { return _type; } + + bool isColorRenderTarget() const; + bool isDepthStencilRenderTarget() const; + + const Element& getTexelFormat() const { return _texelFormat; } + bool hasBorder() const { return false; } + + uint16 getWidth() const { return _width; } + uint16 getHeight() const { return _height; } + uint16 getDepth() const { return _depth; } + + uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); } + + // The number of faces is mostly used for cube map, and maybe for stereo ? otherwise it's 1 + // For cube maps, this means the pixels of the different faces are supposed to be packed back to back in a mip + // as if the height was NUM_FACES time bigger. + static uint8 NUM_FACES_PER_TYPE[NUM_TYPES]; + uint8 getNumFaces() const { return NUM_FACES_PER_TYPE[getType()]; } + + uint32 getNumTexels() const { return _width * _height * _depth * getNumFaces(); } + + uint16 getNumSlices() const { return _numSlices; } + uint16 getNumSamples() const { return _numSamples; } + + + // NumSamples can only have certain values based on the hw + static uint16 evalNumSamplesUsed(uint16 numSamplesTried); + + // Mips size evaluation + + // The number mips that a dimension could haves + // = 1 + log2(size) + static uint16 evalDimNumMips(uint16 size); + + // The number mips that the texture could have if all existed + // = 1 + log2(max(width, height, depth)) + uint16 evalNumMips() const; + + // Eval the size that the mips level SHOULD have + // not the one stored in the Texture + uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); } + uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); } + uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); } + uint32 evalMipNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getNumFaces(); } + uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); } + uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); } + + uint32 evalTotalSize() const { + uint32 size = 0; + uint16 minMipLevel = 0; + uint16 maxMipLevel = maxMip(); + for (uint16 l = minMipLevel; l <= maxMipLevel; l++) { + size += evalMipSize(l); + } + return size * getNumSlices(); + } + + // max mip is in the range [ 1 if no sub mips, log2(max(width, height, depth))] + // if autoGenerateMip is on => will provide the maxMIp level specified + // else provide the deepest mip level provided through assignMip + uint16 maxMip() const; + + // Generate the mips automatically + // But the sysmem version is not available + // Only works for the standard formats + // Specify the maximum Mip level available + // 0 is the default one + // 1 is the first level + // ... + // nbMips - 1 is the last mip level + // + // If -1 then all the mips are generated + // + // Return the totalnumber of mips that will be available + uint16 autoGenerateMips(uint16 maxMip); + bool isAutogenerateMips() const { return _autoGenerateMips; } + + // Managing Storage and mips + + // Manually allocate the mips down until the specified maxMip + // this is just allocating the sysmem version of it + // in case autoGen is on, this doesn't allocate + // Explicitely assign mip data for a certain level + // If Bytes is NULL then simply allocate the space so mip sysmem can be accessed + bool assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes); + + // Access the the sub mips + bool isStoredMipAvailable(uint16 level) const { return _storage->isMipAvailable(level); } + const PixelsPointer accessStoredMip(uint16 level) const { return _storage->getMip(level); } + void notifyGPULoaded(uint16 level) const { return _storage->notifyGPULoaded(level); } + + // access sizes for the stored mips + uint16 getStoredMipWidth(uint16 level) const; + uint16 getStoredMipHeight(uint16 level) const; + uint16 getStoredMipDepth(uint16 level) const; + uint32 getStoredMipNumTexels(uint16 level) const; + uint32 getStoredMipSize(uint16 level) const; + + bool isDefined() const { return _defined; } + + + // Own sampler + void setSampler(const Sampler& sampler); + const Sampler& getSampler() const { return _sampler; } + Stamp getSamplerStamp() const { return _samplerStamp; } + +protected: + std::unique_ptr< Storage > _storage; + + Stamp _stamp = 0; + + Sampler _sampler; + Stamp _samplerStamp; + + uint32 _size = 0; + Element _texelFormat; + + uint16 _width = 1; + uint16 _height = 1; + uint16 _depth = 1; + + uint16 _numSamples = 1; + uint16 _numSlices = 1; + + uint16 _maxMip = 0; + + Type _type = TEX_1D; + bool _autoGenerateMips = false; + bool _defined = false; + + static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler); + Texture(); + + Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices); + + // This shouldn't be used by anything else than the Backend class with the proper casting. + mutable GPUObject* _gpuObject = NULL; + void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; } + GPUObject* getGPUObject() const { return _gpuObject; } + friend class Backend; +}; + +typedef std::shared_ptr TexturePointer; +typedef std::vector< TexturePointer > Textures; + + + // TODO: For now TextureView works with Buffer as a place holder for the Texture. + // The overall logic should be about the same except that the Texture will be a real GL Texture under the hood +class TextureView { +public: + typedef Resource::Size Size; + + TexturePointer _texture = TexturePointer(NULL); + uint16 _subresource = 0; + Element _element = Element(gpu::VEC4, gpu::UINT8, gpu::RGBA); + + TextureView() {}; + + TextureView(const Element& element) : + _element(element) + {}; + + // create the TextureView and own the Texture + TextureView(Texture* newTexture, const Element& element) : + _texture(newTexture), + _subresource(0), + _element(element) + {}; + TextureView(const TexturePointer& texture, uint16 subresource, const Element& element) : + _texture(texture), + _subresource(subresource), + _element(element) + {}; + + TextureView(const TexturePointer& texture, uint16 subresource) : + _texture(texture), + _subresource(subresource) + {}; + + ~TextureView() {} + TextureView(const TextureView& view) = default; + TextureView& operator=(const TextureView& view) = default; + + explicit operator bool() const { return bool(_texture); } + bool operator !() const { return (!_texture); } +}; +typedef std::vector TextureViews; + +}; + + +#endif diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 84a136d215..57a367fdba 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -127,13 +127,13 @@ TransformCamera getTransformCamera() { <$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0)); } <@else@> - <$worldDir$> = vec3(gl_ModelViewMatrixInverseTranspose * vec4(<$eyeDir$>.xyz, 0.0)); + <$worldDir$> = vec3(gl_ModelViewMatrixInverse * vec4(<$eyeDir$>.xyz, 0.0)); <@endif@> <@endfunc@> <@func transformClipToEyeDir(cameraTransform, clipPos, eyeDir)@> <@if GPU_TRANSFORM_PROFILE == GPU_CORE@> - { // transformClipToEyedDir + { // transformClipToEyeDir <$eyeDir$> = vec3(<$cameraTransform$>._projectionInverse * vec4(<$clipPos$>.xyz, 1.0)); } <@else@> diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index e8c01c68aa..6460e0b316 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -18,7 +18,7 @@ Light::Light() : _transform() { // only if created from nothing shall we create the Buffer to store the properties Schema schema; - _schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Buffer::Byte*) &schema)); + _schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Byte*) &schema)); } Light::Light(const Light& light) : diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index ff0691442c..d27bdd4372 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -20,7 +20,7 @@ Material::Material() : // only if created from nothing shall we create the Buffer to store the properties Schema schema; - _schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Buffer::Byte*) &schema)); + _schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Byte*) &schema)); } diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index c9b0d270fb..9fd96a198f 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -17,26 +17,26 @@ #include "skybox_vert.h" #include "skybox_frag.h" -using namespace model; - -Skybox::Skybox() { - - _cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1)); - unsigned char texels[] = { - 255, 0, 0, 255, - 0, 255, 255, 255, - 0, 0, 255, 255, - 255, 255, 0, 255, - 0, 255, 0, 255, - 255, 0, 255, 255, - }; - _cubemap->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, sizeof(texels), texels); -} - -void Skybox::setColor(const Color& color) { - _color = color; -} - +using namespace model; + +Skybox::Skybox() { + + _cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1)); + unsigned char texels[] = { + 255, 0, 0, 255, + 0, 255, 255, 255, + 0, 0, 255, 255, + 255, 255, 0, 255, + 0, 255, 0, 255, + 255, 0, 255, 255, + }; + _cubemap->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, sizeof(texels), texels); +} + +void Skybox::setColor(const Color& color) { + _color = color; +} + void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { _cubemap = cubemap; } @@ -44,23 +44,32 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { if (skybox.getCubemap()) { - - static gpu::PipelinePointer thePipeline; - if (!thePipeline) { - auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); - auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); - auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); - - gpu::Shader::BindingSet bindings; - bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); - - if (!gpu::Shader::makeProgram(*skyShader, bindings)) { - - } - - auto skyState = gpu::StatePointer(new gpu::State()); - + + static gpu::PipelinePointer thePipeline; + static gpu::BufferPointer theBuffer; + static gpu::Stream::FormatPointer theFormat; + if (!thePipeline) { + auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); + auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); + auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); + + gpu::Shader::BindingSet bindings; + bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); + + if (!gpu::Shader::makeProgram(*skyShader, bindings)) { + + } + + auto skyState = gpu::StatePointer(new gpu::State()); + thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); + + const float CLIP = 1.0; + const glm::vec2 vertices[4] = { {-CLIP, -CLIP}, {CLIP, -CLIP}, {-CLIP, CLIP}, {CLIP, CLIP}}; + theBuffer.reset(new gpu::Buffer(sizeof(vertices), (const gpu::Byte*) vertices)); + + theFormat.reset(new gpu::Stream::Format()); + theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ)); } glm::mat4 projMat; @@ -71,7 +80,10 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.setProjectionTransform(projMat); batch.setViewTransform(viewTransform); + batch.setModelTransform(Transform()); // only for Mac batch.setPipeline(thePipeline); + batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); + batch.setInputFormat(theFormat); batch.setUniformTexture(0, skybox.getCubemap()); batch.draw(gpu::TRIANGLE_STRIP, 4); } else { diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index da9f9401bc..452b9daebe 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -18,7 +18,7 @@ varying vec3 color; void main(void) { - vec4 texel = texture(cubeMap, normalize(normal)); + vec4 texel = textureCube(cubeMap, normalize(normal)); gl_FragData[0] = texel; // gl_FragData[0] = vec4(normal, 1.0); } diff --git a/libraries/model/src/model/Skybox.slv b/libraries/model/src/model/Skybox.slv index d4fe58959f..3c7ffbce2d 100755 --- a/libraries/model/src/model/Skybox.slv +++ b/libraries/model/src/model/Skybox.slv @@ -20,9 +20,7 @@ varying vec2 texcoord; varying vec3 color; void main(void) { - const float CLIP = 1.0; - const vec2 vertices[4] = vec2[4](vec2(-CLIP, -CLIP), vec2(CLIP, -CLIP), vec2(-CLIP, CLIP), vec2(CLIP, CLIP)); - texcoord = vertices[gl_VertexID]; + texcoord = gl_Vertex.xy; // pass along the diffuse color color = vec3(texcoord, 0.0); diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 2e579d3618..c29ebfe83e 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -138,7 +138,7 @@ void EarthSunModel::setSunLongitude(float lon) { Atmosphere::Atmosphere() { // only if created from nothing shall we create the Buffer to store the properties Data data; - _dataBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Data), (const gpu::Buffer::Byte*) &data)); + _dataBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Data), (const gpu::Byte*) &data)); setScatteringWavelength(_scatteringWavelength); setRayleighScattering(_rayleighScattering); @@ -246,7 +246,7 @@ void SunSkyStage::setOriginLocation(float longitude, float latitude, float altit invalidate(); } -void SunSkyStage::setSunModelEnable(bool isEnabled) { +void SunSkyStage::setSunModelEnable(bool isEnabled) { _sunModelEnable = isEnabled; invalidate(); } @@ -261,7 +261,7 @@ void SunSkyStage::setSunAmbientIntensity(float intensity) { _sunLight->setAmbientIntensity(intensity); } -void SunSkyStage::setSunDirection(const Vec3& direction) { +void SunSkyStage::setSunDirection(const Vec3& direction) { if (!isSunModelEnabled()) { _sunLight->setDirection(direction); } diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index b28c20fc65..fddf28165a 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -1,27 +1,27 @@ -// -// Stage.h -// libraries/model/src/model -// -// Created by Sam Gateau on 2/24/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_Stage_h -#define hifi_model_Stage_h - -#include "gpu/Pipeline.h" - -#include "Light.h" -#include "Skybox.h" - -namespace model { +// +// Stage.h +// libraries/model/src/model +// +// Created by Sam Gateau on 2/24/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_Stage_h +#define hifi_model_Stage_h + +#include "gpu/Pipeline.h" + +#include "Light.h" +#include "Skybox.h" + +namespace model { typedef glm::dvec3 Vec3d; typedef glm::dvec4 Vec4d; typedef glm::dmat4 Mat4d; -typedef glm::mat4 Mat4; +typedef glm::mat4 Mat4; class EarthSunModel { public: @@ -100,40 +100,40 @@ protected: void updateSun() const; mutable bool _invalid = true; - void invalidate() const { _invalid = true; } + void invalidate() const { _invalid = true; } void valid() const { if (_invalid) { updateAll(); _invalid = false; } } void updateAll() const; static Mat4d evalWorldToGeoLocationMat(double longitude, double latitude, double altitude, double scale); -}; - - -class Atmosphere { -public: - - Atmosphere(); - Atmosphere(const Atmosphere& atmosphere); - Atmosphere& operator= (const Atmosphere& atmosphere); - virtual ~Atmosphere() {}; - - - void setScatteringWavelength(Vec3 wavelength); - const Vec3& getScatteringWavelength() const { return _scatteringWavelength; } - - void setRayleighScattering(float scattering); - float getRayleighScattering() const { return _rayleighScattering; } - - void setMieScattering(float scattering); - float getMieScattering() const { return _mieScattering; } - - void setSunBrightness(float brightness); - float getSunBrightness() const { return _sunBrightness; } - - void setInnerOuterRadiuses(float inner, float outer); - float getInnerRadius() const { return getData()._radiuses.x; } - float getOuterRadius() const { return getData()._radiuses.y; } - - // Data to access the attribute values of the atmosphere +}; + + +class Atmosphere { +public: + + Atmosphere(); + Atmosphere(const Atmosphere& atmosphere); + Atmosphere& operator= (const Atmosphere& atmosphere); + virtual ~Atmosphere() {}; + + + void setScatteringWavelength(Vec3 wavelength); + const Vec3& getScatteringWavelength() const { return _scatteringWavelength; } + + void setRayleighScattering(float scattering); + float getRayleighScattering() const { return _rayleighScattering; } + + void setMieScattering(float scattering); + float getMieScattering() const { return _mieScattering; } + + void setSunBrightness(float brightness); + float getSunBrightness() const { return _sunBrightness; } + + void setInnerOuterRadiuses(float inner, float outer); + float getInnerRadius() const { return getData()._radiuses.x; } + float getOuterRadius() const { return getData()._radiuses.y; } + + // Data to access the attribute values of the atmosphere class Data { public: Vec4 _invWaveLength = Vec4(0.0f); @@ -143,107 +143,107 @@ public: Vec4 _control = Vec4(2.0f, -0.990f, -0.990f*-0.990f, 0.f); Data() {} - }; - - const UniformBufferView& getDataBuffer() const { return _dataBuffer; } - -protected: - UniformBufferView _dataBuffer; - Vec3 _scatteringWavelength = Vec3(0.650f, 0.570f, 0.475f); - float _rayleighScattering = 0.0025f; - float _mieScattering = 0.0010f; - float _sunBrightness = 20.0f; - - const Data& getData() const { return _dataBuffer.get(); } - Data& editData() { return _dataBuffer.edit(); } - - void updateScattering(); -}; -typedef std::shared_ptr< Atmosphere > AtmospherePointer; - -// Sun sky stage generates the rendering primitives to display a scene realistically -// at the specified location and time around earth -class SunSkyStage { -public: - - SunSkyStage(); - ~SunSkyStage(); - - // time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0] - void setDayTime(float hour); - float getDayTime() const { return _dayTime; } - - // time of the year expressed in day in the range [0, 365] - void setYearTime(unsigned int day); - unsigned int getYearTime() const { return _yearTime; } - - // Origin orientation used to modify the cardinal axis alignement used. - // THe default is north along +Z axis and west along +X axis. this orientation gets added - // to the transform stack producing the sun light direction. - void setOriginOrientation(const Quat& orientation); - const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } - - // Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km] - void setOriginLocation(float longitude, float latitude, float surfaceAltitude); - float getOriginLatitude() const { return _earthSunModel.getLatitude(); } - float getOriginLongitude() const { return _earthSunModel.getLongitude(); } - float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); } - - // Enable / disable the effect of the time and location on the sun direction and color - void setSunModelEnable(bool isEnabled); - bool isSunModelEnabled() const { return _sunModelEnable; } - - // Sun properties - void setSunColor(const Vec3& color); - const Vec3& getSunColor() const { return getSunLight()->getColor(); } - void setSunIntensity(float intensity); - float getSunIntensity() const { return getSunLight()->getIntensity(); } - void setSunAmbientIntensity(float intensity); - float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); } - - // The sun direction is expressed in the world space - void setSunDirection(const Vec3& direction); - const Vec3& getSunDirection() const { return getSunLight()->getDirection(); } + }; + + const UniformBufferView& getDataBuffer() const { return _dataBuffer; } + +protected: + UniformBufferView _dataBuffer; + Vec3 _scatteringWavelength = Vec3(0.650f, 0.570f, 0.475f); + float _rayleighScattering = 0.0025f; + float _mieScattering = 0.0010f; + float _sunBrightness = 20.0f; + + const Data& getData() const { return _dataBuffer.get(); } + Data& editData() { return _dataBuffer.edit(); } + + void updateScattering(); +}; +typedef std::shared_ptr< Atmosphere > AtmospherePointer; + +// Sun sky stage generates the rendering primitives to display a scene realistically +// at the specified location and time around earth +class SunSkyStage { +public: + + SunSkyStage(); + ~SunSkyStage(); + + // time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0] + void setDayTime(float hour); + float getDayTime() const { return _dayTime; } + + // time of the year expressed in day in the range [0, 365] + void setYearTime(unsigned int day); + unsigned int getYearTime() const { return _yearTime; } + + // Origin orientation used to modify the cardinal axis alignement used. + // THe default is north along +Z axis and west along +X axis. this orientation gets added + // to the transform stack producing the sun light direction. + void setOriginOrientation(const Quat& orientation); + const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } + + // Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km] + void setOriginLocation(float longitude, float latitude, float surfaceAltitude); + float getOriginLatitude() const { return _earthSunModel.getLatitude(); } + float getOriginLongitude() const { return _earthSunModel.getLongitude(); } + float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); } + + // Enable / disable the effect of the time and location on the sun direction and color + void setSunModelEnable(bool isEnabled); + bool isSunModelEnabled() const { return _sunModelEnable; } + + // Sun properties + void setSunColor(const Vec3& color); + const Vec3& getSunColor() const { return getSunLight()->getColor(); } + void setSunIntensity(float intensity); + float getSunIntensity() const { return getSunLight()->getIntensity(); } + void setSunAmbientIntensity(float intensity); + float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); } + + // The sun direction is expressed in the world space + void setSunDirection(const Vec3& direction); + const Vec3& getSunDirection() const { return getSunLight()->getDirection(); } LightPointer getSunLight() const { valid(); return _sunLight; } AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; } - - enum BackgroundMode { - NO_BACKGROUND = 0, - SKY_DOME, - SKY_BOX, - - NUM_BACKGROUND_MODES, - }; - void setBackgroundMode(BackgroundMode mode); - BackgroundMode getBackgroundMode() const { return _backgroundMode; } - - // Skybox - void setSkybox(const SkyboxPointer& skybox); - const SkyboxPointer& getSkybox() const { valid(); return _skybox; } - -protected: - BackgroundMode _backgroundMode = SKY_DOME; - - LightPointer _sunLight; - AtmospherePointer _atmosphere; - SkyboxPointer _skybox; - - gpu::PipelinePointer _skyPipeline; - - float _dayTime = 12.0f; - int _yearTime = 0; - mutable EarthSunModel _earthSunModel; - bool _sunModelEnable = true; - - mutable bool _invalid = true; - void invalidate() const { _invalid = true; } - void valid() const { if (_invalid) { updateGraphicsObject(); _invalid = false; } } - void updateGraphicsObject() const; -}; - -typedef std::shared_ptr< SunSkyStage > SunSkyStagePointer; - -}; - -#endif + + enum BackgroundMode { + NO_BACKGROUND = 0, + SKY_DOME, + SKY_BOX, + + NUM_BACKGROUND_MODES, + }; + void setBackgroundMode(BackgroundMode mode); + BackgroundMode getBackgroundMode() const { return _backgroundMode; } + + // Skybox + void setSkybox(const SkyboxPointer& skybox); + const SkyboxPointer& getSkybox() const { valid(); return _skybox; } + +protected: + BackgroundMode _backgroundMode = SKY_BOX; + + LightPointer _sunLight; + AtmospherePointer _atmosphere; + SkyboxPointer _skybox; + + gpu::PipelinePointer _skyPipeline; + + float _dayTime = 12.0f; + int _yearTime = 0; + mutable EarthSunModel _earthSunModel; + bool _sunModelEnable = true; + + mutable bool _invalid = true; + void invalidate() const { _invalid = true; } + void valid() const { if (_invalid) { updateGraphicsObject(); _invalid = false; } } + void updateGraphicsObject() const; +}; + +typedef std::shared_ptr< SunSkyStage > SunSkyStagePointer; + +}; + +#endif diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index b5732d1282..9fe00b1ad6 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -111,7 +111,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm *(vertex++) = 0.0f; *(vertex++) = 1.0f * radius; - verticesBuffer->append(sizeof(GLfloat) * vertices * NUM_COORDS_PER_VERTEX, (gpu::Buffer::Byte*) vertexData); + verticesBuffer->append(sizeof(GLfloat) * vertices * NUM_COORDS_PER_VERTEX, (gpu::Byte*) vertexData); delete[] vertexData; #ifdef WANT_DEBUG @@ -196,7 +196,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm indexCount += 3; } - indicesBuffer->append(sizeof(GLushort) * indices, (gpu::Buffer::Byte*) indexData); + indicesBuffer->append(sizeof(GLushort) * indices, (gpu::Byte*) indexData); delete[] indexData; #ifdef WANT_DEBUG @@ -245,7 +245,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm *(colorDataAt++) = compactColor; } - colorBuffer->append(sizeof(int) * vertices, (gpu::Buffer::Byte*) colorData); + colorBuffer->append(sizeof(int) * vertices, (gpu::Byte*) colorData); delete[] colorData; #ifdef WANT_DEBUG @@ -432,7 +432,7 @@ void GeometryCache::renderGrid(int xDivisions, int yDivisions, const glm::vec4& *(vertex++) = y; } - verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Buffer::Byte*) vertexData); + verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Byte*) vertexData); delete[] vertexData; _gridBuffers[key] = verticesBuffer; @@ -454,7 +454,7 @@ void GeometryCache::renderGrid(int xDivisions, int yDivisions, const glm::vec4& *(colorDataAt++) = compactColor; } - colorBuffer->append(sizeof(int) * vertices, (gpu::Buffer::Byte*) colorData); + colorBuffer->append(sizeof(int) * vertices, (gpu::Byte*) colorData); delete[] colorData; } gpu::BufferPointer verticesBuffer = _gridBuffers[key]; @@ -537,7 +537,7 @@ void GeometryCache::renderGrid(int x, int y, int width, int height, int rows, in tx += dx; } - verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Buffer::Byte*) vertexData); + verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Byte*) vertexData); delete[] vertexData; if (registered) { @@ -564,7 +564,7 @@ void GeometryCache::renderGrid(int x, int y, int width, int height, int rows, in *(colorDataAt++) = compactColor; } - colorBuffer->append(sizeof(int) * vertices, (gpu::Buffer::Byte*) colorData); + colorBuffer->append(sizeof(int) * vertices, (gpu::Byte*) colorData); delete[] colorData; } gpu::BufferPointer verticesBuffer = registered ? _registeredAlternateGridBuffers[id] : _alternateGridBuffers[key]; @@ -648,8 +648,8 @@ void GeometryCache::updateVertices(int id, const QVector& points, con *(colorDataAt++) = compactColor; } - details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Buffer::Byte*) vertexData); - details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Buffer::Byte*) colorData); + details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); + details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData); delete[] vertexData; delete[] colorData; @@ -711,8 +711,8 @@ void GeometryCache::updateVertices(int id, const QVector& points, con *(colorDataAt++) = compactColor; } - details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Buffer::Byte*) vertexData); - details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Buffer::Byte*) colorData); + details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); + details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData); delete[] vertexData; delete[] colorData; @@ -793,7 +793,7 @@ void GeometryCache::renderSolidCube(float size, const glm::vec4& color) { *(vertex++) = *cannonicalNormal++; } - verticesBuffer->append(sizeof(GLfloat) * vertexPoints * 2, (gpu::Buffer::Byte*) vertexData); + verticesBuffer->append(sizeof(GLfloat) * vertexPoints * 2, (gpu::Byte*) vertexData); } if (!_solidCubeIndexBuffer) { @@ -808,7 +808,7 @@ void GeometryCache::renderSolidCube(float size, const glm::vec4& color) { gpu::BufferPointer indexBuffer(new gpu::Buffer()); _solidCubeIndexBuffer = indexBuffer; - _solidCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Buffer::Byte*) cannonicalIndices); + _solidCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Byte*) cannonicalIndices); } if (!_solidCubeColors.contains(colorKey)) { @@ -827,7 +827,7 @@ void GeometryCache::renderSolidCube(float size, const glm::vec4& color) { compactColor, compactColor, compactColor, compactColor, compactColor, compactColor, compactColor, compactColor }; - colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); + colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); } gpu::BufferPointer verticesBuffer = _solidCubeVerticies[size]; gpu::BufferPointer colorBuffer = _solidCubeColors[colorKey]; @@ -891,7 +891,7 @@ void GeometryCache::renderWireCube(float size, const glm::vec4& color) { vertex[i] = cannonicalVertices[i] * halfSize; } - verticesBuffer->append(sizeof(GLfloat) * vertexPoints, (gpu::Buffer::Byte*) vertexData); // I'm skeptical that this is right + verticesBuffer->append(sizeof(GLfloat) * vertexPoints, (gpu::Byte*) vertexData); // I'm skeptical that this is right } if (!_wireCubeIndexBuffer) { @@ -904,7 +904,7 @@ void GeometryCache::renderWireCube(float size, const glm::vec4& color) { gpu::BufferPointer indexBuffer(new gpu::Buffer()); _wireCubeIndexBuffer = indexBuffer; - _wireCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Buffer::Byte*) cannonicalIndices); + _wireCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Byte*) cannonicalIndices); } if (!_cubeColors.contains(colorKey)) { @@ -919,7 +919,7 @@ void GeometryCache::renderWireCube(float size, const glm::vec4& color) { int colors[NUM_COLOR_SCALARS_PER_CUBE] = { compactColor, compactColor, compactColor, compactColor, compactColor, compactColor, compactColor, compactColor }; - colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); + colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); } gpu::BufferPointer verticesBuffer = _cubeVerticies[size]; gpu::BufferPointer colorBuffer = _cubeColors[colorKey]; @@ -1037,8 +1037,8 @@ void GeometryCache::renderBevelCornersRect(int x, int y, int width, int height, compactColor, compactColor, compactColor, compactColor }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer); - details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); + details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); + details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); delete[] vertexBuffer; } @@ -1119,8 +1119,8 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer); - details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); + details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); + details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); } gpu::Batch batch; @@ -1208,8 +1208,8 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer); - details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); + details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); + details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); } gpu::Batch batch; @@ -1294,8 +1294,8 @@ void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxC int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer); - details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); + details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); + details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); } gpu::Batch batch; @@ -1396,8 +1396,8 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom ((int(color.w * 255.0f) & 0xFF) << 24); int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer); - details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); + details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); + details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); } gpu::Batch batch; @@ -1510,8 +1510,8 @@ void GeometryCache::renderDashedLine(const glm::vec3& start, const glm::vec3& en *(vertex++) = end.z; *(colorDataAt++) = compactColor; - details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Buffer::Byte*) vertexData); - details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Buffer::Byte*) colorData); + details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); + details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData); delete[] vertexData; delete[] colorData; @@ -1653,8 +1653,8 @@ void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, const int NUM_COLOR_SCALARS = 2; int colors[NUM_COLOR_SCALARS] = { compactColor1, compactColor2 }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer); - details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); + details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); + details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); #ifdef WANT_DEBUG if (id == UNKNOWN_ID) { @@ -1745,8 +1745,8 @@ void GeometryCache::renderLine(const glm::vec2& p1, const glm::vec2& p2, const int NUM_COLOR_SCALARS = 2; int colors[NUM_COLOR_SCALARS] = { compactColor1, compactColor2 }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer); - details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); + details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); + details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); #ifdef WANT_DEBUG if (id == UNKNOWN_ID) { @@ -2234,10 +2234,10 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) { int offset = 0; foreach(const FBXMeshPart& part, mesh.parts) { networkMesh._indexBuffer->setSubData(offset, part.quadIndices.size() * sizeof(int), - (gpu::Resource::Byte*) part.quadIndices.constData()); + (gpu::Byte*) part.quadIndices.constData()); offset += part.quadIndices.size() * sizeof(int); networkMesh._indexBuffer->setSubData(offset, part.triangleIndices.size() * sizeof(int), - (gpu::Resource::Byte*) part.triangleIndices.constData()); + (gpu::Byte*) part.triangleIndices.constData()); offset += part.triangleIndices.size() * sizeof(int); } } @@ -2256,19 +2256,19 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) { networkMesh._vertexBuffer->resize(clusterWeightsOffset + mesh.clusterWeights.size() * sizeof(glm::vec4)); - networkMesh._vertexBuffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.vertices.constData()); - networkMesh._vertexBuffer->setSubData(normalsOffset, mesh.normals.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.normals.constData()); + networkMesh._vertexBuffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.vertices.constData()); + networkMesh._vertexBuffer->setSubData(normalsOffset, mesh.normals.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.normals.constData()); networkMesh._vertexBuffer->setSubData(tangentsOffset, - mesh.tangents.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.tangents.constData()); - networkMesh._vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.colors.constData()); + mesh.tangents.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.tangents.constData()); + networkMesh._vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.colors.constData()); networkMesh._vertexBuffer->setSubData(texCoordsOffset, - mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Resource::Byte*) mesh.texCoords.constData()); + mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Byte*) mesh.texCoords.constData()); networkMesh._vertexBuffer->setSubData(texCoords1Offset, - mesh.texCoords1.size() * sizeof(glm::vec2), (gpu::Resource::Byte*) mesh.texCoords1.constData()); + mesh.texCoords1.size() * sizeof(glm::vec2), (gpu::Byte*) mesh.texCoords1.constData()); networkMesh._vertexBuffer->setSubData(clusterIndicesOffset, - mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Resource::Byte*) mesh.clusterIndices.constData()); + mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterIndices.constData()); networkMesh._vertexBuffer->setSubData(clusterWeightsOffset, - mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Resource::Byte*) mesh.clusterWeights.constData()); + mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterWeights.constData()); // otherwise, at least the cluster indices/weights can be static networkMesh._vertexStream = gpu::BufferStreamPointer(new gpu::BufferStream()); @@ -2304,14 +2304,14 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) { int clusterWeightsOffset = clusterIndicesOffset + mesh.clusterIndices.size() * sizeof(glm::vec4); networkMesh._vertexBuffer->resize(clusterWeightsOffset + mesh.clusterWeights.size() * sizeof(glm::vec4)); - networkMesh._vertexBuffer->setSubData(0, mesh.tangents.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.tangents.constData()); - networkMesh._vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.colors.constData()); + networkMesh._vertexBuffer->setSubData(0, mesh.tangents.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.tangents.constData()); + networkMesh._vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.colors.constData()); networkMesh._vertexBuffer->setSubData(texCoordsOffset, - mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Resource::Byte*) mesh.texCoords.constData()); + mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Byte*) mesh.texCoords.constData()); networkMesh._vertexBuffer->setSubData(clusterIndicesOffset, - mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Resource::Byte*) mesh.clusterIndices.constData()); + mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterIndices.constData()); networkMesh._vertexBuffer->setSubData(clusterWeightsOffset, - mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Resource::Byte*) mesh.clusterWeights.constData()); + mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterWeights.constData()); networkMesh._vertexStream = gpu::BufferStreamPointer(new gpu::BufferStream()); if (mesh.tangents.size()) networkMesh._vertexStream->addBuffer(networkMesh._vertexBuffer, 0, sizeof(glm::vec3)); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 7528d1db4d..59700d70fc 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -451,9 +451,9 @@ bool Model::updateGeometry() { gpu::BufferPointer buffer(new gpu::Buffer()); if (!mesh.blendshapes.isEmpty()) { buffer->resize((mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3)); - buffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.vertices.constData()); + buffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.vertices.constData()); buffer->setSubData(mesh.vertices.size() * sizeof(glm::vec3), - mesh.normals.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.normals.constData()); + mesh.normals.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.normals.constData()); } _blendedVertexBuffers.push_back(buffer); } @@ -1732,9 +1732,9 @@ void Model::setBlendedVertices(int blendNumber, const QWeakPointersetSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) vertices.constData() + index*sizeof(glm::vec3)); + buffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Byte*) vertices.constData() + index*sizeof(glm::vec3)); buffer->setSubData(mesh.vertices.size() * sizeof(glm::vec3), - mesh.normals.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) normals.constData() + index*sizeof(glm::vec3)); + mesh.normals.size() * sizeof(glm::vec3), (gpu::Byte*) normals.constData() + index*sizeof(glm::vec3)); index += mesh.vertices.size(); } From 1b5185abeb8971914745dcdbc1c32f51d2f939e1 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 6 May 2015 12:19:19 -0700 Subject: [PATCH 08/13] fix the conditional on the texture pointer which was wrong and bring back atmosphere sky dome --- interface/src/Application.cpp | 9 +++++++++ libraries/render-utils/src/TextureCache.cpp | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 977a35aea3..78ba11df8a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3114,6 +3114,15 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs if (hasStars) { _stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha); } + + // draw the sky dome + if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { + PerformanceTimer perfTimer("atmosphere"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::displaySide() ... atmosphere..."); + _environment.renderAtmospheres(theCamera); + } + } } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { auto skybox = skyStage->getSkybox(); diff --git a/libraries/render-utils/src/TextureCache.cpp b/libraries/render-utils/src/TextureCache.cpp index 5cf26c9167..ee1d427244 100644 --- a/libraries/render-utils/src/TextureCache.cpp +++ b/libraries/render-utils/src/TextureCache.cpp @@ -90,7 +90,7 @@ const int permutation[256] = #define USE_CHRIS_NOISE 1 const gpu::TexturePointer& TextureCache::getPermutationNormalTexture() { - if (_permutationNormalTexture) { + if (!_permutationNormalTexture) { // the first line consists of random permutation offsets unsigned char data[256 * 2 * 3]; @@ -134,7 +134,7 @@ static void loadSingleColorTexture(const unsigned char* color) { */ const gpu::TexturePointer& TextureCache::getWhiteTexture() { - if (_whiteTexture) { + if (!_whiteTexture) { _whiteTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1)); _whiteTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_WHITE); } @@ -142,7 +142,7 @@ const gpu::TexturePointer& TextureCache::getWhiteTexture() { } const gpu::TexturePointer& TextureCache::getBlueTexture() { - if (_blueTexture) { + if (!_blueTexture) { _blueTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1)); _blueTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(OPAQUE_BLUE), OPAQUE_BLUE); } From 0fbccf1d336e6bc0f9828385d43a1313ce648a3e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 6 May 2015 12:22:19 -0700 Subject: [PATCH 09/13] get ready for PR, SKY_DOME by default --- libraries/model/src/model/Stage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index fddf28165a..b6a19b49cd 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -223,7 +223,7 @@ public: const SkyboxPointer& getSkybox() const { valid(); return _skybox; } protected: - BackgroundMode _backgroundMode = SKY_BOX; + BackgroundMode _backgroundMode = SKY_DOME; LightPointer _sunLight; AtmospherePointer _atmosphere; From 00c45dbb4399aa06b9f735092b02eb51d651e7cc Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 6 May 2015 12:38:12 -0700 Subject: [PATCH 10/13] missing includes --- libraries/gpu/src/gpu/Stream.cpp | 2 ++ libraries/gpu/src/gpu/Texture.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/Stream.cpp b/libraries/gpu/src/gpu/Stream.cpp index 73677f715e..e23a730370 100644 --- a/libraries/gpu/src/gpu/Stream.cpp +++ b/libraries/gpu/src/gpu/Stream.cpp @@ -10,6 +10,8 @@ // #include "Stream.h" + +#include //min max and more using namespace gpu; diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 57b2bb0e69..883b7c7098 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -13,7 +13,7 @@ #include "Resource.h" -#include //min max +#include //min max and more namespace gpu { From 8fd77f964c69b3ab7fd489eb2f2925c21f1e89bf Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 6 May 2015 14:23:42 -0700 Subject: [PATCH 11/13] Fix include filke case for ubuntu... --- libraries/model/src/model/Skybox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 9fd96a198f..8495baf600 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -14,8 +14,8 @@ #include "gpu/Context.h" #include "ViewFrustum.h" -#include "skybox_vert.h" -#include "skybox_frag.h" +#include "Skybox_vert.h" +#include "Skybox_frag.h" using namespace model; From 477447b95fd0bc76c9074a09745d1e75da3d718a Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 6 May 2015 23:36:44 +0200 Subject: [PATCH 12/13] Planky game script --- examples/example/games/planky.js | 140 +++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 examples/example/games/planky.js diff --git a/examples/example/games/planky.js b/examples/example/games/planky.js new file mode 100644 index 0000000000..77711958ea --- /dev/null +++ b/examples/example/games/planky.js @@ -0,0 +1,140 @@ +// +// planky.js +// examples +// +// Created by Thijs Wenker on 5/2/14. +// Copyright 2015 High Fidelity, Inc. +// +// Pull blocks off the bottom and put them on the top using the grab.js script. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + +const NUM_LAYERS = 16; +const BASE_DIMENSION = { x: 7, y: 2, z: 7 }; +const BLOCKS_PER_LAYER = 3; +const BLOCK_SIZE = {x: 0.2, y: 0.1, z: 0.8}; +const BLOCK_SPACING = BLOCK_SIZE.x / 3; +const GRAVITY = {x: 0, y: -2.8, z: 0}; +const DENSITY = 2000; +const DAMPING_FACTOR = 0.98; +const ANGULAR_DAMPING_FACTOR = 0.8; +const SPAWN_DISTANCE = 3; +const BLOCK_YAW_OFFSET = 45; +const BUTTON_DIMENSIONS = {width: 49, height: 49}; + +var windowWidth = Window.innerWidth; +var size; +var pieces = []; +var ground = false; +var layerRotated = false; + +function grabLowestJointY() { + var jointNames = MyAvatar.getJointNames(); + var floorY = MyAvatar.position.y; + for (var jointName in jointNames) { + if (MyAvatar.getJointPosition(jointNames[jointName]).y < floorY) { + floorY = MyAvatar.getJointPosition(jointNames[jointName]).y; + } + } + return floorY; +} + +function getButtonPosX() { + return windowWidth - ((BUTTON_DIMENSIONS.width / 2) + BUTTON_DIMENSIONS.width); +} + +var button = Overlays.addOverlay('image', { + x: getButtonPosX(), + y: 10, + width: BUTTON_DIMENSIONS.width, + height: BUTTON_DIMENSIONS.height, + imageURL: HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/planky_button.svg', + alpha: 1 +}); + + +function resetBlocks() { + pieces.forEach(function(piece) { + Entities.deleteEntity(piece); + }); + pieces = []; + var avatarRot = Quat.fromPitchYawRollDegrees(0.0, MyAvatar.bodyYaw, 0.0); + basePosition = Vec3.sum(MyAvatar.position, Vec3.multiply(SPAWN_DISTANCE, Quat.getFront(avatarRot))); + basePosition.y = grabLowestJointY() - (BASE_DIMENSION.y / 2); + if (!ground) { + ground = Entities.addEntity({ + type: 'Model', + modelURL: HIFI_PUBLIC_BUCKET + 'eric/models/woodFloor.fbx', + dimensions: BASE_DIMENSION, + position: basePosition, + rotation: avatarRot, + shapeType: 'box' + }); + } else { + Entities.editEntity(ground, {position: basePosition, rotation: avatarRot}); + } + var offsetRot = Quat.multiply(avatarRot, Quat.fromPitchYawRollDegrees(0.0, BLOCK_YAW_OFFSET, 0.0)); + basePosition.y += (BASE_DIMENSION.y / 2); + for (var layerIndex = 0; layerIndex < NUM_LAYERS; layerIndex++) { + var layerRotated = layerIndex % 2 === 0; + var offset = -(BLOCK_SPACING); + var layerRotation = Quat.fromPitchYawRollDegrees(0, layerRotated ? 0 : 90, 0.0); + for (var blockIndex = 0; blockIndex < BLOCKS_PER_LAYER; blockIndex++) { + var blockPositionXZ = BLOCK_SIZE.x * blockIndex - (BLOCK_SIZE.x * 3 / 2 - BLOCK_SIZE.x / 2); + var localTransform = Vec3.multiplyQbyV(offsetRot, { + x: (layerRotated ? blockPositionXZ + offset: 0), + y: (BLOCK_SIZE.y / 2) + (BLOCK_SIZE.y * layerIndex), + z: (layerRotated ? 0 : blockPositionXZ + offset) + }); + pieces.push(Entities.addEntity({ + type: 'Model', + modelURL: HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx', + shapeType: 'box', + name: 'JengaBlock' + ((layerIndex * BLOCKS_PER_LAYER) + blockIndex), + dimensions: BLOCK_SIZE, + position: { + x: basePosition.x + localTransform.x, + y: basePosition.y + localTransform.y, + z: basePosition.z + localTransform.z + }, + rotation: Quat.multiply(layerRotation, offsetRot), + collisionsWillMove: true, + damping: DAMPING_FACTOR, + angularDamping: ANGULAR_DAMPING_FACTOR, + gravity: GRAVITY, + density: DENSITY + })); + offset += BLOCK_SPACING; + } + } +} + +function mousePressEvent(event) { + var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + if (clickedOverlay === button) { + resetBlocks(); + } +} + +Controller.mousePressEvent.connect(mousePressEvent); + +function cleanup() { + Overlays.deleteOverlay(button); + if (ground) { + Entities.deleteEntity(ground); + } + pieces.forEach(function(piece) { + Entities.deleteEntity(piece); + }); + pieces = []; +} + +function onUpdate() { + +} + +Script.update.connect(onUpdate) +Script.scriptEnding.connect(cleanup); From 561d275dda13336df375ba625497b1ffeb4179b7 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Wed, 6 May 2015 15:18:17 -0700 Subject: [PATCH 13/13] Fix ensmallened overlay UI --- interface/src/ui/ApplicationOverlay.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index c410b992c4..71fe528700 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -190,8 +190,8 @@ void ApplicationOverlay::renderOverlay() { Overlays& overlays = qApp->getOverlays(); _textureFov = glm::radians(_hmdUIAngularSize); - auto deviceSize = Application::getInstance()->getDeviceSize(); - _textureAspectRatio = (float)deviceSize.width() / (float)deviceSize.height(); + glm::vec2 deviceSize = qApp->getCanvasSize(); + _textureAspectRatio = (float)deviceSize.x / (float)deviceSize.y; //Handle fading and deactivation/activation of UI @@ -209,7 +209,7 @@ void ApplicationOverlay::renderOverlay() { const float NEAR_CLIP = -10000; const float FAR_CLIP = 10000; glLoadIdentity(); - glOrtho(0, deviceSize.width(), deviceSize.height(), 0, NEAR_CLIP, FAR_CLIP); + glOrtho(0, deviceSize.x, deviceSize.y, 0, NEAR_CLIP, FAR_CLIP); glMatrixMode(GL_MODELVIEW); @@ -270,11 +270,11 @@ void ApplicationOverlay::displayOverlayTexture() { glEnable(GL_BLEND); } + static const glm::vec2 topLeft(-1, 1); + static const glm::vec2 bottomRight(1, -1); + static const glm::vec2 texCoordTopLeft(0.0f, 1.0f); + static const glm::vec2 texCoordBottomRight(1.0f, 0.0f); with_each_texture(_overlays.getTexture(), _newUiTexture, [&] { - static const glm::vec2 topLeft(-1, 1); - static const glm::vec2 bottomRight(1, -1); - static const glm::vec2 texCoordTopLeft(0.0f, 1.0f); - static const glm::vec2 texCoordBottomRight(1.0f, 0.0f); DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(1.0f, 1.0f, 1.0f, _alpha)); });