mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge pull request #6123 from AndrewMeadows/fix-line-endings
fix line endings in files that have mixed DOS/unix endings
This commit is contained in:
commit
ea297166d8
16 changed files with 2309 additions and 2309 deletions
|
@ -7,279 +7,279 @@
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Framebuffer.h"
|
#include "Framebuffer.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
Framebuffer::~Framebuffer() {
|
Framebuffer::~Framebuffer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer* Framebuffer::create() {
|
Framebuffer* Framebuffer::create() {
|
||||||
auto framebuffer = new Framebuffer();
|
auto framebuffer = new Framebuffer();
|
||||||
framebuffer->_renderBuffers.resize(MAX_NUM_RENDER_BUFFERS);
|
framebuffer->_renderBuffers.resize(MAX_NUM_RENDER_BUFFERS);
|
||||||
return framebuffer;
|
return framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Framebuffer* Framebuffer::create( const Format& colorBufferFormat, uint16 width, uint16 height) {
|
Framebuffer* Framebuffer::create( const Format& colorBufferFormat, uint16 width, uint16 height) {
|
||||||
auto framebuffer = Framebuffer::create();
|
auto framebuffer = Framebuffer::create();
|
||||||
|
|
||||||
auto colorTexture = TexturePointer(Texture::create2D(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
|
auto colorTexture = TexturePointer(Texture::create2D(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
|
||||||
|
|
||||||
framebuffer->setRenderBuffer(0, colorTexture);
|
framebuffer->setRenderBuffer(0, colorTexture);
|
||||||
|
|
||||||
return framebuffer;
|
return framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer* Framebuffer::create( const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height) {
|
Framebuffer* Framebuffer::create( const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height) {
|
||||||
auto framebuffer = Framebuffer::create();
|
auto framebuffer = Framebuffer::create();
|
||||||
|
|
||||||
auto colorTexture = TexturePointer(Texture::create2D(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
|
auto colorTexture = TexturePointer(Texture::create2D(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
|
||||||
auto depthTexture = TexturePointer(Texture::create2D(depthStencilBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
|
auto depthTexture = TexturePointer(Texture::create2D(depthStencilBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
|
||||||
|
|
||||||
framebuffer->setRenderBuffer(0, colorTexture);
|
framebuffer->setRenderBuffer(0, colorTexture);
|
||||||
framebuffer->setDepthStencilBuffer(depthTexture, depthStencilBufferFormat);
|
framebuffer->setDepthStencilBuffer(depthTexture, depthStencilBufferFormat);
|
||||||
|
|
||||||
return framebuffer;
|
return framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer* Framebuffer::createShadowmap(uint16 width) {
|
Framebuffer* Framebuffer::createShadowmap(uint16 width) {
|
||||||
auto framebuffer = Framebuffer::create();
|
auto framebuffer = Framebuffer::create();
|
||||||
auto depthTexture = TexturePointer(Texture::create2D(Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH), width, width));
|
auto depthTexture = TexturePointer(Texture::create2D(Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH), width, width));
|
||||||
|
|
||||||
Sampler::Desc samplerDesc;
|
Sampler::Desc samplerDesc;
|
||||||
samplerDesc._borderColor = glm::vec4(1.0f);
|
samplerDesc._borderColor = glm::vec4(1.0f);
|
||||||
samplerDesc._wrapModeU = Sampler::WRAP_BORDER;
|
samplerDesc._wrapModeU = Sampler::WRAP_BORDER;
|
||||||
samplerDesc._wrapModeV = Sampler::WRAP_BORDER;
|
samplerDesc._wrapModeV = Sampler::WRAP_BORDER;
|
||||||
samplerDesc._filter = Sampler::FILTER_MIN_MAG_LINEAR;
|
samplerDesc._filter = Sampler::FILTER_MIN_MAG_LINEAR;
|
||||||
samplerDesc._comparisonFunc = LESS_EQUAL;
|
samplerDesc._comparisonFunc = LESS_EQUAL;
|
||||||
|
|
||||||
depthTexture->setSampler(Sampler(samplerDesc));
|
depthTexture->setSampler(Sampler(samplerDesc));
|
||||||
|
|
||||||
framebuffer->setDepthStencilBuffer(depthTexture, Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH));
|
framebuffer->setDepthStencilBuffer(depthTexture, Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH));
|
||||||
|
|
||||||
return framebuffer;
|
return framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Framebuffer::isSwapchain() const {
|
bool Framebuffer::isSwapchain() const {
|
||||||
return _swapchain != 0;
|
return _swapchain != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Framebuffer::getFrameCount() const {
|
uint32 Framebuffer::getFrameCount() const {
|
||||||
if (_swapchain) {
|
if (_swapchain) {
|
||||||
return _swapchain->getFrameCount();
|
return _swapchain->getFrameCount();
|
||||||
} else {
|
} else {
|
||||||
return _frameCount;
|
return _frameCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Framebuffer::validateTargetCompatibility(const Texture& texture, uint32 subresource) const {
|
bool Framebuffer::validateTargetCompatibility(const Texture& texture, uint32 subresource) const {
|
||||||
if (texture.getType() == Texture::TEX_1D) {
|
if (texture.getType() == Texture::TEX_1D) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if ((texture.getWidth() == getWidth()) &&
|
if ((texture.getWidth() == getWidth()) &&
|
||||||
(texture.getHeight() == getHeight()) &&
|
(texture.getHeight() == getHeight()) &&
|
||||||
(texture.getNumSamples() == getNumSamples())) {
|
(texture.getNumSamples() == getNumSamples())) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::updateSize(const TexturePointer& texture) {
|
void Framebuffer::updateSize(const TexturePointer& texture) {
|
||||||
if (!isEmpty()) {
|
if (!isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture) {
|
if (texture) {
|
||||||
_width = texture->getWidth();
|
_width = texture->getWidth();
|
||||||
_height = texture->getHeight();
|
_height = texture->getHeight();
|
||||||
_numSamples = texture->getNumSamples();
|
_numSamples = texture->getNumSamples();
|
||||||
} else {
|
} else {
|
||||||
_width = _height = _numSamples = 0;
|
_width = _height = _numSamples = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::resize(uint16 width, uint16 height, uint16 numSamples) {
|
void Framebuffer::resize(uint16 width, uint16 height, uint16 numSamples) {
|
||||||
if (width && height && numSamples && !isEmpty() && !isSwapchain()) {
|
if (width && height && numSamples && !isEmpty() && !isSwapchain()) {
|
||||||
if ((width != _width) || (height != _height) || (numSamples != _numSamples)) {
|
if ((width != _width) || (height != _height) || (numSamples != _numSamples)) {
|
||||||
for (uint32 i = 0; i < _renderBuffers.size(); ++i) {
|
for (uint32 i = 0; i < _renderBuffers.size(); ++i) {
|
||||||
if (_renderBuffers[i]) {
|
if (_renderBuffers[i]) {
|
||||||
_renderBuffers[i]._texture->resize2D(width, height, numSamples);
|
_renderBuffers[i]._texture->resize2D(width, height, numSamples);
|
||||||
_numSamples = _renderBuffers[i]._texture->getNumSamples();
|
_numSamples = _renderBuffers[i]._texture->getNumSamples();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_depthStencilBuffer) {
|
if (_depthStencilBuffer) {
|
||||||
_depthStencilBuffer._texture->resize2D(width, height, numSamples);
|
_depthStencilBuffer._texture->resize2D(width, height, numSamples);
|
||||||
_numSamples = _depthStencilBuffer._texture->getNumSamples();
|
_numSamples = _depthStencilBuffer._texture->getNumSamples();
|
||||||
}
|
}
|
||||||
|
|
||||||
_width = width;
|
_width = width;
|
||||||
_height = height;
|
_height = height;
|
||||||
// _numSamples = numSamples;
|
// _numSamples = numSamples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 Framebuffer::getWidth() const {
|
uint16 Framebuffer::getWidth() const {
|
||||||
if (isSwapchain()) {
|
if (isSwapchain()) {
|
||||||
return getSwapchain()->getWidth();
|
return getSwapchain()->getWidth();
|
||||||
} else {
|
} else {
|
||||||
return _width;
|
return _width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 Framebuffer::getHeight() const {
|
uint16 Framebuffer::getHeight() const {
|
||||||
if (isSwapchain()) {
|
if (isSwapchain()) {
|
||||||
return getSwapchain()->getHeight();
|
return getSwapchain()->getHeight();
|
||||||
} else {
|
} else {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 Framebuffer::getNumSamples() const {
|
uint16 Framebuffer::getNumSamples() const {
|
||||||
if (isSwapchain()) {
|
if (isSwapchain()) {
|
||||||
return getSwapchain()->getNumSamples();
|
return getSwapchain()->getNumSamples();
|
||||||
} else {
|
} else {
|
||||||
return _numSamples;
|
return _numSamples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render buffers
|
// Render buffers
|
||||||
int Framebuffer::setRenderBuffer(uint32 slot, const TexturePointer& texture, uint32 subresource) {
|
int Framebuffer::setRenderBuffer(uint32 slot, const TexturePointer& texture, uint32 subresource) {
|
||||||
if (isSwapchain()) {
|
if (isSwapchain()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for the slot
|
// Check for the slot
|
||||||
if (slot >= getMaxNumRenderBuffers()) {
|
if (slot >= getMaxNumRenderBuffers()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for the compatibility of size
|
// Check for the compatibility of size
|
||||||
if (texture) {
|
if (texture) {
|
||||||
if (!validateTargetCompatibility(*texture, subresource)) {
|
if (!validateTargetCompatibility(*texture, subresource)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSize(texture);
|
updateSize(texture);
|
||||||
|
|
||||||
// assign the new one
|
// assign the new one
|
||||||
_renderBuffers[slot] = TextureView(texture, subresource);
|
_renderBuffers[slot] = TextureView(texture, subresource);
|
||||||
|
|
||||||
// update the mask
|
// update the mask
|
||||||
int mask = (1<<slot);
|
int mask = (1<<slot);
|
||||||
_bufferMask = (_bufferMask & ~(mask));
|
_bufferMask = (_bufferMask & ~(mask));
|
||||||
if (texture) {
|
if (texture) {
|
||||||
_bufferMask |= mask;
|
_bufferMask |= mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::removeRenderBuffers() {
|
void Framebuffer::removeRenderBuffers() {
|
||||||
if (isSwapchain()) {
|
if (isSwapchain()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_bufferMask = _bufferMask & BUFFER_DEPTHSTENCIL;
|
_bufferMask = _bufferMask & BUFFER_DEPTHSTENCIL;
|
||||||
|
|
||||||
for (auto renderBuffer : _renderBuffers) {
|
for (auto renderBuffer : _renderBuffers) {
|
||||||
renderBuffer._texture.reset();
|
renderBuffer._texture.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSize(TexturePointer(nullptr));
|
updateSize(TexturePointer(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32 Framebuffer::getNumRenderBuffers() const {
|
uint32 Framebuffer::getNumRenderBuffers() const {
|
||||||
uint32 nb = 0;
|
uint32 nb = 0;
|
||||||
for (auto i : _renderBuffers) {
|
for (auto i : _renderBuffers) {
|
||||||
nb += (!i);
|
nb += (!i);
|
||||||
}
|
}
|
||||||
return nb;
|
return nb;
|
||||||
}
|
}
|
||||||
|
|
||||||
TexturePointer Framebuffer::getRenderBuffer(uint32 slot) const {
|
TexturePointer Framebuffer::getRenderBuffer(uint32 slot) const {
|
||||||
if (!isSwapchain() && (slot < getMaxNumRenderBuffers())) {
|
if (!isSwapchain() && (slot < getMaxNumRenderBuffers())) {
|
||||||
return _renderBuffers[slot]._texture;
|
return _renderBuffers[slot]._texture;
|
||||||
} else {
|
} else {
|
||||||
return TexturePointer();
|
return TexturePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Framebuffer::getRenderBufferSubresource(uint32 slot) const {
|
uint32 Framebuffer::getRenderBufferSubresource(uint32 slot) const {
|
||||||
if (!isSwapchain() && (slot < getMaxNumRenderBuffers())) {
|
if (!isSwapchain() && (slot < getMaxNumRenderBuffers())) {
|
||||||
return _renderBuffers[slot]._subresource;
|
return _renderBuffers[slot]._subresource;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Framebuffer::setDepthStencilBuffer(const TexturePointer& texture, const Format& format, uint32 subresource) {
|
bool Framebuffer::setDepthStencilBuffer(const TexturePointer& texture, const Format& format, uint32 subresource) {
|
||||||
if (isSwapchain()) {
|
if (isSwapchain()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for the compatibility of size
|
// Check for the compatibility of size
|
||||||
if (texture) {
|
if (texture) {
|
||||||
if (!validateTargetCompatibility(*texture)) {
|
if (!validateTargetCompatibility(*texture)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSize(texture);
|
updateSize(texture);
|
||||||
|
|
||||||
// assign the new one
|
// assign the new one
|
||||||
_depthStencilBuffer = TextureView(texture, subresource, format);
|
_depthStencilBuffer = TextureView(texture, subresource, format);
|
||||||
|
|
||||||
_bufferMask = ( _bufferMask & ~BUFFER_DEPTHSTENCIL);
|
_bufferMask = ( _bufferMask & ~BUFFER_DEPTHSTENCIL);
|
||||||
if (texture) {
|
if (texture) {
|
||||||
if (format.getSemantic() == gpu::DEPTH) {
|
if (format.getSemantic() == gpu::DEPTH) {
|
||||||
_bufferMask |= BUFFER_DEPTH;
|
_bufferMask |= BUFFER_DEPTH;
|
||||||
} else if (format.getSemantic() == gpu::STENCIL) {
|
} else if (format.getSemantic() == gpu::STENCIL) {
|
||||||
_bufferMask |= BUFFER_STENCIL;
|
_bufferMask |= BUFFER_STENCIL;
|
||||||
} else if (format.getSemantic() == gpu::DEPTH_STENCIL) {
|
} else if (format.getSemantic() == gpu::DEPTH_STENCIL) {
|
||||||
_bufferMask |= BUFFER_DEPTHSTENCIL;
|
_bufferMask |= BUFFER_DEPTHSTENCIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TexturePointer Framebuffer::getDepthStencilBuffer() const {
|
TexturePointer Framebuffer::getDepthStencilBuffer() const {
|
||||||
if (isSwapchain()) {
|
if (isSwapchain()) {
|
||||||
return TexturePointer();
|
return TexturePointer();
|
||||||
} else {
|
} else {
|
||||||
return _depthStencilBuffer._texture;
|
return _depthStencilBuffer._texture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Framebuffer::getDepthStencilBufferSubresource() const {
|
uint32 Framebuffer::getDepthStencilBufferSubresource() const {
|
||||||
if (isSwapchain()) {
|
if (isSwapchain()) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return _depthStencilBuffer._subresource;
|
return _depthStencilBuffer._subresource;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Format Framebuffer::getDepthStencilBufferFormat() const {
|
Format Framebuffer::getDepthStencilBufferFormat() const {
|
||||||
if (isSwapchain()) {
|
if (isSwapchain()) {
|
||||||
// return getSwapchain()->getDepthStencilBufferFormat();
|
// return getSwapchain()->getDepthStencilBufferFormat();
|
||||||
return _depthStencilBuffer._element;
|
return _depthStencilBuffer._element;
|
||||||
} else {
|
} else {
|
||||||
return _depthStencilBuffer._element;
|
return _depthStencilBuffer._element;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,167 +1,167 @@
|
||||||
//
|
//
|
||||||
// Framebuffer.h
|
// Framebuffer.h
|
||||||
// libraries/gpu/src/gpu
|
// libraries/gpu/src/gpu
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 4/12/2015.
|
// Created by Sam Gateau on 4/12/2015.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
#ifndef hifi_gpu_Framebuffer_h
|
#ifndef hifi_gpu_Framebuffer_h
|
||||||
#define hifi_gpu_Framebuffer_h
|
#define hifi_gpu_Framebuffer_h
|
||||||
|
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
typedef Element Format;
|
typedef Element Format;
|
||||||
|
|
||||||
class Swapchain {
|
class Swapchain {
|
||||||
public:
|
public:
|
||||||
// Properties
|
// Properties
|
||||||
uint16 getWidth() const { return _width; }
|
uint16 getWidth() const { return _width; }
|
||||||
uint16 getHeight() const { return _height; }
|
uint16 getHeight() const { return _height; }
|
||||||
uint16 getNumSamples() const { return _numSamples; }
|
uint16 getNumSamples() const { return _numSamples; }
|
||||||
|
|
||||||
bool hasDepthStencil() const { return _hasDepthStencil; }
|
bool hasDepthStencil() const { return _hasDepthStencil; }
|
||||||
bool isFullscreen() const { return _isFullscreen; }
|
bool isFullscreen() const { return _isFullscreen; }
|
||||||
|
|
||||||
uint32 getSwapInterval() const { return _swapInterval; }
|
uint32 getSwapInterval() const { return _swapInterval; }
|
||||||
|
|
||||||
bool isStereo() const { return _isStereo; }
|
bool isStereo() const { return _isStereo; }
|
||||||
|
|
||||||
uint32 getFrameCount() const { return _frameCount; }
|
uint32 getFrameCount() const { return _frameCount; }
|
||||||
|
|
||||||
// Pure interface
|
// Pure interface
|
||||||
void setSwapInterval(uint32 interval);
|
void setSwapInterval(uint32 interval);
|
||||||
|
|
||||||
void resize(uint16 width, uint16 height);
|
void resize(uint16 width, uint16 height);
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
|
|
||||||
Swapchain() {}
|
Swapchain() {}
|
||||||
Swapchain(const Swapchain& swapchain) {}
|
Swapchain(const Swapchain& swapchain) {}
|
||||||
virtual ~Swapchain() {}
|
virtual ~Swapchain() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable uint32 _frameCount = 0;
|
mutable uint32 _frameCount = 0;
|
||||||
|
|
||||||
Format _colorFormat;
|
Format _colorFormat;
|
||||||
uint16 _width = 1;
|
uint16 _width = 1;
|
||||||
uint16 _height = 1;
|
uint16 _height = 1;
|
||||||
uint16 _numSamples = 1;
|
uint16 _numSamples = 1;
|
||||||
uint16 _swapInterval = 0;
|
uint16 _swapInterval = 0;
|
||||||
|
|
||||||
bool _hasDepthStencil = false;
|
bool _hasDepthStencil = false;
|
||||||
bool _isFullscreen = false;
|
bool _isFullscreen = false;
|
||||||
bool _isStereo = false;
|
bool _isStereo = false;
|
||||||
|
|
||||||
// Non exposed
|
// Non exposed
|
||||||
|
|
||||||
friend class Framebuffer;
|
friend class Framebuffer;
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr<Swapchain> SwapchainPointer;
|
typedef std::shared_ptr<Swapchain> SwapchainPointer;
|
||||||
|
|
||||||
|
|
||||||
class Framebuffer {
|
class Framebuffer {
|
||||||
public:
|
public:
|
||||||
enum BufferMask {
|
enum BufferMask {
|
||||||
BUFFER_COLOR0 = 1,
|
BUFFER_COLOR0 = 1,
|
||||||
BUFFER_COLOR1 = 2,
|
BUFFER_COLOR1 = 2,
|
||||||
BUFFER_COLOR2 = 4,
|
BUFFER_COLOR2 = 4,
|
||||||
BUFFER_COLOR3 = 8,
|
BUFFER_COLOR3 = 8,
|
||||||
BUFFER_COLOR4 = 16,
|
BUFFER_COLOR4 = 16,
|
||||||
BUFFER_COLOR5 = 32,
|
BUFFER_COLOR5 = 32,
|
||||||
BUFFER_COLOR6 = 64,
|
BUFFER_COLOR6 = 64,
|
||||||
BUFFER_COLOR7 = 128,
|
BUFFER_COLOR7 = 128,
|
||||||
BUFFER_COLORS = 0x000000FF,
|
BUFFER_COLORS = 0x000000FF,
|
||||||
|
|
||||||
BUFFER_DEPTH = 0x40000000,
|
BUFFER_DEPTH = 0x40000000,
|
||||||
BUFFER_STENCIL = 0x80000000,
|
BUFFER_STENCIL = 0x80000000,
|
||||||
BUFFER_DEPTHSTENCIL = 0xC0000000,
|
BUFFER_DEPTHSTENCIL = 0xC0000000,
|
||||||
};
|
};
|
||||||
typedef uint32 Masks;
|
typedef uint32 Masks;
|
||||||
|
|
||||||
~Framebuffer();
|
~Framebuffer();
|
||||||
|
|
||||||
static Framebuffer* create(const SwapchainPointer& swapchain);
|
static Framebuffer* create(const SwapchainPointer& swapchain);
|
||||||
static Framebuffer* create();
|
static Framebuffer* create();
|
||||||
static Framebuffer* create(const Format& colorBufferFormat, uint16 width, uint16 height);
|
static Framebuffer* create(const Format& colorBufferFormat, uint16 width, uint16 height);
|
||||||
static Framebuffer* create(const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height);
|
static Framebuffer* create(const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height);
|
||||||
static Framebuffer* createShadowmap(uint16 width);
|
static Framebuffer* createShadowmap(uint16 width);
|
||||||
|
|
||||||
bool isSwapchain() const;
|
bool isSwapchain() const;
|
||||||
SwapchainPointer getSwapchain() const { return _swapchain; }
|
SwapchainPointer getSwapchain() const { return _swapchain; }
|
||||||
|
|
||||||
uint32 getFrameCount() const;
|
uint32 getFrameCount() const;
|
||||||
|
|
||||||
// Render buffers
|
// Render buffers
|
||||||
void removeRenderBuffers();
|
void removeRenderBuffers();
|
||||||
uint32 getNumRenderBuffers() const;
|
uint32 getNumRenderBuffers() const;
|
||||||
const TextureViews& getRenderBuffers() const { return _renderBuffers; }
|
const TextureViews& getRenderBuffers() const { return _renderBuffers; }
|
||||||
|
|
||||||
int32 setRenderBuffer(uint32 slot, const TexturePointer& texture, uint32 subresource = 0);
|
int32 setRenderBuffer(uint32 slot, const TexturePointer& texture, uint32 subresource = 0);
|
||||||
TexturePointer getRenderBuffer(uint32 slot) const;
|
TexturePointer getRenderBuffer(uint32 slot) const;
|
||||||
uint32 getRenderBufferSubresource(uint32 slot) const;
|
uint32 getRenderBufferSubresource(uint32 slot) const;
|
||||||
|
|
||||||
bool setDepthStencilBuffer(const TexturePointer& texture, const Format& format, uint32 subresource = 0);
|
bool setDepthStencilBuffer(const TexturePointer& texture, const Format& format, uint32 subresource = 0);
|
||||||
TexturePointer getDepthStencilBuffer() const;
|
TexturePointer getDepthStencilBuffer() const;
|
||||||
uint32 getDepthStencilBufferSubresource() const;
|
uint32 getDepthStencilBufferSubresource() const;
|
||||||
Format getDepthStencilBufferFormat() const;
|
Format getDepthStencilBufferFormat() const;
|
||||||
|
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
Masks getBufferMask() const { return _bufferMask; }
|
Masks getBufferMask() const { return _bufferMask; }
|
||||||
bool isEmpty() const { return (_bufferMask == 0); }
|
bool isEmpty() const { return (_bufferMask == 0); }
|
||||||
bool hasColor() const { return (getBufferMask() & BUFFER_COLORS); }
|
bool hasColor() const { return (getBufferMask() & BUFFER_COLORS); }
|
||||||
bool hasDepthStencil() const { return (getBufferMask() & BUFFER_DEPTHSTENCIL); }
|
bool hasDepthStencil() const { return (getBufferMask() & BUFFER_DEPTHSTENCIL); }
|
||||||
bool hasDepth() const { return (getBufferMask() & BUFFER_DEPTH); }
|
bool hasDepth() const { return (getBufferMask() & BUFFER_DEPTH); }
|
||||||
bool hasStencil() const { return (getBufferMask() & BUFFER_STENCIL); }
|
bool hasStencil() const { return (getBufferMask() & BUFFER_STENCIL); }
|
||||||
|
|
||||||
bool validateTargetCompatibility(const Texture& texture, uint32 subresource = 0) const;
|
bool validateTargetCompatibility(const Texture& texture, uint32 subresource = 0) const;
|
||||||
|
|
||||||
Vec2u getSize() const { return Vec2u(getWidth(), getHeight()); }
|
Vec2u getSize() const { return Vec2u(getWidth(), getHeight()); }
|
||||||
uint16 getWidth() const;
|
uint16 getWidth() const;
|
||||||
uint16 getHeight() const;
|
uint16 getHeight() const;
|
||||||
uint16 getNumSamples() const;
|
uint16 getNumSamples() const;
|
||||||
|
|
||||||
float getAspectRatio() const { return getWidth() / (float) getHeight() ; }
|
float getAspectRatio() const { return getWidth() / (float) getHeight() ; }
|
||||||
|
|
||||||
// If not a swapchain canvas, resize can resize all the render buffers and depth stencil attached in one call
|
// If not a swapchain canvas, resize can resize all the render buffers and depth stencil attached in one call
|
||||||
void resize( uint16 width, uint16 height, uint16 samples = 1 );
|
void resize( uint16 width, uint16 height, uint16 samples = 1 );
|
||||||
|
|
||||||
static const uint32 MAX_NUM_RENDER_BUFFERS = 8;
|
static const uint32 MAX_NUM_RENDER_BUFFERS = 8;
|
||||||
static uint32 getMaxNumRenderBuffers() { return MAX_NUM_RENDER_BUFFERS; }
|
static uint32 getMaxNumRenderBuffers() { return MAX_NUM_RENDER_BUFFERS; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SwapchainPointer _swapchain;
|
SwapchainPointer _swapchain;
|
||||||
|
|
||||||
TextureViews _renderBuffers;
|
TextureViews _renderBuffers;
|
||||||
TextureView _depthStencilBuffer;
|
TextureView _depthStencilBuffer;
|
||||||
|
|
||||||
Masks _bufferMask = 0;
|
Masks _bufferMask = 0;
|
||||||
|
|
||||||
uint32 _frameCount = 0;
|
uint32 _frameCount = 0;
|
||||||
|
|
||||||
uint16 _width = 0;
|
uint16 _width = 0;
|
||||||
uint16 _height = 0;
|
uint16 _height = 0;
|
||||||
uint16 _numSamples = 0;
|
uint16 _numSamples = 0;
|
||||||
|
|
||||||
void updateSize(const TexturePointer& texture);
|
void updateSize(const TexturePointer& texture);
|
||||||
|
|
||||||
// Non exposed
|
// Non exposed
|
||||||
Framebuffer(const Framebuffer& framebuffer) = delete;
|
Framebuffer(const Framebuffer& framebuffer) = delete;
|
||||||
Framebuffer() {}
|
Framebuffer() {}
|
||||||
|
|
||||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||||
mutable GPUObject* _gpuObject = NULL;
|
mutable GPUObject* _gpuObject = NULL;
|
||||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||||
GPUObject* getGPUObject() const { return _gpuObject; }
|
GPUObject* getGPUObject() const { return _gpuObject; }
|
||||||
friend class Backend;
|
friend class Backend;
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr<Framebuffer> FramebufferPointer;
|
typedef std::shared_ptr<Framebuffer> FramebufferPointer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
//
|
//
|
||||||
// Pipeline.cpp
|
// Pipeline.cpp
|
||||||
// libraries/gpu/src/gpu
|
// libraries/gpu/src/gpu
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 3/8/2015.
|
// Created by Sam Gateau on 3/8/2015.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Pipeline.h"
|
#include "Pipeline.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
Pipeline::Pipeline():
|
Pipeline::Pipeline():
|
||||||
_program(),
|
_program(),
|
||||||
_state()
|
_state()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipeline::~Pipeline()
|
Pipeline::~Pipeline()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipeline* Pipeline::create(const ShaderPointer& program, const StatePointer& state) {
|
Pipeline* Pipeline::create(const ShaderPointer& program, const StatePointer& state) {
|
||||||
Pipeline* pipeline = new Pipeline();
|
Pipeline* pipeline = new Pipeline();
|
||||||
|
|
|
@ -1,88 +1,88 @@
|
||||||
//
|
//
|
||||||
// State.cpp
|
// State.cpp
|
||||||
// libraries/gpu/src/gpu
|
// libraries/gpu/src/gpu
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 3/8/2015.
|
// Created by Sam Gateau on 3/8/2015.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "State.h"
|
#include "State.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
State::State() {
|
State::State() {
|
||||||
}
|
}
|
||||||
|
|
||||||
State::~State() {
|
State::~State() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: GLBackend::GLState::_resetStateCommands heavily relies on the fact that State::DEFAULT = State::Data()
|
// WARNING: GLBackend::GLState::_resetStateCommands heavily relies on the fact that State::DEFAULT = State::Data()
|
||||||
// Please make sure to go check makeResetStateCommands() before modifying this value
|
// Please make sure to go check makeResetStateCommands() before modifying this value
|
||||||
const State::Data State::DEFAULT = State::Data();
|
const State::Data State::DEFAULT = State::Data();
|
||||||
|
|
||||||
State::Signature State::evalSignature(const Data& state) {
|
State::Signature State::evalSignature(const Data& state) {
|
||||||
Signature signature(0);
|
Signature signature(0);
|
||||||
|
|
||||||
if (state.fillMode != State::DEFAULT.fillMode) {
|
if (state.fillMode != State::DEFAULT.fillMode) {
|
||||||
signature.set(State::FILL_MODE);
|
signature.set(State::FILL_MODE);
|
||||||
}
|
}
|
||||||
if (state.cullMode != State::DEFAULT.cullMode) {
|
if (state.cullMode != State::DEFAULT.cullMode) {
|
||||||
signature.set(State::CULL_MODE);
|
signature.set(State::CULL_MODE);
|
||||||
}
|
}
|
||||||
if (state.frontFaceClockwise != State::DEFAULT.frontFaceClockwise) {
|
if (state.frontFaceClockwise != State::DEFAULT.frontFaceClockwise) {
|
||||||
signature.set(State::FRONT_FACE_CLOCKWISE);
|
signature.set(State::FRONT_FACE_CLOCKWISE);
|
||||||
}
|
}
|
||||||
if (state.depthClampEnable != State::DEFAULT.depthClampEnable) {
|
if (state.depthClampEnable != State::DEFAULT.depthClampEnable) {
|
||||||
signature.set(State::DEPTH_CLAMP_ENABLE);
|
signature.set(State::DEPTH_CLAMP_ENABLE);
|
||||||
}
|
}
|
||||||
if (state.scissorEnable != State::DEFAULT.scissorEnable) {
|
if (state.scissorEnable != State::DEFAULT.scissorEnable) {
|
||||||
signature.set(State::SCISSOR_ENABLE);
|
signature.set(State::SCISSOR_ENABLE);
|
||||||
}
|
}
|
||||||
if (state.multisampleEnable != State::DEFAULT.multisampleEnable) {
|
if (state.multisampleEnable != State::DEFAULT.multisampleEnable) {
|
||||||
signature.set(State::MULTISAMPLE_ENABLE);
|
signature.set(State::MULTISAMPLE_ENABLE);
|
||||||
}
|
}
|
||||||
if (state.antialisedLineEnable != State::DEFAULT.antialisedLineEnable) {
|
if (state.antialisedLineEnable != State::DEFAULT.antialisedLineEnable) {
|
||||||
signature.set(State::ANTIALISED_LINE_ENABLE);
|
signature.set(State::ANTIALISED_LINE_ENABLE);
|
||||||
}
|
}
|
||||||
if (state.depthBias != State::DEFAULT.depthBias) {
|
if (state.depthBias != State::DEFAULT.depthBias) {
|
||||||
signature.set(State::DEPTH_BIAS);
|
signature.set(State::DEPTH_BIAS);
|
||||||
}
|
}
|
||||||
if (state.depthBiasSlopeScale != State::DEFAULT.depthBiasSlopeScale) {
|
if (state.depthBiasSlopeScale != State::DEFAULT.depthBiasSlopeScale) {
|
||||||
signature.set(State::DEPTH_BIAS_SLOPE_SCALE);
|
signature.set(State::DEPTH_BIAS_SLOPE_SCALE);
|
||||||
}
|
}
|
||||||
if (state.depthTest != State::DEFAULT.depthTest) {
|
if (state.depthTest != State::DEFAULT.depthTest) {
|
||||||
signature.set(State::DEPTH_TEST);
|
signature.set(State::DEPTH_TEST);
|
||||||
}
|
}
|
||||||
if (state.stencilActivation != State::DEFAULT.stencilActivation) {
|
if (state.stencilActivation != State::DEFAULT.stencilActivation) {
|
||||||
signature.set(State::STENCIL_ACTIVATION);
|
signature.set(State::STENCIL_ACTIVATION);
|
||||||
}
|
}
|
||||||
if (state.stencilTestFront != State::DEFAULT.stencilTestFront) {
|
if (state.stencilTestFront != State::DEFAULT.stencilTestFront) {
|
||||||
signature.set(State::STENCIL_TEST_FRONT);
|
signature.set(State::STENCIL_TEST_FRONT);
|
||||||
}
|
}
|
||||||
if (state.stencilTestBack != State::DEFAULT.stencilTestBack) {
|
if (state.stencilTestBack != State::DEFAULT.stencilTestBack) {
|
||||||
signature.set(State::STENCIL_TEST_BACK);
|
signature.set(State::STENCIL_TEST_BACK);
|
||||||
}
|
}
|
||||||
if (state.sampleMask != State::DEFAULT.sampleMask) {
|
if (state.sampleMask != State::DEFAULT.sampleMask) {
|
||||||
signature.set(State::SAMPLE_MASK);
|
signature.set(State::SAMPLE_MASK);
|
||||||
}
|
}
|
||||||
if (state.alphaToCoverageEnable != State::DEFAULT.alphaToCoverageEnable) {
|
if (state.alphaToCoverageEnable != State::DEFAULT.alphaToCoverageEnable) {
|
||||||
signature.set(State::ALPHA_TO_COVERAGE_ENABLE);
|
signature.set(State::ALPHA_TO_COVERAGE_ENABLE);
|
||||||
}
|
}
|
||||||
if (state.blendFunction != State::DEFAULT.blendFunction) {
|
if (state.blendFunction != State::DEFAULT.blendFunction) {
|
||||||
signature.set(State::BLEND_FUNCTION);
|
signature.set(State::BLEND_FUNCTION);
|
||||||
}
|
}
|
||||||
if (state.colorWriteMask != State::DEFAULT.colorWriteMask) {
|
if (state.colorWriteMask != State::DEFAULT.colorWriteMask) {
|
||||||
signature.set(State::COLOR_WRITE_MASK);
|
signature.set(State::COLOR_WRITE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
State::State(const Data& values) :
|
State::State(const Data& values) :
|
||||||
_values(values) {
|
_values(values) {
|
||||||
_signature = evalSignature(_values);
|
_signature = evalSignature(_values);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,448 +1,448 @@
|
||||||
//
|
//
|
||||||
// Texture.h
|
// Texture.h
|
||||||
// libraries/gpu/src/gpu
|
// libraries/gpu/src/gpu
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 1/16/2015.
|
// Created by Sam Gateau on 1/16/2015.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
#ifndef hifi_gpu_Texture_h
|
#ifndef hifi_gpu_Texture_h
|
||||||
#define hifi_gpu_Texture_h
|
#define hifi_gpu_Texture_h
|
||||||
|
|
||||||
#include "Resource.h"
|
#include "Resource.h"
|
||||||
|
|
||||||
#include <algorithm> //min max and more
|
#include <algorithm> //min max and more
|
||||||
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
// THe spherical harmonics is a nice tool for cubemap, so if required, the irradiance SH can be automatically generated
|
// THe spherical harmonics is a nice tool for cubemap, so if required, the irradiance SH can be automatically generated
|
||||||
// with the cube texture
|
// with the cube texture
|
||||||
class Texture;
|
class Texture;
|
||||||
class SphericalHarmonics {
|
class SphericalHarmonics {
|
||||||
public:
|
public:
|
||||||
glm::vec3 L00 ; float spare0;
|
glm::vec3 L00 ; float spare0;
|
||||||
glm::vec3 L1m1 ; float spare1;
|
glm::vec3 L1m1 ; float spare1;
|
||||||
glm::vec3 L10 ; float spare2;
|
glm::vec3 L10 ; float spare2;
|
||||||
glm::vec3 L11 ; float spare3;
|
glm::vec3 L11 ; float spare3;
|
||||||
glm::vec3 L2m2 ; float spare4;
|
glm::vec3 L2m2 ; float spare4;
|
||||||
glm::vec3 L2m1 ; float spare5;
|
glm::vec3 L2m1 ; float spare5;
|
||||||
glm::vec3 L20 ; float spare6;
|
glm::vec3 L20 ; float spare6;
|
||||||
glm::vec3 L21 ; float spare7;
|
glm::vec3 L21 ; float spare7;
|
||||||
glm::vec3 L22 ; float spare8;
|
glm::vec3 L22 ; float spare8;
|
||||||
|
|
||||||
static const int NUM_COEFFICIENTS = 9;
|
static const int NUM_COEFFICIENTS = 9;
|
||||||
|
|
||||||
enum Preset {
|
enum Preset {
|
||||||
OLD_TOWN_SQUARE = 0,
|
OLD_TOWN_SQUARE = 0,
|
||||||
GRACE_CATHEDRAL,
|
GRACE_CATHEDRAL,
|
||||||
EUCALYPTUS_GROVE,
|
EUCALYPTUS_GROVE,
|
||||||
ST_PETERS_BASILICA,
|
ST_PETERS_BASILICA,
|
||||||
UFFIZI_GALLERY,
|
UFFIZI_GALLERY,
|
||||||
GALILEOS_TOMB,
|
GALILEOS_TOMB,
|
||||||
VINE_STREET_KITCHEN,
|
VINE_STREET_KITCHEN,
|
||||||
BREEZEWAY,
|
BREEZEWAY,
|
||||||
CAMPUS_SUNSET,
|
CAMPUS_SUNSET,
|
||||||
FUNSTON_BEACH_SUNSET,
|
FUNSTON_BEACH_SUNSET,
|
||||||
|
|
||||||
NUM_PRESET,
|
NUM_PRESET,
|
||||||
};
|
};
|
||||||
|
|
||||||
void assignPreset(int p);
|
void assignPreset(int p);
|
||||||
|
|
||||||
void evalFromTexture(const Texture& texture);
|
void evalFromTexture(const Texture& texture);
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr< SphericalHarmonics > SHPointer;
|
typedef std::shared_ptr< SphericalHarmonics > SHPointer;
|
||||||
|
|
||||||
class Sampler {
|
class Sampler {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Filter {
|
enum Filter {
|
||||||
FILTER_MIN_MAG_POINT, // top mip only
|
FILTER_MIN_MAG_POINT, // top mip only
|
||||||
FILTER_MIN_POINT_MAG_LINEAR, // top mip only
|
FILTER_MIN_POINT_MAG_LINEAR, // top mip only
|
||||||
FILTER_MIN_LINEAR_MAG_POINT, // top mip only
|
FILTER_MIN_LINEAR_MAG_POINT, // top mip only
|
||||||
FILTER_MIN_MAG_LINEAR, // top mip only
|
FILTER_MIN_MAG_LINEAR, // top mip only
|
||||||
|
|
||||||
FILTER_MIN_MAG_MIP_POINT,
|
FILTER_MIN_MAG_MIP_POINT,
|
||||||
FILTER_MIN_MAG_POINT_MIP_LINEAR,
|
FILTER_MIN_MAG_POINT_MIP_LINEAR,
|
||||||
FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT,
|
FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT,
|
||||||
FILTER_MIN_POINT_MAG_MIP_LINEAR,
|
FILTER_MIN_POINT_MAG_MIP_LINEAR,
|
||||||
FILTER_MIN_LINEAR_MAG_MIP_POINT,
|
FILTER_MIN_LINEAR_MAG_MIP_POINT,
|
||||||
FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR,
|
FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR,
|
||||||
FILTER_MIN_MAG_LINEAR_MIP_POINT,
|
FILTER_MIN_MAG_LINEAR_MIP_POINT,
|
||||||
FILTER_MIN_MAG_MIP_LINEAR,
|
FILTER_MIN_MAG_MIP_LINEAR,
|
||||||
FILTER_ANISOTROPIC,
|
FILTER_ANISOTROPIC,
|
||||||
|
|
||||||
NUM_FILTERS,
|
NUM_FILTERS,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WrapMode {
|
enum WrapMode {
|
||||||
WRAP_REPEAT = 0,
|
WRAP_REPEAT = 0,
|
||||||
WRAP_MIRROR,
|
WRAP_MIRROR,
|
||||||
WRAP_CLAMP,
|
WRAP_CLAMP,
|
||||||
WRAP_BORDER,
|
WRAP_BORDER,
|
||||||
WRAP_MIRROR_ONCE,
|
WRAP_MIRROR_ONCE,
|
||||||
|
|
||||||
NUM_WRAP_MODES
|
NUM_WRAP_MODES
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8 MAX_MIP_LEVEL = 0xFF;
|
static const uint8 MAX_MIP_LEVEL = 0xFF;
|
||||||
|
|
||||||
class Desc {
|
class Desc {
|
||||||
public:
|
public:
|
||||||
glm::vec4 _borderColor{ 1.0f };
|
glm::vec4 _borderColor{ 1.0f };
|
||||||
uint32 _maxAnisotropy = 16;
|
uint32 _maxAnisotropy = 16;
|
||||||
|
|
||||||
uint8 _filter = FILTER_MIN_MAG_POINT;
|
uint8 _filter = FILTER_MIN_MAG_POINT;
|
||||||
uint8 _comparisonFunc = ALWAYS;
|
uint8 _comparisonFunc = ALWAYS;
|
||||||
|
|
||||||
uint8 _wrapModeU = WRAP_REPEAT;
|
uint8 _wrapModeU = WRAP_REPEAT;
|
||||||
uint8 _wrapModeV = WRAP_REPEAT;
|
uint8 _wrapModeV = WRAP_REPEAT;
|
||||||
uint8 _wrapModeW = WRAP_REPEAT;
|
uint8 _wrapModeW = WRAP_REPEAT;
|
||||||
|
|
||||||
uint8 _mipOffset = 0;
|
uint8 _mipOffset = 0;
|
||||||
uint8 _minMip = 0;
|
uint8 _minMip = 0;
|
||||||
uint8 _maxMip = MAX_MIP_LEVEL;
|
uint8 _maxMip = MAX_MIP_LEVEL;
|
||||||
|
|
||||||
Desc() {}
|
Desc() {}
|
||||||
Desc(const Filter filter, const WrapMode wrap = WRAP_REPEAT) : _filter(filter), _wrapModeU(wrap), _wrapModeV(wrap), _wrapModeW(wrap) {}
|
Desc(const Filter filter, const WrapMode wrap = WRAP_REPEAT) : _filter(filter), _wrapModeU(wrap), _wrapModeV(wrap), _wrapModeW(wrap) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Sampler() {}
|
Sampler() {}
|
||||||
Sampler(const Filter filter, const WrapMode wrap = WRAP_REPEAT) : _desc(filter, wrap) {}
|
Sampler(const Filter filter, const WrapMode wrap = WRAP_REPEAT) : _desc(filter, wrap) {}
|
||||||
Sampler(const Desc& desc) : _desc(desc) {}
|
Sampler(const Desc& desc) : _desc(desc) {}
|
||||||
~Sampler() {}
|
~Sampler() {}
|
||||||
|
|
||||||
const glm::vec4& getBorderColor() const { return _desc._borderColor; }
|
const glm::vec4& getBorderColor() const { return _desc._borderColor; }
|
||||||
|
|
||||||
uint32 getMaxAnisotropy() const { return _desc._maxAnisotropy; }
|
uint32 getMaxAnisotropy() const { return _desc._maxAnisotropy; }
|
||||||
|
|
||||||
WrapMode getWrapModeU() const { return WrapMode(_desc._wrapModeU); }
|
WrapMode getWrapModeU() const { return WrapMode(_desc._wrapModeU); }
|
||||||
WrapMode getWrapModeV() const { return WrapMode(_desc._wrapModeV); }
|
WrapMode getWrapModeV() const { return WrapMode(_desc._wrapModeV); }
|
||||||
WrapMode getWrapModeW() const { return WrapMode(_desc._wrapModeW); }
|
WrapMode getWrapModeW() const { return WrapMode(_desc._wrapModeW); }
|
||||||
|
|
||||||
Filter getFilter() const { return Filter(_desc._filter); }
|
Filter getFilter() const { return Filter(_desc._filter); }
|
||||||
ComparisonFunction getComparisonFunction() const { return ComparisonFunction(_desc._comparisonFunc); }
|
ComparisonFunction getComparisonFunction() const { return ComparisonFunction(_desc._comparisonFunc); }
|
||||||
bool doComparison() const { return getComparisonFunction() != ALWAYS; }
|
bool doComparison() const { return getComparisonFunction() != ALWAYS; }
|
||||||
|
|
||||||
uint8 getMipOffset() const { return _desc._mipOffset; }
|
uint8 getMipOffset() const { return _desc._mipOffset; }
|
||||||
uint8 getMinMip() const { return _desc._minMip; }
|
uint8 getMinMip() const { return _desc._minMip; }
|
||||||
uint8 getMaxMip() const { return _desc._maxMip; }
|
uint8 getMaxMip() const { return _desc._maxMip; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Desc _desc;
|
Desc _desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Texture : public Resource {
|
class Texture : public Resource {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class Pixels {
|
class Pixels {
|
||||||
public:
|
public:
|
||||||
Pixels() {}
|
Pixels() {}
|
||||||
Pixels(const Pixels& pixels) = default;
|
Pixels(const Pixels& pixels) = default;
|
||||||
Pixels(const Element& format, Size size, const Byte* bytes);
|
Pixels(const Element& format, Size size, const Byte* bytes);
|
||||||
~Pixels();
|
~Pixels();
|
||||||
|
|
||||||
Sysmem _sysmem;
|
Sysmem _sysmem;
|
||||||
Element _format;
|
Element _format;
|
||||||
bool _isGPULoaded;
|
bool _isGPULoaded;
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr< Pixels > PixelsPointer;
|
typedef std::shared_ptr< Pixels > PixelsPointer;
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
TEX_1D = 0,
|
TEX_1D = 0,
|
||||||
TEX_2D,
|
TEX_2D,
|
||||||
TEX_3D,
|
TEX_3D,
|
||||||
TEX_CUBE,
|
TEX_CUBE,
|
||||||
|
|
||||||
NUM_TYPES,
|
NUM_TYPES,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Definition of the cube face name and layout
|
// Definition of the cube face name and layout
|
||||||
enum CubeFace {
|
enum CubeFace {
|
||||||
CUBE_FACE_RIGHT_POS_X = 0,
|
CUBE_FACE_RIGHT_POS_X = 0,
|
||||||
CUBE_FACE_LEFT_NEG_X,
|
CUBE_FACE_LEFT_NEG_X,
|
||||||
CUBE_FACE_TOP_POS_Y,
|
CUBE_FACE_TOP_POS_Y,
|
||||||
CUBE_FACE_BOTTOM_NEG_Y,
|
CUBE_FACE_BOTTOM_NEG_Y,
|
||||||
CUBE_FACE_BACK_POS_Z,
|
CUBE_FACE_BACK_POS_Z,
|
||||||
CUBE_FACE_FRONT_NEG_Z,
|
CUBE_FACE_FRONT_NEG_Z,
|
||||||
|
|
||||||
NUM_CUBE_FACES, // Not a valid vace index
|
NUM_CUBE_FACES, // Not a valid vace index
|
||||||
};
|
};
|
||||||
|
|
||||||
class Storage {
|
class Storage {
|
||||||
public:
|
public:
|
||||||
Storage() {}
|
Storage() {}
|
||||||
virtual ~Storage() {}
|
virtual ~Storage() {}
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual PixelsPointer editMipFace(uint16 level, uint8 face = 0);
|
virtual PixelsPointer editMipFace(uint16 level, uint8 face = 0);
|
||||||
virtual const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const;
|
virtual const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const;
|
||||||
virtual bool allocateMip(uint16 level);
|
virtual bool allocateMip(uint16 level);
|
||||||
virtual bool assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes);
|
virtual bool assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||||
virtual bool assignMipFaceData(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face);
|
virtual bool assignMipFaceData(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face);
|
||||||
virtual bool isMipAvailable(uint16 level, uint8 face = 0) const;
|
virtual bool isMipAvailable(uint16 level, uint8 face = 0) const;
|
||||||
|
|
||||||
Texture::Type getType() const { return _type; }
|
Texture::Type getType() const { return _type; }
|
||||||
|
|
||||||
Stamp getStamp() const { return _stamp; }
|
Stamp getStamp() const { return _stamp; }
|
||||||
Stamp bumpStamp() { return ++_stamp; }
|
Stamp bumpStamp() { return ++_stamp; }
|
||||||
protected:
|
protected:
|
||||||
Stamp _stamp = 0;
|
Stamp _stamp = 0;
|
||||||
Texture* _texture = nullptr;
|
Texture* _texture = nullptr;
|
||||||
Texture::Type _type = Texture::TEX_2D; // The type of texture is needed to know the number of faces to expect
|
Texture::Type _type = Texture::TEX_2D; // The type of texture is needed to know the number of faces to expect
|
||||||
std::vector<std::vector<PixelsPointer>> _mips; // an array of mips, each mip is an array of faces
|
std::vector<std::vector<PixelsPointer>> _mips; // an array of mips, each mip is an array of faces
|
||||||
|
|
||||||
virtual void assignTexture(Texture* tex); // Texture storage is pointing to ONE corrresponding Texture.
|
virtual void assignTexture(Texture* tex); // Texture storage is pointing to ONE corrresponding Texture.
|
||||||
const Texture* getTexture() const { return _texture; }
|
const Texture* getTexture() const { return _texture; }
|
||||||
|
|
||||||
friend class Texture;
|
friend class Texture;
|
||||||
|
|
||||||
// THis should be only called by the Texture from the Backend to notify the storage that the specified mip face pixels
|
// THis should be only called by the Texture from the Backend to notify the storage that the specified mip face pixels
|
||||||
// have been uploaded to the GPU memory. IT is possible for the storage to free the system memory then
|
// have been uploaded to the GPU memory. IT is possible for the storage to free the system memory then
|
||||||
virtual void notifyMipFaceGPULoaded(uint16 level, uint8 face) const;
|
virtual void notifyMipFaceGPULoaded(uint16 level, uint8 face) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler());
|
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* 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* 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* createCube(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler());
|
||||||
|
|
||||||
static Texture* createFromStorage(Storage* storage);
|
static Texture* createFromStorage(Storage* storage);
|
||||||
|
|
||||||
Texture();
|
Texture();
|
||||||
Texture(const Texture& buf); // deep copy of the sysmem texture
|
Texture(const Texture& buf); // deep copy of the sysmem texture
|
||||||
Texture& operator=(const Texture& buf); // deep copy of the sysmem texture
|
Texture& operator=(const Texture& buf); // deep copy of the sysmem texture
|
||||||
~Texture();
|
~Texture();
|
||||||
|
|
||||||
Stamp getStamp() const { return _stamp; }
|
Stamp getStamp() const { return _stamp; }
|
||||||
Stamp getDataStamp() const { return _storage->getStamp(); }
|
Stamp getDataStamp() const { return _storage->getStamp(); }
|
||||||
|
|
||||||
// The size in bytes of data stored in the texture
|
// The size in bytes of data stored in the texture
|
||||||
Size getSize() const { return _size; }
|
Size getSize() const { return _size; }
|
||||||
|
|
||||||
// Resize, unless auto mips mode would destroy all the sub mips
|
// Resize, unless auto mips mode would destroy all the sub mips
|
||||||
Size resize1D(uint16 width, uint16 numSamples);
|
Size resize1D(uint16 width, uint16 numSamples);
|
||||||
Size resize2D(uint16 width, uint16 height, uint16 numSamples);
|
Size resize2D(uint16 width, uint16 height, uint16 numSamples);
|
||||||
Size resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples);
|
Size resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples);
|
||||||
Size resizeCube(uint16 width, uint16 numSamples);
|
Size resizeCube(uint16 width, uint16 numSamples);
|
||||||
|
|
||||||
// Reformat, unless auto mips mode would destroy all the sub mips
|
// Reformat, unless auto mips mode would destroy all the sub mips
|
||||||
Size reformat(const Element& texelFormat);
|
Size reformat(const Element& texelFormat);
|
||||||
|
|
||||||
// Size and format
|
// Size and format
|
||||||
Type getType() const { return _type; }
|
Type getType() const { return _type; }
|
||||||
|
|
||||||
bool isColorRenderTarget() const;
|
bool isColorRenderTarget() const;
|
||||||
bool isDepthStencilRenderTarget() const;
|
bool isDepthStencilRenderTarget() const;
|
||||||
|
|
||||||
const Element& getTexelFormat() const { return _texelFormat; }
|
const Element& getTexelFormat() const { return _texelFormat; }
|
||||||
bool hasBorder() const { return false; }
|
bool hasBorder() const { return false; }
|
||||||
|
|
||||||
uint16 getWidth() const { return _width; }
|
uint16 getWidth() const { return _width; }
|
||||||
uint16 getHeight() const { return _height; }
|
uint16 getHeight() const { return _height; }
|
||||||
uint16 getDepth() const { return _depth; }
|
uint16 getDepth() const { return _depth; }
|
||||||
|
|
||||||
uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); }
|
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
|
// 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
|
// 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.
|
// as if the height was NUM_FACES time bigger.
|
||||||
static uint8 NUM_FACES_PER_TYPE[NUM_TYPES];
|
static uint8 NUM_FACES_PER_TYPE[NUM_TYPES];
|
||||||
uint8 getNumFaces() const { return NUM_FACES_PER_TYPE[getType()]; }
|
uint8 getNumFaces() const { return NUM_FACES_PER_TYPE[getType()]; }
|
||||||
|
|
||||||
uint32 getNumTexels() const { return _width * _height * _depth * getNumFaces(); }
|
uint32 getNumTexels() const { return _width * _height * _depth * getNumFaces(); }
|
||||||
|
|
||||||
uint16 getNumSlices() const { return _numSlices; }
|
uint16 getNumSlices() const { return _numSlices; }
|
||||||
uint16 getNumSamples() const { return _numSamples; }
|
uint16 getNumSamples() const { return _numSamples; }
|
||||||
|
|
||||||
|
|
||||||
// NumSamples can only have certain values based on the hw
|
// NumSamples can only have certain values based on the hw
|
||||||
static uint16 evalNumSamplesUsed(uint16 numSamplesTried);
|
static uint16 evalNumSamplesUsed(uint16 numSamplesTried);
|
||||||
|
|
||||||
// Mips size evaluation
|
// Mips size evaluation
|
||||||
|
|
||||||
// The number mips that a dimension could haves
|
// The number mips that a dimension could haves
|
||||||
// = 1 + log2(size)
|
// = 1 + log2(size)
|
||||||
static uint16 evalDimNumMips(uint16 size);
|
static uint16 evalDimNumMips(uint16 size);
|
||||||
|
|
||||||
// The number mips that the texture could have if all existed
|
// The number mips that the texture could have if all existed
|
||||||
// = 1 + log2(max(width, height, depth))
|
// = 1 + log2(max(width, height, depth))
|
||||||
uint16 evalNumMips() const;
|
uint16 evalNumMips() const;
|
||||||
|
|
||||||
// Eval the size that the mips level SHOULD have
|
// Eval the size that the mips level SHOULD have
|
||||||
// not the one stored in the Texture
|
// not the one stored in the Texture
|
||||||
uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); }
|
uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); }
|
||||||
uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); }
|
uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); }
|
||||||
uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); }
|
uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); }
|
||||||
|
|
||||||
// Size for each face of a mip at a particular level
|
// Size for each face of a mip at a particular level
|
||||||
uint32 evalMipFaceNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); }
|
uint32 evalMipFaceNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); }
|
||||||
uint32 evalMipFaceSize(uint16 level) const { return evalMipFaceNumTexels(level) * getTexelFormat().getSize(); }
|
uint32 evalMipFaceSize(uint16 level) const { return evalMipFaceNumTexels(level) * getTexelFormat().getSize(); }
|
||||||
|
|
||||||
// Total size for the mip
|
// Total size for the mip
|
||||||
uint32 evalMipNumTexels(uint16 level) const { return evalMipFaceNumTexels(level) * getNumFaces(); }
|
uint32 evalMipNumTexels(uint16 level) const { return evalMipFaceNumTexels(level) * getNumFaces(); }
|
||||||
uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); }
|
uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); }
|
||||||
|
|
||||||
uint32 evalStoredMipFaceSize(uint16 level, const Element& format) const { return evalMipFaceNumTexels(level) * format.getSize(); }
|
uint32 evalStoredMipFaceSize(uint16 level, const Element& format) const { return evalMipFaceNumTexels(level) * format.getSize(); }
|
||||||
uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); }
|
uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); }
|
||||||
|
|
||||||
uint32 evalTotalSize() const {
|
uint32 evalTotalSize() const {
|
||||||
uint32 size = 0;
|
uint32 size = 0;
|
||||||
uint16 minMipLevel = 0;
|
uint16 minMipLevel = 0;
|
||||||
uint16 maxMipLevel = maxMip();
|
uint16 maxMipLevel = maxMip();
|
||||||
for (uint16 l = minMipLevel; l <= maxMipLevel; l++) {
|
for (uint16 l = minMipLevel; l <= maxMipLevel; l++) {
|
||||||
size += evalMipSize(l);
|
size += evalMipSize(l);
|
||||||
}
|
}
|
||||||
return size * getNumSlices();
|
return size * getNumSlices();
|
||||||
}
|
}
|
||||||
|
|
||||||
// max mip is in the range [ 1 if no sub mips, log2(max(width, height, depth))]
|
// 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
|
// if autoGenerateMip is on => will provide the maxMIp level specified
|
||||||
// else provide the deepest mip level provided through assignMip
|
// else provide the deepest mip level provided through assignMip
|
||||||
uint16 maxMip() const;
|
uint16 maxMip() const;
|
||||||
|
|
||||||
// Generate the mips automatically
|
// Generate the mips automatically
|
||||||
// But the sysmem version is not available
|
// But the sysmem version is not available
|
||||||
// Only works for the standard formats
|
// Only works for the standard formats
|
||||||
// Specify the maximum Mip level available
|
// Specify the maximum Mip level available
|
||||||
// 0 is the default one
|
// 0 is the default one
|
||||||
// 1 is the first level
|
// 1 is the first level
|
||||||
// ...
|
// ...
|
||||||
// nbMips - 1 is the last mip level
|
// nbMips - 1 is the last mip level
|
||||||
//
|
//
|
||||||
// If -1 then all the mips are generated
|
// If -1 then all the mips are generated
|
||||||
//
|
//
|
||||||
// Return the totalnumber of mips that will be available
|
// Return the totalnumber of mips that will be available
|
||||||
uint16 autoGenerateMips(uint16 maxMip);
|
uint16 autoGenerateMips(uint16 maxMip);
|
||||||
bool isAutogenerateMips() const { return _autoGenerateMips; }
|
bool isAutogenerateMips() const { return _autoGenerateMips; }
|
||||||
|
|
||||||
// Managing Storage and mips
|
// Managing Storage and mips
|
||||||
|
|
||||||
// Manually allocate the mips down until the specified maxMip
|
// Manually allocate the mips down until the specified maxMip
|
||||||
// this is just allocating the sysmem version of it
|
// this is just allocating the sysmem version of it
|
||||||
// in case autoGen is on, this doesn't allocate
|
// in case autoGen is on, this doesn't allocate
|
||||||
// Explicitely assign mip data for a certain level
|
// Explicitely assign mip data for a certain level
|
||||||
// If Bytes is NULL then simply allocate the space so mip sysmem can be accessed
|
// 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);
|
bool assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||||
bool assignStoredMipFace(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face);
|
bool assignStoredMipFace(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face);
|
||||||
|
|
||||||
// Access the the sub mips
|
// Access the the sub mips
|
||||||
bool isStoredMipFaceAvailable(uint16 level, uint8 face = 0) const { return _storage->isMipAvailable(level, face); }
|
bool isStoredMipFaceAvailable(uint16 level, uint8 face = 0) const { return _storage->isMipAvailable(level, face); }
|
||||||
const PixelsPointer accessStoredMipFace(uint16 level, uint8 face = 0) const { return _storage->getMipFace(level, face); }
|
const PixelsPointer accessStoredMipFace(uint16 level, uint8 face = 0) const { return _storage->getMipFace(level, face); }
|
||||||
|
|
||||||
// access sizes for the stored mips
|
// access sizes for the stored mips
|
||||||
uint16 getStoredMipWidth(uint16 level) const;
|
uint16 getStoredMipWidth(uint16 level) const;
|
||||||
uint16 getStoredMipHeight(uint16 level) const;
|
uint16 getStoredMipHeight(uint16 level) const;
|
||||||
uint16 getStoredMipDepth(uint16 level) const;
|
uint16 getStoredMipDepth(uint16 level) const;
|
||||||
uint32 getStoredMipNumTexels(uint16 level) const;
|
uint32 getStoredMipNumTexels(uint16 level) const;
|
||||||
uint32 getStoredMipSize(uint16 level) const;
|
uint32 getStoredMipSize(uint16 level) const;
|
||||||
|
|
||||||
bool isDefined() const { return _defined; }
|
bool isDefined() const { return _defined; }
|
||||||
|
|
||||||
// For Cube Texture, it's possible to generate the irradiance spherical harmonics and make them availalbe with the texture
|
// For Cube Texture, it's possible to generate the irradiance spherical harmonics and make them availalbe with the texture
|
||||||
bool generateIrradiance();
|
bool generateIrradiance();
|
||||||
const SHPointer& getIrradiance(uint16 slice = 0) const { return _irradiance; }
|
const SHPointer& getIrradiance(uint16 slice = 0) const { return _irradiance; }
|
||||||
bool isIrradianceValid() const { return _isIrradianceValid; }
|
bool isIrradianceValid() const { return _isIrradianceValid; }
|
||||||
|
|
||||||
// Own sampler
|
// Own sampler
|
||||||
void setSampler(const Sampler& sampler);
|
void setSampler(const Sampler& sampler);
|
||||||
const Sampler& getSampler() const { return _sampler; }
|
const Sampler& getSampler() const { return _sampler; }
|
||||||
Stamp getSamplerStamp() const { return _samplerStamp; }
|
Stamp getSamplerStamp() const { return _samplerStamp; }
|
||||||
|
|
||||||
// Only callable by the Backend
|
// Only callable by the Backend
|
||||||
void notifyMipFaceGPULoaded(uint16 level, uint8 face) const { return _storage->notifyMipFaceGPULoaded(level, face); }
|
void notifyMipFaceGPULoaded(uint16 level, uint8 face) const { return _storage->notifyMipFaceGPULoaded(level, face); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr< Storage > _storage;
|
std::unique_ptr< Storage > _storage;
|
||||||
|
|
||||||
Stamp _stamp = 0;
|
Stamp _stamp = 0;
|
||||||
|
|
||||||
Sampler _sampler;
|
Sampler _sampler;
|
||||||
Stamp _samplerStamp;
|
Stamp _samplerStamp;
|
||||||
|
|
||||||
uint32 _size = 0;
|
uint32 _size = 0;
|
||||||
Element _texelFormat;
|
Element _texelFormat;
|
||||||
|
|
||||||
uint16 _width = 1;
|
uint16 _width = 1;
|
||||||
uint16 _height = 1;
|
uint16 _height = 1;
|
||||||
uint16 _depth = 1;
|
uint16 _depth = 1;
|
||||||
|
|
||||||
uint16 _numSamples = 1;
|
uint16 _numSamples = 1;
|
||||||
uint16 _numSlices = 1;
|
uint16 _numSlices = 1;
|
||||||
|
|
||||||
uint16 _maxMip = 0;
|
uint16 _maxMip = 0;
|
||||||
|
|
||||||
Type _type = TEX_1D;
|
Type _type = TEX_1D;
|
||||||
|
|
||||||
SHPointer _irradiance;
|
SHPointer _irradiance;
|
||||||
bool _autoGenerateMips = false;
|
bool _autoGenerateMips = false;
|
||||||
bool _isIrradianceValid = false;
|
bool _isIrradianceValid = false;
|
||||||
bool _defined = 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);
|
static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler);
|
||||||
|
|
||||||
Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices);
|
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.
|
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||||
mutable GPUObject* _gpuObject = NULL;
|
mutable GPUObject* _gpuObject = NULL;
|
||||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||||
GPUObject* getGPUObject() const { return _gpuObject; }
|
GPUObject* getGPUObject() const { return _gpuObject; }
|
||||||
|
|
||||||
friend class Backend;
|
friend class Backend;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Texture> TexturePointer;
|
typedef std::shared_ptr<Texture> TexturePointer;
|
||||||
typedef std::vector< TexturePointer > Textures;
|
typedef std::vector< TexturePointer > Textures;
|
||||||
|
|
||||||
|
|
||||||
// TODO: For now TextureView works with Buffer as a place holder for the Texture.
|
// 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
|
// The overall logic should be about the same except that the Texture will be a real GL Texture under the hood
|
||||||
class TextureView {
|
class TextureView {
|
||||||
public:
|
public:
|
||||||
typedef Resource::Size Size;
|
typedef Resource::Size Size;
|
||||||
|
|
||||||
TexturePointer _texture = TexturePointer(NULL);
|
TexturePointer _texture = TexturePointer(NULL);
|
||||||
uint16 _subresource = 0;
|
uint16 _subresource = 0;
|
||||||
Element _element = Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
|
Element _element = Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
|
||||||
|
|
||||||
TextureView() {};
|
TextureView() {};
|
||||||
|
|
||||||
TextureView(const Element& element) :
|
TextureView(const Element& element) :
|
||||||
_element(element)
|
_element(element)
|
||||||
{};
|
{};
|
||||||
|
|
||||||
// create the TextureView and own the Texture
|
// create the TextureView and own the Texture
|
||||||
TextureView(Texture* newTexture, const Element& element) :
|
TextureView(Texture* newTexture, const Element& element) :
|
||||||
_texture(newTexture),
|
_texture(newTexture),
|
||||||
_subresource(0),
|
_subresource(0),
|
||||||
_element(element)
|
_element(element)
|
||||||
{};
|
{};
|
||||||
TextureView(const TexturePointer& texture, uint16 subresource, const Element& element) :
|
TextureView(const TexturePointer& texture, uint16 subresource, const Element& element) :
|
||||||
_texture(texture),
|
_texture(texture),
|
||||||
_subresource(subresource),
|
_subresource(subresource),
|
||||||
_element(element)
|
_element(element)
|
||||||
{};
|
{};
|
||||||
|
|
||||||
TextureView(const TexturePointer& texture, uint16 subresource) :
|
TextureView(const TexturePointer& texture, uint16 subresource) :
|
||||||
_texture(texture),
|
_texture(texture),
|
||||||
_subresource(subresource)
|
_subresource(subresource)
|
||||||
{};
|
{};
|
||||||
|
|
||||||
~TextureView() {}
|
~TextureView() {}
|
||||||
TextureView(const TextureView& view) = default;
|
TextureView(const TextureView& view) = default;
|
||||||
TextureView& operator=(const TextureView& view) = default;
|
TextureView& operator=(const TextureView& view) = default;
|
||||||
|
|
||||||
explicit operator bool() const { return bool(_texture); }
|
explicit operator bool() const { return bool(_texture); }
|
||||||
bool operator !() const { return (!_texture); }
|
bool operator !() const { return (!_texture); }
|
||||||
|
|
||||||
bool isValid() const { return bool(_texture); }
|
bool isValid() const { return bool(_texture); }
|
||||||
};
|
};
|
||||||
typedef std::vector<TextureView> TextureViews;
|
typedef std::vector<TextureView> TextureViews;
|
||||||
|
|
||||||
// TextureSource is the bridge between a URL or a a way to produce an image and the final gpu::Texture that will be used to render it.
|
// TextureSource is the bridge between a URL or a a way to produce an image and the final gpu::Texture that will be used to render it.
|
||||||
// It provides the mechanism to create a texture using a customizable TextureLoader
|
// It provides the mechanism to create a texture using a customizable TextureLoader
|
||||||
class TextureSource {
|
class TextureSource {
|
||||||
|
@ -463,9 +463,9 @@ protected:
|
||||||
gpu::TexturePointer _gpuTexture;
|
gpu::TexturePointer _gpuTexture;
|
||||||
QUrl _imageUrl;
|
QUrl _imageUrl;
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr< TextureSource > TextureSourcePointer;
|
typedef std::shared_ptr< TextureSource > TextureSourcePointer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,143 +1,143 @@
|
||||||
<!
|
<!
|
||||||
// gpu/TransformState.slh
|
// gpu/TransformState.slh
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 2/10/15.
|
// Created by Sam Gateau on 2/10/15.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
!>
|
!>
|
||||||
<@if not GPU_TRANSFORM_STATE_SLH@>
|
<@if not GPU_TRANSFORM_STATE_SLH@>
|
||||||
<@def GPU_TRANSFORM_STATE_SLH@>
|
<@def GPU_TRANSFORM_STATE_SLH@>
|
||||||
|
|
||||||
<@func declareStandardTransform()@>
|
<@func declareStandardTransform()@>
|
||||||
struct TransformObject {
|
struct TransformObject {
|
||||||
mat4 _model;
|
mat4 _model;
|
||||||
mat4 _modelInverse;
|
mat4 _modelInverse;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TransformCamera {
|
struct TransformCamera {
|
||||||
mat4 _view;
|
mat4 _view;
|
||||||
mat4 _viewInverse;
|
mat4 _viewInverse;
|
||||||
mat4 _projectionViewUntranslated;
|
mat4 _projectionViewUntranslated;
|
||||||
mat4 _projection;
|
mat4 _projection;
|
||||||
mat4 _projectionInverse;
|
mat4 _projectionInverse;
|
||||||
vec4 _viewport;
|
vec4 _viewport;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140) uniform transformObjectBuffer {
|
layout(std140) uniform transformObjectBuffer {
|
||||||
TransformObject _object;
|
TransformObject _object;
|
||||||
};
|
};
|
||||||
TransformObject getTransformObject() {
|
TransformObject getTransformObject() {
|
||||||
return _object;
|
return _object;
|
||||||
}
|
}
|
||||||
|
|
||||||
layout(std140) uniform transformCameraBuffer {
|
layout(std140) uniform transformCameraBuffer {
|
||||||
TransformCamera _camera;
|
TransformCamera _camera;
|
||||||
};
|
};
|
||||||
TransformCamera getTransformCamera() {
|
TransformCamera getTransformCamera() {
|
||||||
return _camera;
|
return _camera;
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformCameraViewport(cameraTransform, viewport)@>
|
<@func transformCameraViewport(cameraTransform, viewport)@>
|
||||||
<$viewport$> = <$cameraTransform$>._viewport;
|
<$viewport$> = <$cameraTransform$>._viewport;
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformModelToClipPos(cameraTransform, objectTransform, modelPos, clipPos)@>
|
<@func transformModelToClipPos(cameraTransform, objectTransform, modelPos, clipPos)@>
|
||||||
<!// Equivalent to the following but hoppefully a tad more accurate
|
<!// Equivalent to the following but hoppefully a tad more accurate
|
||||||
//return camera._projection * camera._view * object._model * pos; !>
|
//return camera._projection * camera._view * object._model * pos; !>
|
||||||
{ // transformModelToClipPos
|
{ // transformModelToClipPos
|
||||||
vec4 _eyepos = (<$objectTransform$>._model * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
vec4 _eyepos = (<$objectTransform$>._model * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
||||||
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformInstancedModelToClipPos(cameraTransform, objectTransform, modelPos, clipPos)@>
|
<@func transformInstancedModelToClipPos(cameraTransform, objectTransform, modelPos, clipPos)@>
|
||||||
<!// Equivalent to the following but hoppefully a tad more accurate
|
<!// Equivalent to the following but hoppefully a tad more accurate
|
||||||
//return camera._projection * camera._view * object._model * pos; !>
|
//return camera._projection * camera._view * object._model * pos; !>
|
||||||
{ // transformModelToClipPos
|
{ // transformModelToClipPos
|
||||||
vec4 _eyepos = (inInstanceTransform * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
vec4 _eyepos = (inInstanceTransform * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
||||||
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func $transformModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
<@func $transformModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
||||||
<!// Equivalent to the following but hoppefully a tad more accurate
|
<!// Equivalent to the following but hoppefully a tad more accurate
|
||||||
//return camera._projection * camera._view * object._model * pos; !>
|
//return camera._projection * camera._view * object._model * pos; !>
|
||||||
{ // transformModelToClipPos
|
{ // transformModelToClipPos
|
||||||
vec4 _worldpos = (<$objectTransform$>._model * <$modelPos$>);
|
vec4 _worldpos = (<$objectTransform$>._model * <$modelPos$>);
|
||||||
<$eyePos$> = (<$cameraTransform$>._view * _worldpos);
|
<$eyePos$> = (<$cameraTransform$>._view * _worldpos);
|
||||||
vec4 _eyepos =(<$objectTransform$>._model * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
vec4 _eyepos =(<$objectTransform$>._model * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
||||||
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
||||||
// <$eyePos$> = (<$cameraTransform$>._projectionInverse * <$clipPos$>);
|
// <$eyePos$> = (<$cameraTransform$>._projectionInverse * <$clipPos$>);
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func $transformInstancedModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
<@func $transformInstancedModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
||||||
<!// Equivalent to the following but hoppefully a tad more accurate
|
<!// Equivalent to the following but hoppefully a tad more accurate
|
||||||
//return camera._projection * camera._view * object._model * pos; !>
|
//return camera._projection * camera._view * object._model * pos; !>
|
||||||
{ // transformModelToClipPos
|
{ // transformModelToClipPos
|
||||||
vec4 _worldpos = (inInstanceTransform * <$modelPos$>);
|
vec4 _worldpos = (inInstanceTransform * <$modelPos$>);
|
||||||
<$eyePos$> = (<$cameraTransform$>._view * _worldpos);
|
<$eyePos$> = (<$cameraTransform$>._view * _worldpos);
|
||||||
vec4 _eyepos =(inInstanceTransform * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
vec4 _eyepos =(inInstanceTransform * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
||||||
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
||||||
// <$eyePos$> = (<$cameraTransform$>._projectionInverse * <$clipPos$>);
|
// <$eyePos$> = (<$cameraTransform$>._projectionInverse * <$clipPos$>);
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
|
||||||
<@func transformModelToWorldPos(objectTransform, modelPos, worldPos)@>
|
<@func transformModelToWorldPos(objectTransform, modelPos, worldPos)@>
|
||||||
{ // transformModelToWorldPos
|
{ // transformModelToWorldPos
|
||||||
<$worldPos$> = (<$objectTransform$>._model * <$modelPos$>);
|
<$worldPos$> = (<$objectTransform$>._model * <$modelPos$>);
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformInstancedModelToWorldPos(objectTransform, modelPos, worldPos)@>
|
<@func transformInstancedModelToWorldPos(objectTransform, modelPos, worldPos)@>
|
||||||
{ // transformModelToWorldPos
|
{ // transformModelToWorldPos
|
||||||
<$worldPos$> = (inInstanceTransform * <$modelPos$>);
|
<$worldPos$> = (inInstanceTransform * <$modelPos$>);
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
|
<@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
|
||||||
{ // transformModelToEyeDir
|
{ // transformModelToEyeDir
|
||||||
vec3 mr0 = vec3(<$objectTransform$>._modelInverse[0].x, <$objectTransform$>._modelInverse[1].x, <$objectTransform$>._modelInverse[2].x);
|
vec3 mr0 = vec3(<$objectTransform$>._modelInverse[0].x, <$objectTransform$>._modelInverse[1].x, <$objectTransform$>._modelInverse[2].x);
|
||||||
vec3 mr1 = vec3(<$objectTransform$>._modelInverse[0].y, <$objectTransform$>._modelInverse[1].y, <$objectTransform$>._modelInverse[2].y);
|
vec3 mr1 = vec3(<$objectTransform$>._modelInverse[0].y, <$objectTransform$>._modelInverse[1].y, <$objectTransform$>._modelInverse[2].y);
|
||||||
vec3 mr2 = vec3(<$objectTransform$>._modelInverse[0].z, <$objectTransform$>._modelInverse[1].z, <$objectTransform$>._modelInverse[2].z);
|
vec3 mr2 = vec3(<$objectTransform$>._modelInverse[0].z, <$objectTransform$>._modelInverse[1].z, <$objectTransform$>._modelInverse[2].z);
|
||||||
|
|
||||||
vec3 mvc0 = vec3(dot(<$cameraTransform$>._viewInverse[0].xyz, mr0), dot(<$cameraTransform$>._viewInverse[0].xyz, mr1), dot(<$cameraTransform$>._viewInverse[0].xyz, mr2));
|
vec3 mvc0 = vec3(dot(<$cameraTransform$>._viewInverse[0].xyz, mr0), dot(<$cameraTransform$>._viewInverse[0].xyz, mr1), dot(<$cameraTransform$>._viewInverse[0].xyz, mr2));
|
||||||
vec3 mvc1 = vec3(dot(<$cameraTransform$>._viewInverse[1].xyz, mr0), dot(<$cameraTransform$>._viewInverse[1].xyz, mr1), dot(<$cameraTransform$>._viewInverse[1].xyz, mr2));
|
vec3 mvc1 = vec3(dot(<$cameraTransform$>._viewInverse[1].xyz, mr0), dot(<$cameraTransform$>._viewInverse[1].xyz, mr1), dot(<$cameraTransform$>._viewInverse[1].xyz, mr2));
|
||||||
vec3 mvc2 = vec3(dot(<$cameraTransform$>._viewInverse[2].xyz, mr0), dot(<$cameraTransform$>._viewInverse[2].xyz, mr1), dot(<$cameraTransform$>._viewInverse[2].xyz, mr2));
|
vec3 mvc2 = vec3(dot(<$cameraTransform$>._viewInverse[2].xyz, mr0), dot(<$cameraTransform$>._viewInverse[2].xyz, mr1), dot(<$cameraTransform$>._viewInverse[2].xyz, mr2));
|
||||||
|
|
||||||
<$eyeDir$> = vec3(dot(mvc0, <$modelDir$>), dot(mvc1, <$modelDir$>), dot(mvc2, <$modelDir$>));
|
<$eyeDir$> = vec3(dot(mvc0, <$modelDir$>), dot(mvc1, <$modelDir$>), dot(mvc2, <$modelDir$>));
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformInstancedModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
|
<@func transformInstancedModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
|
||||||
{ // transformModelToEyeDir
|
{ // transformModelToEyeDir
|
||||||
mat4 modelInverse = inverse(inInstanceTransform);
|
mat4 modelInverse = inverse(inInstanceTransform);
|
||||||
vec3 mr0 = vec3(modelInverse[0].x, modelInverse[1].x, modelInverse[2].x);
|
vec3 mr0 = vec3(modelInverse[0].x, modelInverse[1].x, modelInverse[2].x);
|
||||||
vec3 mr1 = vec3(modelInverse[0].y, modelInverse[1].y, modelInverse[2].y);
|
vec3 mr1 = vec3(modelInverse[0].y, modelInverse[1].y, modelInverse[2].y);
|
||||||
vec3 mr2 = vec3(modelInverse[0].z, modelInverse[1].z, modelInverse[2].z);
|
vec3 mr2 = vec3(modelInverse[0].z, modelInverse[1].z, modelInverse[2].z);
|
||||||
|
|
||||||
vec3 mvc0 = vec3(dot(<$cameraTransform$>._viewInverse[0].xyz, mr0), dot(<$cameraTransform$>._viewInverse[0].xyz, mr1), dot(<$cameraTransform$>._viewInverse[0].xyz, mr2));
|
vec3 mvc0 = vec3(dot(<$cameraTransform$>._viewInverse[0].xyz, mr0), dot(<$cameraTransform$>._viewInverse[0].xyz, mr1), dot(<$cameraTransform$>._viewInverse[0].xyz, mr2));
|
||||||
vec3 mvc1 = vec3(dot(<$cameraTransform$>._viewInverse[1].xyz, mr0), dot(<$cameraTransform$>._viewInverse[1].xyz, mr1), dot(<$cameraTransform$>._viewInverse[1].xyz, mr2));
|
vec3 mvc1 = vec3(dot(<$cameraTransform$>._viewInverse[1].xyz, mr0), dot(<$cameraTransform$>._viewInverse[1].xyz, mr1), dot(<$cameraTransform$>._viewInverse[1].xyz, mr2));
|
||||||
vec3 mvc2 = vec3(dot(<$cameraTransform$>._viewInverse[2].xyz, mr0), dot(<$cameraTransform$>._viewInverse[2].xyz, mr1), dot(<$cameraTransform$>._viewInverse[2].xyz, mr2));
|
vec3 mvc2 = vec3(dot(<$cameraTransform$>._viewInverse[2].xyz, mr0), dot(<$cameraTransform$>._viewInverse[2].xyz, mr1), dot(<$cameraTransform$>._viewInverse[2].xyz, mr2));
|
||||||
|
|
||||||
<$eyeDir$> = vec3(dot(mvc0, <$modelDir$>), dot(mvc1, <$modelDir$>), dot(mvc2, <$modelDir$>));
|
<$eyeDir$> = vec3(dot(mvc0, <$modelDir$>), dot(mvc1, <$modelDir$>), dot(mvc2, <$modelDir$>));
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformEyeToWorldDir(cameraTransform, eyeDir, worldDir)@>
|
<@func transformEyeToWorldDir(cameraTransform, eyeDir, worldDir)@>
|
||||||
{ // transformEyeToWorldDir
|
{ // transformEyeToWorldDir
|
||||||
<$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0));
|
<$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0));
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformClipToEyeDir(cameraTransform, clipPos, eyeDir)@>
|
<@func transformClipToEyeDir(cameraTransform, clipPos, eyeDir)@>
|
||||||
{ // transformClipToEyeDir
|
{ // transformClipToEyeDir
|
||||||
<$eyeDir$> = vec3(<$cameraTransform$>._projectionInverse * vec4(<$clipPos$>.xyz, 1.0));
|
<$eyeDir$> = vec3(<$cameraTransform$>._projectionInverse * vec4(<$clipPos$>.xyz, 1.0));
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -1,245 +1,245 @@
|
||||||
<!
|
<!
|
||||||
// Atmospheric.slh
|
// Atmospheric.slh
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 3/9/15.
|
// Created by Sam Gateau on 3/9/15.
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
!>
|
!>
|
||||||
<@if not MODEL_ATMOSPHERE_SLH@>
|
<@if not MODEL_ATMOSPHERE_SLH@>
|
||||||
<@def MODEL_ATMOSPHERE_SLH@>
|
<@def MODEL_ATMOSPHERE_SLH@>
|
||||||
|
|
||||||
<!
|
<!
|
||||||
// Code is a modified version of:
|
// Code is a modified version of:
|
||||||
// http://http.developer.nvidia.com/GPUGems/gpugems_app01.html
|
// http://http.developer.nvidia.com/GPUGems/gpugems_app01.html
|
||||||
// Atmospheric scattering fragment shader
|
// Atmospheric scattering fragment shader
|
||||||
//
|
//
|
||||||
// Author: Sean O'Neil
|
// Author: Sean O'Neil
|
||||||
//
|
//
|
||||||
// Copyright (c) 2004 Sean O'Neil
|
// Copyright (c) 2004 Sean O'Neil
|
||||||
|
|
||||||
//
|
//
|
||||||
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
|
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
|
||||||
//
|
//
|
||||||
// NVIDIA Statement on the Software
|
// NVIDIA Statement on the Software
|
||||||
//
|
//
|
||||||
// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are
|
// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are
|
||||||
// detailed.
|
// detailed.
|
||||||
//
|
//
|
||||||
// No Warranty
|
// No Warranty
|
||||||
//
|
//
|
||||||
// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL
|
// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL
|
||||||
// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
|
// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
//
|
//
|
||||||
// Limitation of Liability
|
// Limitation of Liability
|
||||||
//
|
//
|
||||||
// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR
|
// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR
|
||||||
// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT
|
// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT
|
||||||
// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE
|
// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY
|
// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY
|
||||||
// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH
|
// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH
|
||||||
// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
||||||
//
|
//
|
||||||
!>
|
!>
|
||||||
|
|
||||||
struct Atmosphere {
|
struct Atmosphere {
|
||||||
vec4 _invWaveLength;
|
vec4 _invWaveLength;
|
||||||
vec4 _radiuses;
|
vec4 _radiuses;
|
||||||
vec4 _scales;
|
vec4 _scales;
|
||||||
vec4 _scatterings;
|
vec4 _scatterings;
|
||||||
vec4 _control;
|
vec4 _control;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int numSamples = 2;
|
const int numSamples = 2;
|
||||||
|
|
||||||
vec3 getAtmosphereInvWaveLength(Atmosphere a) { return a._invWaveLength.xyz; } // 1 / pow(wavelength, 4) for the red, green, and blue channels
|
vec3 getAtmosphereInvWaveLength(Atmosphere a) { return a._invWaveLength.xyz; } // 1 / pow(wavelength, 4) for the red, green, and blue channels
|
||||||
|
|
||||||
float getAtmosphereInnerRadius(Atmosphere a) { return a._radiuses.x; } // The inner (planetary) radius
|
float getAtmosphereInnerRadius(Atmosphere a) { return a._radiuses.x; } // The inner (planetary) radius
|
||||||
float getAtmosphereOuterRadius(Atmosphere a) { return a._radiuses.y; } // The outer (atmosphere) radius
|
float getAtmosphereOuterRadius(Atmosphere a) { return a._radiuses.y; } // The outer (atmosphere) radius
|
||||||
|
|
||||||
float getAtmosphereScale(Atmosphere a) { return a._scales.x; } // 1 / (outerRadius - innerRadius)
|
float getAtmosphereScale(Atmosphere a) { return a._scales.x; } // 1 / (outerRadius - innerRadius)
|
||||||
float getAtmosphereScaleDepth(Atmosphere a) { return a._scales.y; } // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
|
float getAtmosphereScaleDepth(Atmosphere a) { return a._scales.y; } // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
|
||||||
float getAtmosphereScaleOverScaleDepth(Atmosphere a) { return a._scales.z; } // scale / scaleDepth
|
float getAtmosphereScaleOverScaleDepth(Atmosphere a) { return a._scales.z; } // scale / scaleDepth
|
||||||
|
|
||||||
vec4 getAtmosphereScattering(Atmosphere a) { return a._scatterings; } // The full Mie and Rayleigh scattering coefficients
|
vec4 getAtmosphereScattering(Atmosphere a) { return a._scatterings; } // The full Mie and Rayleigh scattering coefficients
|
||||||
float getAtmosphereKrESun(Atmosphere a) { return a._scatterings.x; } // Kr * ESun
|
float getAtmosphereKrESun(Atmosphere a) { return a._scatterings.x; } // Kr * ESun
|
||||||
float getAtmosphereKmESun(Atmosphere a) { return a._scatterings.y; } // Km * ESun
|
float getAtmosphereKmESun(Atmosphere a) { return a._scatterings.y; } // Km * ESun
|
||||||
float getAtmosphereKr4PI(Atmosphere a) { return a._scatterings.z; } // Kr * 4 * PI
|
float getAtmosphereKr4PI(Atmosphere a) { return a._scatterings.z; } // Kr * 4 * PI
|
||||||
float getAtmosphereKm4PI(Atmosphere a) { return a._scatterings.w; } // Km * 4 * PI
|
float getAtmosphereKm4PI(Atmosphere a) { return a._scatterings.w; } // Km * 4 * PI
|
||||||
|
|
||||||
float getAtmosphereNumSamples(Atmosphere a) { return a._control.x; } // numSamples
|
float getAtmosphereNumSamples(Atmosphere a) { return a._control.x; } // numSamples
|
||||||
vec2 getAtmosphereGAndG2(Atmosphere a) { return a._control.yz; } // g and g2
|
vec2 getAtmosphereGAndG2(Atmosphere a) { return a._control.yz; } // g and g2
|
||||||
|
|
||||||
float atmosphereScale(float scaleDepth, float fCos)
|
float atmosphereScale(float scaleDepth, float fCos)
|
||||||
{
|
{
|
||||||
float x = 1.0 - fCos;
|
float x = 1.0 - fCos;
|
||||||
return scaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
return scaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 evalAtmosphereContribution(Atmosphere atmospheric, vec3 position, vec3 cameraPos, vec3 lightPos) {
|
vec4 evalAtmosphereContribution(Atmosphere atmospheric, vec3 position, vec3 cameraPos, vec3 lightPos) {
|
||||||
float fInnerRadius = getAtmosphereInnerRadius(atmospheric);
|
float fInnerRadius = getAtmosphereInnerRadius(atmospheric);
|
||||||
float fSamples = getAtmosphereNumSamples(atmospheric);
|
float fSamples = getAtmosphereNumSamples(atmospheric);
|
||||||
|
|
||||||
vec3 v3InvWavelength = getAtmosphereInvWaveLength(atmospheric);
|
vec3 v3InvWavelength = getAtmosphereInvWaveLength(atmospheric);
|
||||||
vec4 scatteringCoefs = getAtmosphereScattering(atmospheric);
|
vec4 scatteringCoefs = getAtmosphereScattering(atmospheric);
|
||||||
float fKrESun = scatteringCoefs.x;
|
float fKrESun = scatteringCoefs.x;
|
||||||
float fKmESun = scatteringCoefs.y;
|
float fKmESun = scatteringCoefs.y;
|
||||||
float fKr4PI = scatteringCoefs.z;
|
float fKr4PI = scatteringCoefs.z;
|
||||||
float fKm4PI = scatteringCoefs.w;
|
float fKm4PI = scatteringCoefs.w;
|
||||||
|
|
||||||
vec2 gAndg2 = getAtmosphereGAndG2(atmospheric);
|
vec2 gAndg2 = getAtmosphereGAndG2(atmospheric);
|
||||||
float g = gAndg2.x;
|
float g = gAndg2.x;
|
||||||
float g2 = gAndg2.y;
|
float g2 = gAndg2.y;
|
||||||
|
|
||||||
float fScale = getAtmosphereScale(atmospheric);
|
float fScale = getAtmosphereScale(atmospheric);
|
||||||
float fScaleDepth = getAtmosphereScaleDepth(atmospheric);
|
float fScaleDepth = getAtmosphereScaleDepth(atmospheric);
|
||||||
float fScaleOverScaleDepth = getAtmosphereScaleOverScaleDepth(atmospheric);
|
float fScaleOverScaleDepth = getAtmosphereScaleOverScaleDepth(atmospheric);
|
||||||
|
|
||||||
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
|
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
|
||||||
vec3 v3Pos = position;
|
vec3 v3Pos = position;
|
||||||
vec3 v3Ray = v3Pos - cameraPos;
|
vec3 v3Ray = v3Pos - cameraPos;
|
||||||
float fFar = length(v3Ray);
|
float fFar = length(v3Ray);
|
||||||
v3Ray /= fFar;
|
v3Ray /= fFar;
|
||||||
|
|
||||||
// Calculate the ray's starting position, then calculate its scattering offset
|
// Calculate the ray's starting position, then calculate its scattering offset
|
||||||
vec3 v3Start = cameraPos;
|
vec3 v3Start = cameraPos;
|
||||||
float fHeight = length(v3Start);
|
float fHeight = length(v3Start);
|
||||||
float fDepthStart = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
float fDepthStart = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||||
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
||||||
float fStartOffset = fDepthStart * atmosphereScale(fScaleDepth, fStartAngle);
|
float fStartOffset = fDepthStart * atmosphereScale(fScaleDepth, fStartAngle);
|
||||||
|
|
||||||
// Initialize the scattering loop variables
|
// Initialize the scattering loop variables
|
||||||
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
float fSampleLength = fFar / fSamples;
|
float fSampleLength = fFar / fSamples;
|
||||||
float fScaledLength = fSampleLength * fScale;
|
float fScaledLength = fSampleLength * fScale;
|
||||||
|
|
||||||
vec3 v3SampleRay = v3Ray * fSampleLength;
|
vec3 v3SampleRay = v3Ray * fSampleLength;
|
||||||
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
||||||
|
|
||||||
// Now loop through the sample rays
|
// Now loop through the sample rays
|
||||||
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
||||||
// int nSamples = numSamples;
|
// int nSamples = numSamples;
|
||||||
int nSamples = int(fSamples);
|
int nSamples = int(fSamples);
|
||||||
for(int i=0; i<nSamples; i++)
|
for(int i=0; i<nSamples; i++)
|
||||||
{
|
{
|
||||||
float fHeight = length(v3SamplePoint);
|
float fHeight = length(v3SamplePoint);
|
||||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||||
float fLightAngle = dot(lightPos, v3SamplePoint) / fHeight;
|
float fLightAngle = dot(lightPos, v3SamplePoint) / fHeight;
|
||||||
float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99;
|
float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99;
|
||||||
float fScatter = (fStartOffset + fDepth * (atmosphereScale(fScaleDepth, fLightAngle) - atmosphereScale(fScaleDepth, fCameraAngle)));
|
float fScatter = (fStartOffset + fDepth * (atmosphereScale(fScaleDepth, fLightAngle) - atmosphereScale(fScaleDepth, fCameraAngle)));
|
||||||
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
||||||
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
||||||
v3SamplePoint += v3SampleRay;
|
v3SamplePoint += v3SampleRay;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
||||||
vec3 secondaryFrontColor = v3FrontColor * fKmESun;
|
vec3 secondaryFrontColor = v3FrontColor * fKmESun;
|
||||||
vec3 frontColor = v3FrontColor * (v3InvWavelength * fKrESun);
|
vec3 frontColor = v3FrontColor * (v3InvWavelength * fKrESun);
|
||||||
vec3 v3Direction = cameraPos - v3Pos;
|
vec3 v3Direction = cameraPos - v3Pos;
|
||||||
|
|
||||||
float fCos = dot(lightPos, v3Direction) / length(v3Direction);
|
float fCos = dot(lightPos, v3Direction) / length(v3Direction);
|
||||||
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
||||||
vec4 finalColor;
|
vec4 finalColor;
|
||||||
|
|
||||||
finalColor.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
|
finalColor.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
|
||||||
finalColor.a = finalColor.b;
|
finalColor.a = finalColor.b;
|
||||||
finalColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2));
|
finalColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2));
|
||||||
|
|
||||||
return finalColor;
|
return finalColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
<@if GLPROFILE == PC_GL@>
|
<@if GLPROFILE == PC_GL@>
|
||||||
uniform atmosphereBuffer {
|
uniform atmosphereBuffer {
|
||||||
Atmosphere _atmosphere;
|
Atmosphere _atmosphere;
|
||||||
};
|
};
|
||||||
Atmosphere getAtmosphere() {
|
Atmosphere getAtmosphere() {
|
||||||
return _atmosphere;
|
return _atmosphere;
|
||||||
}
|
}
|
||||||
<@else@>
|
<@else@>
|
||||||
uniform vec4 atmosphereBuffer[9];
|
uniform vec4 atmosphereBuffer[9];
|
||||||
Atmosphere getAtmosphere() {
|
Atmosphere getAtmosphere() {
|
||||||
Atmosphere atmosphere;
|
Atmosphere atmosphere;
|
||||||
atmosphere._invWaveLength = atmosphereBuffer[0];
|
atmosphere._invWaveLength = atmosphereBuffer[0];
|
||||||
atmosphere._radiuses = atmosphereBuffer[1];
|
atmosphere._radiuses = atmosphereBuffer[1];
|
||||||
atmosphere._scales = atmosphereBuffer[2];
|
atmosphere._scales = atmosphereBuffer[2];
|
||||||
atmosphere._scatterings = atmosphereBuffer[3];
|
atmosphere._scatterings = atmosphereBuffer[3];
|
||||||
atmosphere._control = atmosphereBuffer[4];
|
atmosphere._control = atmosphereBuffer[4];
|
||||||
|
|
||||||
return atmosphere;
|
return atmosphere;
|
||||||
}
|
}
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
||||||
<!
|
<!
|
||||||
/*
|
/*
|
||||||
// uniform vec3 v3CameraPos; // The camera's current position
|
// uniform vec3 v3CameraPos; // The camera's current position
|
||||||
|
|
||||||
|
|
||||||
const int nSamples = 2;
|
const int nSamples = 2;
|
||||||
const float fSamples = 2.0;
|
const float fSamples = 2.0;
|
||||||
|
|
||||||
uniform vec3 v3LightPos;
|
uniform vec3 v3LightPos;
|
||||||
uniform float g;
|
uniform float g;
|
||||||
uniform float g2;
|
uniform float g2;
|
||||||
|
|
||||||
varying vec3 position;
|
varying vec3 position;
|
||||||
|
|
||||||
float scale(float fCos)
|
float scale(float fCos)
|
||||||
{
|
{
|
||||||
float x = 1.0 - fCos;
|
float x = 1.0 - fCos;
|
||||||
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void main (void)
|
void main (void)
|
||||||
{
|
{
|
||||||
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
|
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
|
||||||
vec3 v3Pos = position;
|
vec3 v3Pos = position;
|
||||||
vec3 v3Ray = v3Pos - v3CameraPos;
|
vec3 v3Ray = v3Pos - v3CameraPos;
|
||||||
float fFar = length(v3Ray);
|
float fFar = length(v3Ray);
|
||||||
v3Ray /= fFar;
|
v3Ray /= fFar;
|
||||||
|
|
||||||
// Calculate the ray's starting position, then calculate its scattering offset
|
// Calculate the ray's starting position, then calculate its scattering offset
|
||||||
vec3 v3Start = v3CameraPos;
|
vec3 v3Start = v3CameraPos;
|
||||||
float fHeight = length(v3Start);
|
float fHeight = length(v3Start);
|
||||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||||
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
||||||
float fStartOffset = fDepth * scale(fStartAngle);
|
float fStartOffset = fDepth * scale(fStartAngle);
|
||||||
|
|
||||||
// Initialize the scattering loop variables
|
// Initialize the scattering loop variables
|
||||||
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
float fSampleLength = fFar / fSamples;
|
float fSampleLength = fFar / fSamples;
|
||||||
float fScaledLength = fSampleLength * fScale;
|
float fScaledLength = fSampleLength * fScale;
|
||||||
vec3 v3SampleRay = v3Ray * fSampleLength;
|
vec3 v3SampleRay = v3Ray * fSampleLength;
|
||||||
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
||||||
|
|
||||||
// Now loop through the sample rays
|
// Now loop through the sample rays
|
||||||
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
||||||
for(int i=0; i<nSamples; i++)
|
for(int i=0; i<nSamples; i++)
|
||||||
{
|
{
|
||||||
float fHeight = length(v3SamplePoint);
|
float fHeight = length(v3SamplePoint);
|
||||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||||
float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
|
float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
|
||||||
float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99;
|
float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99;
|
||||||
float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle)));
|
float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle)));
|
||||||
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
||||||
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
||||||
v3SamplePoint += v3SampleRay;
|
v3SamplePoint += v3SampleRay;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
||||||
vec3 secondaryFrontColor = v3FrontColor * fKmESun;
|
vec3 secondaryFrontColor = v3FrontColor * fKmESun;
|
||||||
vec3 frontColor = v3FrontColor * (v3InvWavelength * fKrESun);
|
vec3 frontColor = v3FrontColor * (v3InvWavelength * fKrESun);
|
||||||
vec3 v3Direction = v3CameraPos - v3Pos;
|
vec3 v3Direction = v3CameraPos - v3Pos;
|
||||||
|
|
||||||
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
|
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
|
||||||
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
||||||
outFragColor.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
|
outFragColor.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
|
||||||
outFragColor.a = outFragColor.b;
|
outFragColor.a = outFragColor.b;
|
||||||
outFragColor.rgb = pow(outFragColor.rgb, vec3(1.0/2.2));
|
outFragColor.rgb = pow(outFragColor.rgb, vec3(1.0/2.2));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
!>
|
!>
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -77,13 +77,13 @@ public:
|
||||||
void setMaximumRadius(float radius);
|
void setMaximumRadius(float radius);
|
||||||
float getMaximumRadius() const { return getSchema()._attenuation.w; }
|
float getMaximumRadius() const { return getSchema()._attenuation.w; }
|
||||||
|
|
||||||
// Spot properties
|
// Spot properties
|
||||||
bool isSpot() const { return getType() == SPOT; }
|
bool isSpot() const { return getType() == SPOT; }
|
||||||
void setSpotAngle(float angle);
|
void setSpotAngle(float angle);
|
||||||
float getSpotAngle() const { return getSchema()._spot.z; }
|
float getSpotAngle() const { return getSchema()._spot.z; }
|
||||||
glm::vec2 getSpotAngleCosSin() const { return glm::vec2(getSchema()._spot.x, getSchema()._spot.y); }
|
glm::vec2 getSpotAngleCosSin() const { return glm::vec2(getSchema()._spot.x, getSchema()._spot.y); }
|
||||||
void setSpotExponent(float exponent);
|
void setSpotExponent(float exponent);
|
||||||
float getSpotExponent() const { return getSchema()._spot.w; }
|
float getSpotExponent() const { return getSchema()._spot.w; }
|
||||||
|
|
||||||
// For editing purpose, show the light volume contour.
|
// For editing purpose, show the light volume contour.
|
||||||
// Set to non 0 to show it, the value is used as the intensity of the contour color
|
// Set to non 0 to show it, the value is used as the intensity of the contour color
|
||||||
|
@ -100,20 +100,20 @@ public:
|
||||||
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) { _ambientSphere.assignPreset(preset); }
|
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) { _ambientSphere.assignPreset(preset); }
|
||||||
|
|
||||||
// Schema to access the attribute values of the light
|
// Schema to access the attribute values of the light
|
||||||
class Schema {
|
class Schema {
|
||||||
public:
|
public:
|
||||||
Vec4 _position{0.0f, 0.0f, 0.0f, 1.0f};
|
Vec4 _position{0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
Vec3 _direction{0.0f, 0.0f, -1.0f};
|
Vec3 _direction{0.0f, 0.0f, -1.0f};
|
||||||
float _ambientIntensity{0.0f};
|
float _ambientIntensity{0.0f};
|
||||||
Color _color{1.0f};
|
Color _color{1.0f};
|
||||||
float _intensity{1.0f};
|
float _intensity{1.0f};
|
||||||
Vec4 _attenuation{1.0f};
|
Vec4 _attenuation{1.0f};
|
||||||
Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f};
|
Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
Vec4 _shadow{0.0f};
|
Vec4 _shadow{0.0f};
|
||||||
|
|
||||||
Vec4 _control{0.0f, 0.0f, 0.0f, 0.0f};
|
Vec4 _control{0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
Schema() {}
|
Schema() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; }
|
const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; }
|
||||||
|
|
|
@ -1,93 +1,93 @@
|
||||||
<!
|
<!
|
||||||
// Light.slh
|
// Light.slh
|
||||||
// fragment shader
|
// fragment shader
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 1/25/14.
|
// Created by Sam Gateau on 1/25/14.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
!>
|
!>
|
||||||
<@if not MODEL_LIGHT_SLH@>
|
<@if not MODEL_LIGHT_SLH@>
|
||||||
<@def MODEL_LIGHT_SLH@>
|
<@def MODEL_LIGHT_SLH@>
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
vec4 _position;
|
vec4 _position;
|
||||||
vec4 _direction;
|
vec4 _direction;
|
||||||
vec4 _color;
|
vec4 _color;
|
||||||
vec4 _attenuation;
|
vec4 _attenuation;
|
||||||
vec4 _spot;
|
vec4 _spot;
|
||||||
|
|
||||||
vec4 _shadow;
|
vec4 _shadow;
|
||||||
vec4 _control;
|
vec4 _control;
|
||||||
};
|
};
|
||||||
|
|
||||||
vec3 getLightPosition(Light l) { return l._position.xyz; }
|
vec3 getLightPosition(Light l) { return l._position.xyz; }
|
||||||
vec3 getLightDirection(Light l) { return l._direction.xyz; } // direction is -Z axis
|
vec3 getLightDirection(Light l) { return l._direction.xyz; } // direction is -Z axis
|
||||||
|
|
||||||
vec3 getLightColor(Light l) { return l._color.rgb; }
|
vec3 getLightColor(Light l) { return l._color.rgb; }
|
||||||
float getLightIntensity(Light l) { return l._color.w; }
|
float getLightIntensity(Light l) { return l._color.w; }
|
||||||
float getLightAmbientIntensity(Light l) { return l._direction.w; }
|
float getLightAmbientIntensity(Light l) { return l._direction.w; }
|
||||||
|
|
||||||
float evalLightAttenuation(Light l, float r) {
|
float evalLightAttenuation(Light l, float r) {
|
||||||
float d = max(r - l._attenuation.x, 0.0);
|
float d = max(r - l._attenuation.x, 0.0);
|
||||||
float denom = d * l._attenuation.y + 1.0;
|
float denom = d * l._attenuation.y + 1.0;
|
||||||
float attenuation = 1.0 / (denom * denom);
|
float attenuation = 1.0 / (denom * denom);
|
||||||
return max((attenuation - l._attenuation.z)/(1.0 - l._attenuation.z), 0.0);
|
return max((attenuation - l._attenuation.z)/(1.0 - l._attenuation.z), 0.0);
|
||||||
// return clamp(1.0/(l._attenuation.x + l._attenuation.y * r + l._attenuation.z * r * r), 0.0, 1.0);
|
// return clamp(1.0/(l._attenuation.x + l._attenuation.y * r + l._attenuation.z * r * r), 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getLightSpotAngleCos(Light l) {
|
float getLightSpotAngleCos(Light l) {
|
||||||
return l._spot.x;
|
return l._spot.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 getLightSpotOutsideNormal2(Light l) {
|
vec2 getLightSpotOutsideNormal2(Light l) {
|
||||||
return vec2(-l._spot.y, l._spot.x);
|
return vec2(-l._spot.y, l._spot.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
float evalLightSpotAttenuation(Light l, float cosA) {
|
float evalLightSpotAttenuation(Light l, float cosA) {
|
||||||
return pow(cosA, l._spot.w);
|
return pow(cosA, l._spot.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getLightSquareRadius(Light l) {
|
float getLightSquareRadius(Light l) {
|
||||||
return l._attenuation.w * l._attenuation.w;
|
return l._attenuation.w * l._attenuation.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getLightRadius(Light l) {
|
float getLightRadius(Light l) {
|
||||||
return l._attenuation.w;
|
return l._attenuation.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getLightAttenuationCutoff(Light l) {
|
float getLightAttenuationCutoff(Light l) {
|
||||||
return l._attenuation.z;
|
return l._attenuation.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getLightShowContour(Light l) {
|
float getLightShowContour(Light l) {
|
||||||
return l._control.w;
|
return l._control.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
<@if GPU_FEATURE_PROFILE == GPU_CORE @>
|
<@if GPU_FEATURE_PROFILE == GPU_CORE @>
|
||||||
uniform lightBuffer {
|
uniform lightBuffer {
|
||||||
Light light;
|
Light light;
|
||||||
};
|
};
|
||||||
Light getLight() {
|
Light getLight() {
|
||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
<@else@>
|
<@else@>
|
||||||
uniform vec4 lightBuffer[7];
|
uniform vec4 lightBuffer[7];
|
||||||
Light getLight() {
|
Light getLight() {
|
||||||
Light light;
|
Light light;
|
||||||
light._position = lightBuffer[0];
|
light._position = lightBuffer[0];
|
||||||
light._direction = lightBuffer[1];
|
light._direction = lightBuffer[1];
|
||||||
light._color = lightBuffer[2];
|
light._color = lightBuffer[2];
|
||||||
light._attenuation = lightBuffer[3];
|
light._attenuation = lightBuffer[3];
|
||||||
light._spot = lightBuffer[4];
|
light._spot = lightBuffer[4];
|
||||||
light._shadow = lightBuffer[5];
|
light._shadow = lightBuffer[5];
|
||||||
light._control = lightBuffer[6];
|
light._control = lightBuffer[6];
|
||||||
|
|
||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -1,66 +1,66 @@
|
||||||
<!
|
<!
|
||||||
// Material.slh
|
// Material.slh
|
||||||
// fragment shader
|
// fragment shader
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 12/16/14.
|
// Created by Sam Gateau on 12/16/14.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
!>
|
!>
|
||||||
<@if not MODEL_MATERIAL_SLH@>
|
<@if not MODEL_MATERIAL_SLH@>
|
||||||
<@def MODEL_MATERIAL_SLH@>
|
<@def MODEL_MATERIAL_SLH@>
|
||||||
|
|
||||||
struct Material {
|
struct Material {
|
||||||
vec4 _diffuse;
|
vec4 _diffuse;
|
||||||
vec4 _specular;
|
vec4 _specular;
|
||||||
vec4 _emissive;
|
vec4 _emissive;
|
||||||
vec4 _spare;
|
vec4 _spare;
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform materialBuffer {
|
uniform materialBuffer {
|
||||||
Material _mat;
|
Material _mat;
|
||||||
};
|
};
|
||||||
|
|
||||||
Material getMaterial() {
|
Material getMaterial() {
|
||||||
return _mat;
|
return _mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
<! // TODO: use this code for correct gamma correction
|
<! // TODO: use this code for correct gamma correction
|
||||||
/*
|
/*
|
||||||
float componentSRGBToLinear(float cs) {
|
float componentSRGBToLinear(float cs) {
|
||||||
// sRGB to linear conversion
|
// sRGB to linear conversion
|
||||||
// { cs / 12.92, cs <= 0.04045
|
// { cs / 12.92, cs <= 0.04045
|
||||||
// cl = {
|
// cl = {
|
||||||
// { ((cs + 0.055)/1.055)^2.4, cs > 0.04045
|
// { ((cs + 0.055)/1.055)^2.4, cs > 0.04045
|
||||||
// constants:
|
// constants:
|
||||||
// T = 0.04045
|
// T = 0.04045
|
||||||
// A = 1 / 1.055 = 0.94786729857
|
// A = 1 / 1.055 = 0.94786729857
|
||||||
// B = 0.055 * A = 0.05213270142
|
// B = 0.055 * A = 0.05213270142
|
||||||
// C = 1 / 12.92 = 0.0773993808
|
// C = 1 / 12.92 = 0.0773993808
|
||||||
// G = 2.4
|
// G = 2.4
|
||||||
const float T = 0.04045;
|
const float T = 0.04045;
|
||||||
const float A = 0.947867;
|
const float A = 0.947867;
|
||||||
const float B = 0.052132;
|
const float B = 0.052132;
|
||||||
const float C = 0.077399;
|
const float C = 0.077399;
|
||||||
const float G = 2.4;
|
const float G = 2.4;
|
||||||
|
|
||||||
if (cs > T) {
|
if (cs > T) {
|
||||||
return pow((cs * A + B), G);
|
return pow((cs * A + B), G);
|
||||||
} else {
|
} else {
|
||||||
return cs * C;
|
return cs * C;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 SRGBToLinear(vec3 srgb) {
|
vec3 SRGBToLinear(vec3 srgb) {
|
||||||
return vec3(componentSRGBToLinear(srgb.x),componentSRGBToLinear(srgb.y),componentSRGBToLinear(srgb.z));
|
return vec3(componentSRGBToLinear(srgb.x),componentSRGBToLinear(srgb.y),componentSRGBToLinear(srgb.z));
|
||||||
}
|
}
|
||||||
vec3 getMaterialDiffuse(Material m) { return (gl_FragCoord.x < 800 ? SRGBToLinear(m._diffuse.rgb) : m._diffuse.rgb); }
|
vec3 getMaterialDiffuse(Material m) { return (gl_FragCoord.x < 800 ? SRGBToLinear(m._diffuse.rgb) : m._diffuse.rgb); }
|
||||||
*/!>
|
*/!>
|
||||||
|
|
||||||
float getMaterialOpacity(Material m) { return m._diffuse.a; }
|
float getMaterialOpacity(Material m) { return m._diffuse.a; }
|
||||||
vec3 getMaterialDiffuse(Material m) { return m._diffuse.rgb; }
|
vec3 getMaterialDiffuse(Material m) { return m._diffuse.rgb; }
|
||||||
vec3 getMaterialSpecular(Material m) { return m._specular.rgb; }
|
vec3 getMaterialSpecular(Material m) { return m._specular.rgb; }
|
||||||
float getMaterialShininess(Material m) { return m._specular.a; }
|
float getMaterialShininess(Material m) { return m._specular.a; }
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -1,303 +1,303 @@
|
||||||
//
|
//
|
||||||
// Stage.cpp
|
// Stage.cpp
|
||||||
// libraries/model/src/model
|
// libraries/model/src/model
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 2/24/2015.
|
// Created by Sam Gateau on 2/24/2015.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
#include "Stage.h"
|
#include "Stage.h"
|
||||||
|
|
||||||
#include <glm/gtx/transform.hpp>
|
#include <glm/gtx/transform.hpp>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <qcompilerdetection.h>
|
#include <qcompilerdetection.h>
|
||||||
|
|
||||||
using namespace model;
|
using namespace model;
|
||||||
|
|
||||||
|
|
||||||
void EarthSunModel::updateAll() const {
|
void EarthSunModel::updateAll() const {
|
||||||
updateWorldToSurface();
|
updateWorldToSurface();
|
||||||
updateSurfaceToEye();
|
updateSurfaceToEye();
|
||||||
updateSun();
|
updateSun();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat4d EarthSunModel::evalWorldToGeoLocationMat(double longitude, double latitude, double absAltitude, double scale) {
|
Mat4d EarthSunModel::evalWorldToGeoLocationMat(double longitude, double latitude, double absAltitude, double scale) {
|
||||||
// Longitude is along Z axis but - from east to west
|
// Longitude is along Z axis but - from east to west
|
||||||
Mat4d rotLon = glm::rotate(glm::radians(longitude), Vec3d(0.0, 0.0, 1.0));
|
Mat4d rotLon = glm::rotate(glm::radians(longitude), Vec3d(0.0, 0.0, 1.0));
|
||||||
|
|
||||||
// latitude is along X axis + from south to north
|
// latitude is along X axis + from south to north
|
||||||
Mat4d rotLat = glm::rotate(-glm::radians(latitude), Vec3d(1.0, 0.0, 0.0));
|
Mat4d rotLat = glm::rotate(-glm::radians(latitude), Vec3d(1.0, 0.0, 0.0));
|
||||||
|
|
||||||
// translation is movin to the earth surface + altiture at the radius along Y axis
|
// translation is movin to the earth surface + altiture at the radius along Y axis
|
||||||
Mat4d surfaceT = glm::translate(Vec3d(0.0, -absAltitude, 0.0));
|
Mat4d surfaceT = glm::translate(Vec3d(0.0, -absAltitude, 0.0));
|
||||||
|
|
||||||
// Mat4d worldScale = glm::scale(Vec3d(scale));
|
// Mat4d worldScale = glm::scale(Vec3d(scale));
|
||||||
|
|
||||||
Mat4d worldToGeoLocMat = surfaceT * rotLat * rotLon;
|
Mat4d worldToGeoLocMat = surfaceT * rotLat * rotLon;
|
||||||
|
|
||||||
return worldToGeoLocMat;
|
return worldToGeoLocMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EarthSunModel::updateWorldToSurface() const {
|
void EarthSunModel::updateWorldToSurface() const {
|
||||||
// Check if the final position is too close to the earth center ?
|
// Check if the final position is too close to the earth center ?
|
||||||
float absAltitude = _earthRadius + _altitude;
|
float absAltitude = _earthRadius + _altitude;
|
||||||
if ( absAltitude < 0.01f) {
|
if ( absAltitude < 0.01f) {
|
||||||
absAltitude = 0.01f;
|
absAltitude = 0.01f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final world to local Frame
|
// Final world to local Frame
|
||||||
_worldToSurfaceMat = evalWorldToGeoLocationMat(_longitude, _latitude, absAltitude, _scale);
|
_worldToSurfaceMat = evalWorldToGeoLocationMat(_longitude, _latitude, absAltitude, _scale);
|
||||||
// and the inverse
|
// and the inverse
|
||||||
_surfaceToWorldMat = glm::inverse(_worldToSurfaceMat);
|
_surfaceToWorldMat = glm::inverse(_worldToSurfaceMat);
|
||||||
|
|
||||||
_surfacePos = Vec3d(_surfaceToWorldMat * Vec4d(0.0, 0.0, 0.0, 1.0));
|
_surfacePos = Vec3d(_surfaceToWorldMat * Vec4d(0.0, 0.0, 0.0, 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EarthSunModel::updateSurfaceToEye() const {
|
void EarthSunModel::updateSurfaceToEye() const {
|
||||||
_surfaceToEyeMat = glm::inverse(_eyeToSurfaceMat);
|
_surfaceToEyeMat = glm::inverse(_eyeToSurfaceMat);
|
||||||
_worldToEyeMat = _surfaceToEyeMat * _worldToSurfaceMat;
|
_worldToEyeMat = _surfaceToEyeMat * _worldToSurfaceMat;
|
||||||
_eyeToWorldMat = _surfaceToWorldMat * _eyeToSurfaceMat;
|
_eyeToWorldMat = _surfaceToWorldMat * _eyeToSurfaceMat;
|
||||||
_eyePos = Vec3d(_eyeToWorldMat * Vec4d(0.0, 0.0, 0.0, 1.0) );
|
_eyePos = Vec3d(_eyeToWorldMat * Vec4d(0.0, 0.0, 0.0, 1.0) );
|
||||||
_eyeDir = Vec3d(_eyeToWorldMat * Vec4d(0.0, 0.0, -1.0, 0.0) );
|
_eyeDir = Vec3d(_eyeToWorldMat * Vec4d(0.0, 0.0, -1.0, 0.0) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EarthSunModel::updateSun() const {
|
void EarthSunModel::updateSun() const {
|
||||||
// Longitude is along Y axis but - from east to west
|
// Longitude is along Y axis but - from east to west
|
||||||
Mat4d rotSunLon;
|
Mat4d rotSunLon;
|
||||||
|
|
||||||
Mat4d rotSun = evalWorldToGeoLocationMat(_sunLongitude, _sunLatitude, _earthRadius, _scale);
|
Mat4d rotSun = evalWorldToGeoLocationMat(_sunLongitude, _sunLatitude, _earthRadius, _scale);
|
||||||
rotSun = glm::inverse(rotSun);
|
rotSun = glm::inverse(rotSun);
|
||||||
|
|
||||||
_sunDir = Vec3d(rotSun * Vec4d(0.0, 1.0, 0.0, 0.0));
|
_sunDir = Vec3d(rotSun * Vec4d(0.0, 1.0, 0.0, 0.0));
|
||||||
|
|
||||||
// sun direction is looking up toward Y axis at the specified sun lat, long
|
// sun direction is looking up toward Y axis at the specified sun lat, long
|
||||||
Vec3d lssd = Vec3d(_worldToSurfaceMat * Vec4d(_sunDir.x, _sunDir.y, _sunDir.z, 0.0));
|
Vec3d lssd = Vec3d(_worldToSurfaceMat * Vec4d(_sunDir.x, _sunDir.y, _sunDir.z, 0.0));
|
||||||
|
|
||||||
// apply surface rotation offset
|
// apply surface rotation offset
|
||||||
glm::dquat dSurfOrient(_surfaceOrientation);
|
glm::dquat dSurfOrient(_surfaceOrientation);
|
||||||
lssd = glm::rotate(dSurfOrient, lssd);
|
lssd = glm::rotate(dSurfOrient, lssd);
|
||||||
|
|
||||||
_surfaceSunDir = glm::normalize(Vec3(lssd.x, lssd.y, lssd.z));
|
_surfaceSunDir = glm::normalize(Vec3(lssd.x, lssd.y, lssd.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EarthSunModel::setSurfaceOrientation(const Quat& orientation) {
|
void EarthSunModel::setSurfaceOrientation(const Quat& orientation) {
|
||||||
_surfaceOrientation = orientation;
|
_surfaceOrientation = orientation;
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
double moduloRange(double val, double minVal, double maxVal) {
|
double moduloRange(double val, double minVal, double maxVal) {
|
||||||
double range = maxVal - minVal;
|
double range = maxVal - minVal;
|
||||||
double rval = (val - minVal) / range;
|
double rval = (val - minVal) / range;
|
||||||
rval = rval - floor(rval);
|
rval = rval - floor(rval);
|
||||||
return rval * range + minVal;
|
return rval * range + minVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float MAX_LONGITUDE = 180.0f;
|
const float MAX_LONGITUDE = 180.0f;
|
||||||
const float MAX_LATITUDE = 90.0f;
|
const float MAX_LATITUDE = 90.0f;
|
||||||
|
|
||||||
float validateLongitude(float lon) {
|
float validateLongitude(float lon) {
|
||||||
return moduloRange(lon, -MAX_LONGITUDE, MAX_LONGITUDE);
|
return moduloRange(lon, -MAX_LONGITUDE, MAX_LONGITUDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
float validateLatitude(float lat) {
|
float validateLatitude(float lat) {
|
||||||
return moduloRange(lat, -MAX_LATITUDE, MAX_LATITUDE);
|
return moduloRange(lat, -MAX_LATITUDE, MAX_LATITUDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
float validateAltitude(float altitude) {
|
float validateAltitude(float altitude) {
|
||||||
const float MIN_ALTITUDE = -1000.0f;
|
const float MIN_ALTITUDE = -1000.0f;
|
||||||
const float MAX_ALTITUDE = 100000.0f;
|
const float MAX_ALTITUDE = 100000.0f;
|
||||||
return std::min(std::max(altitude, MIN_ALTITUDE), MAX_ALTITUDE);
|
return std::min(std::max(altitude, MIN_ALTITUDE), MAX_ALTITUDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EarthSunModel::setLatitude(float lat) {
|
void EarthSunModel::setLatitude(float lat) {
|
||||||
_latitude = validateLatitude(lat);
|
_latitude = validateLatitude(lat);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
void EarthSunModel::setLongitude(float lon) {
|
void EarthSunModel::setLongitude(float lon) {
|
||||||
_longitude = validateLongitude(lon);
|
_longitude = validateLongitude(lon);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
void EarthSunModel::setAltitude(float altitude) {
|
void EarthSunModel::setAltitude(float altitude) {
|
||||||
_altitude = validateAltitude(altitude);
|
_altitude = validateAltitude(altitude);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EarthSunModel::setSunLatitude(float lat) {
|
void EarthSunModel::setSunLatitude(float lat) {
|
||||||
_sunLatitude = validateLatitude(lat);
|
_sunLatitude = validateLatitude(lat);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
void EarthSunModel::setSunLongitude(float lon) {
|
void EarthSunModel::setSunLongitude(float lon) {
|
||||||
_sunLongitude = validateLongitude(lon);
|
_sunLongitude = validateLongitude(lon);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
Atmosphere::Atmosphere() {
|
Atmosphere::Atmosphere() {
|
||||||
// only if created from nothing shall we create the Buffer to store the properties
|
// only if created from nothing shall we create the Buffer to store the properties
|
||||||
Data data;
|
Data data;
|
||||||
_dataBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Data), (const gpu::Byte*) &data));
|
_dataBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Data), (const gpu::Byte*) &data));
|
||||||
|
|
||||||
setScatteringWavelength(_scatteringWavelength);
|
setScatteringWavelength(_scatteringWavelength);
|
||||||
setRayleighScattering(_rayleighScattering);
|
setRayleighScattering(_rayleighScattering);
|
||||||
setInnerOuterRadiuses(getInnerRadius(), getOuterRadius());
|
setInnerOuterRadiuses(getInnerRadius(), getOuterRadius());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atmosphere::setScatteringWavelength(Vec3 wavelength) {
|
void Atmosphere::setScatteringWavelength(Vec3 wavelength) {
|
||||||
_scatteringWavelength = wavelength;
|
_scatteringWavelength = wavelength;
|
||||||
Data& data = editData();
|
Data& data = editData();
|
||||||
data._invWaveLength = Vec4(1.0f / powf(wavelength.x, 4.0f), 1.0f / powf(wavelength.y, 4.0f), 1.0f / powf(wavelength.z, 4.0f), 0.0f);
|
data._invWaveLength = Vec4(1.0f / powf(wavelength.x, 4.0f), 1.0f / powf(wavelength.y, 4.0f), 1.0f / powf(wavelength.z, 4.0f), 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atmosphere::setRayleighScattering(float scattering) {
|
void Atmosphere::setRayleighScattering(float scattering) {
|
||||||
_rayleighScattering = scattering;
|
_rayleighScattering = scattering;
|
||||||
updateScattering();
|
updateScattering();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atmosphere::setMieScattering(float scattering) {
|
void Atmosphere::setMieScattering(float scattering) {
|
||||||
_mieScattering = scattering;
|
_mieScattering = scattering;
|
||||||
updateScattering();
|
updateScattering();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atmosphere::setSunBrightness(float brightness) {
|
void Atmosphere::setSunBrightness(float brightness) {
|
||||||
_sunBrightness = brightness;
|
_sunBrightness = brightness;
|
||||||
updateScattering();
|
updateScattering();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atmosphere::updateScattering() {
|
void Atmosphere::updateScattering() {
|
||||||
Data& data = editData();
|
Data& data = editData();
|
||||||
|
|
||||||
data._scatterings.x = getRayleighScattering() * getSunBrightness();
|
data._scatterings.x = getRayleighScattering() * getSunBrightness();
|
||||||
data._scatterings.y = getMieScattering() * getSunBrightness();
|
data._scatterings.y = getMieScattering() * getSunBrightness();
|
||||||
|
|
||||||
data._scatterings.z = getRayleighScattering() * 4.0f * glm::pi<float>();
|
data._scatterings.z = getRayleighScattering() * 4.0f * glm::pi<float>();
|
||||||
data._scatterings.w = getMieScattering() * 4.0f * glm::pi<float>();
|
data._scatterings.w = getMieScattering() * 4.0f * glm::pi<float>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atmosphere::setInnerOuterRadiuses(float inner, float outer) {
|
void Atmosphere::setInnerOuterRadiuses(float inner, float outer) {
|
||||||
Data& data = editData();
|
Data& data = editData();
|
||||||
data._radiuses.x = inner;
|
data._radiuses.x = inner;
|
||||||
data._radiuses.y = outer;
|
data._radiuses.y = outer;
|
||||||
data._scales.x = 1.0f / (outer - inner);
|
data._scales.x = 1.0f / (outer - inner);
|
||||||
data._scales.z = data._scales.x / data._scales.y;
|
data._scales.z = data._scales.x / data._scales.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int NUM_DAYS_PER_YEAR = 365;
|
const int NUM_DAYS_PER_YEAR = 365;
|
||||||
const float NUM_HOURS_PER_DAY = 24.0f;
|
const float NUM_HOURS_PER_DAY = 24.0f;
|
||||||
const float NUM_HOURS_PER_HALF_DAY = NUM_HOURS_PER_DAY * 0.5f;
|
const float NUM_HOURS_PER_HALF_DAY = NUM_HOURS_PER_DAY * 0.5f;
|
||||||
|
|
||||||
SunSkyStage::SunSkyStage() :
|
SunSkyStage::SunSkyStage() :
|
||||||
_sunLight(std::make_shared<Light>()),
|
_sunLight(std::make_shared<Light>()),
|
||||||
_skybox(std::make_shared<Skybox>())
|
_skybox(std::make_shared<Skybox>())
|
||||||
{
|
{
|
||||||
_sunLight->setType(Light::SUN);
|
_sunLight->setType(Light::SUN);
|
||||||
|
|
||||||
setSunIntensity(1.0f);
|
setSunIntensity(1.0f);
|
||||||
setSunAmbientIntensity(0.5f);
|
setSunAmbientIntensity(0.5f);
|
||||||
setSunColor(Vec3(1.0f, 1.0f, 1.0f));
|
setSunColor(Vec3(1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
// Default origin location is a special place in the world...
|
// Default origin location is a special place in the world...
|
||||||
setOriginLocation(122.407f, 37.777f, 0.03f);
|
setOriginLocation(122.407f, 37.777f, 0.03f);
|
||||||
// Noun
|
// Noun
|
||||||
setDayTime(12.0f);
|
setDayTime(12.0f);
|
||||||
// Begining of march
|
// Begining of march
|
||||||
setYearTime(60.0f);
|
setYearTime(60.0f);
|
||||||
|
|
||||||
_skybox->setColor(Color(1.0f, 0.0f, 0.0f));
|
_skybox->setColor(Color(1.0f, 0.0f, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
SunSkyStage::~SunSkyStage() {
|
SunSkyStage::~SunSkyStage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::setDayTime(float hour) {
|
void SunSkyStage::setDayTime(float hour) {
|
||||||
_dayTime = moduloRange(hour, 0.f, NUM_HOURS_PER_DAY);
|
_dayTime = moduloRange(hour, 0.f, NUM_HOURS_PER_DAY);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::setYearTime(unsigned int day) {
|
void SunSkyStage::setYearTime(unsigned int day) {
|
||||||
_yearTime = day % NUM_DAYS_PER_YEAR;
|
_yearTime = day % NUM_DAYS_PER_YEAR;
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::setOriginOrientation(const Quat& orientation) {
|
void SunSkyStage::setOriginOrientation(const Quat& orientation) {
|
||||||
_earthSunModel.setSurfaceOrientation(orientation);
|
_earthSunModel.setSurfaceOrientation(orientation);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::setOriginLocation(float longitude, float latitude, float altitude) {
|
void SunSkyStage::setOriginLocation(float longitude, float latitude, float altitude) {
|
||||||
_earthSunModel.setLongitude(longitude);
|
_earthSunModel.setLongitude(longitude);
|
||||||
_earthSunModel.setLatitude(latitude);
|
_earthSunModel.setLatitude(latitude);
|
||||||
_earthSunModel.setAltitude(altitude);
|
_earthSunModel.setAltitude(altitude);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::setSunModelEnable(bool isEnabled) {
|
void SunSkyStage::setSunModelEnable(bool isEnabled) {
|
||||||
_sunModelEnable = isEnabled;
|
_sunModelEnable = isEnabled;
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::setSunColor(const Vec3& color) {
|
void SunSkyStage::setSunColor(const Vec3& color) {
|
||||||
_sunLight->setColor(color);
|
_sunLight->setColor(color);
|
||||||
}
|
}
|
||||||
void SunSkyStage::setSunIntensity(float intensity) {
|
void SunSkyStage::setSunIntensity(float intensity) {
|
||||||
_sunLight->setIntensity(intensity);
|
_sunLight->setIntensity(intensity);
|
||||||
}
|
}
|
||||||
void SunSkyStage::setSunAmbientIntensity(float intensity) {
|
void SunSkyStage::setSunAmbientIntensity(float intensity) {
|
||||||
_sunLight->setAmbientIntensity(intensity);
|
_sunLight->setAmbientIntensity(intensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::setSunDirection(const Vec3& direction) {
|
void SunSkyStage::setSunDirection(const Vec3& direction) {
|
||||||
if (!isSunModelEnabled()) {
|
if (!isSunModelEnabled()) {
|
||||||
_sunLight->setDirection(direction);
|
_sunLight->setDirection(direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// THe sun declinaison calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun
|
// THe sun declinaison calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun
|
||||||
double evalSunDeclinaison(double dayNumber) {
|
double evalSunDeclinaison(double dayNumber) {
|
||||||
return -(23.0 + 44.0/60.0)*cos(glm::radians((360.0/365.0)*(dayNumber + 10.0)));
|
return -(23.0 + 44.0/60.0)*cos(glm::radians((360.0/365.0)*(dayNumber + 10.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::updateGraphicsObject() const {
|
void SunSkyStage::updateGraphicsObject() const {
|
||||||
// Always update the sunLongitude based on the current dayTime and the current origin
|
// Always update the sunLongitude based on the current dayTime and the current origin
|
||||||
// The day time is supposed to be local at the origin
|
// The day time is supposed to be local at the origin
|
||||||
float signedNormalizedDayTime = (_dayTime - NUM_HOURS_PER_HALF_DAY) / NUM_HOURS_PER_HALF_DAY;
|
float signedNormalizedDayTime = (_dayTime - NUM_HOURS_PER_HALF_DAY) / NUM_HOURS_PER_HALF_DAY;
|
||||||
float sunLongitude = _earthSunModel.getLongitude() + (MAX_LONGITUDE * signedNormalizedDayTime);
|
float sunLongitude = _earthSunModel.getLongitude() + (MAX_LONGITUDE * signedNormalizedDayTime);
|
||||||
_earthSunModel.setSunLongitude(sunLongitude);
|
_earthSunModel.setSunLongitude(sunLongitude);
|
||||||
|
|
||||||
// And update the sunLAtitude as the declinaison depending of the time of the year
|
// And update the sunLAtitude as the declinaison depending of the time of the year
|
||||||
_earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime));
|
_earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime));
|
||||||
|
|
||||||
if (isSunModelEnabled()) {
|
if (isSunModelEnabled()) {
|
||||||
Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir();
|
Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir();
|
||||||
_sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z));
|
_sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z));
|
||||||
|
|
||||||
double originAlt = _earthSunModel.getAltitude();
|
double originAlt = _earthSunModel.getAltitude();
|
||||||
_sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f));
|
_sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background
|
// Background
|
||||||
switch (getBackgroundMode()) {
|
switch (getBackgroundMode()) {
|
||||||
case NO_BACKGROUND: {
|
case NO_BACKGROUND: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SKY_DOME: {
|
case SKY_DOME: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SKY_BOX: {
|
case SKY_BOX: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NUM_BACKGROUND_MODES:
|
case NUM_BACKGROUND_MODES:
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::setBackgroundMode(BackgroundMode mode) {
|
void SunSkyStage::setBackgroundMode(BackgroundMode mode) {
|
||||||
_backgroundMode = mode;
|
_backgroundMode = mode;
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SunSkyStage::setSkybox(const SkyboxPointer& skybox) {
|
void SunSkyStage::setSkybox(const SkyboxPointer& skybox) {
|
||||||
_skybox = skybox;
|
_skybox = skybox;
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,247 +1,247 @@
|
||||||
//
|
//
|
||||||
// Stage.h
|
// Stage.h
|
||||||
// libraries/model/src/model
|
// libraries/model/src/model
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 2/24/2015.
|
// Created by Sam Gateau on 2/24/2015.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
#ifndef hifi_model_Stage_h
|
#ifndef hifi_model_Stage_h
|
||||||
#define hifi_model_Stage_h
|
#define hifi_model_Stage_h
|
||||||
|
|
||||||
#include "gpu/Pipeline.h"
|
#include "gpu/Pipeline.h"
|
||||||
|
|
||||||
#include "Light.h"
|
#include "Light.h"
|
||||||
#include "Skybox.h"
|
#include "Skybox.h"
|
||||||
|
|
||||||
namespace model {
|
namespace model {
|
||||||
|
|
||||||
typedef glm::dvec3 Vec3d;
|
typedef glm::dvec3 Vec3d;
|
||||||
typedef glm::dvec4 Vec4d;
|
typedef glm::dvec4 Vec4d;
|
||||||
typedef glm::dmat4 Mat4d;
|
typedef glm::dmat4 Mat4d;
|
||||||
typedef glm::mat4 Mat4;
|
typedef glm::mat4 Mat4;
|
||||||
|
|
||||||
class EarthSunModel {
|
class EarthSunModel {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void setScale(float scale);
|
void setScale(float scale);
|
||||||
float getScale() const { return _scale; }
|
float getScale() const { return _scale; }
|
||||||
|
|
||||||
void setLatitude(float lat);
|
void setLatitude(float lat);
|
||||||
float getLatitude() const { return _latitude; }
|
float getLatitude() const { return _latitude; }
|
||||||
void setLongitude(float lon);
|
void setLongitude(float lon);
|
||||||
float getLongitude() const { return _longitude; }
|
float getLongitude() const { return _longitude; }
|
||||||
void setAltitude(float altitude);
|
void setAltitude(float altitude);
|
||||||
float getAltitude() const { return _altitude; }
|
float getAltitude() const { return _altitude; }
|
||||||
|
|
||||||
|
|
||||||
void setSurfaceOrientation(const Quat& orientation);
|
void setSurfaceOrientation(const Quat& orientation);
|
||||||
const Quat& getSurfaceOrientation() const { valid(); return _surfaceOrientation; }
|
const Quat& getSurfaceOrientation() const { valid(); return _surfaceOrientation; }
|
||||||
|
|
||||||
const Vec3d& getSurfacePos() const { valid(); return _surfacePos; }
|
const Vec3d& getSurfacePos() const { valid(); return _surfacePos; }
|
||||||
|
|
||||||
const Mat4d& getSurfaceToWorldMat() const { valid(); return _surfaceToWorldMat; }
|
const Mat4d& getSurfaceToWorldMat() const { valid(); return _surfaceToWorldMat; }
|
||||||
const Mat4d& getWoldToSurfaceMat() const { valid(); return _worldToSurfaceMat; }
|
const Mat4d& getWoldToSurfaceMat() const { valid(); return _worldToSurfaceMat; }
|
||||||
|
|
||||||
const Mat4d& getEyeToSurfaceMat() const { valid(); return _eyeToSurfaceMat; }
|
const Mat4d& getEyeToSurfaceMat() const { valid(); return _eyeToSurfaceMat; }
|
||||||
const Mat4d& getSurfaceToEyeMat() const { valid(); return _surfaceToEyeMat; }
|
const Mat4d& getSurfaceToEyeMat() const { valid(); return _surfaceToEyeMat; }
|
||||||
|
|
||||||
const Mat4d& getEyeToWorldMat() const { valid(); return _eyeToWorldMat; }
|
const Mat4d& getEyeToWorldMat() const { valid(); return _eyeToWorldMat; }
|
||||||
const Mat4d& getWorldToEyeMat() const { valid(); return _worldToEyeMat; }
|
const Mat4d& getWorldToEyeMat() const { valid(); return _worldToEyeMat; }
|
||||||
|
|
||||||
|
|
||||||
//or set the surfaceToEye mat directly
|
//or set the surfaceToEye mat directly
|
||||||
void setEyeToSurfaceMat( const Mat4d& e2s);
|
void setEyeToSurfaceMat( const Mat4d& e2s);
|
||||||
|
|
||||||
const Vec3d& getEyePos() const { valid(); return _eyePos; }
|
const Vec3d& getEyePos() const { valid(); return _eyePos; }
|
||||||
const Vec3d& getEyeDir() const { valid(); return _eyeDir; }
|
const Vec3d& getEyeDir() const { valid(); return _eyeDir; }
|
||||||
|
|
||||||
void setSunLongitude(float lon);
|
void setSunLongitude(float lon);
|
||||||
float getSunLongitude() const { return _sunLongitude; }
|
float getSunLongitude() const { return _sunLongitude; }
|
||||||
|
|
||||||
void setSunLatitude(float lat);
|
void setSunLatitude(float lat);
|
||||||
float getSunLatitude() const { return _sunLatitude; }
|
float getSunLatitude() const { return _sunLatitude; }
|
||||||
|
|
||||||
const Vec3d& getWorldSunDir() const { valid(); return _sunDir; }
|
const Vec3d& getWorldSunDir() const { valid(); return _sunDir; }
|
||||||
const Vec3d& getSurfaceSunDir() const { valid(); return _surfaceSunDir; }
|
const Vec3d& getSurfaceSunDir() const { valid(); return _surfaceSunDir; }
|
||||||
|
|
||||||
|
|
||||||
EarthSunModel() { valid(); }
|
EarthSunModel() { valid(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float _scale = 1000.0f; //Km
|
float _scale = 1000.0f; //Km
|
||||||
float _earthRadius = 6360.0;
|
float _earthRadius = 6360.0;
|
||||||
|
|
||||||
Quat _surfaceOrientation;
|
Quat _surfaceOrientation;
|
||||||
|
|
||||||
float _longitude = 0.0f;
|
float _longitude = 0.0f;
|
||||||
float _latitude = 0.0f;
|
float _latitude = 0.0f;
|
||||||
float _altitude = 0.01f;
|
float _altitude = 0.01f;
|
||||||
mutable Vec3d _surfacePos;
|
mutable Vec3d _surfacePos;
|
||||||
mutable Mat4d _worldToSurfaceMat;
|
mutable Mat4d _worldToSurfaceMat;
|
||||||
mutable Mat4d _surfaceToWorldMat;
|
mutable Mat4d _surfaceToWorldMat;
|
||||||
void updateWorldToSurface() const;
|
void updateWorldToSurface() const;
|
||||||
|
|
||||||
mutable Mat4d _surfaceToEyeMat;
|
mutable Mat4d _surfaceToEyeMat;
|
||||||
mutable Mat4d _eyeToSurfaceMat;
|
mutable Mat4d _eyeToSurfaceMat;
|
||||||
mutable Vec3d _eyeDir;
|
mutable Vec3d _eyeDir;
|
||||||
mutable Vec3d _eyePos;
|
mutable Vec3d _eyePos;
|
||||||
void updateSurfaceToEye() const;
|
void updateSurfaceToEye() const;
|
||||||
|
|
||||||
mutable Mat4d _worldToEyeMat;
|
mutable Mat4d _worldToEyeMat;
|
||||||
mutable Mat4d _eyeToWorldMat;
|
mutable Mat4d _eyeToWorldMat;
|
||||||
|
|
||||||
float _sunLongitude = 0.0f;
|
float _sunLongitude = 0.0f;
|
||||||
float _sunLatitude = 0.0f;
|
float _sunLatitude = 0.0f;
|
||||||
mutable Vec3d _sunDir;
|
mutable Vec3d _sunDir;
|
||||||
mutable Vec3d _surfaceSunDir;
|
mutable Vec3d _surfaceSunDir;
|
||||||
void updateSun() const;
|
void updateSun() const;
|
||||||
|
|
||||||
mutable bool _invalid = true;
|
mutable bool _invalid = true;
|
||||||
void invalidate() const { _invalid = true; }
|
void invalidate() const { _invalid = true; }
|
||||||
void valid() const { if (_invalid) { updateAll(); _invalid = false; } }
|
void valid() const { if (_invalid) { updateAll(); _invalid = false; } }
|
||||||
void updateAll() const;
|
void updateAll() const;
|
||||||
|
|
||||||
static Mat4d evalWorldToGeoLocationMat(double longitude, double latitude, double altitude, double scale);
|
static Mat4d evalWorldToGeoLocationMat(double longitude, double latitude, double altitude, double scale);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Atmosphere {
|
class Atmosphere {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Atmosphere();
|
Atmosphere();
|
||||||
Atmosphere(const Atmosphere& atmosphere);
|
Atmosphere(const Atmosphere& atmosphere);
|
||||||
Atmosphere& operator= (const Atmosphere& atmosphere);
|
Atmosphere& operator= (const Atmosphere& atmosphere);
|
||||||
virtual ~Atmosphere() {};
|
virtual ~Atmosphere() {};
|
||||||
|
|
||||||
|
|
||||||
void setScatteringWavelength(Vec3 wavelength);
|
void setScatteringWavelength(Vec3 wavelength);
|
||||||
const Vec3& getScatteringWavelength() const { return _scatteringWavelength; }
|
const Vec3& getScatteringWavelength() const { return _scatteringWavelength; }
|
||||||
|
|
||||||
void setRayleighScattering(float scattering);
|
void setRayleighScattering(float scattering);
|
||||||
float getRayleighScattering() const { return _rayleighScattering; }
|
float getRayleighScattering() const { return _rayleighScattering; }
|
||||||
|
|
||||||
void setMieScattering(float scattering);
|
void setMieScattering(float scattering);
|
||||||
float getMieScattering() const { return _mieScattering; }
|
float getMieScattering() const { return _mieScattering; }
|
||||||
|
|
||||||
void setSunBrightness(float brightness);
|
void setSunBrightness(float brightness);
|
||||||
float getSunBrightness() const { return _sunBrightness; }
|
float getSunBrightness() const { return _sunBrightness; }
|
||||||
|
|
||||||
void setInnerOuterRadiuses(float inner, float outer);
|
void setInnerOuterRadiuses(float inner, float outer);
|
||||||
float getInnerRadius() const { return getData()._radiuses.x; }
|
float getInnerRadius() const { return getData()._radiuses.x; }
|
||||||
float getOuterRadius() const { return getData()._radiuses.y; }
|
float getOuterRadius() const { return getData()._radiuses.y; }
|
||||||
|
|
||||||
// Data to access the attribute values of the atmosphere
|
// Data to access the attribute values of the atmosphere
|
||||||
class Data {
|
class Data {
|
||||||
public:
|
public:
|
||||||
Vec4 _invWaveLength = Vec4(0.0f);
|
Vec4 _invWaveLength = Vec4(0.0f);
|
||||||
Vec4 _radiuses = Vec4(6000.0f, 6025.0f, 0.0f, 0.0f);
|
Vec4 _radiuses = Vec4(6000.0f, 6025.0f, 0.0f, 0.0f);
|
||||||
Vec4 _scales = Vec4(0.0f, 0.25f, 0.0f, 0.0f);
|
Vec4 _scales = Vec4(0.0f, 0.25f, 0.0f, 0.0f);
|
||||||
Vec4 _scatterings = Vec4(0.0f);
|
Vec4 _scatterings = Vec4(0.0f);
|
||||||
Vec4 _control = Vec4(2.0f, -0.990f, -0.990f*-0.990f, 0.f);
|
Vec4 _control = Vec4(2.0f, -0.990f, -0.990f*-0.990f, 0.f);
|
||||||
|
|
||||||
Data() {}
|
Data() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const UniformBufferView& getDataBuffer() const { return _dataBuffer; }
|
const UniformBufferView& getDataBuffer() const { return _dataBuffer; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UniformBufferView _dataBuffer;
|
UniformBufferView _dataBuffer;
|
||||||
Vec3 _scatteringWavelength = Vec3(0.650f, 0.570f, 0.475f);
|
Vec3 _scatteringWavelength = Vec3(0.650f, 0.570f, 0.475f);
|
||||||
float _rayleighScattering = 0.0025f;
|
float _rayleighScattering = 0.0025f;
|
||||||
float _mieScattering = 0.0010f;
|
float _mieScattering = 0.0010f;
|
||||||
float _sunBrightness = 20.0f;
|
float _sunBrightness = 20.0f;
|
||||||
|
|
||||||
const Data& getData() const { return _dataBuffer.get<Data>(); }
|
const Data& getData() const { return _dataBuffer.get<Data>(); }
|
||||||
Data& editData() { return _dataBuffer.edit<Data>(); }
|
Data& editData() { return _dataBuffer.edit<Data>(); }
|
||||||
|
|
||||||
void updateScattering();
|
void updateScattering();
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr< Atmosphere > AtmospherePointer;
|
typedef std::shared_ptr< Atmosphere > AtmospherePointer;
|
||||||
|
|
||||||
// Sun sky stage generates the rendering primitives to display a scene realistically
|
// Sun sky stage generates the rendering primitives to display a scene realistically
|
||||||
// at the specified location and time around earth
|
// at the specified location and time around earth
|
||||||
class SunSkyStage {
|
class SunSkyStage {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SunSkyStage();
|
SunSkyStage();
|
||||||
~SunSkyStage();
|
~SunSkyStage();
|
||||||
|
|
||||||
// time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0]
|
// time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0]
|
||||||
void setDayTime(float hour);
|
void setDayTime(float hour);
|
||||||
float getDayTime() const { return _dayTime; }
|
float getDayTime() const { return _dayTime; }
|
||||||
|
|
||||||
// time of the year expressed in day in the range [0, 365]
|
// time of the year expressed in day in the range [0, 365]
|
||||||
void setYearTime(unsigned int day);
|
void setYearTime(unsigned int day);
|
||||||
unsigned int getYearTime() const { return _yearTime; }
|
unsigned int getYearTime() const { return _yearTime; }
|
||||||
|
|
||||||
// Origin orientation used to modify the cardinal axis alignement used.
|
// 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
|
// 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.
|
// to the transform stack producing the sun light direction.
|
||||||
void setOriginOrientation(const Quat& orientation);
|
void setOriginOrientation(const Quat& orientation);
|
||||||
const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); }
|
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]
|
// 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);
|
void setOriginLocation(float longitude, float latitude, float surfaceAltitude);
|
||||||
float getOriginLatitude() const { return _earthSunModel.getLatitude(); }
|
float getOriginLatitude() const { return _earthSunModel.getLatitude(); }
|
||||||
float getOriginLongitude() const { return _earthSunModel.getLongitude(); }
|
float getOriginLongitude() const { return _earthSunModel.getLongitude(); }
|
||||||
float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); }
|
float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); }
|
||||||
|
|
||||||
// Enable / disable the effect of the time and location on the sun direction and color
|
// Enable / disable the effect of the time and location on the sun direction and color
|
||||||
void setSunModelEnable(bool isEnabled);
|
void setSunModelEnable(bool isEnabled);
|
||||||
bool isSunModelEnabled() const { return _sunModelEnable; }
|
bool isSunModelEnabled() const { return _sunModelEnable; }
|
||||||
|
|
||||||
// Sun properties
|
// Sun properties
|
||||||
void setSunColor(const Vec3& color);
|
void setSunColor(const Vec3& color);
|
||||||
const Vec3& getSunColor() const { return getSunLight()->getColor(); }
|
const Vec3& getSunColor() const { return getSunLight()->getColor(); }
|
||||||
void setSunIntensity(float intensity);
|
void setSunIntensity(float intensity);
|
||||||
float getSunIntensity() const { return getSunLight()->getIntensity(); }
|
float getSunIntensity() const { return getSunLight()->getIntensity(); }
|
||||||
void setSunAmbientIntensity(float intensity);
|
void setSunAmbientIntensity(float intensity);
|
||||||
float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); }
|
float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); }
|
||||||
|
|
||||||
// The sun direction is expressed in the world space
|
// The sun direction is expressed in the world space
|
||||||
void setSunDirection(const Vec3& direction);
|
void setSunDirection(const Vec3& direction);
|
||||||
const Vec3& getSunDirection() const { return getSunLight()->getDirection(); }
|
const Vec3& getSunDirection() const { return getSunLight()->getDirection(); }
|
||||||
|
|
||||||
LightPointer getSunLight() const { valid(); return _sunLight; }
|
LightPointer getSunLight() const { valid(); return _sunLight; }
|
||||||
AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; }
|
AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; }
|
||||||
|
|
||||||
enum BackgroundMode {
|
enum BackgroundMode {
|
||||||
NO_BACKGROUND = 0,
|
NO_BACKGROUND = 0,
|
||||||
SKY_DOME,
|
SKY_DOME,
|
||||||
SKY_BOX,
|
SKY_BOX,
|
||||||
|
|
||||||
NUM_BACKGROUND_MODES,
|
NUM_BACKGROUND_MODES,
|
||||||
};
|
};
|
||||||
void setBackgroundMode(BackgroundMode mode);
|
void setBackgroundMode(BackgroundMode mode);
|
||||||
BackgroundMode getBackgroundMode() const { return _backgroundMode; }
|
BackgroundMode getBackgroundMode() const { return _backgroundMode; }
|
||||||
|
|
||||||
// Skybox
|
// Skybox
|
||||||
void setSkybox(const SkyboxPointer& skybox);
|
void setSkybox(const SkyboxPointer& skybox);
|
||||||
const SkyboxPointer& getSkybox() const { valid(); return _skybox; }
|
const SkyboxPointer& getSkybox() const { valid(); return _skybox; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BackgroundMode _backgroundMode = SKY_BOX;
|
BackgroundMode _backgroundMode = SKY_BOX;
|
||||||
|
|
||||||
LightPointer _sunLight;
|
LightPointer _sunLight;
|
||||||
AtmospherePointer _atmosphere;
|
AtmospherePointer _atmosphere;
|
||||||
mutable SkyboxPointer _skybox;
|
mutable SkyboxPointer _skybox;
|
||||||
|
|
||||||
float _dayTime = 12.0f;
|
float _dayTime = 12.0f;
|
||||||
int _yearTime = 0;
|
int _yearTime = 0;
|
||||||
mutable EarthSunModel _earthSunModel;
|
mutable EarthSunModel _earthSunModel;
|
||||||
bool _sunModelEnable = true;
|
bool _sunModelEnable = true;
|
||||||
|
|
||||||
mutable bool _invalid = true;
|
mutable bool _invalid = true;
|
||||||
void invalidate() const { _invalid = true; }
|
void invalidate() const { _invalid = true; }
|
||||||
void valid() const { if (_invalid) { updateGraphicsObject(); _invalid = false; } }
|
void valid() const { if (_invalid) { updateGraphicsObject(); _invalid = false; } }
|
||||||
void updateGraphicsObject() const;
|
void updateGraphicsObject() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr< SunSkyStage > SunSkyStagePointer;
|
typedef std::shared_ptr< SunSkyStage > SunSkyStagePointer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,71 +1,71 @@
|
||||||
//
|
//
|
||||||
// Plane.cpp
|
// Plane.cpp
|
||||||
// libraries/octree/src/
|
// libraries/octree/src/
|
||||||
//
|
//
|
||||||
// Created by Brad Hefta-Gaub on 04/11/13.
|
// Created by Brad Hefta-Gaub on 04/11/13.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards
|
// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards
|
||||||
// Simple plane class.
|
// Simple plane class.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Plane.h"
|
#include "Plane.h"
|
||||||
#include "OctreeLogging.h"
|
#include "OctreeLogging.h"
|
||||||
|
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void Plane::set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) {
|
void Plane::set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) {
|
||||||
glm::vec3 linev1v2, linev1v3;
|
glm::vec3 linev1v2, linev1v3;
|
||||||
|
|
||||||
linev1v2 = v2 - v1;
|
linev1v2 = v2 - v1;
|
||||||
linev1v3 = v3 - v1;
|
linev1v3 = v3 - v1;
|
||||||
|
|
||||||
// this will be perpendicular to both lines
|
// this will be perpendicular to both lines
|
||||||
_normal = glm::cross(linev1v2,linev1v3);
|
_normal = glm::cross(linev1v2,linev1v3);
|
||||||
_normal = glm::normalize(_normal);
|
_normal = glm::normalize(_normal);
|
||||||
|
|
||||||
// this is a point on the plane
|
// this is a point on the plane
|
||||||
_point = v2;
|
_point = v2;
|
||||||
|
|
||||||
// the D coefficient from the form Ax+By+Cz=D
|
// the D coefficient from the form Ax+By+Cz=D
|
||||||
_dCoefficient = -(glm::dot(_normal,_point));
|
_dCoefficient = -(glm::dot(_normal,_point));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plane::setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point) {
|
void Plane::setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point) {
|
||||||
_point = point;
|
_point = point;
|
||||||
_normal = normal;
|
_normal = normal;
|
||||||
glm::normalize(_normal);
|
glm::normalize(_normal);
|
||||||
|
|
||||||
// the D coefficient from the form Ax+By+Cz=D
|
// the D coefficient from the form Ax+By+Cz=D
|
||||||
_dCoefficient = -(glm::dot(_normal,_point));
|
_dCoefficient = -(glm::dot(_normal,_point));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plane::setCoefficients(float a, float b, float c, float d) {
|
void Plane::setCoefficients(float a, float b, float c, float d) {
|
||||||
// set the normal vector
|
// set the normal vector
|
||||||
_normal = glm::vec3(a,b,c);
|
_normal = glm::vec3(a,b,c);
|
||||||
|
|
||||||
//compute the lenght of the vector
|
//compute the lenght of the vector
|
||||||
float l = glm::length(_normal);
|
float l = glm::length(_normal);
|
||||||
|
|
||||||
// normalize the vector
|
// normalize the vector
|
||||||
_normal = glm::vec3(a/l,b/l,c/l);
|
_normal = glm::vec3(a/l,b/l,c/l);
|
||||||
|
|
||||||
// and divide d by th length as well
|
// and divide d by th length as well
|
||||||
_dCoefficient = d/l;
|
_dCoefficient = d/l;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Plane::distance(const glm::vec3 &point) const {
|
float Plane::distance(const glm::vec3 &point) const {
|
||||||
return (_dCoefficient + glm::dot(_normal,point));
|
return (_dCoefficient + glm::dot(_normal,point));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plane::print() const {
|
void Plane::print() const {
|
||||||
qCDebug(octree, "Plane - point (x=%f y=%f z=%f) normal (x=%f y=%f z=%f) d=%f",
|
qCDebug(octree, "Plane - point (x=%f y=%f z=%f) normal (x=%f y=%f z=%f) d=%f",
|
||||||
(double)_point.x, (double)_point.y, (double)_point.z,
|
(double)_point.x, (double)_point.y, (double)_point.z,
|
||||||
(double)_normal.x, (double)_normal.y, (double)_normal.z, (double)_dCoefficient);
|
(double)_normal.x, (double)_normal.y, (double)_normal.z, (double)_dCoefficient);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
//
|
//
|
||||||
// Plane.h
|
// Plane.h
|
||||||
// libraries/octree/src/
|
// libraries/octree/src/
|
||||||
//
|
//
|
||||||
// Created by Brad Hefta-Gaub on 04/11/13.
|
// Created by Brad Hefta-Gaub on 04/11/13.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards
|
// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards
|
||||||
// Simple plane class.
|
// Simple plane class.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef hifi_Plane_h
|
#ifndef hifi_Plane_h
|
||||||
#define hifi_Plane_h
|
#define hifi_Plane_h
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
class Plane {
|
class Plane {
|
||||||
public:
|
public:
|
||||||
Plane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) { set3Points(v1,v2,v3); }
|
Plane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) { set3Points(v1,v2,v3); }
|
||||||
Plane() : _normal(0,0,0), _point(0,0,0), _dCoefficient(0) {};
|
Plane() : _normal(0,0,0), _point(0,0,0), _dCoefficient(0) {};
|
||||||
~Plane() {} ;
|
~Plane() {} ;
|
||||||
|
|
||||||
// methods for defining the plane
|
// methods for defining the plane
|
||||||
void set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3);
|
void set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3);
|
||||||
void setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point);
|
void setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point);
|
||||||
void setCoefficients(float a, float b, float c, float d);
|
void setCoefficients(float a, float b, float c, float d);
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
const glm::vec3& getNormal() const { return _normal; };
|
const glm::vec3& getNormal() const { return _normal; };
|
||||||
const glm::vec3& getPoint() const { return _point; };
|
const glm::vec3& getPoint() const { return _point; };
|
||||||
float getDCoefficient() const { return _dCoefficient; };
|
float getDCoefficient() const { return _dCoefficient; };
|
||||||
|
|
||||||
// utilities
|
// utilities
|
||||||
float distance(const glm::vec3 &point) const;
|
float distance(const glm::vec3 &point) const;
|
||||||
void print() const;
|
void print() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glm::vec3 _normal;
|
glm::vec3 _normal;
|
||||||
glm::vec3 _point;
|
glm::vec3 _point;
|
||||||
float _dCoefficient;
|
float _dCoefficient;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_Plane_h
|
#endif // hifi_Plane_h
|
|
@ -16,66 +16,66 @@
|
||||||
#include <ViewFrustum.h>
|
#include <ViewFrustum.h>
|
||||||
|
|
||||||
#include "ProceduralSkybox_vert.h"
|
#include "ProceduralSkybox_vert.h"
|
||||||
#include "ProceduralSkybox_frag.h"
|
#include "ProceduralSkybox_frag.h"
|
||||||
|
|
||||||
ProceduralSkybox::ProceduralSkybox() : model::Skybox() {
|
ProceduralSkybox::ProceduralSkybox() : model::Skybox() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ProceduralSkybox::ProceduralSkybox(const ProceduralSkybox& skybox) :
|
ProceduralSkybox::ProceduralSkybox(const ProceduralSkybox& skybox) :
|
||||||
model::Skybox(skybox),
|
model::Skybox(skybox),
|
||||||
_procedural(skybox._procedural) {
|
_procedural(skybox._procedural) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProceduralSkybox::setProcedural(const ProceduralPointer& procedural) {
|
void ProceduralSkybox::setProcedural(const ProceduralPointer& procedural) {
|
||||||
_procedural = procedural;
|
_procedural = procedural;
|
||||||
if (_procedural) {
|
if (_procedural) {
|
||||||
_procedural->_vertexSource = ProceduralSkybox_vert;
|
_procedural->_vertexSource = ProceduralSkybox_vert;
|
||||||
_procedural->_fragmentSource = ProceduralSkybox_frag;
|
_procedural->_fragmentSource = ProceduralSkybox_frag;
|
||||||
// Adjust the pipeline state for background using the stencil test
|
// Adjust the pipeline state for background using the stencil test
|
||||||
_procedural->_state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
_procedural->_state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const {
|
void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const {
|
||||||
ProceduralSkybox::render(batch, frustum, (*this));
|
ProceduralSkybox::render(batch, frustum, (*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const ProceduralSkybox& skybox) {
|
void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const ProceduralSkybox& skybox) {
|
||||||
if (!(skybox._procedural)) {
|
if (!(skybox._procedural)) {
|
||||||
skybox.updateDataBuffer();
|
skybox.updateDataBuffer();
|
||||||
Skybox::render(batch, viewFrustum, skybox);
|
Skybox::render(batch, viewFrustum, skybox);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpu::BufferPointer theBuffer;
|
static gpu::BufferPointer theBuffer;
|
||||||
static gpu::Stream::FormatPointer theFormat;
|
static gpu::Stream::FormatPointer theFormat;
|
||||||
|
|
||||||
if (skybox._procedural && skybox._procedural->_enabled && skybox._procedural->ready()) {
|
if (skybox._procedural && skybox._procedural->_enabled && skybox._procedural->ready()) {
|
||||||
if (!theBuffer) {
|
if (!theBuffer) {
|
||||||
const float CLIP = 1.0f;
|
const float CLIP = 1.0f;
|
||||||
const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } };
|
const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } };
|
||||||
theBuffer = std::make_shared<gpu::Buffer>(sizeof(vertices), (const gpu::Byte*) vertices);
|
theBuffer = std::make_shared<gpu::Buffer>(sizeof(vertices), (const gpu::Byte*) vertices);
|
||||||
theFormat = std::make_shared<gpu::Stream::Format>();
|
theFormat = std::make_shared<gpu::Stream::Format>();
|
||||||
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
viewFrustum.evalProjectionMatrix(projMat);
|
viewFrustum.evalProjectionMatrix(projMat);
|
||||||
|
|
||||||
Transform viewTransform;
|
Transform viewTransform;
|
||||||
viewFrustum.evalViewTransform(viewTransform);
|
viewFrustum.evalViewTransform(viewTransform);
|
||||||
batch.setProjectionTransform(projMat);
|
batch.setProjectionTransform(projMat);
|
||||||
batch.setViewTransform(viewTransform);
|
batch.setViewTransform(viewTransform);
|
||||||
batch.setModelTransform(Transform()); // only for Mac
|
batch.setModelTransform(Transform()); // only for Mac
|
||||||
batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8);
|
batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8);
|
||||||
batch.setInputFormat(theFormat);
|
batch.setInputFormat(theFormat);
|
||||||
|
|
||||||
if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) {
|
if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) {
|
||||||
batch.setResourceTexture(0, skybox.getCubemap());
|
batch.setResourceTexture(0, skybox.getCubemap());
|
||||||
}
|
}
|
||||||
|
|
||||||
skybox._procedural->prepare(batch, glm::vec3(0), glm::vec3(1));
|
skybox._procedural->prepare(batch, glm::vec3(0), glm::vec3(1));
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,19 +25,19 @@ uniform sampler2D specularMap;
|
||||||
uniform sampler2D depthMap;
|
uniform sampler2D depthMap;
|
||||||
|
|
||||||
|
|
||||||
struct DeferredTransform {
|
struct DeferredTransform {
|
||||||
mat4 projection;
|
mat4 projection;
|
||||||
mat4 viewInverse;
|
mat4 viewInverse;
|
||||||
|
|
||||||
vec4 stereoSide_spareABC;
|
vec4 stereoSide_spareABC;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140) uniform deferredTransformBuffer {
|
layout(std140) uniform deferredTransformBuffer {
|
||||||
DeferredTransform _deferredTransform;
|
DeferredTransform _deferredTransform;
|
||||||
};
|
};
|
||||||
DeferredTransform getDeferredTransform() {
|
DeferredTransform getDeferredTransform() {
|
||||||
return _deferredTransform;
|
return _deferredTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getStereoMode(DeferredTransform deferredTransform) {
|
bool getStereoMode(DeferredTransform deferredTransform) {
|
||||||
return (deferredTransform.stereoSide_spareABC.x != 0.0);
|
return (deferredTransform.stereoSide_spareABC.x != 0.0);
|
||||||
|
|
Loading…
Reference in a new issue