diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 5ac830baf3..e6bcca1f87 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -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()->getTexture( - uniqueUrl, DEFAULT_TEXTURE, false, _billboard); + uniqueUrl, DEFAULT_TEXTURE, _billboard); } if (!_billboardTexture || !_billboardTexture->isLoaded()) { return; diff --git a/libraries/gpu-networking/src/gpu-networking/TextureCache.cpp b/libraries/gpu-networking/src/gpu-networking/TextureCache.cpp index 8e268d9f04..12b9ce423d 100644 --- a/libraries/gpu-networking/src/gpu-networking/TextureCache.cpp +++ b/libraries/gpu-networking/src/gpu-networking/TextureCache.cpp @@ -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(); - } - 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(); } /// 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(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 DilatableNetworkTexture::getDilatedTexture(float dilation) { - QSharedPointer texture = _dilatedTextures.value(dilation); - if (texture.isNull()) { - texture = QSharedPointer::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(_cache.data())->_dilatableNetworkTextures.insert(_url, - qWeakPointerCast(_self)); -} - diff --git a/libraries/gpu-networking/src/gpu-networking/TextureCache.h b/libraries/gpu-networking/src/gpu-networking/TextureCache.h index ad18550541..d17691a484 100644 --- a/libraries/gpu-networking/src/gpu-networking/TextureCache.h +++ b/libraries/gpu-networking/src/gpu-networking/TextureCache.h @@ -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 getDilatedTexture(float dilation); - -protected: - - virtual void imageLoaded(const QImage& image); - virtual void reinsert(); - -private: - - QImage _image; - int _innerRadius; - int _outerRadius; - - QMap > _dilatedTextures; -}; - #endif // hifi_TextureCache_h diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index d5c3635816..65a0439864 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.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); diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index a013fcd845..679e22c9e7 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -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 { diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index 0bb79fa7e1..0e7388f722 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -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(); } }; diff --git a/libraries/model/src/model/TextureStorage.cpp b/libraries/model/src/model/TextureStorage.cpp index a0c64dda4a..cc098e7356 100755 --- a/libraries/model/src/model/TextureStorage.cpp +++ b/libraries/model/src/model/TextureStorage.cpp @@ -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(); } -} \ No newline at end of file +} + +void TextureMap::setTextureTransform(const Transform& texcoordTransform) { + _texcoordTransform = texcoordTransform; +} + +void TextureMap::setLightmapOffsetScale(float offset, float scale) { + _lightmapOffsetScale.x = offset; + _lightmapOffsetScale.y = scale; +} + diff --git a/libraries/model/src/model/TextureStorage.h b/libraries/model/src/model/TextureStorage.h index 250217fb0b..c879918ea9 100755 --- a/libraries/model/src/model/TextureStorage.h +++ b/libraries/model/src/model/TextureStorage.h @@ -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 @@ -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; diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 69e08c353c..3b68e82339 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -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; diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index b0e5346261..38e9fa54c2 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -438,11 +438,6 @@ public: QSharedPointer specularTexture; QString emissiveTextureName; QSharedPointer emissiveTexture; - - Transform _diffuseTexTransform; - Transform _emissiveTexTransform; - - glm::vec2 _emissiveParams; }; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index cd407766fa..c87be06dba 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -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(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(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()->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()->setupTransparent(args, locations->lightBufferUnit); - } } }