mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 20:42:56 +02:00
Migrating the rendering code to the Material Maps and adding the simplae variables to the the TextutreMap
This commit is contained in:
parent
a804767d8f
commit
8941741508
11 changed files with 157 additions and 208 deletions
|
@ -645,7 +645,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) {
|
||||||
// Using a unique URL ensures we don't get another avatar's texture from TextureCache
|
// Using a unique URL ensures we don't get another avatar's texture from TextureCache
|
||||||
QUrl uniqueUrl = QUrl(QUuid::createUuid().toString());
|
QUrl uniqueUrl = QUrl(QUuid::createUuid().toString());
|
||||||
_billboardTexture = DependencyManager::get<TextureCache>()->getTexture(
|
_billboardTexture = DependencyManager::get<TextureCache>()->getTexture(
|
||||||
uniqueUrl, DEFAULT_TEXTURE, false, _billboard);
|
uniqueUrl, DEFAULT_TEXTURE, _billboard);
|
||||||
}
|
}
|
||||||
if (!_billboardTexture || !_billboardTexture->isLoaded()) {
|
if (!_billboardTexture || !_billboardTexture->isLoaded()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -143,21 +143,9 @@ public:
|
||||||
const QByteArray& content;
|
const QByteArray& content;
|
||||||
};
|
};
|
||||||
|
|
||||||
NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type, bool dilatable, const QByteArray& content) {
|
NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type, const QByteArray& content) {
|
||||||
if (!dilatable) {
|
|
||||||
TextureExtra extra = { type, content };
|
TextureExtra extra = { type, content };
|
||||||
return ResourceCache::getResource(url, QUrl(), false, &extra).staticCast<NetworkTexture>();
|
return ResourceCache::getResource(url, QUrl(), false, &extra).staticCast<NetworkTexture>();
|
||||||
}
|
|
||||||
NetworkTexturePointer texture = _dilatableNetworkTextures.value(url);
|
|
||||||
if (texture.isNull()) {
|
|
||||||
texture = NetworkTexturePointer(new DilatableNetworkTexture(url, content), &Resource::allReferencesCleared);
|
|
||||||
texture->setSelf(texture);
|
|
||||||
texture->setCache(this);
|
|
||||||
_dilatableNetworkTextures.insert(url, texture);
|
|
||||||
} else {
|
|
||||||
removeUnusedResource(texture);
|
|
||||||
}
|
|
||||||
return texture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a texture version of an image file
|
/// Returns a texture version of an image file
|
||||||
|
@ -567,12 +555,13 @@ void NetworkTexture::setImage(const QImage& image, void* voidTexture, bool trans
|
||||||
|
|
||||||
gpu::Texture* texture = static_cast<gpu::Texture*>(voidTexture);
|
gpu::Texture* texture = static_cast<gpu::Texture*>(voidTexture);
|
||||||
// Passing ownership
|
// Passing ownership
|
||||||
_gpuTexture.reset(texture);
|
// _gpuTexture.reset(texture);
|
||||||
_textureStorage->resetTexture(texture);
|
_textureStorage->resetTexture(texture);
|
||||||
|
auto gpuTexture = _textureStorage->getGPUTexture();
|
||||||
|
|
||||||
if (_gpuTexture) {
|
if (gpuTexture) {
|
||||||
_width = _gpuTexture->getWidth();
|
_width = gpuTexture->getWidth();
|
||||||
_height = _gpuTexture->getHeight();
|
_height = gpuTexture->getHeight();
|
||||||
} else {
|
} else {
|
||||||
_width = _height = 0;
|
_width = _height = 0;
|
||||||
}
|
}
|
||||||
|
@ -586,69 +575,3 @@ void NetworkTexture::imageLoaded(const QImage& image) {
|
||||||
// nothing by default
|
// nothing by default
|
||||||
}
|
}
|
||||||
|
|
||||||
DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url, const QByteArray& content) :
|
|
||||||
NetworkTexture(url, DEFAULT_TEXTURE, content),
|
|
||||||
_innerRadius(0),
|
|
||||||
_outerRadius(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QSharedPointer<Texture> DilatableNetworkTexture::getDilatedTexture(float dilation) {
|
|
||||||
QSharedPointer<Texture> texture = _dilatedTextures.value(dilation);
|
|
||||||
if (texture.isNull()) {
|
|
||||||
texture = QSharedPointer<Texture>::create();
|
|
||||||
|
|
||||||
if (!_image.isNull()) {
|
|
||||||
QImage dilatedImage = _image;
|
|
||||||
QPainter painter;
|
|
||||||
painter.begin(&dilatedImage);
|
|
||||||
QPainterPath path;
|
|
||||||
qreal radius = glm::mix((float) _innerRadius, (float) _outerRadius, dilation);
|
|
||||||
path.addEllipse(QPointF(_image.width() / 2.0, _image.height() / 2.0), radius, radius);
|
|
||||||
painter.fillPath(path, Qt::black);
|
|
||||||
painter.end();
|
|
||||||
|
|
||||||
bool isLinearRGB = true;// (_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
|
|
||||||
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
|
||||||
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
|
||||||
if (dilatedImage.hasAlphaChannel()) {
|
|
||||||
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
|
|
||||||
// FIXME either remove the ?: operator or provide different arguments depending on linear
|
|
||||||
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::BGRA));
|
|
||||||
}
|
|
||||||
texture->_gpuTexture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, dilatedImage.width(), dilatedImage.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
|
||||||
texture->_gpuTexture->assignStoredMip(0, formatMip, dilatedImage.byteCount(), dilatedImage.constBits());
|
|
||||||
texture->_gpuTexture->autoGenerateMips(-1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_dilatedTextures.insert(dilation, texture);
|
|
||||||
}
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DilatableNetworkTexture::imageLoaded(const QImage& image) {
|
|
||||||
_image = image;
|
|
||||||
|
|
||||||
// scan out from the center to find inner and outer radii
|
|
||||||
int halfWidth = image.width() / 2;
|
|
||||||
int halfHeight = image.height() / 2;
|
|
||||||
const int BLACK_THRESHOLD = 32;
|
|
||||||
while (_innerRadius < halfWidth && qGray(image.pixel(halfWidth + _innerRadius, halfHeight)) < BLACK_THRESHOLD) {
|
|
||||||
_innerRadius++;
|
|
||||||
}
|
|
||||||
_outerRadius = _innerRadius;
|
|
||||||
const int TRANSPARENT_THRESHOLD = 32;
|
|
||||||
while (_outerRadius < halfWidth && qAlpha(image.pixel(halfWidth + _outerRadius, halfHeight)) > TRANSPARENT_THRESHOLD) {
|
|
||||||
_outerRadius++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear out any textures we generated before loading
|
|
||||||
_dilatedTextures.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DilatableNetworkTexture::reinsert() {
|
|
||||||
static_cast<TextureCache*>(_cache.data())->_dilatableNetworkTextures.insert(_url,
|
|
||||||
qWeakPointerCast<NetworkTexture, Resource>(_self));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
static gpu::TexturePointer getImageTexture(const QString& path);
|
static gpu::TexturePointer getImageTexture(const QString& path);
|
||||||
|
|
||||||
/// Loads a texture from the specified URL.
|
/// Loads a texture from the specified URL.
|
||||||
NetworkTexturePointer getTexture(const QUrl& url, TextureType type = DEFAULT_TEXTURE, bool dilatable = false,
|
NetworkTexturePointer getTexture(const QUrl& url, TextureType type = DEFAULT_TEXTURE,
|
||||||
const QByteArray& content = QByteArray());
|
const QByteArray& content = QByteArray());
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -88,7 +88,6 @@ private:
|
||||||
class Texture {
|
class Texture {
|
||||||
public:
|
public:
|
||||||
friend class TextureCache;
|
friend class TextureCache;
|
||||||
friend class DilatableNetworkTexture;
|
|
||||||
Texture();
|
Texture();
|
||||||
~Texture();
|
~Texture();
|
||||||
|
|
||||||
|
@ -97,8 +96,6 @@ public:
|
||||||
model::TextureStoragePointer _textureStorage;
|
model::TextureStoragePointer _textureStorage;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
gpu::TexturePointer _gpuTexture;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
@ -146,29 +143,4 @@ private:
|
||||||
int _height;
|
int _height;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Caches derived, dilated textures.
|
|
||||||
class DilatableNetworkTexture : public NetworkTexture {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DilatableNetworkTexture(const QUrl& url, const QByteArray& content);
|
|
||||||
|
|
||||||
/// Returns a pointer to a texture with the requested amount of dilation.
|
|
||||||
QSharedPointer<Texture> getDilatedTexture(float dilation);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void imageLoaded(const QImage& image);
|
|
||||||
virtual void reinsert();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
QImage _image;
|
|
||||||
int _innerRadius;
|
|
||||||
int _outerRadius;
|
|
||||||
|
|
||||||
QMap<float, QWeakPointer<Texture> > _dilatedTextures;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // hifi_TextureCache_h
|
#endif // hifi_TextureCache_h
|
||||||
|
|
|
@ -381,7 +381,6 @@ protected:
|
||||||
bool _isIrradianceValid = false;
|
bool _isIrradianceValid = false;
|
||||||
bool _defined = false;
|
bool _defined = false;
|
||||||
|
|
||||||
|
|
||||||
static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler);
|
static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler);
|
||||||
|
|
||||||
Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices);
|
Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices);
|
||||||
|
|
|
@ -82,7 +82,7 @@ void Material::setOpacity(float opacity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) {
|
void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) {
|
||||||
if (textureMap && !textureMap->isNull()) {
|
if (textureMap) {
|
||||||
_key.setMapChannel(channel, (true));
|
_key.setMapChannel(channel, (true));
|
||||||
_textureMaps[channel] = textureMap;
|
_textureMaps[channel] = textureMap;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
GLOSS_MAP_BIT,
|
GLOSS_MAP_BIT,
|
||||||
TRANSPARENT_MAP_BIT,
|
TRANSPARENT_MAP_BIT,
|
||||||
NORMAL_MAP_BIT,
|
NORMAL_MAP_BIT,
|
||||||
|
LIGHTMAP_MAP_BIT,
|
||||||
|
|
||||||
NUM_FLAGS,
|
NUM_FLAGS,
|
||||||
};
|
};
|
||||||
|
@ -53,6 +54,7 @@ public:
|
||||||
GLOSS_MAP,
|
GLOSS_MAP,
|
||||||
TRANSPARENT_MAP,
|
TRANSPARENT_MAP,
|
||||||
NORMAL_MAP,
|
NORMAL_MAP,
|
||||||
|
LIGHTMAP_MAP,
|
||||||
|
|
||||||
NUM_MAP_CHANNELS,
|
NUM_MAP_CHANNELS,
|
||||||
};
|
};
|
||||||
|
@ -83,6 +85,7 @@ public:
|
||||||
Builder& withTransparentMap() { _flags.set(TRANSPARENT_MAP_BIT); return (*this); }
|
Builder& withTransparentMap() { _flags.set(TRANSPARENT_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); }
|
Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); }
|
||||||
|
Builder& withLightmapMap() { _flags.set(LIGHTMAP_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
// Convenient standard keys that we will keep on using all over the place
|
// Convenient standard keys that we will keep on using all over the place
|
||||||
static MaterialKey opaqueDiffuse() { return Builder().withDiffuse().build(); }
|
static MaterialKey opaqueDiffuse() { return Builder().withDiffuse().build(); }
|
||||||
|
@ -122,6 +125,9 @@ public:
|
||||||
void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); }
|
void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); }
|
||||||
bool isNormalMap() const { return _flags[NORMAL_MAP_BIT]; }
|
bool isNormalMap() const { return _flags[NORMAL_MAP_BIT]; }
|
||||||
|
|
||||||
|
void setLightmapMap(bool value) { _flags.set(LIGHTMAP_MAP_BIT, value); }
|
||||||
|
bool isLightmapMap() const { return _flags[LIGHTMAP_MAP_BIT]; }
|
||||||
|
|
||||||
void setMapChannel(MapChannel channel, bool value) { _flags.set(EMISSIVE_MAP_BIT + channel, value); }
|
void setMapChannel(MapChannel channel, bool value) { _flags.set(EMISSIVE_MAP_BIT + channel, value); }
|
||||||
bool isMapChannel(MapChannel channel) const { return _flags[EMISSIVE_MAP_BIT + channel]; }
|
bool isMapChannel(MapChannel channel) const { return _flags[EMISSIVE_MAP_BIT + channel]; }
|
||||||
|
|
||||||
|
@ -177,6 +183,9 @@ public:
|
||||||
Builder& withoutNormalMap() { _value.reset(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
|
Builder& withoutNormalMap() { _value.reset(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
|
||||||
Builder& withNormalMap() { _value.set(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
|
Builder& withNormalMap() { _value.set(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
|
Builder& withoutLightmapMap() { _value.reset(MaterialKey::LIGHTMAP_MAP_BIT); _mask.set(MaterialKey::LIGHTMAP_MAP_BIT); return (*this); }
|
||||||
|
Builder& withLightmapMap() { _value.set(MaterialKey::LIGHTMAP_MAP_BIT); _mask.set(MaterialKey::LIGHTMAP_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
// Convenient standard keys that we will keep on using all over the place
|
// Convenient standard keys that we will keep on using all over the place
|
||||||
static MaterialFilter opaqueDiffuse() { return Builder().withDiffuse().withoutTransparent().build(); }
|
static MaterialFilter opaqueDiffuse() { return Builder().withDiffuse().withoutTransparent().build(); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,9 +14,10 @@ using namespace model;
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
// TextureStorage
|
// TextureStorage
|
||||||
TextureStorage::TextureStorage() : Texture::Storage()//,
|
TextureStorage::TextureStorage()
|
||||||
// _gpuTexture(Texture::createFromStorage(this))
|
{/* : Texture::Storage()//,
|
||||||
{}
|
// _gpuTexture(Texture::createFromStorage(this))*/
|
||||||
|
}
|
||||||
|
|
||||||
TextureStorage::~TextureStorage() {
|
TextureStorage::~TextureStorage() {
|
||||||
}
|
}
|
||||||
|
@ -30,16 +31,22 @@ void TextureStorage::resetTexture(gpu::Texture* texture) {
|
||||||
_gpuTexture.reset(texture);
|
_gpuTexture.reset(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextureStorage::isDefined() const {
|
||||||
|
if (_gpuTexture) {
|
||||||
|
return _gpuTexture->isDefined();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextureMap::setTextureStorage(TextureStoragePointer& texStorage) {
|
void TextureMap::setTextureStorage(TextureStoragePointer& texStorage) {
|
||||||
_textureStorage = texStorage;
|
_textureStorage = texStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureMap::isNull() const {
|
bool TextureMap::isDefined() const {
|
||||||
if (_textureStorage) {
|
if (_textureStorage) {
|
||||||
return _textureStorage->isMipAvailable(0);
|
return _textureStorage->isDefined();
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -52,3 +59,13 @@ gpu::TextureView TextureMap::getTextureView() const {
|
||||||
return gpu::TextureView();
|
return gpu::TextureView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureMap::setTextureTransform(const Transform& texcoordTransform) {
|
||||||
|
_texcoordTransform = texcoordTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureMap::setLightmapOffsetScale(float offset, float scale) {
|
||||||
|
_lightmapOffsetScale.x = offset;
|
||||||
|
_lightmapOffsetScale.y = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// TextureStorage.h
|
// TextureMap.h
|
||||||
// libraries/model/src/model
|
// libraries/model/src/model
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 5/6/2015.
|
// Created by Sam Gateau on 5/6/2015.
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
#include "gpu/Texture.h"
|
#include "gpu/Texture.h"
|
||||||
|
|
||||||
#include "Material.h"
|
#include "Material.h"
|
||||||
|
#include "Transform.h"
|
||||||
|
|
||||||
#include <qurl.h>
|
#include <qurl.h>
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ public:
|
||||||
// TextureStorage is a specialized version of the gpu::Texture::Storage
|
// TextureStorage is a specialized version of the gpu::Texture::Storage
|
||||||
// It provides the mechanism to create a texture from a Url and the intended usage
|
// It provides the mechanism to create a texture from a Url and the intended usage
|
||||||
// that guides the internal format used
|
// that guides the internal format used
|
||||||
class TextureStorage : public gpu::Texture::Storage {
|
class TextureStorage {
|
||||||
public:
|
public:
|
||||||
TextureStorage();
|
TextureStorage();
|
||||||
~TextureStorage();
|
~TextureStorage();
|
||||||
|
@ -41,11 +42,12 @@ public:
|
||||||
gpu::Texture::Type getType() const { return _usage._type; }
|
gpu::Texture::Type getType() const { return _usage._type; }
|
||||||
const gpu::TexturePointer getGPUTexture() const { return _gpuTexture; }
|
const gpu::TexturePointer getGPUTexture() const { return _gpuTexture; }
|
||||||
|
|
||||||
virtual void reset() { Storage::reset(); }
|
|
||||||
void reset(const QUrl& url, const TextureUsage& usage);
|
void reset(const QUrl& url, const TextureUsage& usage);
|
||||||
|
|
||||||
void resetTexture(gpu::Texture* texture);
|
void resetTexture(gpu::Texture* texture);
|
||||||
|
|
||||||
|
bool isDefined() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
gpu::TexturePointer _gpuTexture;
|
gpu::TexturePointer _gpuTexture;
|
||||||
TextureUsage _usage;
|
TextureUsage _usage;
|
||||||
|
@ -59,12 +61,20 @@ public:
|
||||||
|
|
||||||
void setTextureStorage(TextureStoragePointer& texStorage);
|
void setTextureStorage(TextureStoragePointer& texStorage);
|
||||||
|
|
||||||
bool isNull() const;
|
bool isDefined() const;
|
||||||
|
|
||||||
gpu::TextureView getTextureView() const;
|
gpu::TextureView getTextureView() const;
|
||||||
|
|
||||||
|
void setTextureTransform(const Transform& texcoordTransform);
|
||||||
|
const Transform& getTextureTransform() const { return _texcoordTransform; }
|
||||||
|
|
||||||
|
void setLightmapOffsetScale(float offset, float scale);
|
||||||
|
const glm::vec2& getLightmapOffsetScale() const { return _lightmapOffsetScale; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TextureStoragePointer _textureStorage;
|
TextureStoragePointer _textureStorage;
|
||||||
|
|
||||||
|
Transform _texcoordTransform;
|
||||||
|
glm::vec2 _lightmapOffsetScale{ 0.0f, 1.0f };
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr< TextureMap > TextureMapPointer;
|
typedef std::shared_ptr< TextureMap > TextureMapPointer;
|
||||||
|
|
||||||
|
|
|
@ -2035,33 +2035,45 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
|
||||||
networkMaterial->_material = material._material;
|
networkMaterial->_material = material._material;
|
||||||
|
|
||||||
if (!material.diffuseTexture.filename.isEmpty()) {
|
if (!material.diffuseTexture.filename.isEmpty()) {
|
||||||
// TODO: SOlve the eye case
|
networkMaterial->diffuseTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.diffuseTexture.filename)), DEFAULT_TEXTURE, material.diffuseTexture.content);
|
||||||
networkMaterial->diffuseTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.diffuseTexture.filename)), DEFAULT_TEXTURE,
|
|
||||||
/* mesh.isEye*/ false, material.diffuseTexture.content);
|
|
||||||
networkMaterial->diffuseTextureName = material.diffuseTexture.name;
|
networkMaterial->diffuseTextureName = material.diffuseTexture.name;
|
||||||
networkMaterial->_diffuseTexTransform = material.diffuseTexture.transform;
|
|
||||||
|
|
||||||
auto diffuseMap = model::TextureMapPointer(new model::TextureMap());
|
auto diffuseMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
diffuseMap->setTextureStorage(networkMaterial->diffuseTexture->_textureStorage);
|
diffuseMap->setTextureStorage(networkMaterial->diffuseTexture->_textureStorage);
|
||||||
|
diffuseMap->setTextureTransform(material.diffuseTexture.transform);
|
||||||
|
|
||||||
material._material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
|
material._material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
|
||||||
}
|
}
|
||||||
if (!material.normalTexture.filename.isEmpty()) {
|
if (!material.normalTexture.filename.isEmpty()) {
|
||||||
networkMaterial->normalTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.normalTexture.filename)), NORMAL_TEXTURE,
|
networkMaterial->normalTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.normalTexture.filename)), NORMAL_TEXTURE, material.normalTexture.content);
|
||||||
false, material.normalTexture.content);
|
|
||||||
networkMaterial->normalTextureName = material.normalTexture.name;
|
networkMaterial->normalTextureName = material.normalTexture.name;
|
||||||
|
|
||||||
|
auto normalMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
|
normalMap->setTextureStorage(networkMaterial->normalTexture->_textureStorage);
|
||||||
|
|
||||||
|
material._material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
|
||||||
}
|
}
|
||||||
if (!material.specularTexture.filename.isEmpty()) {
|
if (!material.specularTexture.filename.isEmpty()) {
|
||||||
networkMaterial->specularTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.specularTexture.filename)), SPECULAR_TEXTURE,
|
networkMaterial->specularTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.specularTexture.filename)), SPECULAR_TEXTURE, material.specularTexture.content);
|
||||||
false, material.specularTexture.content);
|
|
||||||
networkMaterial->specularTextureName = material.specularTexture.name;
|
networkMaterial->specularTextureName = material.specularTexture.name;
|
||||||
|
|
||||||
|
auto glossMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
|
glossMap->setTextureStorage(networkMaterial->specularTexture->_textureStorage);
|
||||||
|
|
||||||
|
material._material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
|
||||||
}
|
}
|
||||||
if (!material.emissiveTexture.filename.isEmpty()) {
|
if (!material.emissiveTexture.filename.isEmpty()) {
|
||||||
networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), EMISSIVE_TEXTURE,
|
networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), EMISSIVE_TEXTURE, material.emissiveTexture.content);
|
||||||
false, material.emissiveTexture.content);
|
|
||||||
networkMaterial->emissiveTextureName = material.emissiveTexture.name;
|
networkMaterial->emissiveTextureName = material.emissiveTexture.name;
|
||||||
networkMaterial->_emissiveTexTransform = material.emissiveTexture.transform;
|
|
||||||
networkMaterial->_emissiveParams = material.emissiveParams;
|
|
||||||
checkForTexcoordLightmap = true;
|
checkForTexcoordLightmap = true;
|
||||||
|
|
||||||
|
auto lightmapMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
|
lightmapMap->setTextureStorage(networkMaterial->emissiveTexture->_textureStorage);
|
||||||
|
lightmapMap->setTextureTransform(material.emissiveTexture.transform);
|
||||||
|
lightmapMap->setLightmapOffsetScale(material.emissiveParams.x, material.emissiveParams.y);
|
||||||
|
|
||||||
|
material._material->setTextureMap(model::MaterialKey::LIGHTMAP_MAP, lightmapMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return networkMaterial;
|
return networkMaterial;
|
||||||
|
|
|
@ -438,11 +438,6 @@ public:
|
||||||
QSharedPointer<NetworkTexture> specularTexture;
|
QSharedPointer<NetworkTexture> specularTexture;
|
||||||
QString emissiveTextureName;
|
QString emissiveTextureName;
|
||||||
QSharedPointer<NetworkTexture> emissiveTexture;
|
QSharedPointer<NetworkTexture> emissiveTexture;
|
||||||
|
|
||||||
Transform _diffuseTexTransform;
|
|
||||||
Transform _emissiveTexTransform;
|
|
||||||
|
|
||||||
glm::vec2 _emissiveParams;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,11 @@ Model::~Model() {
|
||||||
|
|
||||||
Model::RenderPipelineLib Model::_renderPipelineLib;
|
Model::RenderPipelineLib Model::_renderPipelineLib;
|
||||||
const int MATERIAL_GPU_SLOT = 3;
|
const int MATERIAL_GPU_SLOT = 3;
|
||||||
|
const int DIFFUSE_MAP_SLOT = 0;
|
||||||
|
const int NORMAL_MAP_SLOT = 1;
|
||||||
|
const int SPECULAR_MAP_SLOT = 2;
|
||||||
|
const int LIGHTMAP_MAP_SLOT = 3;
|
||||||
|
const int LIGHT_BUFFER_SLOT = 4;
|
||||||
|
|
||||||
void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
||||||
gpu::ShaderPointer& vertexShader,
|
gpu::ShaderPointer& vertexShader,
|
||||||
|
@ -104,11 +109,11 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
||||||
|
|
||||||
gpu::Shader::BindingSet slotBindings;
|
gpu::Shader::BindingSet slotBindings;
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
|
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0));
|
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), DIFFUSE_MAP_SLOT));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1));
|
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), NORMAL_MAP_SLOT));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2));
|
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), SPECULAR_MAP_SLOT));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3));
|
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), LIGHTMAP_MAP_SLOT));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), 4));
|
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_BUFFER_SLOT));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT));
|
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT));
|
||||||
|
|
||||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader));
|
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader));
|
||||||
|
@ -1642,75 +1647,82 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape
|
||||||
batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer());
|
batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto textureMaps = drawMaterial->_material->getTextureMaps();
|
auto materialKey = material->getKey();
|
||||||
|
auto textureMaps = material->getTextureMaps();
|
||||||
auto diffuseMap2 = textureMaps[model::MaterialKey::DIFFUSE_MAP];
|
|
||||||
Texture* diffuseMap = drawMaterial->diffuseTexture.data();
|
|
||||||
if (mesh.isEye && diffuseMap) {
|
|
||||||
// FIXME - guard against out of bounds here
|
|
||||||
if (meshIndex < _dilatedTextures.size()) {
|
|
||||||
if (partIndex < _dilatedTextures[meshIndex].size()) {
|
|
||||||
diffuseMap = (_dilatedTextures[meshIndex][partIndex] =
|
|
||||||
static_cast<DilatableNetworkTexture*>(diffuseMap)->getDilatedTexture(_pupilDilation)).data();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//if (diffuseMap && static_cast<NetworkTexture*>(diffuseMap)->isLoaded()) {
|
|
||||||
|
|
||||||
if (diffuseMap2 && !diffuseMap2->isNull()) {
|
|
||||||
|
|
||||||
batch.setResourceTexture(0, diffuseMap2->getTextureView());
|
|
||||||
// batch.setResourceTexture(0, diffuseMap->getGPUTexture());
|
|
||||||
} else {
|
|
||||||
batch.setResourceTexture(0, textureCache->getGrayTexture());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (locations->texcoordMatrices >= 0) {
|
|
||||||
glm::mat4 texcoordTransform[2];
|
glm::mat4 texcoordTransform[2];
|
||||||
if (!drawMaterial->_diffuseTexTransform.isIdentity()) {
|
|
||||||
drawMaterial->_diffuseTexTransform.getMatrix(texcoordTransform[0]);
|
// Diffuse
|
||||||
|
if (materialKey.isDiffuseMap()) {
|
||||||
|
auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP];
|
||||||
|
|
||||||
|
if (diffuseMap && diffuseMap->isDefined()) {
|
||||||
|
batch.setResourceTexture(DIFFUSE_MAP_SLOT, diffuseMap->getTextureView());
|
||||||
|
|
||||||
|
if (!diffuseMap->getTextureTransform().isIdentity()) {
|
||||||
|
diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(DIFFUSE_MAP_SLOT, textureCache->getGrayTexture());
|
||||||
}
|
}
|
||||||
if (!drawMaterial->_emissiveTexTransform.isIdentity()) {
|
|
||||||
drawMaterial->_emissiveTexTransform.getMatrix(texcoordTransform[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform);
|
// Normal map
|
||||||
|
if (materialKey.isNormalMap()) {
|
||||||
|
auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP];
|
||||||
|
if (normalMap && normalMap->isDefined()) {
|
||||||
|
batch.setResourceTexture(NORMAL_MAP_SLOT, normalMap->getTextureView());
|
||||||
|
|
||||||
|
// texcoord are assumed to be the same has diffuse
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(NORMAL_MAP_SLOT, textureCache->getBlueTexture());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mesh.tangents.isEmpty()) {
|
// TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that
|
||||||
NetworkTexture* normalMap = drawMaterial->normalTexture.data();
|
if ((locations->specularTextureUnit >= 0) && materialKey.isGlossMap()) {
|
||||||
batch.setResourceTexture(1, (!normalMap || !normalMap->isLoaded()) ?
|
auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP];
|
||||||
textureCache->getBlueTexture() : normalMap->getGPUTexture());
|
if (specularMap && specularMap->isDefined()) {
|
||||||
|
batch.setResourceTexture(SPECULAR_MAP_SLOT, specularMap->getTextureView());
|
||||||
|
|
||||||
|
// texcoord are assumed to be the same has diffuse
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(SPECULAR_MAP_SLOT, textureCache->getBlackTexture());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locations->specularTextureUnit >= 0) {
|
// TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too
|
||||||
NetworkTexture* specularMap = drawMaterial->specularTexture.data();
|
if ((locations->emissiveTextureUnit >= 0) && materialKey.isLightmapMap()) {
|
||||||
batch.setResourceTexture(locations->specularTextureUnit, (!specularMap || !specularMap->isLoaded()) ?
|
auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP];
|
||||||
textureCache->getBlackTexture() : specularMap->getGPUTexture());
|
|
||||||
|
if (lightmapMap && lightmapMap->isDefined()) {
|
||||||
|
batch.setResourceTexture(LIGHTMAP_MAP_SLOT, lightmapMap->getTextureView());
|
||||||
|
|
||||||
|
auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale();
|
||||||
|
batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y);
|
||||||
|
|
||||||
|
if (!lightmapMap->getTextureTransform().isIdentity()) {
|
||||||
|
lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
batch.setResourceTexture(LIGHTMAP_MAP_SLOT, textureCache->getGrayTexture());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Texcoord transforms ?
|
||||||
|
if (locations->texcoordMatrices >= 0) {
|
||||||
|
batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: We should be able to do that just in the renderTransparentJob
|
||||||
|
if (translucentMesh && locations->lightBufferUnit >= 0) {
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (args) {
|
if (args) {
|
||||||
args->_details._materialSwitches++;
|
args->_details._materialSwitches++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: For unknown reason (yet!) this code that should be assigned only if the material changes need to be called for every
|
|
||||||
// drawcall with an emissive, so let's do it for now.
|
|
||||||
if (locations->emissiveTextureUnit >= 0) {
|
|
||||||
// assert(locations->emissiveParams >= 0); // we should have the emissiveParams defined in the shader
|
|
||||||
//float emissiveOffset = part.emissiveParams.x;
|
|
||||||
//float emissiveScale = part.emissiveParams.y;
|
|
||||||
float emissiveOffset = drawMaterial->_emissiveParams.x;
|
|
||||||
float emissiveScale = drawMaterial->_emissiveParams.y;
|
|
||||||
batch._glUniform2f(locations->emissiveParams, emissiveOffset, emissiveScale);
|
|
||||||
|
|
||||||
NetworkTexture* emissiveMap = drawMaterial->emissiveTexture.data();
|
|
||||||
batch.setResourceTexture(locations->emissiveTextureUnit, (!emissiveMap || !emissiveMap->isLoaded()) ?
|
|
||||||
textureCache->getGrayTexture() : emissiveMap->getGPUTexture());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (translucentMesh && locations->lightBufferUnit >= 0) {
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue