mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 12:23:24 +02:00
Merge pull request #4780 from samcake/blue
Add support for Skybox and rendering path of background according to Zones
This commit is contained in:
commit
5551997cdc
36 changed files with 1050 additions and 606 deletions
|
@ -3161,39 +3161,62 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][2]);
|
||||
}
|
||||
|
||||
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) {
|
||||
PerformanceTimer perfTimer("stars");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... stars...");
|
||||
if (!_stars.isStarsLoaded()) {
|
||||
_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED);
|
||||
}
|
||||
// should be the first rendering pass - w/o depth buffer / lighting
|
||||
|
||||
// compute starfield alpha based on distance from atmosphere
|
||||
float alpha = 1.0f;
|
||||
bool hasStars = true;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||
// TODO: handle this correctly for zones
|
||||
const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition());
|
||||
|
||||
if (closestData.getHasStars()) {
|
||||
float height = glm::distance(theCamera.getPosition(), closestData.getAtmosphereCenter());
|
||||
if (height < closestData.getAtmosphereInnerRadius()) {
|
||||
alpha = 0.0f;
|
||||
|
||||
} else if (height < closestData.getAtmosphereOuterRadius()) {
|
||||
alpha = (height - closestData.getAtmosphereInnerRadius()) /
|
||||
(closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
|
||||
}
|
||||
} else {
|
||||
hasStars = false;
|
||||
// Background rendering decision
|
||||
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||
if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) {
|
||||
} else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) {
|
||||
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) {
|
||||
PerformanceTimer perfTimer("stars");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... stars...");
|
||||
if (!_stars.isStarsLoaded()) {
|
||||
_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED);
|
||||
}
|
||||
}
|
||||
// should be the first rendering pass - w/o depth buffer / lighting
|
||||
|
||||
// finally render the starfield
|
||||
if (hasStars) {
|
||||
_stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha);
|
||||
// compute starfield alpha based on distance from atmosphere
|
||||
float alpha = 1.0f;
|
||||
bool hasStars = true;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||
// TODO: handle this correctly for zones
|
||||
const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition());
|
||||
|
||||
if (closestData.getHasStars()) {
|
||||
float height = glm::distance(theCamera.getPosition(), closestData.getAtmosphereCenter());
|
||||
if (height < closestData.getAtmosphereInnerRadius()) {
|
||||
alpha = 0.0f;
|
||||
|
||||
} else if (height < closestData.getAtmosphereOuterRadius()) {
|
||||
alpha = (height - closestData.getAtmosphereInnerRadius()) /
|
||||
(closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
|
||||
}
|
||||
} else {
|
||||
hasStars = false;
|
||||
}
|
||||
}
|
||||
|
||||
// finally render the starfield
|
||||
if (hasStars) {
|
||||
_stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha);
|
||||
}
|
||||
|
||||
// draw the sky dome
|
||||
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||
PerformanceTimer perfTimer("atmosphere");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... atmosphere...");
|
||||
_environment.renderAtmospheres(theCamera);
|
||||
}
|
||||
|
||||
}
|
||||
} else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
|
||||
auto skybox = skyStage->getSkybox();
|
||||
if (skybox) {
|
||||
gpu::Batch batch;
|
||||
model::Skybox::render(batch, _viewFrustum, *skybox);
|
||||
|
||||
gpu::GLBackend::renderBatch(batch);
|
||||
glUseProgram(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3201,13 +3224,6 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
}
|
||||
|
||||
// draw the sky dome
|
||||
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||
PerformanceTimer perfTimer("atmosphere");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... atmosphere...");
|
||||
_environment.renderAtmospheres(theCamera);
|
||||
}
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
|
|
|
@ -123,7 +123,11 @@ void KeyboardMouseDevice::touchUpdateEvent(const QTouchEvent* event) {
|
|||
}
|
||||
|
||||
UserInputMapper::Input KeyboardMouseDevice::makeInput(Qt::Key code) {
|
||||
return UserInputMapper::Input(_deviceID, code & KEYBOARD_MASK, UserInputMapper::ChannelType::BUTTON);
|
||||
auto shortCode = (UserInputMapper::uint16)(code & KEYBOARD_MASK);
|
||||
if (shortCode != code) {
|
||||
shortCode |= 0x0800; // add this bit instead of the way Qt::Key add a bit on the 3rd byte for some keys
|
||||
}
|
||||
return UserInputMapper::Input(_deviceID, shortCode, UserInputMapper::ChannelType::BUTTON);
|
||||
}
|
||||
|
||||
UserInputMapper::Input KeyboardMouseDevice::makeInput(Qt::MouseButton code) {
|
||||
|
|
|
@ -1688,7 +1688,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
}
|
||||
} else if (object.name == "Material") {
|
||||
Material material = { glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(), 96.0f, 1.0f,
|
||||
QString(""), QSharedPointer<model::Material>(NULL)};
|
||||
QString(""), model::MaterialPointer(NULL)};
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
bool properties = false;
|
||||
QByteArray propertyName;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ typedef short int16;
|
|||
typedef unsigned char uint8;
|
||||
typedef char int8;
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
||||
typedef uint32 Offset;
|
||||
|
||||
typedef glm::mat4 Mat4;
|
||||
|
@ -182,18 +184,18 @@ public:
|
|||
uint8 _type : 4;
|
||||
};
|
||||
|
||||
|
||||
enum ComparisonFunction {
|
||||
NEVER = 0,
|
||||
LESS,
|
||||
EQUAL,
|
||||
LESS_EQUAL,
|
||||
GREATER,
|
||||
NOT_EQUAL,
|
||||
GREATER_EQUAL,
|
||||
ALWAYS,
|
||||
|
||||
NUM_COMPARISON_FUNCS,
|
||||
|
||||
enum ComparisonFunction {
|
||||
NEVER = 0,
|
||||
LESS,
|
||||
EQUAL,
|
||||
LESS_EQUAL,
|
||||
GREATER,
|
||||
NOT_EQUAL,
|
||||
GREATER_EQUAL,
|
||||
ALWAYS,
|
||||
|
||||
NUM_COMPARISON_FUNCS,
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -297,7 +297,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
|
|||
if (needUpdate) {
|
||||
if (texture.isStoredMipAvailable(0)) {
|
||||
Texture::PixelsPointer mip = texture.accessStoredMip(0);
|
||||
const GLvoid* bytes = mip->_sysmem.read<Resource::Byte>();
|
||||
const GLvoid* bytes = mip->_sysmem.read<Byte>();
|
||||
Element srcFormat = mip->_format;
|
||||
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat);
|
||||
|
@ -328,7 +328,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
|
|||
if (texture.isStoredMipAvailable(0)) {
|
||||
Texture::PixelsPointer mip = texture.accessStoredMip(0);
|
||||
|
||||
bytes = mip->_sysmem.read<Resource::Byte>();
|
||||
bytes = mip->_sysmem.read<Byte>();
|
||||
srcFormat = mip->_format;
|
||||
|
||||
object->_contentStamp = texture.getDataStamp();
|
||||
|
@ -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<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::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<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) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <memory>
|
||||
#ifdef _DEBUG
|
||||
#include <QDebug>
|
||||
#endif
|
||||
|
@ -26,7 +26,6 @@ namespace gpu {
|
|||
|
||||
class Resource {
|
||||
public:
|
||||
typedef unsigned char Byte;
|
||||
typedef unsigned int Size;
|
||||
|
||||
static const Size NOT_ALLOCATED = -1;
|
||||
|
@ -156,7 +155,7 @@ protected:
|
|||
friend class Backend;
|
||||
};
|
||||
|
||||
typedef QSharedPointer<Buffer> BufferPointer;
|
||||
typedef std::shared_ptr<Buffer> BufferPointer;
|
||||
typedef std::vector< BufferPointer > Buffers;
|
||||
|
||||
|
||||
|
@ -317,7 +316,7 @@ public:
|
|||
|
||||
template <typename T> const T& get() const {
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
if (!_buffer) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - _offset)) {
|
||||
|
@ -333,7 +332,7 @@ public:
|
|||
|
||||
template <typename T> T& edit() {
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
if (!_buffer) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - _offset)) {
|
||||
|
@ -350,7 +349,7 @@ public:
|
|||
template <typename T> const T& get(const Index index) const {
|
||||
Resource::Size elementOffset = index * sizeof(T) + _offset;
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
if (!_buffer) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - elementOffset)) {
|
||||
|
@ -366,7 +365,7 @@ public:
|
|||
template <typename T> T& edit(const Index index) const {
|
||||
Resource::Size elementOffset = index * sizeof(T) + _offset;
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
if (!_buffer) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - elementOffset)) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define hifi_gpu_Shader_h
|
||||
|
||||
#include "Resource.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace gpu {
|
|||
class Shader {
|
||||
public:
|
||||
|
||||
typedef QSharedPointer< Shader > Pointer;
|
||||
typedef std::shared_ptr< Shader > Pointer;
|
||||
typedef std::vector< Pointer > Shaders;
|
||||
|
||||
class Source {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
//
|
||||
|
||||
#include "Stream.h"
|
||||
|
||||
#include <algorithm> //min max and more
|
||||
|
||||
using namespace gpu;
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ public:
|
|||
void evaluateCache();
|
||||
};
|
||||
|
||||
typedef QSharedPointer<Format> FormatPointer;
|
||||
typedef std::shared_ptr<Format> FormatPointer;
|
||||
};
|
||||
|
||||
typedef std::vector< Offset > Offsets;
|
||||
|
@ -143,7 +143,7 @@ protected:
|
|||
Offsets _offsets;
|
||||
Strides _strides;
|
||||
};
|
||||
typedef QSharedPointer<BufferStream> BufferStreamPointer;
|
||||
typedef std::shared_ptr<BufferStream> BufferStreamPointer;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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())) {
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
//
|
||||
// Texture.h
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 1/16/2015.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_gpu_Texture_h
|
||||
#define hifi_gpu_Texture_h
|
||||
|
||||
#include "Resource.h"
|
||||
#include <memory>
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class Sampler {
|
||||
public:
|
||||
|
||||
//
|
||||
// Texture.h
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 1/16/2015.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_gpu_Texture_h
|
||||
#define hifi_gpu_Texture_h
|
||||
|
||||
#include "Resource.h"
|
||||
|
||||
#include <algorithm> //min max and more
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class Sampler {
|
||||
public:
|
||||
|
||||
enum Filter {
|
||||
FILTER_MIN_MAG_POINT, // top mip only
|
||||
FILTER_MIN_POINT_MAG_LINEAR, // top mip only
|
||||
|
@ -46,7 +47,7 @@ public:
|
|||
WRAP_MIRROR_ONCE,
|
||||
|
||||
NUM_WRAP_MODES
|
||||
};
|
||||
};
|
||||
|
||||
static const uint8 MAX_MIP_LEVEL = 0xFF;
|
||||
|
||||
|
@ -92,264 +93,273 @@ public:
|
|||
uint8 getMaxMip() const { return _desc._maxMip; }
|
||||
|
||||
protected:
|
||||
Desc _desc;
|
||||
};
|
||||
|
||||
class Texture : public Resource {
|
||||
public:
|
||||
|
||||
class Pixels {
|
||||
public:
|
||||
Pixels() {}
|
||||
Pixels(const Pixels& pixels) = default;
|
||||
Pixels(const Element& format, Size size, const Byte* bytes);
|
||||
~Pixels();
|
||||
|
||||
Sysmem _sysmem;
|
||||
Element _format;
|
||||
bool _isGPULoaded;
|
||||
};
|
||||
typedef QSharedPointer< Pixels > PixelsPointer;
|
||||
|
||||
class Storage {
|
||||
public:
|
||||
Storage() {}
|
||||
virtual ~Storage() {}
|
||||
virtual void reset();
|
||||
virtual PixelsPointer editMip(uint16 level);
|
||||
virtual const PixelsPointer getMip(uint16 level) const;
|
||||
virtual Stamp getStamp(uint16 level) const;
|
||||
virtual bool allocateMip(uint16 level);
|
||||
virtual bool assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||
virtual bool isMipAvailable(uint16 level) const;
|
||||
virtual void notifyGPULoaded(uint16 level) const;
|
||||
|
||||
protected:
|
||||
Texture* _texture;
|
||||
std::vector<PixelsPointer> _mips;
|
||||
|
||||
virtual void assignTexture(Texture* tex);
|
||||
|
||||
friend class Texture;
|
||||
};
|
||||
|
||||
enum Type {
|
||||
TEX_1D = 0,
|
||||
TEX_2D,
|
||||
TEX_3D,
|
||||
TEX_CUBE,
|
||||
};
|
||||
|
||||
static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler());
|
||||
static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler = Sampler());
|
||||
static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, const Sampler& sampler = Sampler());
|
||||
static Texture* createCube(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler());
|
||||
|
||||
static Texture* createFromStorage(Storage* storage);
|
||||
|
||||
Texture(const Texture& buf); // deep copy of the sysmem texture
|
||||
Texture& operator=(const Texture& buf); // deep copy of the sysmem texture
|
||||
~Texture();
|
||||
|
||||
Stamp getStamp() const { return _stamp; }
|
||||
Stamp getDataStamp(uint16 level = 0) const { return _storage->getStamp(level); }
|
||||
|
||||
// The size in bytes of data stored in the texture
|
||||
Size getSize() const { return _size; }
|
||||
|
||||
// Resize, unless auto mips mode would destroy all the sub mips
|
||||
Size resize1D(uint16 width, uint16 numSamples);
|
||||
Size resize2D(uint16 width, uint16 height, uint16 numSamples);
|
||||
Size resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples);
|
||||
Size resizeCube(uint16 width, uint16 numSamples);
|
||||
|
||||
// Reformat, unless auto mips mode would destroy all the sub mips
|
||||
Size reformat(const Element& texelFormat);
|
||||
|
||||
// Size and format
|
||||
Type getType() const { return _type; }
|
||||
|
||||
bool isColorRenderTarget() const;
|
||||
bool isDepthStencilRenderTarget() const;
|
||||
|
||||
const Element& getTexelFormat() const { return _texelFormat; }
|
||||
bool hasBorder() const { return false; }
|
||||
|
||||
uint16 getWidth() const { return _width; }
|
||||
uint16 getHeight() const { return _height; }
|
||||
uint16 getDepth() const { return _depth; }
|
||||
|
||||
uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); }
|
||||
uint32 getNumTexels() const { return _width * _height * _depth; }
|
||||
|
||||
uint16 getNumSlices() const { return _numSlices; }
|
||||
uint16 getNumSamples() const { return _numSamples; }
|
||||
|
||||
// NumSamples can only have certain values based on the hw
|
||||
static uint16 evalNumSamplesUsed(uint16 numSamplesTried);
|
||||
|
||||
// Mips size evaluation
|
||||
|
||||
// The number mips that a dimension could haves
|
||||
// = 1 + log2(size)
|
||||
static uint16 evalDimNumMips(uint16 size);
|
||||
|
||||
// The number mips that the texture could have if all existed
|
||||
// = 1 + log2(max(width, height, depth))
|
||||
uint16 evalNumMips() const;
|
||||
|
||||
// Eval the size that the mips level SHOULD have
|
||||
// not the one stored in the Texture
|
||||
uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); }
|
||||
uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); }
|
||||
uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); }
|
||||
uint32 evalMipNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); }
|
||||
uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); }
|
||||
uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); }
|
||||
|
||||
uint32 evalTotalSize() const {
|
||||
uint32 size = 0;
|
||||
uint16 minMipLevel = 0;
|
||||
uint16 maxMipLevel = maxMip();
|
||||
for (uint16 l = minMipLevel; l <= maxMipLevel; l++) {
|
||||
size += evalMipSize(l);
|
||||
}
|
||||
return size * getNumSlices();
|
||||
}
|
||||
|
||||
// max mip is in the range [ 1 if no sub mips, log2(max(width, height, depth))]
|
||||
// if autoGenerateMip is on => will provide the maxMIp level specified
|
||||
// else provide the deepest mip level provided through assignMip
|
||||
uint16 maxMip() const;
|
||||
|
||||
// Generate the mips automatically
|
||||
// But the sysmem version is not available
|
||||
// Only works for the standard formats
|
||||
// Specify the maximum Mip level available
|
||||
// 0 is the default one
|
||||
// 1 is the first level
|
||||
// ...
|
||||
// nbMips - 1 is the last mip level
|
||||
//
|
||||
// If -1 then all the mips are generated
|
||||
//
|
||||
// Return the totalnumber of mips that will be available
|
||||
uint16 autoGenerateMips(uint16 maxMip);
|
||||
bool isAutogenerateMips() const { return _autoGenerateMips; }
|
||||
|
||||
// Managing Storage and mips
|
||||
|
||||
// Manually allocate the mips down until the specified maxMip
|
||||
// this is just allocating the sysmem version of it
|
||||
// in case autoGen is on, this doesn't allocate
|
||||
// Explicitely assign mip data for a certain level
|
||||
// If Bytes is NULL then simply allocate the space so mip sysmem can be accessed
|
||||
bool assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||
|
||||
// Access the the sub mips
|
||||
bool isStoredMipAvailable(uint16 level) const { return _storage->isMipAvailable(level); }
|
||||
const PixelsPointer accessStoredMip(uint16 level) const { return _storage->getMip(level); }
|
||||
void notifyGPULoaded(uint16 level) const { return _storage->notifyGPULoaded(level); }
|
||||
|
||||
// access sizes for the stored mips
|
||||
uint16 getStoredMipWidth(uint16 level) const;
|
||||
uint16 getStoredMipHeight(uint16 level) const;
|
||||
uint16 getStoredMipDepth(uint16 level) const;
|
||||
uint32 getStoredMipNumTexels(uint16 level) const;
|
||||
uint32 getStoredMipSize(uint16 level) const;
|
||||
|
||||
bool isDefined() const { return _defined; }
|
||||
|
||||
|
||||
// Own sampler
|
||||
void setSampler(const Sampler& sampler);
|
||||
const Sampler& getSampler() const { return _sampler; }
|
||||
Stamp getSamplerStamp() const { return _samplerStamp; }
|
||||
|
||||
protected:
|
||||
std::unique_ptr< Storage > _storage;
|
||||
|
||||
Stamp _stamp;
|
||||
|
||||
Sampler _sampler;
|
||||
Stamp _samplerStamp;
|
||||
|
||||
|
||||
uint32 _size;
|
||||
Element _texelFormat;
|
||||
|
||||
uint16 _width;
|
||||
uint16 _height;
|
||||
uint16 _depth;
|
||||
|
||||
uint16 _numSamples;
|
||||
uint16 _numSlices;
|
||||
|
||||
uint16 _maxMip;
|
||||
|
||||
Type _type;
|
||||
bool _autoGenerateMips;
|
||||
bool _defined;
|
||||
|
||||
static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler);
|
||||
Texture();
|
||||
|
||||
Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices);
|
||||
|
||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||
mutable GPUObject* _gpuObject = NULL;
|
||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||
GPUObject* getGPUObject() const { return _gpuObject; }
|
||||
friend class Backend;
|
||||
};
|
||||
|
||||
typedef QSharedPointer<Texture> TexturePointer;
|
||||
typedef std::vector< TexturePointer > Textures;
|
||||
|
||||
|
||||
// TODO: For now TextureView works with Buffer as a place holder for the Texture.
|
||||
// The overall logic should be about the same except that the Texture will be a real GL Texture under the hood
|
||||
class TextureView {
|
||||
public:
|
||||
typedef Resource::Size Size;
|
||||
|
||||
TexturePointer _texture = TexturePointer(NULL);
|
||||
uint16 _subresource = 0;
|
||||
Element _element = Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
|
||||
|
||||
TextureView() {};
|
||||
|
||||
TextureView(const Element& element) :
|
||||
_element(element)
|
||||
{};
|
||||
|
||||
// create the TextureView and own the Texture
|
||||
TextureView(Texture* newTexture, const Element& element) :
|
||||
_texture(newTexture),
|
||||
_subresource(0),
|
||||
_element(element)
|
||||
{};
|
||||
TextureView(const TexturePointer& texture, uint16 subresource, const Element& element) :
|
||||
_texture(texture),
|
||||
_subresource(subresource),
|
||||
_element(element)
|
||||
{};
|
||||
|
||||
TextureView(const TexturePointer& texture, uint16 subresource) :
|
||||
_texture(texture),
|
||||
_subresource(subresource)
|
||||
{};
|
||||
|
||||
~TextureView() {}
|
||||
TextureView(const TextureView& view) = default;
|
||||
TextureView& operator=(const TextureView& view) = default;
|
||||
|
||||
explicit operator bool() const { return (_texture); }
|
||||
bool operator !() const { return (!_texture); }
|
||||
};
|
||||
typedef std::vector<TextureView> TextureViews;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Desc _desc;
|
||||
};
|
||||
|
||||
class Texture : public Resource {
|
||||
public:
|
||||
|
||||
class Pixels {
|
||||
public:
|
||||
Pixels() {}
|
||||
Pixels(const Pixels& pixels) = default;
|
||||
Pixels(const Element& format, Size size, const Byte* bytes);
|
||||
~Pixels();
|
||||
|
||||
Sysmem _sysmem;
|
||||
Element _format;
|
||||
bool _isGPULoaded;
|
||||
};
|
||||
typedef std::shared_ptr< Pixels > PixelsPointer;
|
||||
|
||||
class Storage {
|
||||
public:
|
||||
Storage() {}
|
||||
virtual ~Storage() {}
|
||||
virtual void reset();
|
||||
virtual PixelsPointer editMip(uint16 level);
|
||||
virtual const PixelsPointer getMip(uint16 level) const;
|
||||
virtual Stamp getStamp(uint16 level) const;
|
||||
virtual bool allocateMip(uint16 level);
|
||||
virtual bool assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||
virtual bool isMipAvailable(uint16 level) const;
|
||||
virtual void notifyGPULoaded(uint16 level) const;
|
||||
|
||||
protected:
|
||||
Texture* _texture;
|
||||
std::vector<PixelsPointer> _mips;
|
||||
|
||||
virtual void assignTexture(Texture* tex);
|
||||
|
||||
friend class Texture;
|
||||
};
|
||||
|
||||
enum Type {
|
||||
TEX_1D = 0,
|
||||
TEX_2D,
|
||||
TEX_3D,
|
||||
TEX_CUBE,
|
||||
|
||||
NUM_TYPES,
|
||||
};
|
||||
|
||||
static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler());
|
||||
static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler = Sampler());
|
||||
static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, const Sampler& sampler = Sampler());
|
||||
static Texture* createCube(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler());
|
||||
|
||||
static Texture* createFromStorage(Storage* storage);
|
||||
|
||||
Texture(const Texture& buf); // deep copy of the sysmem texture
|
||||
Texture& operator=(const Texture& buf); // deep copy of the sysmem texture
|
||||
~Texture();
|
||||
|
||||
Stamp getStamp() const { return _stamp; }
|
||||
Stamp getDataStamp(uint16 level = 0) const { return _storage->getStamp(level); }
|
||||
|
||||
// The size in bytes of data stored in the texture
|
||||
Size getSize() const { return _size; }
|
||||
|
||||
// Resize, unless auto mips mode would destroy all the sub mips
|
||||
Size resize1D(uint16 width, uint16 numSamples);
|
||||
Size resize2D(uint16 width, uint16 height, uint16 numSamples);
|
||||
Size resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples);
|
||||
Size resizeCube(uint16 width, uint16 numSamples);
|
||||
|
||||
// Reformat, unless auto mips mode would destroy all the sub mips
|
||||
Size reformat(const Element& texelFormat);
|
||||
|
||||
// Size and format
|
||||
Type getType() const { return _type; }
|
||||
|
||||
bool isColorRenderTarget() const;
|
||||
bool isDepthStencilRenderTarget() const;
|
||||
|
||||
const Element& getTexelFormat() const { return _texelFormat; }
|
||||
bool hasBorder() const { return false; }
|
||||
|
||||
uint16 getWidth() const { return _width; }
|
||||
uint16 getHeight() const { return _height; }
|
||||
uint16 getDepth() const { return _depth; }
|
||||
|
||||
uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); }
|
||||
|
||||
// The number of faces is mostly used for cube map, and maybe for stereo ? otherwise it's 1
|
||||
// For cube maps, this means the pixels of the different faces are supposed to be packed back to back in a mip
|
||||
// as if the height was NUM_FACES time bigger.
|
||||
static uint8 NUM_FACES_PER_TYPE[NUM_TYPES];
|
||||
uint8 getNumFaces() const { return NUM_FACES_PER_TYPE[getType()]; }
|
||||
|
||||
uint32 getNumTexels() const { return _width * _height * _depth * getNumFaces(); }
|
||||
|
||||
uint16 getNumSlices() const { return _numSlices; }
|
||||
uint16 getNumSamples() const { return _numSamples; }
|
||||
|
||||
|
||||
// NumSamples can only have certain values based on the hw
|
||||
static uint16 evalNumSamplesUsed(uint16 numSamplesTried);
|
||||
|
||||
// Mips size evaluation
|
||||
|
||||
// The number mips that a dimension could haves
|
||||
// = 1 + log2(size)
|
||||
static uint16 evalDimNumMips(uint16 size);
|
||||
|
||||
// The number mips that the texture could have if all existed
|
||||
// = 1 + log2(max(width, height, depth))
|
||||
uint16 evalNumMips() const;
|
||||
|
||||
// Eval the size that the mips level SHOULD have
|
||||
// not the one stored in the Texture
|
||||
uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); }
|
||||
uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); }
|
||||
uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); }
|
||||
uint32 evalMipNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getNumFaces(); }
|
||||
uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); }
|
||||
uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); }
|
||||
|
||||
uint32 evalTotalSize() const {
|
||||
uint32 size = 0;
|
||||
uint16 minMipLevel = 0;
|
||||
uint16 maxMipLevel = maxMip();
|
||||
for (uint16 l = minMipLevel; l <= maxMipLevel; l++) {
|
||||
size += evalMipSize(l);
|
||||
}
|
||||
return size * getNumSlices();
|
||||
}
|
||||
|
||||
// max mip is in the range [ 1 if no sub mips, log2(max(width, height, depth))]
|
||||
// if autoGenerateMip is on => will provide the maxMIp level specified
|
||||
// else provide the deepest mip level provided through assignMip
|
||||
uint16 maxMip() const;
|
||||
|
||||
// Generate the mips automatically
|
||||
// But the sysmem version is not available
|
||||
// Only works for the standard formats
|
||||
// Specify the maximum Mip level available
|
||||
// 0 is the default one
|
||||
// 1 is the first level
|
||||
// ...
|
||||
// nbMips - 1 is the last mip level
|
||||
//
|
||||
// If -1 then all the mips are generated
|
||||
//
|
||||
// Return the totalnumber of mips that will be available
|
||||
uint16 autoGenerateMips(uint16 maxMip);
|
||||
bool isAutogenerateMips() const { return _autoGenerateMips; }
|
||||
|
||||
// Managing Storage and mips
|
||||
|
||||
// Manually allocate the mips down until the specified maxMip
|
||||
// this is just allocating the sysmem version of it
|
||||
// in case autoGen is on, this doesn't allocate
|
||||
// Explicitely assign mip data for a certain level
|
||||
// If Bytes is NULL then simply allocate the space so mip sysmem can be accessed
|
||||
bool assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||
|
||||
// Access the the sub mips
|
||||
bool isStoredMipAvailable(uint16 level) const { return _storage->isMipAvailable(level); }
|
||||
const PixelsPointer accessStoredMip(uint16 level) const { return _storage->getMip(level); }
|
||||
void notifyGPULoaded(uint16 level) const { return _storage->notifyGPULoaded(level); }
|
||||
|
||||
// access sizes for the stored mips
|
||||
uint16 getStoredMipWidth(uint16 level) const;
|
||||
uint16 getStoredMipHeight(uint16 level) const;
|
||||
uint16 getStoredMipDepth(uint16 level) const;
|
||||
uint32 getStoredMipNumTexels(uint16 level) const;
|
||||
uint32 getStoredMipSize(uint16 level) const;
|
||||
|
||||
bool isDefined() const { return _defined; }
|
||||
|
||||
|
||||
// Own sampler
|
||||
void setSampler(const Sampler& sampler);
|
||||
const Sampler& getSampler() const { return _sampler; }
|
||||
Stamp getSamplerStamp() const { return _samplerStamp; }
|
||||
|
||||
protected:
|
||||
std::unique_ptr< Storage > _storage;
|
||||
|
||||
Stamp _stamp = 0;
|
||||
|
||||
Sampler _sampler;
|
||||
Stamp _samplerStamp;
|
||||
|
||||
uint32 _size = 0;
|
||||
Element _texelFormat;
|
||||
|
||||
uint16 _width = 1;
|
||||
uint16 _height = 1;
|
||||
uint16 _depth = 1;
|
||||
|
||||
uint16 _numSamples = 1;
|
||||
uint16 _numSlices = 1;
|
||||
|
||||
uint16 _maxMip = 0;
|
||||
|
||||
Type _type = TEX_1D;
|
||||
bool _autoGenerateMips = false;
|
||||
bool _defined = false;
|
||||
|
||||
static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler);
|
||||
Texture();
|
||||
|
||||
Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices);
|
||||
|
||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||
mutable GPUObject* _gpuObject = NULL;
|
||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||
GPUObject* getGPUObject() const { return _gpuObject; }
|
||||
friend class Backend;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Texture> TexturePointer;
|
||||
typedef std::vector< TexturePointer > Textures;
|
||||
|
||||
|
||||
// TODO: For now TextureView works with Buffer as a place holder for the Texture.
|
||||
// The overall logic should be about the same except that the Texture will be a real GL Texture under the hood
|
||||
class TextureView {
|
||||
public:
|
||||
typedef Resource::Size Size;
|
||||
|
||||
TexturePointer _texture = TexturePointer(NULL);
|
||||
uint16 _subresource = 0;
|
||||
Element _element = Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
|
||||
|
||||
TextureView() {};
|
||||
|
||||
TextureView(const Element& element) :
|
||||
_element(element)
|
||||
{};
|
||||
|
||||
// create the TextureView and own the Texture
|
||||
TextureView(Texture* newTexture, const Element& element) :
|
||||
_texture(newTexture),
|
||||
_subresource(0),
|
||||
_element(element)
|
||||
{};
|
||||
TextureView(const TexturePointer& texture, uint16 subresource, const Element& element) :
|
||||
_texture(texture),
|
||||
_subresource(subresource),
|
||||
_element(element)
|
||||
{};
|
||||
|
||||
TextureView(const TexturePointer& texture, uint16 subresource) :
|
||||
_texture(texture),
|
||||
_subresource(subresource)
|
||||
{};
|
||||
|
||||
~TextureView() {}
|
||||
TextureView(const TextureView& view) = default;
|
||||
TextureView& operator=(const TextureView& view) = default;
|
||||
|
||||
explicit operator bool() const { return bool(_texture); }
|
||||
bool operator !() const { return (!_texture); }
|
||||
};
|
||||
typedef std::vector<TextureView> TextureViews;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@ struct TransformCamera {
|
|||
mat4 _viewInverse;
|
||||
mat4 _projectionViewUntranslated;
|
||||
mat4 _projection;
|
||||
mat4 _projectionInverse;
|
||||
vec4 _viewport;
|
||||
};
|
||||
|
||||
|
@ -120,4 +121,24 @@ 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@>
|
||||
<$worldDir$> = vec3(gl_ModelViewMatrixInverse * vec4(<$eyeDir$>.xyz, 0.0));
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@func transformClipToEyeDir(cameraTransform, clipPos, eyeDir)@>
|
||||
<@if GPU_TRANSFORM_PROFILE == GPU_CORE@>
|
||||
{ // transformClipToEyeDir
|
||||
<$eyeDir$> = vec3(<$cameraTransform$>._projectionInverse * vec4(<$clipPos$>.xyz, 1.0));
|
||||
}
|
||||
<@else@>
|
||||
<$eyeDir$> = vec3(gl_ProjectionMatrixInverse * vec4(<$clipPos$>.xyz, 1.0));
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
void setVertexBuffer(const BufferView& buffer);
|
||||
const BufferView& getVertexBuffer() const { return _vertexBuffer; }
|
||||
uint getNumVertices() const { return _vertexBuffer.getNumElements(); }
|
||||
bool hasVertexData() const { return !_vertexBuffer._buffer.isNull(); }
|
||||
bool hasVertexData() const { return !_vertexBuffer._buffer; }
|
||||
|
||||
// Attribute Buffers
|
||||
int getNumAttributes() const { return _attributeBuffers.size(); }
|
||||
|
@ -126,7 +126,7 @@ protected:
|
|||
void evalVertexFormat();
|
||||
|
||||
};
|
||||
typedef QSharedPointer< Mesh > MeshPointer;
|
||||
typedef std::shared_ptr< Mesh > MeshPointer;
|
||||
|
||||
|
||||
class Geometry {
|
||||
|
|
|
@ -18,7 +18,7 @@ Light::Light() :
|
|||
_transform() {
|
||||
// only if created from nothing shall we create the Buffer to store the properties
|
||||
Schema schema;
|
||||
_schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Buffer::Byte*) &schema));
|
||||
_schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Byte*) &schema));
|
||||
}
|
||||
|
||||
Light::Light(const Light& light) :
|
||||
|
|
|
@ -282,7 +282,7 @@ protected:
|
|||
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
|
||||
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }
|
||||
};
|
||||
typedef QSharedPointer< Light > LightPointer;
|
||||
typedef std::shared_ptr< Light > LightPointer;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Material.h"
|
||||
|
||||
using namespace model;
|
||||
using namespace gpu;
|
||||
|
||||
Material::Material() :
|
||||
_flags(0),
|
||||
|
@ -19,7 +20,7 @@ Material::Material() :
|
|||
|
||||
// only if created from nothing shall we create the Buffer to store the properties
|
||||
Schema schema;
|
||||
_schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Buffer::Byte*) &schema));
|
||||
_schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Byte*) &schema));
|
||||
|
||||
|
||||
}
|
||||
|
@ -86,7 +87,20 @@ void Material::setOpacity(float opacity) {
|
|||
_schemaBuffer.edit<Schema>()._opacity = opacity;
|
||||
}
|
||||
|
||||
void Material::setTextureView(MapChannel channel, const TextureView& view) {
|
||||
void Material::setTextureView(MapChannel channel, const gpu::TextureView& view) {
|
||||
_flags.set(DIFFUSE_MAP_BIT + channel);
|
||||
_textureMap[channel] = view;
|
||||
}
|
||||
|
||||
// TextureStorage
|
||||
TextureStorage::TextureStorage(const QUrl& url) : gpu::Texture::Storage(), _url(url) {
|
||||
init();
|
||||
}
|
||||
|
||||
TextureStorage::~TextureStorage() {
|
||||
}
|
||||
|
||||
void TextureStorage::init() {
|
||||
_gpuTexture = TexturePointer(Texture::createFromStorage(this));
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,35 @@
|
|||
#include "gpu/Resource.h"
|
||||
#include "gpu/Texture.h"
|
||||
|
||||
#include <qurl.h>
|
||||
|
||||
namespace model {
|
||||
typedef gpu::BufferView UniformBufferView;
|
||||
typedef gpu::TextureView TextureView;
|
||||
|
||||
typedef glm::vec3 Color;
|
||||
|
||||
// TextureStorage is a specialized version of the gpu::Texture::Storage
|
||||
// It adds the URL and the notion that it owns the gpu::Texture
|
||||
class TextureStorage : public gpu::Texture::Storage {
|
||||
public:
|
||||
TextureStorage(const QUrl& url);
|
||||
~TextureStorage();
|
||||
|
||||
const QUrl& getUrl() const { return _url; }
|
||||
const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; }
|
||||
|
||||
protected:
|
||||
gpu::TexturePointer _gpuTexture;
|
||||
QUrl _url;
|
||||
void init();
|
||||
};
|
||||
typedef std::shared_ptr< TextureStorage > TextureStoragePointer;
|
||||
|
||||
|
||||
|
||||
class Material {
|
||||
public:
|
||||
typedef gpu::BufferView UniformBufferView;
|
||||
typedef gpu::TextureView TextureView;
|
||||
|
||||
typedef glm::vec3 Color;
|
||||
|
||||
|
@ -102,7 +125,7 @@ protected:
|
|||
TextureMap _textureMap;
|
||||
|
||||
};
|
||||
typedef QSharedPointer< Material > MaterialPointer;
|
||||
typedef std::shared_ptr< Material > MaterialPointer;
|
||||
|
||||
};
|
||||
|
||||
|
|
94
libraries/model/src/model/Skybox.cpp
Executable file
94
libraries/model/src/model/Skybox.cpp
Executable file
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// Skybox.cpp
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Sam Gateau on 5/4/2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "Skybox.h"
|
||||
|
||||
#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;
|
||||
static gpu::BufferPointer theBuffer;
|
||||
static gpu::Stream::FormatPointer theFormat;
|
||||
if (!thePipeline) {
|
||||
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
|
||||
auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag)));
|
||||
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS));
|
||||
|
||||
gpu::Shader::BindingSet bindings;
|
||||
bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0));
|
||||
|
||||
if (!gpu::Shader::makeProgram(*skyShader, bindings)) {
|
||||
|
||||
}
|
||||
|
||||
auto skyState = gpu::StatePointer(new gpu::State());
|
||||
|
||||
thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
|
||||
|
||||
const float CLIP = 1.0;
|
||||
const glm::vec2 vertices[4] = { {-CLIP, -CLIP}, {CLIP, -CLIP}, {-CLIP, CLIP}, {CLIP, CLIP}};
|
||||
theBuffer.reset(new gpu::Buffer(sizeof(vertices), (const gpu::Byte*) vertices));
|
||||
|
||||
theFormat.reset(new gpu::Stream::Format());
|
||||
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
||||
}
|
||||
|
||||
glm::mat4 projMat;
|
||||
viewFrustum.evalProjectionMatrix(projMat);
|
||||
|
||||
Transform viewTransform;
|
||||
viewFrustum.evalViewTransform(viewTransform);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewTransform);
|
||||
batch.setModelTransform(Transform()); // only for Mac
|
||||
batch.setPipeline(thePipeline);
|
||||
batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8);
|
||||
batch.setInputFormat(theFormat);
|
||||
batch.setUniformTexture(0, skybox.getCubemap());
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
} else {
|
||||
// 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);
|
||||
}
|
||||
}
|
46
libraries/model/src/model/Skybox.h
Executable file
46
libraries/model/src/model/Skybox.h
Executable file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// Skybox.h
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Sam Gateau on 5/4/2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_model_Skybox_h
|
||||
#define hifi_model_Skybox_h
|
||||
|
||||
#include "gpu/Texture.h"
|
||||
|
||||
class ViewFrustum;
|
||||
//class Transform;
|
||||
namespace gpu { class Batch; }
|
||||
|
||||
namespace model {
|
||||
|
||||
typedef glm::vec3 Color;
|
||||
|
||||
class Skybox {
|
||||
public:
|
||||
Skybox();
|
||||
Skybox& operator= (const Skybox& skybox);
|
||||
virtual ~Skybox() {};
|
||||
|
||||
void setColor(const Color& color);
|
||||
const Color& getColor() 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{1.0f, 1.0f, 1.0f};
|
||||
};
|
||||
typedef std::shared_ptr< Skybox > SkyboxPointer;
|
||||
|
||||
};
|
||||
|
||||
#endif //hifi_model_Skybox_h
|
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 = textureCube(cubeMap, normalize(normal));
|
||||
gl_FragData[0] = texel;
|
||||
// gl_FragData[0] = vec4(normal, 1.0);
|
||||
}
|
40
libraries/model/src/model/Skybox.slv
Executable file
40
libraries/model/src/model/Skybox.slv
Executable file
|
@ -0,0 +1,40 @@
|
|||
<@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) {
|
||||
texcoord = gl_Vertex.xy;
|
||||
|
||||
// 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);
|
||||
}
|
|
@ -138,7 +138,7 @@ void EarthSunModel::setSunLongitude(float lon) {
|
|||
Atmosphere::Atmosphere() {
|
||||
// only if created from nothing shall we create the Buffer to store the properties
|
||||
Data data;
|
||||
_dataBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Data), (const gpu::Buffer::Byte*) &data));
|
||||
_dataBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Data), (const gpu::Byte*) &data));
|
||||
|
||||
setScatteringWavelength(_scatteringWavelength);
|
||||
setRayleighScattering(_rayleighScattering);
|
||||
|
@ -184,14 +184,6 @@ void Atmosphere::setInnerOuterRadiuses(float inner, float outer) {
|
|||
data._scales.z = data._scales.x / data._scales.y;
|
||||
}
|
||||
|
||||
Skybox::Skybox() {
|
||||
}
|
||||
|
||||
void Skybox::setCubemap(const gpu::TexturePointer& cubemap) {
|
||||
_cubemap = cubemap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const int NUM_DAYS_PER_YEAR = 365;
|
||||
const float NUM_HOURS_PER_DAY = 24.0f;
|
||||
|
@ -223,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() {
|
||||
|
@ -250,7 +246,7 @@ void SunSkyStage::setOriginLocation(float longitude, float latitude, float altit
|
|||
invalidate();
|
||||
}
|
||||
|
||||
void SunSkyStage::setSunModelEnable(bool isEnabled) {
|
||||
void SunSkyStage::setSunModelEnable(bool isEnabled) {
|
||||
_sunModelEnable = isEnabled;
|
||||
invalidate();
|
||||
}
|
||||
|
@ -265,7 +261,7 @@ void SunSkyStage::setSunAmbientIntensity(float intensity) {
|
|||
_sunLight->setAmbientIntensity(intensity);
|
||||
}
|
||||
|
||||
void SunSkyStage::setSunDirection(const Vec3& direction) {
|
||||
void SunSkyStage::setSunDirection(const Vec3& direction) {
|
||||
if (!isSunModelEnabled()) {
|
||||
_sunLight->setDirection(direction);
|
||||
}
|
||||
|
@ -301,6 +297,11 @@ void SunSkyStage::updateGraphicsObject() const {
|
|||
}
|
||||
}
|
||||
|
||||
void SunSkyStage::setBackgroundMode(BackgroundMode mode) {
|
||||
_backgroundMode = mode;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void SunSkyStage::setSkybox(const SkyboxPointer& skybox) {
|
||||
_skybox = skybox;
|
||||
invalidate();
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
//
|
||||
// Stage.h
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Sam Gateau on 2/24/2015.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_model_Stage_h
|
||||
#define hifi_model_Stage_h
|
||||
|
||||
#include "gpu/Pipeline.h"
|
||||
|
||||
#include "Light.h"
|
||||
|
||||
namespace model {
|
||||
//
|
||||
// Stage.h
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Sam Gateau on 2/24/2015.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_model_Stage_h
|
||||
#define hifi_model_Stage_h
|
||||
|
||||
#include "gpu/Pipeline.h"
|
||||
|
||||
#include "Light.h"
|
||||
#include "Skybox.h"
|
||||
|
||||
namespace model {
|
||||
|
||||
typedef glm::dvec3 Vec3d;
|
||||
typedef glm::dvec4 Vec4d;
|
||||
typedef glm::dmat4 Mat4d;
|
||||
typedef glm::mat4 Mat4;
|
||||
typedef glm::mat4 Mat4;
|
||||
|
||||
class EarthSunModel {
|
||||
public:
|
||||
|
@ -99,40 +100,40 @@ protected:
|
|||
void updateSun() const;
|
||||
|
||||
mutable bool _invalid = true;
|
||||
void invalidate() const { _invalid = true; }
|
||||
void invalidate() const { _invalid = true; }
|
||||
void valid() const { if (_invalid) { updateAll(); _invalid = false; } }
|
||||
void updateAll() const;
|
||||
|
||||
static Mat4d evalWorldToGeoLocationMat(double longitude, double latitude, double altitude, double scale);
|
||||
};
|
||||
|
||||
|
||||
class Atmosphere {
|
||||
public:
|
||||
|
||||
Atmosphere();
|
||||
Atmosphere(const Atmosphere& atmosphere);
|
||||
Atmosphere& operator= (const Atmosphere& atmosphere);
|
||||
virtual ~Atmosphere() {};
|
||||
|
||||
|
||||
void setScatteringWavelength(Vec3 wavelength);
|
||||
const Vec3& getScatteringWavelength() const { return _scatteringWavelength; }
|
||||
|
||||
void setRayleighScattering(float scattering);
|
||||
float getRayleighScattering() const { return _rayleighScattering; }
|
||||
|
||||
void setMieScattering(float scattering);
|
||||
float getMieScattering() const { return _mieScattering; }
|
||||
|
||||
void setSunBrightness(float brightness);
|
||||
float getSunBrightness() const { return _sunBrightness; }
|
||||
|
||||
void setInnerOuterRadiuses(float inner, float outer);
|
||||
float getInnerRadius() const { return getData()._radiuses.x; }
|
||||
float getOuterRadius() const { return getData()._radiuses.y; }
|
||||
|
||||
// Data to access the attribute values of the atmosphere
|
||||
};
|
||||
|
||||
|
||||
class Atmosphere {
|
||||
public:
|
||||
|
||||
Atmosphere();
|
||||
Atmosphere(const Atmosphere& atmosphere);
|
||||
Atmosphere& operator= (const Atmosphere& atmosphere);
|
||||
virtual ~Atmosphere() {};
|
||||
|
||||
|
||||
void setScatteringWavelength(Vec3 wavelength);
|
||||
const Vec3& getScatteringWavelength() const { return _scatteringWavelength; }
|
||||
|
||||
void setRayleighScattering(float scattering);
|
||||
float getRayleighScattering() const { return _rayleighScattering; }
|
||||
|
||||
void setMieScattering(float scattering);
|
||||
float getMieScattering() const { return _mieScattering; }
|
||||
|
||||
void setSunBrightness(float brightness);
|
||||
float getSunBrightness() const { return _sunBrightness; }
|
||||
|
||||
void setInnerOuterRadiuses(float inner, float outer);
|
||||
float getInnerRadius() const { return getData()._radiuses.x; }
|
||||
float getOuterRadius() const { return getData()._radiuses.y; }
|
||||
|
||||
// Data to access the attribute values of the atmosphere
|
||||
class Data {
|
||||
public:
|
||||
Vec4 _invWaveLength = Vec4(0.0f);
|
||||
|
@ -142,110 +143,107 @@ public:
|
|||
Vec4 _control = Vec4(2.0f, -0.990f, -0.990f*-0.990f, 0.f);
|
||||
|
||||
Data() {}
|
||||
};
|
||||
|
||||
const UniformBufferView& getDataBuffer() const { return _dataBuffer; }
|
||||
|
||||
protected:
|
||||
UniformBufferView _dataBuffer;
|
||||
Vec3 _scatteringWavelength = Vec3(0.650f, 0.570f, 0.475f);
|
||||
float _rayleighScattering = 0.0025f;
|
||||
float _mieScattering = 0.0010f;
|
||||
float _sunBrightness = 20.0f;
|
||||
|
||||
const Data& getData() const { return _dataBuffer.get<Data>(); }
|
||||
Data& editData() { return _dataBuffer.edit<Data>(); }
|
||||
|
||||
void updateScattering();
|
||||
};
|
||||
typedef QSharedPointer< Atmosphere > AtmospherePointer;
|
||||
|
||||
|
||||
class Skybox {
|
||||
public:
|
||||
Skybox();
|
||||
Skybox& operator= (const Atmosphere& Skybox);
|
||||
virtual ~Skybox() {};
|
||||
|
||||
void setCubemap(const gpu::TexturePointer& cubemap);
|
||||
const gpu::TexturePointer& getCubemap() const { return _cubemap; }
|
||||
|
||||
protected:
|
||||
gpu::TexturePointer _cubemap;
|
||||
};
|
||||
typedef QSharedPointer< Skybox > SkyboxPointer;
|
||||
|
||||
// Sun sky stage generates the rendering primitives to display a scene realistically
|
||||
// at the specified location and time around earth
|
||||
class SunSkyStage {
|
||||
public:
|
||||
|
||||
SunSkyStage();
|
||||
~SunSkyStage();
|
||||
|
||||
// time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0]
|
||||
void setDayTime(float hour);
|
||||
float getDayTime() const { return _dayTime; }
|
||||
|
||||
// time of the year expressed in day in the range [0, 365]
|
||||
void setYearTime(unsigned int day);
|
||||
unsigned int getYearTime() const { return _yearTime; }
|
||||
|
||||
// Origin orientation used to modify the cardinal axis alignement used.
|
||||
// THe default is north along +Z axis and west along +X axis. this orientation gets added
|
||||
// to the transform stack producing the sun light direction.
|
||||
void setOriginOrientation(const Quat& orientation);
|
||||
const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); }
|
||||
|
||||
// Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km]
|
||||
void setOriginLocation(float longitude, float latitude, float surfaceAltitude);
|
||||
float getOriginLatitude() const { return _earthSunModel.getLatitude(); }
|
||||
float getOriginLongitude() const { return _earthSunModel.getLongitude(); }
|
||||
float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); }
|
||||
|
||||
// Enable / disable the effect of the time and location on the sun direction and color
|
||||
void setSunModelEnable(bool isEnabled);
|
||||
bool isSunModelEnabled() const { return _sunModelEnable; }
|
||||
|
||||
// Sun properties
|
||||
void setSunColor(const Vec3& color);
|
||||
const Vec3& getSunColor() const { return getSunLight()->getColor(); }
|
||||
void setSunIntensity(float intensity);
|
||||
float getSunIntensity() const { return getSunLight()->getIntensity(); }
|
||||
void setSunAmbientIntensity(float intensity);
|
||||
float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); }
|
||||
|
||||
// The sun direction is expressed in the world space
|
||||
void setSunDirection(const Vec3& direction);
|
||||
const Vec3& getSunDirection() const { return getSunLight()->getDirection(); }
|
||||
};
|
||||
|
||||
const UniformBufferView& getDataBuffer() const { return _dataBuffer; }
|
||||
|
||||
protected:
|
||||
UniformBufferView _dataBuffer;
|
||||
Vec3 _scatteringWavelength = Vec3(0.650f, 0.570f, 0.475f);
|
||||
float _rayleighScattering = 0.0025f;
|
||||
float _mieScattering = 0.0010f;
|
||||
float _sunBrightness = 20.0f;
|
||||
|
||||
const Data& getData() const { return _dataBuffer.get<Data>(); }
|
||||
Data& editData() { return _dataBuffer.edit<Data>(); }
|
||||
|
||||
void updateScattering();
|
||||
};
|
||||
typedef std::shared_ptr< Atmosphere > AtmospherePointer;
|
||||
|
||||
// Sun sky stage generates the rendering primitives to display a scene realistically
|
||||
// at the specified location and time around earth
|
||||
class SunSkyStage {
|
||||
public:
|
||||
|
||||
SunSkyStage();
|
||||
~SunSkyStage();
|
||||
|
||||
// time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0]
|
||||
void setDayTime(float hour);
|
||||
float getDayTime() const { return _dayTime; }
|
||||
|
||||
// time of the year expressed in day in the range [0, 365]
|
||||
void setYearTime(unsigned int day);
|
||||
unsigned int getYearTime() const { return _yearTime; }
|
||||
|
||||
// Origin orientation used to modify the cardinal axis alignement used.
|
||||
// THe default is north along +Z axis and west along +X axis. this orientation gets added
|
||||
// to the transform stack producing the sun light direction.
|
||||
void setOriginOrientation(const Quat& orientation);
|
||||
const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); }
|
||||
|
||||
// Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km]
|
||||
void setOriginLocation(float longitude, float latitude, float surfaceAltitude);
|
||||
float getOriginLatitude() const { return _earthSunModel.getLatitude(); }
|
||||
float getOriginLongitude() const { return _earthSunModel.getLongitude(); }
|
||||
float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); }
|
||||
|
||||
// Enable / disable the effect of the time and location on the sun direction and color
|
||||
void setSunModelEnable(bool isEnabled);
|
||||
bool isSunModelEnabled() const { return _sunModelEnable; }
|
||||
|
||||
// Sun properties
|
||||
void setSunColor(const Vec3& color);
|
||||
const Vec3& getSunColor() const { return getSunLight()->getColor(); }
|
||||
void setSunIntensity(float intensity);
|
||||
float getSunIntensity() const { return getSunLight()->getIntensity(); }
|
||||
void setSunAmbientIntensity(float intensity);
|
||||
float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); }
|
||||
|
||||
// The sun direction is expressed in the world space
|
||||
void setSunDirection(const Vec3& direction);
|
||||
const Vec3& getSunDirection() const { return getSunLight()->getDirection(); }
|
||||
|
||||
LightPointer getSunLight() const { valid(); return _sunLight; }
|
||||
AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; }
|
||||
|
||||
// Skybox
|
||||
void setSkybox(const SkyboxPointer& skybox);
|
||||
const SkyboxPointer& getSkybox() const { valid(); return _skybox; }
|
||||
|
||||
protected:
|
||||
LightPointer _sunLight;
|
||||
AtmospherePointer _atmosphere;
|
||||
SkyboxPointer _skybox;
|
||||
|
||||
gpu::PipelinePointer _skyPipeline;
|
||||
|
||||
float _dayTime = 12.0f;
|
||||
int _yearTime = 0;
|
||||
mutable EarthSunModel _earthSunModel;
|
||||
bool _sunModelEnable = true;
|
||||
|
||||
mutable bool _invalid = true;
|
||||
void invalidate() const { _invalid = true; }
|
||||
void valid() const { if (_invalid) { updateGraphicsObject(); _invalid = false; } }
|
||||
void updateGraphicsObject() const;
|
||||
};
|
||||
|
||||
typedef QSharedPointer< SunSkyStage > SunSkyStagePointer;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
enum BackgroundMode {
|
||||
NO_BACKGROUND = 0,
|
||||
SKY_DOME,
|
||||
SKY_BOX,
|
||||
|
||||
NUM_BACKGROUND_MODES,
|
||||
};
|
||||
void setBackgroundMode(BackgroundMode mode);
|
||||
BackgroundMode getBackgroundMode() const { return _backgroundMode; }
|
||||
|
||||
// Skybox
|
||||
void setSkybox(const SkyboxPointer& skybox);
|
||||
const SkyboxPointer& getSkybox() const { valid(); return _skybox; }
|
||||
|
||||
protected:
|
||||
BackgroundMode _backgroundMode = SKY_DOME;
|
||||
|
||||
LightPointer _sunLight;
|
||||
AtmospherePointer _atmosphere;
|
||||
SkyboxPointer _skybox;
|
||||
|
||||
gpu::PipelinePointer _skyPipeline;
|
||||
|
||||
float _dayTime = 12.0f;
|
||||
int _yearTime = 0;
|
||||
mutable EarthSunModel _earthSunModel;
|
||||
bool _sunModelEnable = true;
|
||||
|
||||
mutable bool _invalid = true;
|
||||
void invalidate() const { _invalid = true; }
|
||||
void valid() const { if (_invalid) { updateGraphicsObject(); _invalid = false; } }
|
||||
void updateGraphicsObject() const;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr< SunSkyStage > SunSkyStagePointer;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -69,7 +69,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
|| (!registered && !_sphereVertices.contains(radiusKey))) {
|
||||
|
||||
if (registered && _registeredSphereVertices.contains(id)) {
|
||||
_registeredSphereVertices[id].clear();
|
||||
_registeredSphereVertices[id].reset();
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED VERTICES BUFFER";
|
||||
#endif
|
||||
|
@ -111,7 +111,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
*(vertex++) = 0.0f;
|
||||
*(vertex++) = 1.0f * radius;
|
||||
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertices * NUM_COORDS_PER_VERTEX, (gpu::Buffer::Byte*) vertexData);
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertices * NUM_COORDS_PER_VERTEX, (gpu::Byte*) vertexData);
|
||||
delete[] vertexData;
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
|
@ -133,7 +133,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
|| (!registered && !_sphereIndices.contains(slicesStacksKey))) {
|
||||
|
||||
if (registered && _registeredSphereIndices.contains(id)) {
|
||||
_registeredSphereIndices[id].clear();
|
||||
_registeredSphereIndices[id].reset();
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED INDICES BUFFER";
|
||||
#endif
|
||||
|
@ -196,7 +196,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
indexCount += 3;
|
||||
|
||||
}
|
||||
indicesBuffer->append(sizeof(GLushort) * indices, (gpu::Buffer::Byte*) indexData);
|
||||
indicesBuffer->append(sizeof(GLushort) * indices, (gpu::Byte*) indexData);
|
||||
delete[] indexData;
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
|
@ -219,7 +219,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
|| (!registered && !_sphereColors.contains(colorKey))) {
|
||||
|
||||
if (registered && _registeredSphereColors.contains(id)) {
|
||||
_registeredSphereColors[id].clear();
|
||||
_registeredSphereColors[id].reset();
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(renderutils) << "renderSphere()... RELEASING REGISTERED COLORS BUFFER";
|
||||
#endif
|
||||
|
@ -245,7 +245,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
*(colorDataAt++) = compactColor;
|
||||
}
|
||||
|
||||
colorBuffer->append(sizeof(int) * vertices, (gpu::Buffer::Byte*) colorData);
|
||||
colorBuffer->append(sizeof(int) * vertices, (gpu::Byte*) colorData);
|
||||
delete[] colorData;
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
|
@ -432,7 +432,7 @@ void GeometryCache::renderGrid(int xDivisions, int yDivisions, const glm::vec4&
|
|||
*(vertex++) = y;
|
||||
}
|
||||
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Buffer::Byte*) vertexData);
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Byte*) vertexData);
|
||||
delete[] vertexData;
|
||||
|
||||
_gridBuffers[key] = verticesBuffer;
|
||||
|
@ -454,7 +454,7 @@ void GeometryCache::renderGrid(int xDivisions, int yDivisions, const glm::vec4&
|
|||
*(colorDataAt++) = compactColor;
|
||||
}
|
||||
|
||||
colorBuffer->append(sizeof(int) * vertices, (gpu::Buffer::Byte*) colorData);
|
||||
colorBuffer->append(sizeof(int) * vertices, (gpu::Byte*) colorData);
|
||||
delete[] colorData;
|
||||
}
|
||||
gpu::BufferPointer verticesBuffer = _gridBuffers[key];
|
||||
|
@ -537,7 +537,7 @@ void GeometryCache::renderGrid(int x, int y, int width, int height, int rows, in
|
|||
tx += dx;
|
||||
}
|
||||
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Buffer::Byte*) vertexData);
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertices * 2, (gpu::Byte*) vertexData);
|
||||
delete[] vertexData;
|
||||
|
||||
if (registered) {
|
||||
|
@ -564,7 +564,7 @@ void GeometryCache::renderGrid(int x, int y, int width, int height, int rows, in
|
|||
*(colorDataAt++) = compactColor;
|
||||
}
|
||||
|
||||
colorBuffer->append(sizeof(int) * vertices, (gpu::Buffer::Byte*) colorData);
|
||||
colorBuffer->append(sizeof(int) * vertices, (gpu::Byte*) colorData);
|
||||
delete[] colorData;
|
||||
}
|
||||
gpu::BufferPointer verticesBuffer = registered ? _registeredAlternateGridBuffers[id] : _alternateGridBuffers[key];
|
||||
|
@ -648,8 +648,8 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, con
|
|||
*(colorDataAt++) = compactColor;
|
||||
}
|
||||
|
||||
details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Buffer::Byte*) vertexData);
|
||||
details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Buffer::Byte*) colorData);
|
||||
details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData);
|
||||
details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData);
|
||||
delete[] vertexData;
|
||||
delete[] colorData;
|
||||
|
||||
|
@ -711,8 +711,8 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
|
|||
*(colorDataAt++) = compactColor;
|
||||
}
|
||||
|
||||
details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Buffer::Byte*) vertexData);
|
||||
details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Buffer::Byte*) colorData);
|
||||
details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData);
|
||||
details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData);
|
||||
delete[] vertexData;
|
||||
delete[] colorData;
|
||||
|
||||
|
@ -793,7 +793,7 @@ void GeometryCache::renderSolidCube(float size, const glm::vec4& color) {
|
|||
*(vertex++) = *cannonicalNormal++;
|
||||
}
|
||||
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertexPoints * 2, (gpu::Buffer::Byte*) vertexData);
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertexPoints * 2, (gpu::Byte*) vertexData);
|
||||
}
|
||||
|
||||
if (!_solidCubeIndexBuffer) {
|
||||
|
@ -808,7 +808,7 @@ void GeometryCache::renderSolidCube(float size, const glm::vec4& color) {
|
|||
gpu::BufferPointer indexBuffer(new gpu::Buffer());
|
||||
_solidCubeIndexBuffer = indexBuffer;
|
||||
|
||||
_solidCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Buffer::Byte*) cannonicalIndices);
|
||||
_solidCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Byte*) cannonicalIndices);
|
||||
}
|
||||
|
||||
if (!_solidCubeColors.contains(colorKey)) {
|
||||
|
@ -827,7 +827,7 @@ void GeometryCache::renderSolidCube(float size, const glm::vec4& color) {
|
|||
compactColor, compactColor, compactColor, compactColor,
|
||||
compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors);
|
||||
colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
}
|
||||
gpu::BufferPointer verticesBuffer = _solidCubeVerticies[size];
|
||||
gpu::BufferPointer colorBuffer = _solidCubeColors[colorKey];
|
||||
|
@ -891,7 +891,7 @@ void GeometryCache::renderWireCube(float size, const glm::vec4& color) {
|
|||
vertex[i] = cannonicalVertices[i] * halfSize;
|
||||
}
|
||||
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertexPoints, (gpu::Buffer::Byte*) vertexData); // I'm skeptical that this is right
|
||||
verticesBuffer->append(sizeof(GLfloat) * vertexPoints, (gpu::Byte*) vertexData); // I'm skeptical that this is right
|
||||
}
|
||||
|
||||
if (!_wireCubeIndexBuffer) {
|
||||
|
@ -904,7 +904,7 @@ void GeometryCache::renderWireCube(float size, const glm::vec4& color) {
|
|||
gpu::BufferPointer indexBuffer(new gpu::Buffer());
|
||||
_wireCubeIndexBuffer = indexBuffer;
|
||||
|
||||
_wireCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Buffer::Byte*) cannonicalIndices);
|
||||
_wireCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Byte*) cannonicalIndices);
|
||||
}
|
||||
|
||||
if (!_cubeColors.contains(colorKey)) {
|
||||
|
@ -919,7 +919,7 @@ void GeometryCache::renderWireCube(float size, const glm::vec4& color) {
|
|||
int colors[NUM_COLOR_SCALARS_PER_CUBE] = { compactColor, compactColor, compactColor, compactColor,
|
||||
compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors);
|
||||
colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
}
|
||||
gpu::BufferPointer verticesBuffer = _cubeVerticies[size];
|
||||
gpu::BufferPointer colorBuffer = _cubeColors[colorKey];
|
||||
|
@ -1037,8 +1037,8 @@ void GeometryCache::renderBevelCornersRect(int x, int y, int width, int height,
|
|||
compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors);
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
|
||||
delete[] vertexBuffer;
|
||||
}
|
||||
|
@ -1119,8 +1119,8 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC
|
|||
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors);
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
}
|
||||
|
||||
gpu::Batch batch;
|
||||
|
@ -1208,8 +1208,8 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC
|
|||
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors);
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
}
|
||||
|
||||
gpu::Batch batch;
|
||||
|
@ -1294,8 +1294,8 @@ void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxC
|
|||
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors);
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
}
|
||||
|
||||
gpu::Batch batch;
|
||||
|
@ -1396,8 +1396,8 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom
|
|||
((int(color.w * 255.0f) & 0xFF) << 24);
|
||||
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors);
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
}
|
||||
|
||||
gpu::Batch batch;
|
||||
|
@ -1510,8 +1510,8 @@ void GeometryCache::renderDashedLine(const glm::vec3& start, const glm::vec3& en
|
|||
*(vertex++) = end.z;
|
||||
*(colorDataAt++) = compactColor;
|
||||
|
||||
details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Buffer::Byte*) vertexData);
|
||||
details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Buffer::Byte*) colorData);
|
||||
details.verticesBuffer->append(sizeof(GLfloat) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData);
|
||||
details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData);
|
||||
delete[] vertexData;
|
||||
delete[] colorData;
|
||||
|
||||
|
@ -1581,10 +1581,10 @@ GeometryCache::BatchItemDetails::~BatchItemDetails() {
|
|||
|
||||
void GeometryCache::BatchItemDetails::clear() {
|
||||
isCreated = false;
|
||||
verticesBuffer.clear();
|
||||
colorBuffer.clear();
|
||||
streamFormat.clear();
|
||||
stream.clear();
|
||||
verticesBuffer.reset();
|
||||
colorBuffer.reset();
|
||||
streamFormat.reset();
|
||||
stream.reset();
|
||||
}
|
||||
|
||||
void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2,
|
||||
|
@ -1653,8 +1653,8 @@ void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2,
|
|||
const int NUM_COLOR_SCALARS = 2;
|
||||
int colors[NUM_COLOR_SCALARS] = { compactColor1, compactColor2 };
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors);
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
if (id == UNKNOWN_ID) {
|
||||
|
@ -1745,8 +1745,8 @@ void GeometryCache::renderLine(const glm::vec2& p1, const glm::vec2& p2,
|
|||
const int NUM_COLOR_SCALARS = 2;
|
||||
int colors[NUM_COLOR_SCALARS] = { compactColor1, compactColor2 };
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors);
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
if (id == UNKNOWN_ID) {
|
||||
|
@ -2234,10 +2234,10 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
|||
int offset = 0;
|
||||
foreach(const FBXMeshPart& part, mesh.parts) {
|
||||
networkMesh._indexBuffer->setSubData(offset, part.quadIndices.size() * sizeof(int),
|
||||
(gpu::Resource::Byte*) part.quadIndices.constData());
|
||||
(gpu::Byte*) part.quadIndices.constData());
|
||||
offset += part.quadIndices.size() * sizeof(int);
|
||||
networkMesh._indexBuffer->setSubData(offset, part.triangleIndices.size() * sizeof(int),
|
||||
(gpu::Resource::Byte*) part.triangleIndices.constData());
|
||||
(gpu::Byte*) part.triangleIndices.constData());
|
||||
offset += part.triangleIndices.size() * sizeof(int);
|
||||
}
|
||||
}
|
||||
|
@ -2256,19 +2256,19 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
|||
|
||||
networkMesh._vertexBuffer->resize(clusterWeightsOffset + mesh.clusterWeights.size() * sizeof(glm::vec4));
|
||||
|
||||
networkMesh._vertexBuffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.vertices.constData());
|
||||
networkMesh._vertexBuffer->setSubData(normalsOffset, mesh.normals.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.normals.constData());
|
||||
networkMesh._vertexBuffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.vertices.constData());
|
||||
networkMesh._vertexBuffer->setSubData(normalsOffset, mesh.normals.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.normals.constData());
|
||||
networkMesh._vertexBuffer->setSubData(tangentsOffset,
|
||||
mesh.tangents.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.tangents.constData());
|
||||
networkMesh._vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.colors.constData());
|
||||
mesh.tangents.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.tangents.constData());
|
||||
networkMesh._vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.colors.constData());
|
||||
networkMesh._vertexBuffer->setSubData(texCoordsOffset,
|
||||
mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Resource::Byte*) mesh.texCoords.constData());
|
||||
mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Byte*) mesh.texCoords.constData());
|
||||
networkMesh._vertexBuffer->setSubData(texCoords1Offset,
|
||||
mesh.texCoords1.size() * sizeof(glm::vec2), (gpu::Resource::Byte*) mesh.texCoords1.constData());
|
||||
mesh.texCoords1.size() * sizeof(glm::vec2), (gpu::Byte*) mesh.texCoords1.constData());
|
||||
networkMesh._vertexBuffer->setSubData(clusterIndicesOffset,
|
||||
mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Resource::Byte*) mesh.clusterIndices.constData());
|
||||
mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterIndices.constData());
|
||||
networkMesh._vertexBuffer->setSubData(clusterWeightsOffset,
|
||||
mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Resource::Byte*) mesh.clusterWeights.constData());
|
||||
mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterWeights.constData());
|
||||
|
||||
// otherwise, at least the cluster indices/weights can be static
|
||||
networkMesh._vertexStream = gpu::BufferStreamPointer(new gpu::BufferStream());
|
||||
|
@ -2304,14 +2304,14 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
|||
int clusterWeightsOffset = clusterIndicesOffset + mesh.clusterIndices.size() * sizeof(glm::vec4);
|
||||
|
||||
networkMesh._vertexBuffer->resize(clusterWeightsOffset + mesh.clusterWeights.size() * sizeof(glm::vec4));
|
||||
networkMesh._vertexBuffer->setSubData(0, mesh.tangents.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.tangents.constData());
|
||||
networkMesh._vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.colors.constData());
|
||||
networkMesh._vertexBuffer->setSubData(0, mesh.tangents.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.tangents.constData());
|
||||
networkMesh._vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.colors.constData());
|
||||
networkMesh._vertexBuffer->setSubData(texCoordsOffset,
|
||||
mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Resource::Byte*) mesh.texCoords.constData());
|
||||
mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Byte*) mesh.texCoords.constData());
|
||||
networkMesh._vertexBuffer->setSubData(clusterIndicesOffset,
|
||||
mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Resource::Byte*) mesh.clusterIndices.constData());
|
||||
mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterIndices.constData());
|
||||
networkMesh._vertexBuffer->setSubData(clusterWeightsOffset,
|
||||
mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Resource::Byte*) mesh.clusterWeights.constData());
|
||||
mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterWeights.constData());
|
||||
|
||||
networkMesh._vertexStream = gpu::BufferStreamPointer(new gpu::BufferStream());
|
||||
if (mesh.tangents.size()) networkMesh._vertexStream->addBuffer(networkMesh._vertexBuffer, 0, sizeof(glm::vec3));
|
||||
|
|
|
@ -451,9 +451,9 @@ bool Model::updateGeometry() {
|
|||
gpu::BufferPointer buffer(new gpu::Buffer());
|
||||
if (!mesh.blendshapes.isEmpty()) {
|
||||
buffer->resize((mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3));
|
||||
buffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.vertices.constData());
|
||||
buffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.vertices.constData());
|
||||
buffer->setSubData(mesh.vertices.size() * sizeof(glm::vec3),
|
||||
mesh.normals.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.normals.constData());
|
||||
mesh.normals.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.normals.constData());
|
||||
}
|
||||
_blendedVertexBuffers.push_back(buffer);
|
||||
}
|
||||
|
@ -1732,9 +1732,9 @@ void Model::setBlendedVertices(int blendNumber, const QWeakPointer<NetworkGeomet
|
|||
}
|
||||
|
||||
gpu::BufferPointer& buffer = _blendedVertexBuffers[i];
|
||||
buffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) vertices.constData() + index*sizeof(glm::vec3));
|
||||
buffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Byte*) vertices.constData() + index*sizeof(glm::vec3));
|
||||
buffer->setSubData(mesh.vertices.size() * sizeof(glm::vec3),
|
||||
mesh.normals.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) normals.constData() + index*sizeof(glm::vec3));
|
||||
mesh.normals.size() * sizeof(glm::vec3), (gpu::Byte*) normals.constData() + index*sizeof(glm::vec3));
|
||||
|
||||
index += mesh.vertices.size();
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ const int permutation[256] =
|
|||
#define USE_CHRIS_NOISE 1
|
||||
|
||||
const gpu::TexturePointer& TextureCache::getPermutationNormalTexture() {
|
||||
if (_permutationNormalTexture.isNull()) {
|
||||
if (!_permutationNormalTexture) {
|
||||
|
||||
// the first line consists of random permutation offsets
|
||||
unsigned char data[256 * 2 * 3];
|
||||
|
@ -133,7 +133,7 @@ static void loadSingleColorTexture(const unsigned char* color) {
|
|||
*/
|
||||
|
||||
const gpu::TexturePointer& TextureCache::getWhiteTexture() {
|
||||
if (_whiteTexture.isNull()) {
|
||||
if (!_whiteTexture) {
|
||||
_whiteTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1));
|
||||
_whiteTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_WHITE);
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ const gpu::TexturePointer& TextureCache::getWhiteTexture() {
|
|||
}
|
||||
|
||||
const gpu::TexturePointer& TextureCache::getBlueTexture() {
|
||||
if (_blueTexture.isNull()) {
|
||||
if (!_blueTexture) {
|
||||
_blueTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1));
|
||||
_blueTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(OPAQUE_BLUE), OPAQUE_BLUE);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue