Add TextureType to NetworkTexture for reflection

This commit is contained in:
Zach Pomerantz 2016-04-20 15:47:47 -07:00
parent a148a69a35
commit c096b0dfa1
5 changed files with 63 additions and 57 deletions

View file

@ -380,7 +380,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
_pendingAmbientTexture = false; _pendingAmbientTexture = false;
_ambientTexture.clear(); _ambientTexture.clear();
} else { } else {
_ambientTexture = textureCache->getTexture(zone->getKeyLightProperties().getAmbientURL(), CUBE_TEXTURE); _ambientTexture = textureCache->getTexture(zone->getKeyLightProperties().getAmbientURL(), NetworkTexture::CUBE_TEXTURE);
_pendingAmbientTexture = true; _pendingAmbientTexture = true;
if (_ambientTexture && _ambientTexture->isLoaded()) { if (_ambientTexture && _ambientTexture->isLoaded()) {
@ -410,7 +410,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
_skyboxTexture.clear(); _skyboxTexture.clear();
} else { } else {
// Update the Texture of the Skybox with the one pointed by this zone // Update the Texture of the Skybox with the one pointed by this zone
_skyboxTexture = textureCache->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE); _skyboxTexture = textureCache->getTexture(zone->getSkyboxProperties().getURL(), NetworkTexture::CUBE_TEXTURE);
_pendingSkyboxTexture = true; _pendingSkyboxTexture = true;
if (_skyboxTexture && _skyboxTexture->isLoaded()) { if (_skyboxTexture && _skyboxTexture->isLoaded()) {

View file

@ -425,7 +425,7 @@ NetworkMaterial::NetworkMaterial(const FBXMaterial& material, const QUrl& textur
{ {
_textures = Textures(MapChannel::NUM_MAP_CHANNELS); _textures = Textures(MapChannel::NUM_MAP_CHANNELS);
if (!material.albedoTexture.filename.isEmpty()) { if (!material.albedoTexture.filename.isEmpty()) {
auto map = fetchTextureMap(textureBaseUrl, material.albedoTexture, ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP); auto map = fetchTextureMap(textureBaseUrl, material.albedoTexture, NetworkTexture::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
_albedoTransform = material.albedoTexture.transform; _albedoTransform = material.albedoTexture.transform;
map->setTextureTransform(_albedoTransform); map->setTextureTransform(_albedoTransform);
@ -442,39 +442,39 @@ NetworkMaterial::NetworkMaterial(const FBXMaterial& material, const QUrl& textur
if (!material.normalTexture.filename.isEmpty()) { if (!material.normalTexture.filename.isEmpty()) {
auto type = (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE); auto type = (material.normalTexture.isBumpmap ? NetworkTexture::BUMP_TEXTURE : NetworkTexture::NORMAL_TEXTURE);
auto map = fetchTextureMap(textureBaseUrl, material.normalTexture, type, MapChannel::NORMAL_MAP); auto map = fetchTextureMap(textureBaseUrl, material.normalTexture, type, MapChannel::NORMAL_MAP);
setTextureMap(MapChannel::NORMAL_MAP, map); setTextureMap(MapChannel::NORMAL_MAP, map);
} }
if (!material.roughnessTexture.filename.isEmpty()) { if (!material.roughnessTexture.filename.isEmpty()) {
auto map = fetchTextureMap(textureBaseUrl, material.roughnessTexture, ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP); auto map = fetchTextureMap(textureBaseUrl, material.roughnessTexture, NetworkTexture::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
setTextureMap(MapChannel::ROUGHNESS_MAP, map); setTextureMap(MapChannel::ROUGHNESS_MAP, map);
} else if (!material.glossTexture.filename.isEmpty()) { } else if (!material.glossTexture.filename.isEmpty()) {
auto map = fetchTextureMap(textureBaseUrl, material.glossTexture, GLOSS_TEXTURE, MapChannel::ROUGHNESS_MAP); auto map = fetchTextureMap(textureBaseUrl, material.glossTexture, NetworkTexture::GLOSS_TEXTURE, MapChannel::ROUGHNESS_MAP);
setTextureMap(MapChannel::ROUGHNESS_MAP, map); setTextureMap(MapChannel::ROUGHNESS_MAP, map);
} }
if (!material.metallicTexture.filename.isEmpty()) { if (!material.metallicTexture.filename.isEmpty()) {
auto map = fetchTextureMap(textureBaseUrl, material.metallicTexture, METALLIC_TEXTURE, MapChannel::METALLIC_MAP); auto map = fetchTextureMap(textureBaseUrl, material.metallicTexture, NetworkTexture::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
setTextureMap(MapChannel::METALLIC_MAP, map); setTextureMap(MapChannel::METALLIC_MAP, map);
} else if (!material.specularTexture.filename.isEmpty()) { } else if (!material.specularTexture.filename.isEmpty()) {
auto map = fetchTextureMap(textureBaseUrl, material.specularTexture, SPECULAR_TEXTURE, MapChannel::METALLIC_MAP); auto map = fetchTextureMap(textureBaseUrl, material.specularTexture, NetworkTexture::SPECULAR_TEXTURE, MapChannel::METALLIC_MAP);
setTextureMap(MapChannel::METALLIC_MAP, map); setTextureMap(MapChannel::METALLIC_MAP, map);
} }
if (!material.occlusionTexture.filename.isEmpty()) { if (!material.occlusionTexture.filename.isEmpty()) {
auto map = fetchTextureMap(textureBaseUrl, material.occlusionTexture, OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP); auto map = fetchTextureMap(textureBaseUrl, material.occlusionTexture, NetworkTexture::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
setTextureMap(MapChannel::OCCLUSION_MAP, map); setTextureMap(MapChannel::OCCLUSION_MAP, map);
} }
if (!material.emissiveTexture.filename.isEmpty()) { if (!material.emissiveTexture.filename.isEmpty()) {
auto map = fetchTextureMap(textureBaseUrl, material.emissiveTexture, EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP); auto map = fetchTextureMap(textureBaseUrl, material.emissiveTexture, NetworkTexture::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
setTextureMap(MapChannel::EMISSIVE_MAP, map); setTextureMap(MapChannel::EMISSIVE_MAP, map);
} }
if (!material.lightmapTexture.filename.isEmpty()) { if (!material.lightmapTexture.filename.isEmpty()) {
auto map = fetchTextureMap(textureBaseUrl, material.lightmapTexture, LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP); auto map = fetchTextureMap(textureBaseUrl, material.lightmapTexture, NetworkTexture::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
_lightmapTransform = material.lightmapTexture.transform; _lightmapTransform = material.lightmapTexture.transform;
_lightmapParams = material.lightmapParams; _lightmapParams = material.lightmapParams;
map->setTextureTransform(_lightmapTransform); map->setTextureTransform(_lightmapTransform);
@ -496,7 +496,7 @@ void NetworkMaterial::setTextures(const QVariantMap& textureMap) {
if (!albedoName.isEmpty()) { if (!albedoName.isEmpty()) {
auto url = textureMap.contains(albedoName) ? textureMap[albedoName].toUrl() : QUrl(); auto url = textureMap.contains(albedoName) ? textureMap[albedoName].toUrl() : QUrl();
auto map = fetchTextureMap(url, ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP); auto map = fetchTextureMap(url, NetworkTexture::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
map->setTextureTransform(_albedoTransform); map->setTextureTransform(_albedoTransform);
// when reassigning the albedo texture we also check for the alpha channel used as opacity // when reassigning the albedo texture we also check for the alpha channel used as opacity
map->setUseAlphaChannel(true); map->setUseAlphaChannel(true);
@ -505,39 +505,39 @@ void NetworkMaterial::setTextures(const QVariantMap& textureMap) {
if (!normalName.isEmpty()) { if (!normalName.isEmpty()) {
auto url = textureMap.contains(normalName) ? textureMap[normalName].toUrl() : QUrl(); auto url = textureMap.contains(normalName) ? textureMap[normalName].toUrl() : QUrl();
auto map = fetchTextureMap(url, NORMAL_TEXTURE, MapChannel::NORMAL_MAP); auto map = fetchTextureMap(url, NetworkTexture::NORMAL_TEXTURE, MapChannel::NORMAL_MAP);
setTextureMap(MapChannel::NORMAL_MAP, map); setTextureMap(MapChannel::NORMAL_MAP, map);
} }
if (!roughnessName.isEmpty()) { if (!roughnessName.isEmpty()) {
auto url = textureMap.contains(roughnessName) ? textureMap[roughnessName].toUrl() : QUrl(); auto url = textureMap.contains(roughnessName) ? textureMap[roughnessName].toUrl() : QUrl();
// FIXME: If passing a gloss map instead of a roughmap how do we know? // FIXME: If passing a gloss map instead of a roughmap how do we know?
auto map = fetchTextureMap(url, ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP); auto map = fetchTextureMap(url, NetworkTexture::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
setTextureMap(MapChannel::ROUGHNESS_MAP, map); setTextureMap(MapChannel::ROUGHNESS_MAP, map);
} }
if (!metallicName.isEmpty()) { if (!metallicName.isEmpty()) {
auto url = textureMap.contains(metallicName) ? textureMap[metallicName].toUrl() : QUrl(); auto url = textureMap.contains(metallicName) ? textureMap[metallicName].toUrl() : QUrl();
// FIXME: If passing a specular map instead of a metallic how do we know? // FIXME: If passing a specular map instead of a metallic how do we know?
auto map = fetchTextureMap(url, METALLIC_TEXTURE, MapChannel::METALLIC_MAP); auto map = fetchTextureMap(url, NetworkTexture::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
setTextureMap(MapChannel::METALLIC_MAP, map); setTextureMap(MapChannel::METALLIC_MAP, map);
} }
if (!occlusionName.isEmpty()) { if (!occlusionName.isEmpty()) {
auto url = textureMap.contains(occlusionName) ? textureMap[occlusionName].toUrl() : QUrl(); auto url = textureMap.contains(occlusionName) ? textureMap[occlusionName].toUrl() : QUrl();
auto map = fetchTextureMap(url, OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP); auto map = fetchTextureMap(url, NetworkTexture::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
setTextureMap(MapChannel::OCCLUSION_MAP, map); setTextureMap(MapChannel::OCCLUSION_MAP, map);
} }
if (!emissiveName.isEmpty()) { if (!emissiveName.isEmpty()) {
auto url = textureMap.contains(emissiveName) ? textureMap[emissiveName].toUrl() : QUrl(); auto url = textureMap.contains(emissiveName) ? textureMap[emissiveName].toUrl() : QUrl();
auto map = fetchTextureMap(url, EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP); auto map = fetchTextureMap(url, NetworkTexture::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
setTextureMap(MapChannel::EMISSIVE_MAP, map); setTextureMap(MapChannel::EMISSIVE_MAP, map);
} }
if (!lightmapName.isEmpty()) { if (!lightmapName.isEmpty()) {
auto url = textureMap.contains(lightmapName) ? textureMap[lightmapName].toUrl() : QUrl(); auto url = textureMap.contains(lightmapName) ? textureMap[lightmapName].toUrl() : QUrl();
auto map = fetchTextureMap(url, LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP); auto map = fetchTextureMap(url, NetworkTexture::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
map->setTextureTransform(_lightmapTransform); map->setTextureTransform(_lightmapTransform);
map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y); map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
setTextureMap(MapChannel::LIGHTMAP_MAP, map); setTextureMap(MapChannel::LIGHTMAP_MAP, map);

View file

@ -170,6 +170,8 @@ protected:
const bool& isOriginal() const { return _isOriginal; } const bool& isOriginal() const { return _isOriginal; }
private: private:
using TextureType = NetworkTexture::Type;
// Helpers for the ctors // Helpers for the ctors
QUrl getTextureUrl(const QUrl& baseUrl, const FBXTexture& fbxTexture); QUrl getTextureUrl(const QUrl& baseUrl, const FBXTexture& fbxTexture);
model::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture, model::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture,

View file

@ -145,60 +145,62 @@ const gpu::TexturePointer& TextureCache::getNormalFittingTexture() {
/// Extra data for creating textures. /// Extra data for creating textures.
class TextureExtra { class TextureExtra {
public: public:
TextureType type; NetworkTexture::Type type;
const QByteArray& content; const QByteArray& content;
}; };
NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type, const QByteArray& content) { NetworkTexturePointer TextureCache::getTexture(const QUrl& url, Type type, const QByteArray& content) {
TextureExtra extra = { type, content }; TextureExtra extra = { type, content };
return ResourceCache::getResource(url, QUrl(), content.isEmpty(), &extra).staticCast<NetworkTexture>(); return ResourceCache::getResource(url, QUrl(), content.isEmpty(), &extra).staticCast<NetworkTexture>();
} }
NetworkTexture::TextureLoaderFunc getTextureLoaderForType(TextureType type) { NetworkTexture::TextureLoaderFunc getTextureLoaderForType(NetworkTexture::Type type) {
using Type = NetworkTexture;
switch (type) { switch (type) {
case ALBEDO_TEXTURE: { case Type::ALBEDO_TEXTURE: {
return model::TextureUsage::createAlbedoTextureFromImage; return model::TextureUsage::createAlbedoTextureFromImage;
break; break;
} }
case EMISSIVE_TEXTURE: { case Type::EMISSIVE_TEXTURE: {
return model::TextureUsage::createEmissiveTextureFromImage; return model::TextureUsage::createEmissiveTextureFromImage;
break; break;
} }
case LIGHTMAP_TEXTURE: { case Type::LIGHTMAP_TEXTURE: {
return model::TextureUsage::createLightmapTextureFromImage; return model::TextureUsage::createLightmapTextureFromImage;
break; break;
} }
case CUBE_TEXTURE: { case Type::CUBE_TEXTURE: {
return model::TextureUsage::createCubeTextureFromImage; return model::TextureUsage::createCubeTextureFromImage;
break; break;
} }
case BUMP_TEXTURE: { case Type::BUMP_TEXTURE: {
return model::TextureUsage::createNormalTextureFromBumpImage; return model::TextureUsage::createNormalTextureFromBumpImage;
break; break;
} }
case NORMAL_TEXTURE: { case Type::NORMAL_TEXTURE: {
return model::TextureUsage::createNormalTextureFromNormalImage; return model::TextureUsage::createNormalTextureFromNormalImage;
break; break;
} }
case ROUGHNESS_TEXTURE: { case Type::ROUGHNESS_TEXTURE: {
return model::TextureUsage::createRoughnessTextureFromImage; return model::TextureUsage::createRoughnessTextureFromImage;
break; break;
} }
case GLOSS_TEXTURE: { case Type::GLOSS_TEXTURE: {
return model::TextureUsage::createRoughnessTextureFromGlossImage; return model::TextureUsage::createRoughnessTextureFromGlossImage;
break; break;
} }
case SPECULAR_TEXTURE: { case Type::SPECULAR_TEXTURE: {
return model::TextureUsage::createMetallicTextureFromImage; return model::TextureUsage::createMetallicTextureFromImage;
break; break;
} }
case CUSTOM_TEXTURE: { case Type::CUSTOM_TEXTURE: {
Q_ASSERT(false); Q_ASSERT(false);
return NetworkTexture::TextureLoaderFunc(); return NetworkTexture::TextureLoaderFunc();
break; break;
} }
case DEFAULT_TEXTURE: case Type::DEFAULT_TEXTURE:
default: { default: {
return model::TextureUsage::create2DTextureFromImage; return model::TextureUsage::create2DTextureFromImage;
break; break;
@ -207,7 +209,7 @@ NetworkTexture::TextureLoaderFunc getTextureLoaderForType(TextureType type) {
} }
/// Returns a texture version of an image file /// Returns a texture version of an image file
gpu::TexturePointer TextureCache::getImageTexture(const QString& path, TextureType type) { gpu::TexturePointer TextureCache::getImageTexture(const QString& path, Type type) {
QImage image = QImage(path); QImage image = QImage(path);
auto loader = getTextureLoaderForType(type); auto loader = getTextureLoaderForType(type);
return gpu::TexturePointer(loader(image, QUrl::fromLocalFile(path).fileName().toStdString())); return gpu::TexturePointer(loader(image, QUrl::fromLocalFile(path).fileName().toStdString()));
@ -216,13 +218,13 @@ gpu::TexturePointer TextureCache::getImageTexture(const QString& path, TextureTy
QSharedPointer<Resource> TextureCache::createResource(const QUrl& url, QSharedPointer<Resource> TextureCache::createResource(const QUrl& url,
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) { const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) {
const TextureExtra* textureExtra = static_cast<const TextureExtra*>(extra); const TextureExtra* textureExtra = static_cast<const TextureExtra*>(extra);
auto type = textureExtra ? textureExtra->type : TextureType::DEFAULT_TEXTURE; auto type = textureExtra ? textureExtra->type : Type::DEFAULT_TEXTURE;
auto content = textureExtra ? textureExtra->content : QByteArray(); auto content = textureExtra ? textureExtra->content : QByteArray();
return QSharedPointer<Resource>(new NetworkTexture(url, type, content), return QSharedPointer<Resource>(new NetworkTexture(url, type, content),
&Resource::deleter); &Resource::deleter);
} }
NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) : NetworkTexture::NetworkTexture(const QUrl& url, Type type, const QByteArray& content) :
Resource(url, !content.isEmpty()), Resource(url, !content.isEmpty()),
_type(type) _type(type)
{ {

View file

@ -26,22 +26,6 @@ namespace gpu {
class Batch; class Batch;
} }
enum TextureType {
DEFAULT_TEXTURE,
ALBEDO_TEXTURE,
NORMAL_TEXTURE,
BUMP_TEXTURE,
SPECULAR_TEXTURE,
METALLIC_TEXTURE = SPECULAR_TEXTURE, // for now spec and metallic texture are the same, converted to grey
ROUGHNESS_TEXTURE,
GLOSS_TEXTURE,
EMISSIVE_TEXTURE,
CUBE_TEXTURE,
OCCLUSION_TEXTURE,
LIGHTMAP_TEXTURE,
CUSTOM_TEXTURE
};
/// A simple object wrapper for an OpenGL texture. /// A simple object wrapper for an OpenGL texture.
class Texture { class Texture {
public: public:
@ -55,11 +39,27 @@ class NetworkTexture : public Resource, public Texture {
Q_OBJECT Q_OBJECT
public: public:
enum Type {
DEFAULT_TEXTURE,
ALBEDO_TEXTURE,
NORMAL_TEXTURE,
BUMP_TEXTURE,
SPECULAR_TEXTURE,
METALLIC_TEXTURE = SPECULAR_TEXTURE, // for now spec and metallic texture are the same, converted to grey
ROUGHNESS_TEXTURE,
GLOSS_TEXTURE,
EMISSIVE_TEXTURE,
CUBE_TEXTURE,
OCCLUSION_TEXTURE,
LIGHTMAP_TEXTURE,
CUSTOM_TEXTURE
};
Q_ENUM(Type)
typedef gpu::Texture* TextureLoader(const QImage& image, const std::string& srcImageName); typedef gpu::Texture* TextureLoader(const QImage& image, const std::string& srcImageName);
using TextureLoaderFunc = std::function<TextureLoader>; using TextureLoaderFunc = std::function<TextureLoader>;
NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content); NetworkTexture(const QUrl& url, Type type, const QByteArray& content);
NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content); NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content);
int getOriginalWidth() const { return _originalWidth; } int getOriginalWidth() const { return _originalWidth; }
@ -82,7 +82,7 @@ protected:
Q_INVOKABLE void setImage(gpu::TexturePointer texture, int originalWidth, int originalHeight); Q_INVOKABLE void setImage(gpu::TexturePointer texture, int originalWidth, int originalHeight);
private: private:
TextureType _type; Type _type;
TextureLoaderFunc _textureLoader; TextureLoaderFunc _textureLoader;
int _originalWidth { 0 }; int _originalWidth { 0 };
int _originalHeight { 0 }; int _originalHeight { 0 };
@ -96,6 +96,8 @@ using NetworkTexturePointer = QSharedPointer<NetworkTexture>;
class TextureCache : public ResourceCache, public Dependency { class TextureCache : public ResourceCache, public Dependency {
Q_OBJECT Q_OBJECT
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
using Type = NetworkTexture::Type;
public: public:
/// Returns the ID of the permutation/normal texture used for Perlin noise shader programs. This texture /// Returns the ID of the permutation/normal texture used for Perlin noise shader programs. This texture
@ -119,10 +121,10 @@ public:
const gpu::TexturePointer& getNormalFittingTexture(); const gpu::TexturePointer& getNormalFittingTexture();
/// Returns a texture version of an image file /// Returns a texture version of an image file
static gpu::TexturePointer getImageTexture(const QString& path, TextureType type = DEFAULT_TEXTURE); static gpu::TexturePointer getImageTexture(const QString& path, Type type = Type::DEFAULT_TEXTURE);
/// Loads a texture from the specified URL. /// Loads a texture from the specified URL.
NetworkTexturePointer getTexture(const QUrl& url, TextureType type = DEFAULT_TEXTURE, NetworkTexturePointer getTexture(const QUrl& url, Type type = Type::DEFAULT_TEXTURE,
const QByteArray& content = QByteArray()); const QByteArray& content = QByteArray());
protected: protected: