mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +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
|
||||
QUrl uniqueUrl = QUrl(QUuid::createUuid().toString());
|
||||
_billboardTexture = DependencyManager::get<TextureCache>()->getTexture(
|
||||
uniqueUrl, DEFAULT_TEXTURE, false, _billboard);
|
||||
uniqueUrl, DEFAULT_TEXTURE, _billboard);
|
||||
}
|
||||
if (!_billboardTexture || !_billboardTexture->isLoaded()) {
|
||||
return;
|
||||
|
|
|
@ -143,21 +143,9 @@ public:
|
|||
const QByteArray& content;
|
||||
};
|
||||
|
||||
NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type, bool dilatable, const QByteArray& content) {
|
||||
if (!dilatable) {
|
||||
TextureExtra extra = { type, content };
|
||||
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;
|
||||
NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type, const QByteArray& content) {
|
||||
TextureExtra extra = { type, content };
|
||||
return ResourceCache::getResource(url, QUrl(), false, &extra).staticCast<NetworkTexture>();
|
||||
}
|
||||
|
||||
/// 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);
|
||||
// Passing ownership
|
||||
_gpuTexture.reset(texture);
|
||||
// _gpuTexture.reset(texture);
|
||||
_textureStorage->resetTexture(texture);
|
||||
auto gpuTexture = _textureStorage->getGPUTexture();
|
||||
|
||||
if (_gpuTexture) {
|
||||
_width = _gpuTexture->getWidth();
|
||||
_height = _gpuTexture->getHeight();
|
||||
if (gpuTexture) {
|
||||
_width = gpuTexture->getWidth();
|
||||
_height = gpuTexture->getHeight();
|
||||
} else {
|
||||
_width = _height = 0;
|
||||
}
|
||||
|
@ -586,69 +575,3 @@ void NetworkTexture::imageLoaded(const QImage& image) {
|
|||
// 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);
|
||||
|
||||
/// 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());
|
||||
|
||||
protected:
|
||||
|
@ -88,7 +88,6 @@ private:
|
|||
class Texture {
|
||||
public:
|
||||
friend class TextureCache;
|
||||
friend class DilatableNetworkTexture;
|
||||
Texture();
|
||||
~Texture();
|
||||
|
||||
|
@ -97,8 +96,6 @@ public:
|
|||
model::TextureStoragePointer _textureStorage;
|
||||
|
||||
protected:
|
||||
gpu::TexturePointer _gpuTexture;
|
||||
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -146,29 +143,4 @@ private:
|
|||
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
|
||||
|
|
|
@ -356,7 +356,7 @@ public:
|
|||
|
||||
protected:
|
||||
std::unique_ptr< Storage > _storage;
|
||||
|
||||
|
||||
Stamp _stamp = 0;
|
||||
|
||||
Sampler _sampler;
|
||||
|
@ -380,7 +380,6 @@ protected:
|
|||
bool _autoGenerateMips = false;
|
||||
bool _isIrradianceValid = 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);
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ void Material::setOpacity(float opacity) {
|
|||
}
|
||||
|
||||
void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) {
|
||||
if (textureMap && !textureMap->isNull()) {
|
||||
if (textureMap) {
|
||||
_key.setMapChannel(channel, (true));
|
||||
_textureMaps[channel] = textureMap;
|
||||
} else {
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
GLOSS_MAP_BIT,
|
||||
TRANSPARENT_MAP_BIT,
|
||||
NORMAL_MAP_BIT,
|
||||
LIGHTMAP_MAP_BIT,
|
||||
|
||||
NUM_FLAGS,
|
||||
};
|
||||
|
@ -53,6 +54,7 @@ public:
|
|||
GLOSS_MAP,
|
||||
TRANSPARENT_MAP,
|
||||
NORMAL_MAP,
|
||||
LIGHTMAP_MAP,
|
||||
|
||||
NUM_MAP_CHANNELS,
|
||||
};
|
||||
|
@ -83,6 +85,7 @@ public:
|
|||
Builder& withTransparentMap() { _flags.set(TRANSPARENT_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
|
||||
static MaterialKey opaqueDiffuse() { return Builder().withDiffuse().build(); }
|
||||
|
@ -122,6 +125,9 @@ public:
|
|||
void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); }
|
||||
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); }
|
||||
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& 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
|
||||
static MaterialFilter opaqueDiffuse() { return Builder().withDiffuse().withoutTransparent().build(); }
|
||||
};
|
||||
|
|
|
@ -14,9 +14,10 @@ using namespace model;
|
|||
using namespace gpu;
|
||||
|
||||
// TextureStorage
|
||||
TextureStorage::TextureStorage() : Texture::Storage()//,
|
||||
// _gpuTexture(Texture::createFromStorage(this))
|
||||
{}
|
||||
TextureStorage::TextureStorage()
|
||||
{/* : Texture::Storage()//,
|
||||
// _gpuTexture(Texture::createFromStorage(this))*/
|
||||
}
|
||||
|
||||
TextureStorage::~TextureStorage() {
|
||||
}
|
||||
|
@ -30,16 +31,22 @@ void TextureStorage::resetTexture(gpu::Texture* texture) {
|
|||
_gpuTexture.reset(texture);
|
||||
}
|
||||
|
||||
|
||||
bool TextureStorage::isDefined() const {
|
||||
if (_gpuTexture) {
|
||||
return _gpuTexture->isDefined();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TextureMap::setTextureStorage(TextureStoragePointer& texStorage) {
|
||||
_textureStorage = texStorage;
|
||||
}
|
||||
|
||||
bool TextureMap::isNull() const {
|
||||
bool TextureMap::isDefined() const {
|
||||
if (_textureStorage) {
|
||||
return _textureStorage->isMipAvailable(0);
|
||||
return _textureStorage->isDefined();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -51,4 +58,14 @@ gpu::TextureView TextureMap::getTextureView() const {
|
|||
} else {
|
||||
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
|
||||
//
|
||||
// Created by Sam Gateau on 5/6/2015.
|
||||
|
@ -14,6 +14,7 @@
|
|||
#include "gpu/Texture.h"
|
||||
|
||||
#include "Material.h"
|
||||
#include "Transform.h"
|
||||
|
||||
#include <qurl.h>
|
||||
|
||||
|
@ -32,7 +33,7 @@ public:
|
|||
// 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
|
||||
// that guides the internal format used
|
||||
class TextureStorage : public gpu::Texture::Storage {
|
||||
class TextureStorage {
|
||||
public:
|
||||
TextureStorage();
|
||||
~TextureStorage();
|
||||
|
@ -40,12 +41,13 @@ public:
|
|||
const QUrl& getUrl() const { return _imageUrl; }
|
||||
gpu::Texture::Type getType() const { return _usage._type; }
|
||||
const gpu::TexturePointer getGPUTexture() const { return _gpuTexture; }
|
||||
|
||||
virtual void reset() { Storage::reset(); }
|
||||
|
||||
void reset(const QUrl& url, const TextureUsage& usage);
|
||||
|
||||
void resetTexture(gpu::Texture* texture);
|
||||
|
||||
bool isDefined() const;
|
||||
|
||||
protected:
|
||||
gpu::TexturePointer _gpuTexture;
|
||||
TextureUsage _usage;
|
||||
|
@ -59,12 +61,20 @@ public:
|
|||
|
||||
void setTextureStorage(TextureStoragePointer& texStorage);
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
bool isDefined() 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:
|
||||
TextureStoragePointer _textureStorage;
|
||||
|
||||
Transform _texcoordTransform;
|
||||
glm::vec2 _lightmapOffsetScale{ 0.0f, 1.0f };
|
||||
};
|
||||
typedef std::shared_ptr< TextureMap > TextureMapPointer;
|
||||
|
||||
|
|
|
@ -2035,33 +2035,45 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
|
|||
networkMaterial->_material = material._material;
|
||||
|
||||
if (!material.diffuseTexture.filename.isEmpty()) {
|
||||
// TODO: SOlve the eye case
|
||||
networkMaterial->diffuseTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.diffuseTexture.filename)), DEFAULT_TEXTURE,
|
||||
/* mesh.isEye*/ false, material.diffuseTexture.content);
|
||||
networkMaterial->diffuseTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.diffuseTexture.filename)), DEFAULT_TEXTURE, material.diffuseTexture.content);
|
||||
networkMaterial->diffuseTextureName = material.diffuseTexture.name;
|
||||
networkMaterial->_diffuseTexTransform = material.diffuseTexture.transform;
|
||||
|
||||
auto diffuseMap = model::TextureMapPointer(new model::TextureMap());
|
||||
diffuseMap->setTextureStorage(networkMaterial->diffuseTexture->_textureStorage);
|
||||
diffuseMap->setTextureTransform(material.diffuseTexture.transform);
|
||||
|
||||
material._material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
|
||||
}
|
||||
if (!material.normalTexture.filename.isEmpty()) {
|
||||
networkMaterial->normalTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.normalTexture.filename)), NORMAL_TEXTURE,
|
||||
false, material.normalTexture.content);
|
||||
networkMaterial->normalTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.normalTexture.filename)), NORMAL_TEXTURE, material.normalTexture.content);
|
||||
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()) {
|
||||
networkMaterial->specularTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.specularTexture.filename)), SPECULAR_TEXTURE,
|
||||
false, material.specularTexture.content);
|
||||
networkMaterial->specularTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.specularTexture.filename)), SPECULAR_TEXTURE, material.specularTexture.content);
|
||||
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()) {
|
||||
networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), EMISSIVE_TEXTURE,
|
||||
false, material.emissiveTexture.content);
|
||||
networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), EMISSIVE_TEXTURE, material.emissiveTexture.content);
|
||||
networkMaterial->emissiveTextureName = material.emissiveTexture.name;
|
||||
networkMaterial->_emissiveTexTransform = material.emissiveTexture.transform;
|
||||
networkMaterial->_emissiveParams = material.emissiveParams;
|
||||
|
||||
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;
|
||||
|
|
|
@ -438,11 +438,6 @@ public:
|
|||
QSharedPointer<NetworkTexture> specularTexture;
|
||||
QString emissiveTextureName;
|
||||
QSharedPointer<NetworkTexture> emissiveTexture;
|
||||
|
||||
Transform _diffuseTexTransform;
|
||||
Transform _emissiveTexTransform;
|
||||
|
||||
glm::vec2 _emissiveParams;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -97,6 +97,11 @@ Model::~Model() {
|
|||
|
||||
Model::RenderPipelineLib Model::_renderPipelineLib;
|
||||
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,
|
||||
gpu::ShaderPointer& vertexShader,
|
||||
|
@ -104,11 +109,11 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
|||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
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("normalMap"), 1));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), 4));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), DIFFUSE_MAP_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), NORMAL_MAP_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), SPECULAR_MAP_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), LIGHTMAP_MAP_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_BUFFER_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT));
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
auto textureMaps = drawMaterial->_material->getTextureMaps();
|
||||
auto materialKey = material->getKey();
|
||||
auto textureMaps = material->getTextureMaps();
|
||||
glm::mat4 texcoordTransform[2];
|
||||
|
||||
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();
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that
|
||||
if ((locations->specularTextureUnit >= 0) && materialKey.isGlossMap()) {
|
||||
auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP];
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too
|
||||
if ((locations->emissiveTextureUnit >= 0) && materialKey.isLightmapMap()) {
|
||||
auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP];
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
//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());
|
||||
else {
|
||||
batch.setResourceTexture(LIGHTMAP_MAP_SLOT, textureCache->getGrayTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Texcoord transforms ?
|
||||
if (locations->texcoordMatrices >= 0) {
|
||||
glm::mat4 texcoordTransform[2];
|
||||
if (!drawMaterial->_diffuseTexTransform.isIdentity()) {
|
||||
drawMaterial->_diffuseTexTransform.getMatrix(texcoordTransform[0]);
|
||||
}
|
||||
if (!drawMaterial->_emissiveTexTransform.isIdentity()) {
|
||||
drawMaterial->_emissiveTexTransform.getMatrix(texcoordTransform[1]);
|
||||
}
|
||||
|
||||
batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform);
|
||||
batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform);
|
||||
}
|
||||
|
||||
if (!mesh.tangents.isEmpty()) {
|
||||
NetworkTexture* normalMap = drawMaterial->normalTexture.data();
|
||||
batch.setResourceTexture(1, (!normalMap || !normalMap->isLoaded()) ?
|
||||
textureCache->getBlueTexture() : normalMap->getGPUTexture());
|
||||
// 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 (locations->specularTextureUnit >= 0) {
|
||||
NetworkTexture* specularMap = drawMaterial->specularTexture.data();
|
||||
batch.setResourceTexture(locations->specularTextureUnit, (!specularMap || !specularMap->isLoaded()) ?
|
||||
textureCache->getBlackTexture() : specularMap->getGPUTexture());
|
||||
}
|
||||
|
||||
if (args) {
|
||||
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