mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 16:33:56 +02:00
Cube texture are working with the GL backend, useing it in SKybox successfullly
This commit is contained in:
parent
b1fb05e543
commit
dc81a3ecc2
21 changed files with 363 additions and 41 deletions
|
@ -3116,6 +3116,14 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
}
|
||||
}
|
||||
} else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
|
||||
auto skybox = skyStage->getSkybox();
|
||||
if (skybox) {
|
||||
gpu::Batch batch;
|
||||
model::Skybox::render(batch, _viewFrustum, *skybox);
|
||||
|
||||
gpu::GLBackend::renderBatch(batch);
|
||||
glUseProgram(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
||||
|
|
|
@ -91,6 +91,18 @@ void Batch::drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, ui
|
|||
_params.push_back(nbInstances);
|
||||
}
|
||||
|
||||
void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil) {
|
||||
ADD_COMMAND(clearFramebuffer);
|
||||
|
||||
_params.push_back(stencil);
|
||||
_params.push_back(depth);
|
||||
_params.push_back(color.w);
|
||||
_params.push_back(color.z);
|
||||
_params.push_back(color.y);
|
||||
_params.push_back(color.x);
|
||||
_params.push_back(targets);
|
||||
}
|
||||
|
||||
void Batch::setInputFormat(const Stream::FormatPointer& format) {
|
||||
ADD_COMMAND(setInputFormat);
|
||||
|
||||
|
|
|
@ -81,6 +81,9 @@ public:
|
|||
void drawInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbVertices, uint32 startVertex = 0, uint32 startInstance = 0);
|
||||
void drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbIndices, uint32 startIndex = 0, uint32 startInstance = 0);
|
||||
|
||||
// Clear framebuffer layers
|
||||
void clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil);
|
||||
|
||||
// Input Stage
|
||||
// InputFormat
|
||||
// InputBuffers
|
||||
|
@ -160,6 +163,8 @@ public:
|
|||
COMMAND_drawInstanced,
|
||||
COMMAND_drawIndexedInstanced,
|
||||
|
||||
COMMAND_clearFramebuffer,
|
||||
|
||||
COMMAND_setInputFormat,
|
||||
COMMAND_setInputBuffer,
|
||||
COMMAND_setIndexBuffer,
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
Mat4 _viewInverse;
|
||||
Mat4 _projectionViewUntranslated;
|
||||
Mat4 _projection;
|
||||
Mat4 _projectionInverse;
|
||||
Vec4 _viewport;
|
||||
};
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ public:
|
|||
BUFFER_STENCIL = 0x80000000,
|
||||
BUFFER_DEPTHSTENCIL = 0xC0000000,
|
||||
};
|
||||
typedef uint32 Masks;
|
||||
|
||||
~Framebuffer();
|
||||
|
||||
|
@ -111,7 +112,7 @@ public:
|
|||
|
||||
|
||||
// Properties
|
||||
uint32 getBufferMask() const { return _bufferMask; }
|
||||
Masks getBufferMask() const { return _bufferMask; }
|
||||
bool isEmpty() const { return (_bufferMask == 0); }
|
||||
bool hasColor() const { return (getBufferMask() & BUFFER_COLORS); }
|
||||
bool hasDepthStencil() const { return (getBufferMask() & BUFFER_DEPTHSTENCIL); }
|
||||
|
@ -137,7 +138,7 @@ protected:
|
|||
TextureViews _renderBuffers;
|
||||
TextureView _depthStencilBuffer;
|
||||
|
||||
uint32 _bufferMask = 0;
|
||||
Masks _bufferMask = 0;
|
||||
|
||||
uint32 _frameCount = 0;
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_drawIndexed),
|
||||
(&::gpu::GLBackend::do_drawInstanced),
|
||||
(&::gpu::GLBackend::do_drawIndexedInstanced),
|
||||
|
||||
(&::gpu::GLBackend::do_clearFramebuffer),
|
||||
|
||||
(&::gpu::GLBackend::do_setInputFormat),
|
||||
(&::gpu::GLBackend::do_setInputBuffer),
|
||||
(&::gpu::GLBackend::do_setIndexBuffer),
|
||||
|
@ -170,6 +171,39 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) {
|
|||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) {
|
||||
|
||||
uint32 masks = batch._params[paramOffset + 6]._uint;
|
||||
Vec4 color;
|
||||
color.x = batch._params[paramOffset + 5]._float;
|
||||
color.y = batch._params[paramOffset + 4]._float;
|
||||
color.z = batch._params[paramOffset + 3]._float;
|
||||
color.w = batch._params[paramOffset + 2]._float;
|
||||
float depth = batch._params[paramOffset + 1]._float;
|
||||
int stencil = batch._params[paramOffset + 0]._float;
|
||||
|
||||
GLuint glmask = 0;
|
||||
if (masks & Framebuffer::BUFFER_DEPTH) {
|
||||
glClearStencil(stencil);
|
||||
glmask |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (masks & Framebuffer::BUFFER_DEPTH) {
|
||||
glClearDepth(depth);
|
||||
glmask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (masks & Framebuffer::BUFFER_COLORS) {
|
||||
glClearColor(color.x, color.y, color.z, color.w);
|
||||
glmask |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
glClear(glmask);
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
|
|
@ -191,6 +191,8 @@ protected:
|
|||
void do_drawInstanced(Batch& batch, uint32 paramOffset);
|
||||
void do_drawIndexedInstanced(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_clearFramebuffer(Batch& batch, uint32 paramOffset);
|
||||
|
||||
// Input Stage
|
||||
void do_setInputFormat(Batch& batch, uint32 paramOffset);
|
||||
void do_setInputBuffer(Batch& batch, uint32 paramOffset);
|
||||
|
|
|
@ -171,10 +171,21 @@ void GLBackend::do_setUniformTexture(Batch& batch, uint32 paramOffset) {
|
|||
GLuint slot = batch._params[paramOffset + 1]._uint;
|
||||
TexturePointer uniformTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
|
||||
|
||||
GLuint to = getTextureID(uniformTexture);
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, to);
|
||||
if (!uniformTexture) {
|
||||
return;
|
||||
}
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
GLTexture* object = GLBackend::syncGPUObject(*uniformTexture);
|
||||
if (object) {
|
||||
GLuint to = object->_texture;
|
||||
GLuint target = object->_target;
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(target, to);
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -363,6 +363,93 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case Texture::TEX_CUBE: {
|
||||
if (texture.getNumSlices() == 1) {
|
||||
GLint boundTex = -1;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &boundTex);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, object->_texture);
|
||||
const int NUM_FACES = 6;
|
||||
const GLenum FACE_LAYOUT[] = {
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
|
||||
|
||||
if (needUpdate) {
|
||||
if (texture.isStoredMipAvailable(0)) {
|
||||
Texture::PixelsPointer mip = texture.accessStoredMip(0);
|
||||
Element srcFormat = mip->_format;
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat);
|
||||
|
||||
uint16 width = texture.getWidth();
|
||||
int faceSize = mip->_sysmem.getSize() / NUM_FACES;
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, object->_texture);
|
||||
for (int f = 0; f < NUM_FACES; f++) {
|
||||
glTexSubImage2D(FACE_LAYOUT[f], 0, texelFormat.internalFormat, width, width, 0,
|
||||
texelFormat.format, texelFormat.type, (GLvoid*) (mip->_sysmem.read<Resource::Byte>() + f * faceSize));
|
||||
}
|
||||
|
||||
if (texture.isAutogenerateMips()) {
|
||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
|
||||
object->_target = GL_TEXTURE_CUBE_MAP;
|
||||
|
||||
syncSampler(texture.getSampler(), texture.getType(), object);
|
||||
|
||||
// At this point the mip piels have been loaded, we can notify
|
||||
texture.notifyGPULoaded(0);
|
||||
|
||||
object->_contentStamp = texture.getDataStamp();
|
||||
}
|
||||
} else {
|
||||
const gpu::Resource::Byte* bytes = 0;
|
||||
Element srcFormat = texture.getTexelFormat();
|
||||
uint16 width = texture.getWidth();
|
||||
int faceSize = 0;
|
||||
|
||||
if (texture.isStoredMipAvailable(0)) {
|
||||
Texture::PixelsPointer mip = texture.accessStoredMip(0);
|
||||
|
||||
bytes = mip->_sysmem.read<Resource::Byte>();
|
||||
srcFormat = mip->_format;
|
||||
faceSize = mip->_sysmem.getSize() / NUM_FACES;
|
||||
|
||||
object->_contentStamp = texture.getDataStamp();
|
||||
}
|
||||
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat);
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, object->_texture);
|
||||
for (int f = 0; f < NUM_FACES; f++) {
|
||||
glTexImage2D(FACE_LAYOUT[f], 0, texelFormat.internalFormat, width, width, 0,
|
||||
texelFormat.format, texelFormat.type, (GLvoid*) (bytes + f * faceSize));
|
||||
}
|
||||
|
||||
if (bytes && texture.isAutogenerateMips()) {
|
||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
object->_target = GL_TEXTURE_CUBE_MAP;
|
||||
|
||||
syncSampler(texture.getSampler(), texture.getType(), object);
|
||||
|
||||
// At this point the mip piels have been loaded, we can notify
|
||||
texture.notifyGPULoaded(0);
|
||||
|
||||
object->_storageStamp = texture.getStamp();
|
||||
object->_size = texture.getSize();
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, boundTex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qCDebug(gpulogging) << "GLBackend::syncGPUObject(const Texture&) case for Texture Type " << texture.getType() << " not supported";
|
||||
}
|
||||
|
@ -449,6 +536,5 @@ void GLBackend::syncSampler(const Sampler& sampler, Texture::Type type, GLTextur
|
|||
glTexParameterf(object->_target, GL_TEXTURE_MIN_LOD, (float) sampler.getMinMip());
|
||||
glTexParameterf(object->_target, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip()));
|
||||
glTexParameterf(object->_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy());
|
||||
(void) CHECK_GL_ERROR();
|
||||
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ void GLBackend::updateTransform() {
|
|||
// Check all the dirty flags and update the state accordingly
|
||||
if (_transform._invalidProj) {
|
||||
_transform._transformCamera._projection = _transform._projection;
|
||||
_transform._transformCamera._projectionInverse = glm::inverse(_transform._projection);
|
||||
}
|
||||
|
||||
if (_transform._invalidView) {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
using namespace gpu;
|
||||
|
||||
uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = {1, 1, 1, 6};
|
||||
|
||||
Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) :
|
||||
_sysmem(size, bytes),
|
||||
_format(format),
|
||||
|
@ -131,19 +133,7 @@ Texture* Texture::createFromStorage(Storage* storage) {
|
|||
}
|
||||
|
||||
Texture::Texture():
|
||||
Resource(),
|
||||
_storage(),
|
||||
_stamp(0),
|
||||
_size(0),
|
||||
_width(1),
|
||||
_height(1),
|
||||
_depth(1),
|
||||
_numSamples(1),
|
||||
_numSlices(1),
|
||||
_maxMip(0),
|
||||
_type(TEX_1D),
|
||||
_autoGenerateMips(false),
|
||||
_defined(false)
|
||||
Resource()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -186,10 +176,9 @@ Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 widt
|
|||
_depth = depth;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
// Evaluate the new size with the new format
|
||||
const int DIM_SIZE[] = {1, 1, 1, 6};
|
||||
uint32_t size = DIM_SIZE[_type] *_width * _height * _depth * _numSamples * texelFormat.getSize();
|
||||
uint32_t size = NUM_FACES_PER_TYPE[_type] *_width * _height * _depth * _numSamples * texelFormat.getSize();
|
||||
|
||||
// If size change then we need to reset
|
||||
if (changed || (size != getSize())) {
|
||||
|
|
|
@ -138,6 +138,8 @@ public:
|
|||
TEX_2D,
|
||||
TEX_3D,
|
||||
TEX_CUBE,
|
||||
|
||||
NUM_TYPES,
|
||||
};
|
||||
|
||||
static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler());
|
||||
|
@ -180,11 +182,19 @@ public:
|
|||
uint16 getDepth() const { return _depth; }
|
||||
|
||||
uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); }
|
||||
uint32 getNumTexels() const { return _width * _height * _depth; }
|
||||
|
||||
// The number of faces is mostly used for cube map, and maybe for stereo ? otherwise it's 1
|
||||
// For cube maps, this means the pixels of the different faces are supposed to bepacked back to back in a mip
|
||||
// as if the height was NUM_FACES time bigger.
|
||||
static uint8 NUM_FACES_PER_TYPE[NUM_TYPES];
|
||||
uint8 getNumFaces() const { return NUM_FACES_PER_TYPE[getType()]; }
|
||||
|
||||
uint32 getNumTexels() const { return _width * _height * _depth * getNumFaces(); }
|
||||
|
||||
uint16 getNumSlices() const { return _numSlices; }
|
||||
uint16 getNumSamples() const { return _numSamples; }
|
||||
|
||||
|
||||
// NumSamples can only have certain values based on the hw
|
||||
static uint16 evalNumSamplesUsed(uint16 numSamplesTried);
|
||||
|
||||
|
@ -203,7 +213,7 @@ public:
|
|||
uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); }
|
||||
uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); }
|
||||
uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); }
|
||||
uint32 evalMipNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); }
|
||||
uint32 evalMipNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getNumFaces(); }
|
||||
uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); }
|
||||
uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); }
|
||||
|
||||
|
@ -269,27 +279,26 @@ public:
|
|||
protected:
|
||||
std::unique_ptr< Storage > _storage;
|
||||
|
||||
Stamp _stamp;
|
||||
Stamp _stamp = 0;
|
||||
|
||||
Sampler _sampler;
|
||||
Stamp _samplerStamp;
|
||||
|
||||
|
||||
uint32 _size;
|
||||
uint32 _size = 0;
|
||||
Element _texelFormat;
|
||||
|
||||
uint16 _width;
|
||||
uint16 _height;
|
||||
uint16 _depth;
|
||||
uint16 _width = 1;
|
||||
uint16 _height = 1;
|
||||
uint16 _depth = 1;
|
||||
|
||||
uint16 _numSamples;
|
||||
uint16 _numSlices;
|
||||
uint16 _numSamples = 1;
|
||||
uint16 _numSlices = 1;
|
||||
|
||||
uint16 _maxMip;
|
||||
uint16 _maxMip = 0;
|
||||
|
||||
Type _type;
|
||||
bool _autoGenerateMips;
|
||||
bool _defined;
|
||||
Type _type = TEX_1D;
|
||||
bool _autoGenerateMips = false;
|
||||
bool _defined = false;
|
||||
|
||||
static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler);
|
||||
Texture();
|
||||
|
|
|
@ -21,6 +21,7 @@ struct TransformCamera {
|
|||
mat4 _viewInverse;
|
||||
mat4 _projectionViewUntranslated;
|
||||
mat4 _projection;
|
||||
mat4 _projectionInverse;
|
||||
vec4 _viewport;
|
||||
};
|
||||
|
||||
|
@ -120,4 +121,22 @@ TransformCamera getTransformCamera() {
|
|||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@func transformEyeToWorldDir(cameraTransform, eyeDir, worldDir)@>
|
||||
<@if GPU_TRANSFORM_PROFILE == GPU_CORE@>
|
||||
{ // transformEyeToWorldDir
|
||||
<$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0));
|
||||
}
|
||||
<@else@>
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@func transformClipToEyeDir(cameraTransform, clipPos, eyeDir)@>
|
||||
<@if GPU_TRANSFORM_PROFILE == GPU_CORE@>
|
||||
{ // transformClipToEyedDir
|
||||
<$eyeDir$> = vec3(<$cameraTransform$>._projectionInverse * vec4(<$clipPos$>.xyz, 1.0));
|
||||
}
|
||||
<@else@>
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -10,12 +10,73 @@
|
|||
//
|
||||
#include "Skybox.h"
|
||||
|
||||
#include "gpu/Batch.h"
|
||||
#include "gpu/Context.h"
|
||||
|
||||
#include "ViewFrustum.h"
|
||||
#include "skybox_vert.h"
|
||||
#include "skybox_frag.h"
|
||||
|
||||
using namespace model;
|
||||
|
||||
Skybox::Skybox() {
|
||||
|
||||
_cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1));
|
||||
unsigned char texels[] = {
|
||||
255, 0, 0, 255,
|
||||
0, 255, 255, 255,
|
||||
0, 0, 255, 255,
|
||||
255, 255, 0, 255,
|
||||
0, 255, 0, 255,
|
||||
255, 0, 255, 255,
|
||||
};
|
||||
_cubemap->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, sizeof(texels), texels);
|
||||
}
|
||||
|
||||
void Skybox::setColor(const Color& color) {
|
||||
_color = color;
|
||||
}
|
||||
|
||||
void Skybox::setCubemap(const gpu::TexturePointer& cubemap) {
|
||||
_cubemap = cubemap;
|
||||
}
|
||||
|
||||
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) {
|
||||
|
||||
if (skybox.getCubemap()) {
|
||||
|
||||
static gpu::PipelinePointer thePipeline;
|
||||
if (!thePipeline) {
|
||||
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
|
||||
auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag)));
|
||||
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS));
|
||||
|
||||
gpu::Shader::BindingSet bindings;
|
||||
bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0));
|
||||
|
||||
if (!gpu::Shader::makeProgram(*skyShader, bindings)) {
|
||||
|
||||
}
|
||||
|
||||
auto skyState = gpu::StatePointer(new gpu::State());
|
||||
|
||||
thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
|
||||
}
|
||||
|
||||
glm::mat4 projMat;
|
||||
viewFrustum.evalProjectionMatrix(projMat);
|
||||
|
||||
Transform viewTransform;
|
||||
viewFrustum.evalViewTransform(viewTransform);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewTransform);
|
||||
batch.setPipeline(thePipeline);
|
||||
batch.setUniformTexture(0, skybox.getCubemap());
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
} else {
|
||||
// skybox has no cubemap, just clear the color buffer
|
||||
auto color = skybox.getColor();
|
||||
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(skybox.getColor(),1.0f), 0.f, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
|
||||
#include "gpu/Texture.h"
|
||||
|
||||
class ViewFrustum;
|
||||
//class Transform;
|
||||
namespace gpu { class Batch; }
|
||||
|
||||
namespace model {
|
||||
|
||||
typedef glm::vec3 Color;
|
||||
|
@ -24,14 +28,16 @@ public:
|
|||
virtual ~Skybox() {};
|
||||
|
||||
void setColor(const Color& color);
|
||||
const Color& getColor() { return _color; }
|
||||
const Color& getColor() const { return _color; }
|
||||
|
||||
void setCubemap(const gpu::TexturePointer& cubemap);
|
||||
const gpu::TexturePointer& getCubemap() const { return _cubemap; }
|
||||
|
||||
static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox);
|
||||
|
||||
protected:
|
||||
gpu::TexturePointer _cubemap;
|
||||
Color _color;
|
||||
Color _color{1.0f, 1.0f, 1.0f};
|
||||
};
|
||||
typedef std::shared_ptr< Skybox > SkyboxPointer;
|
||||
|
||||
|
|
24
libraries/model/src/model/Skybox.slf
Executable file
24
libraries/model/src/model/Skybox.slf
Executable file
|
@ -0,0 +1,24 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// skybox.frag
|
||||
//
|
||||
// Created by Sam Gateau on 5/5/2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
uniform samplerCube cubeMap;
|
||||
|
||||
varying vec3 normal;
|
||||
varying vec2 texcoord;
|
||||
varying vec3 color;
|
||||
|
||||
|
||||
void main(void) {
|
||||
vec4 texel = texture(cubeMap, normalize(normal));
|
||||
gl_FragData[0] = texel;
|
||||
// gl_FragData[0] = vec4(normal, 1.0);
|
||||
}
|
42
libraries/model/src/model/Skybox.slv
Executable file
42
libraries/model/src/model/Skybox.slv
Executable file
|
@ -0,0 +1,42 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// skybox.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Sam Gateau on 5/5/2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
varying vec3 normal;
|
||||
varying vec2 texcoord;
|
||||
varying vec3 color;
|
||||
|
||||
void main(void) {
|
||||
const float CLIP = 1.0;
|
||||
const vec2 vertices[4] = vec2[4](vec2(-CLIP, -CLIP), vec2(CLIP, -CLIP), vec2(-CLIP, CLIP), vec2(CLIP, CLIP));
|
||||
texcoord = vertices[gl_VertexID];
|
||||
|
||||
// pass along the diffuse color
|
||||
color = vec3(texcoord, 0.0);
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 clipDir = vec3(texcoord.xy, 0.0);
|
||||
vec3 eyeDir;
|
||||
|
||||
<$transformClipToEyeDir(cam, clipDir, eyeDir)$>;
|
||||
normal = normalize(eyeDir);
|
||||
<$transformEyeToWorldDir(cam, eyeDir, normal)$>;
|
||||
normal = normalize(normal);
|
||||
|
||||
// Position is supposed to cmoe in clip space
|
||||
gl_Position = vec4(texcoord.xy, 0.0, 1.0);
|
||||
}
|
|
@ -215,6 +215,10 @@ SunSkyStage::SunSkyStage() :
|
|||
|
||||
_skyPipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
|
||||
|
||||
|
||||
_skybox.reset(new Skybox());
|
||||
_skybox->setColor(Color(1.0f, 0.0f, 0.0f));
|
||||
|
||||
}
|
||||
|
||||
SunSkyStage::~SunSkyStage() {
|
||||
|
|
|
@ -223,7 +223,7 @@ public:
|
|||
const SkyboxPointer& getSkybox() const { valid(); return _skybox; }
|
||||
|
||||
protected:
|
||||
BackgroundMode _backgroundMode = SKY_DOME;
|
||||
BackgroundMode _backgroundMode = SKY_BOX;
|
||||
|
||||
LightPointer _sunLight;
|
||||
AtmospherePointer _atmosphere;
|
||||
|
|
|
@ -862,3 +862,7 @@ void ViewFrustum::evalProjectionMatrix(glm::mat4& proj) const {
|
|||
}
|
||||
}
|
||||
|
||||
void ViewFrustum::evalViewTransform(Transform& view) const {
|
||||
view.setTranslation(getPosition());
|
||||
view.setRotation(getOrientation());
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <GLMHelpers.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
||||
#include "Transform.h"
|
||||
#include "AABox.h"
|
||||
#include "AACube.h"
|
||||
#include "Plane.h"
|
||||
|
@ -121,6 +122,8 @@ public:
|
|||
float distanceToCamera(const glm::vec3& point) const;
|
||||
|
||||
void evalProjectionMatrix(glm::mat4& proj) const;
|
||||
void evalViewTransform(Transform& view) const;
|
||||
|
||||
private:
|
||||
// Used for keyhole calculations
|
||||
ViewFrustum::location pointInKeyhole(const glm::vec3& point) const;
|
||||
|
|
Loading…
Reference in a new issue