mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 20:58:38 +02:00
move materialcache et al to material-networking library
This commit is contained in:
parent
e601f6c59f
commit
f7a487a020
37 changed files with 480 additions and 451 deletions
|
@ -14,7 +14,7 @@ link_hifi_libraries(
|
||||||
audio avatars octree gpu graphics shaders fbx hfm entities
|
audio avatars octree gpu graphics shaders fbx hfm entities
|
||||||
networking animation recording shared script-engine embedded-webserver
|
networking animation recording shared script-engine embedded-webserver
|
||||||
controllers physics plugins midi image
|
controllers physics plugins midi image
|
||||||
model-networking ktx shaders
|
material-networking model-networking ktx shaders
|
||||||
)
|
)
|
||||||
|
|
||||||
add_dependencies(${TARGET_NAME} oven)
|
add_dependencies(${TARGET_NAME} oven)
|
||||||
|
|
|
@ -205,8 +205,8 @@ endif()
|
||||||
# link required hifi libraries
|
# link required hifi libraries
|
||||||
link_hifi_libraries(
|
link_hifi_libraries(
|
||||||
shared workload task octree ktx gpu gl procedural graphics graphics-scripting render
|
shared workload task octree ktx gpu gl procedural graphics graphics-scripting render
|
||||||
pointers
|
pointers recording hfm fbx networking material-networking
|
||||||
recording hfm fbx networking model-networking model-baker entities avatars trackers
|
model-networking model-baker entities avatars trackers
|
||||||
audio audio-client animation script-engine physics
|
audio audio-client animation script-engine physics
|
||||||
render-utils entities-renderer avatars-renderer ui qml auto-updater midi
|
render-utils entities-renderer avatars-renderer ui qml auto-updater midi
|
||||||
controllers plugins image trackers
|
controllers plugins image trackers
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
#include <MessagesClient.h>
|
#include <MessagesClient.h>
|
||||||
#include <hfm/ModelFormatRegistry.h>
|
#include <hfm/ModelFormatRegistry.h>
|
||||||
#include <model-networking/ModelCacheScriptingInterface.h>
|
#include <model-networking/ModelCacheScriptingInterface.h>
|
||||||
#include <model-networking/TextureCacheScriptingInterface.h>
|
#include <material-networking/TextureCacheScriptingInterface.h>
|
||||||
#include <ModelEntityItem.h>
|
#include <ModelEntityItem.h>
|
||||||
#include <NetworkAccessManager.h>
|
#include <NetworkAccessManager.h>
|
||||||
#include <NetworkingConstants.h>
|
#include <NetworkingConstants.h>
|
||||||
|
@ -153,7 +153,7 @@
|
||||||
#include <avatars-renderer/ScriptAvatar.h>
|
#include <avatars-renderer/ScriptAvatar.h>
|
||||||
#include <RenderableEntityItem.h>
|
#include <RenderableEntityItem.h>
|
||||||
#include <RenderableWebEntityItem.h>
|
#include <RenderableWebEntityItem.h>
|
||||||
#include <model-networking/MaterialCache.h>
|
#include <material-networking/MaterialCache.h>
|
||||||
#include "recording/ClipCache.h"
|
#include "recording/ClipCache.h"
|
||||||
|
|
||||||
#include "AudioClient.h"
|
#include "AudioClient.h"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
set(TARGET_NAME avatars-renderer)
|
set(TARGET_NAME avatars-renderer)
|
||||||
setup_hifi_library(Network Script)
|
setup_hifi_library(Network Script)
|
||||||
link_hifi_libraries(shared shaders gpu graphics animation model-networking script-engine render render-utils image trackers entities-renderer)
|
link_hifi_libraries(shared shaders gpu graphics animation material-networking model-networking script-engine render render-utils image trackers entities-renderer)
|
||||||
include_hifi_library_headers(avatars)
|
include_hifi_library_headers(avatars)
|
||||||
include_hifi_library_headers(networking)
|
include_hifi_library_headers(networking)
|
||||||
include_hifi_library_headers(hfm)
|
include_hifi_library_headers(hfm)
|
||||||
|
|
|
@ -2,6 +2,7 @@ set(TARGET_NAME display-plugins)
|
||||||
setup_hifi_library(Gui)
|
setup_hifi_library(Gui)
|
||||||
link_hifi_libraries(shared shaders plugins ui-plugins gl ui render-utils ${PLATFORM_GL_BACKEND})
|
link_hifi_libraries(shared shaders plugins ui-plugins gl ui render-utils ${PLATFORM_GL_BACKEND})
|
||||||
include_hifi_library_headers(gpu)
|
include_hifi_library_headers(gpu)
|
||||||
|
include_hifi_library_headers(material-networking)
|
||||||
include_hifi_library_headers(model-networking)
|
include_hifi_library_headers(model-networking)
|
||||||
include_hifi_library_headers(networking)
|
include_hifi_library_headers(networking)
|
||||||
include_hifi_library_headers(graphics)
|
include_hifi_library_headers(graphics)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
set(TARGET_NAME entities-renderer)
|
set(TARGET_NAME entities-renderer)
|
||||||
setup_hifi_library(Network Script)
|
setup_hifi_library(Network Script)
|
||||||
link_hifi_libraries(shared workload gpu shaders procedural graphics model-networking script-engine render render-utils image qml ui pointers)
|
link_hifi_libraries(shared workload gpu shaders procedural graphics material-networking model-networking script-engine render render-utils image qml ui pointers)
|
||||||
include_hifi_library_headers(networking)
|
include_hifi_library_headers(networking)
|
||||||
include_hifi_library_headers(gl)
|
include_hifi_library_headers(gl)
|
||||||
include_hifi_library_headers(ktx)
|
include_hifi_library_headers(ktx)
|
||||||
|
|
|
@ -6,4 +6,4 @@ include_hifi_library_headers(fbx)
|
||||||
include_hifi_library_headers(gpu)
|
include_hifi_library_headers(gpu)
|
||||||
include_hifi_library_headers(image)
|
include_hifi_library_headers(image)
|
||||||
include_hifi_library_headers(ktx)
|
include_hifi_library_headers(ktx)
|
||||||
link_hifi_libraries(shared shaders networking octree avatars graphics model-networking)
|
link_hifi_libraries(shared shaders networking octree avatars graphics material-networking model-networking)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include "MaterialMappingMode.h"
|
#include "MaterialMappingMode.h"
|
||||||
#include <model-networking/ModelCache.h>
|
#include <model-networking/ModelCache.h>
|
||||||
#include <model-networking/MaterialCache.h>
|
#include <material-networking/MaterialCache.h>
|
||||||
|
|
||||||
class MaterialEntityItem : public EntityItem {
|
class MaterialEntityItem : public EntityItem {
|
||||||
using Pointer = std::shared_ptr<MaterialEntityItem>;
|
using Pointer = std::shared_ptr<MaterialEntityItem>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
set(TARGET_NAME graphics-scripting)
|
set(TARGET_NAME graphics-scripting)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared networking graphics fbx image model-networking script-engine)
|
link_hifi_libraries(shared networking graphics fbx image material-networking model-networking script-engine)
|
||||||
include_hifi_library_headers(gpu)
|
include_hifi_library_headers(gpu)
|
||||||
|
|
5
libraries/material-networking/CMakeLists.txt
Normal file
5
libraries/material-networking/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
set(TARGET_NAME material-networking)
|
||||||
|
setup_hifi_library()
|
||||||
|
link_hifi_libraries(shared shaders networking graphics fbx ktx image gl)
|
||||||
|
include_hifi_library_headers(gpu)
|
||||||
|
include_hifi_library_headers(hfm)
|
|
@ -426,4 +426,310 @@ QSharedPointer<Resource> MaterialCache::createResource(const QUrl& url) {
|
||||||
|
|
||||||
QSharedPointer<Resource> MaterialCache::createResourceCopy(const QSharedPointer<Resource>& resource) {
|
QSharedPointer<Resource> MaterialCache::createResourceCopy(const QSharedPointer<Resource>& resource) {
|
||||||
return QSharedPointer<Resource>(new NetworkMaterialResource(*resource.staticCast<NetworkMaterialResource>().data()), &Resource::deleter);
|
return QSharedPointer<Resource>(new NetworkMaterialResource(*resource.staticCast<NetworkMaterialResource>().data()), &Resource::deleter);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkMaterial::NetworkMaterial(const NetworkMaterial& m) :
|
||||||
|
Material(m),
|
||||||
|
_textures(m._textures),
|
||||||
|
_albedoTransform(m._albedoTransform),
|
||||||
|
_lightmapTransform(m._lightmapTransform),
|
||||||
|
_lightmapParams(m._lightmapParams),
|
||||||
|
_isOriginal(m._isOriginal)
|
||||||
|
{}
|
||||||
|
|
||||||
|
const QString NetworkMaterial::NO_TEXTURE = QString();
|
||||||
|
|
||||||
|
const QString& NetworkMaterial::getTextureName(MapChannel channel) {
|
||||||
|
if (_textures[channel].texture) {
|
||||||
|
return _textures[channel].name;
|
||||||
|
}
|
||||||
|
return NO_TEXTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const HFMTexture& texture) {
|
||||||
|
if (texture.content.isEmpty()) {
|
||||||
|
// External file: search relative to the baseUrl, in case filename is relative
|
||||||
|
return baseUrl.resolved(QUrl(texture.filename));
|
||||||
|
} else {
|
||||||
|
// Inlined file: cache under the fbx file to avoid namespace clashes
|
||||||
|
// NOTE: We cannot resolve the path because filename may be an absolute path
|
||||||
|
assert(texture.filename.size() > 0);
|
||||||
|
auto baseUrlStripped = baseUrl.toDisplayString(QUrl::RemoveFragment | QUrl::RemoveQuery | QUrl::RemoveUserInfo);
|
||||||
|
if (texture.filename.at(0) == '/') {
|
||||||
|
return baseUrlStripped + texture.filename;
|
||||||
|
} else {
|
||||||
|
return baseUrlStripped + '/' + texture.filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const HFMTexture& hfmTexture,
|
||||||
|
image::TextureUsage::Type type, MapChannel channel) {
|
||||||
|
|
||||||
|
if (baseUrl.isEmpty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto url = getTextureUrl(baseUrl, hfmTexture);
|
||||||
|
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, hfmTexture.content, hfmTexture.maxNumPixels);
|
||||||
|
_textures[channel] = Texture { hfmTexture.name, texture };
|
||||||
|
|
||||||
|
auto map = std::make_shared<graphics::TextureMap>();
|
||||||
|
if (texture) {
|
||||||
|
map->setTextureSource(texture->_textureSource);
|
||||||
|
}
|
||||||
|
map->setTextureTransform(hfmTexture.transform);
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel) {
|
||||||
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
|
if (textureCache && !url.isEmpty()) {
|
||||||
|
auto texture = textureCache->getTexture(url, type);
|
||||||
|
_textures[channel].texture = texture;
|
||||||
|
|
||||||
|
auto map = std::make_shared<graphics::TextureMap>();
|
||||||
|
if (texture) {
|
||||||
|
map->setTextureSource(texture->_textureSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::setAlbedoMap(const QUrl& url, bool useAlphaChannel) {
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
|
||||||
|
if (map) {
|
||||||
|
map->setUseAlphaChannel(useAlphaChannel);
|
||||||
|
setTextureMap(MapChannel::ALBEDO_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::setNormalMap(const QUrl& url, bool isBumpmap) {
|
||||||
|
auto map = fetchTextureMap(url, isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP);
|
||||||
|
if (map) {
|
||||||
|
setTextureMap(MapChannel::NORMAL_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::setRoughnessMap(const QUrl& url, bool isGloss) {
|
||||||
|
auto map = fetchTextureMap(url, isGloss ? image::TextureUsage::GLOSS_TEXTURE : image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
||||||
|
if (map) {
|
||||||
|
setTextureMap(MapChannel::ROUGHNESS_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::setMetallicMap(const QUrl& url, bool isSpecular) {
|
||||||
|
auto map = fetchTextureMap(url, isSpecular ? image::TextureUsage::SPECULAR_TEXTURE : image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
|
||||||
|
if (map) {
|
||||||
|
setTextureMap(MapChannel::METALLIC_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::setOcclusionMap(const QUrl& url) {
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
|
||||||
|
if (map) {
|
||||||
|
setTextureMap(MapChannel::OCCLUSION_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::setEmissiveMap(const QUrl& url) {
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
|
||||||
|
if (map) {
|
||||||
|
setTextureMap(MapChannel::EMISSIVE_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::setScatteringMap(const QUrl& url) {
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP);
|
||||||
|
if (map) {
|
||||||
|
setTextureMap(MapChannel::SCATTERING_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::setLightmapMap(const QUrl& url) {
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
||||||
|
if (map) {
|
||||||
|
//map->setTextureTransform(_lightmapTransform);
|
||||||
|
//map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
||||||
|
setTextureMap(MapChannel::LIGHTMAP_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkMaterial::NetworkMaterial(const HFMMaterial& material, const QUrl& textureBaseUrl) :
|
||||||
|
graphics::Material(*material._material),
|
||||||
|
_textures(MapChannel::NUM_MAP_CHANNELS)
|
||||||
|
{
|
||||||
|
_name = material.name.toStdString();
|
||||||
|
if (!material.albedoTexture.filename.isEmpty()) {
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.albedoTexture, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
|
||||||
|
if (map) {
|
||||||
|
_albedoTransform = material.albedoTexture.transform;
|
||||||
|
map->setTextureTransform(_albedoTransform);
|
||||||
|
|
||||||
|
if (!material.opacityTexture.filename.isEmpty()) {
|
||||||
|
if (material.albedoTexture.filename == material.opacityTexture.filename) {
|
||||||
|
// Best case scenario, just indicating that the albedo map contains transparency
|
||||||
|
// TODO: Different albedo/opacity maps are not currently supported
|
||||||
|
map->setUseAlphaChannel(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTextureMap(MapChannel::ALBEDO_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!material.normalTexture.filename.isEmpty()) {
|
||||||
|
auto type = (material.normalTexture.isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE);
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.normalTexture, type, MapChannel::NORMAL_MAP);
|
||||||
|
setTextureMap(MapChannel::NORMAL_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!material.roughnessTexture.filename.isEmpty()) {
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.roughnessTexture, image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
||||||
|
setTextureMap(MapChannel::ROUGHNESS_MAP, map);
|
||||||
|
} else if (!material.glossTexture.filename.isEmpty()) {
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.glossTexture, image::TextureUsage::GLOSS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
||||||
|
setTextureMap(MapChannel::ROUGHNESS_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!material.metallicTexture.filename.isEmpty()) {
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.metallicTexture, image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
|
||||||
|
setTextureMap(MapChannel::METALLIC_MAP, map);
|
||||||
|
} else if (!material.specularTexture.filename.isEmpty()) {
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.specularTexture, image::TextureUsage::SPECULAR_TEXTURE, MapChannel::METALLIC_MAP);
|
||||||
|
setTextureMap(MapChannel::METALLIC_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!material.occlusionTexture.filename.isEmpty()) {
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.occlusionTexture, image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
|
||||||
|
if (map) {
|
||||||
|
map->setTextureTransform(material.occlusionTexture.transform);
|
||||||
|
}
|
||||||
|
setTextureMap(MapChannel::OCCLUSION_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!material.emissiveTexture.filename.isEmpty()) {
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.emissiveTexture, image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
|
||||||
|
setTextureMap(MapChannel::EMISSIVE_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!material.scatteringTexture.filename.isEmpty()) {
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.scatteringTexture, image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP);
|
||||||
|
setTextureMap(MapChannel::SCATTERING_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!material.lightmapTexture.filename.isEmpty()) {
|
||||||
|
auto map = fetchTextureMap(textureBaseUrl, material.lightmapTexture, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
||||||
|
if (map) {
|
||||||
|
_lightmapTransform = material.lightmapTexture.transform;
|
||||||
|
_lightmapParams = material.lightmapParams;
|
||||||
|
map->setTextureTransform(_lightmapTransform);
|
||||||
|
map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
||||||
|
}
|
||||||
|
setTextureMap(MapChannel::LIGHTMAP_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::setTextures(const QVariantMap& textureMap) {
|
||||||
|
_isOriginal = false;
|
||||||
|
|
||||||
|
const auto& albedoName = getTextureName(MapChannel::ALBEDO_MAP);
|
||||||
|
const auto& normalName = getTextureName(MapChannel::NORMAL_MAP);
|
||||||
|
const auto& roughnessName = getTextureName(MapChannel::ROUGHNESS_MAP);
|
||||||
|
const auto& metallicName = getTextureName(MapChannel::METALLIC_MAP);
|
||||||
|
const auto& occlusionName = getTextureName(MapChannel::OCCLUSION_MAP);
|
||||||
|
const auto& emissiveName = getTextureName(MapChannel::EMISSIVE_MAP);
|
||||||
|
const auto& lightmapName = getTextureName(MapChannel::LIGHTMAP_MAP);
|
||||||
|
const auto& scatteringName = getTextureName(MapChannel::SCATTERING_MAP);
|
||||||
|
|
||||||
|
if (!albedoName.isEmpty()) {
|
||||||
|
auto url = textureMap.contains(albedoName) ? textureMap[albedoName].toUrl() : QUrl();
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
|
||||||
|
if (map) {
|
||||||
|
map->setTextureTransform(_albedoTransform);
|
||||||
|
// when reassigning the albedo texture we also check for the alpha channel used as opacity
|
||||||
|
map->setUseAlphaChannel(true);
|
||||||
|
}
|
||||||
|
setTextureMap(MapChannel::ALBEDO_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!normalName.isEmpty()) {
|
||||||
|
auto url = textureMap.contains(normalName) ? textureMap[normalName].toUrl() : QUrl();
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP);
|
||||||
|
setTextureMap(MapChannel::NORMAL_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!roughnessName.isEmpty()) {
|
||||||
|
auto url = textureMap.contains(roughnessName) ? textureMap[roughnessName].toUrl() : QUrl();
|
||||||
|
// FIXME: If passing a gloss map instead of a roughmap how do we know?
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
||||||
|
setTextureMap(MapChannel::ROUGHNESS_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!metallicName.isEmpty()) {
|
||||||
|
auto url = textureMap.contains(metallicName) ? textureMap[metallicName].toUrl() : QUrl();
|
||||||
|
// FIXME: If passing a specular map instead of a metallic how do we know?
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
|
||||||
|
setTextureMap(MapChannel::METALLIC_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!occlusionName.isEmpty()) {
|
||||||
|
auto url = textureMap.contains(occlusionName) ? textureMap[occlusionName].toUrl() : QUrl();
|
||||||
|
// FIXME: we need to handle the occlusion map transform here
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
|
||||||
|
setTextureMap(MapChannel::OCCLUSION_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!emissiveName.isEmpty()) {
|
||||||
|
auto url = textureMap.contains(emissiveName) ? textureMap[emissiveName].toUrl() : QUrl();
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
|
||||||
|
setTextureMap(MapChannel::EMISSIVE_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scatteringName.isEmpty()) {
|
||||||
|
auto url = textureMap.contains(scatteringName) ? textureMap[scatteringName].toUrl() : QUrl();
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP);
|
||||||
|
setTextureMap(MapChannel::SCATTERING_MAP, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lightmapName.isEmpty()) {
|
||||||
|
auto url = textureMap.contains(lightmapName) ? textureMap[lightmapName].toUrl() : QUrl();
|
||||||
|
auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
||||||
|
if (map) {
|
||||||
|
map->setTextureTransform(_lightmapTransform);
|
||||||
|
map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
||||||
|
}
|
||||||
|
setTextureMap(MapChannel::LIGHTMAP_MAP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetworkMaterial::isMissingTexture() {
|
||||||
|
for (auto& networkTexture : _textures) {
|
||||||
|
auto& texture = networkTexture.texture;
|
||||||
|
if (!texture) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Failed texture downloads need to be considered as 'loaded'
|
||||||
|
// or the object will never fade in
|
||||||
|
bool finished = texture->isFailed() || (texture->isLoaded() && texture->getGPUTexture() && texture->getGPUTexture()->isDefined());
|
||||||
|
if (!finished) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMaterial::checkResetOpacityMap() {
|
||||||
|
// If material textures are loaded, check the material translucency
|
||||||
|
// FIXME: This should not be done here. The opacity map should already be reset in Material::setTextureMap.
|
||||||
|
// However, currently that code can be called before the albedo map is defined, so resetOpacityMap will fail.
|
||||||
|
// Geometry::areTexturesLoaded() is called repeatedly until it returns true, so we do the check here for now
|
||||||
|
const auto& albedoTexture = _textures[NetworkMaterial::MapChannel::ALBEDO_MAP];
|
||||||
|
if (albedoTexture.texture) {
|
||||||
|
resetOpacityMap();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
//
|
||||||
|
// Created by Sam Gondelman on 2/9/2018
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#ifndef hifi_MaterialCache_h
|
||||||
|
#define hifi_MaterialCache_h
|
||||||
|
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
|
||||||
|
#include <ResourceCache.h>
|
||||||
|
#include <graphics/Material.h>
|
||||||
|
#include <hfm/HFM.h>
|
||||||
|
|
||||||
|
#include "TextureCache.h"
|
||||||
|
|
||||||
|
class NetworkMaterial : public graphics::Material {
|
||||||
|
public:
|
||||||
|
using MapChannel = graphics::Material::MapChannel;
|
||||||
|
|
||||||
|
NetworkMaterial() : _textures(MapChannel::NUM_MAP_CHANNELS) {}
|
||||||
|
NetworkMaterial(const HFMMaterial& material, const QUrl& textureBaseUrl);
|
||||||
|
NetworkMaterial(const NetworkMaterial& material);
|
||||||
|
|
||||||
|
void setAlbedoMap(const QUrl& url, bool useAlphaChannel);
|
||||||
|
void setNormalMap(const QUrl& url, bool isBumpmap);
|
||||||
|
void setRoughnessMap(const QUrl& url, bool isGloss);
|
||||||
|
void setMetallicMap(const QUrl& url, bool isSpecular);
|
||||||
|
void setOcclusionMap(const QUrl& url);
|
||||||
|
void setEmissiveMap(const QUrl& url);
|
||||||
|
void setScatteringMap(const QUrl& url);
|
||||||
|
void setLightmapMap(const QUrl& url);
|
||||||
|
|
||||||
|
bool isMissingTexture();
|
||||||
|
void checkResetOpacityMap();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class Geometry;
|
||||||
|
|
||||||
|
class Texture {
|
||||||
|
public:
|
||||||
|
QString name;
|
||||||
|
NetworkTexturePointer texture;
|
||||||
|
};
|
||||||
|
using Textures = std::vector<Texture>;
|
||||||
|
|
||||||
|
Textures _textures;
|
||||||
|
|
||||||
|
static const QString NO_TEXTURE;
|
||||||
|
const QString& getTextureName(MapChannel channel);
|
||||||
|
|
||||||
|
void setTextures(const QVariantMap& textureMap);
|
||||||
|
|
||||||
|
const bool& isOriginal() const { return _isOriginal; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Helpers for the ctors
|
||||||
|
QUrl getTextureUrl(const QUrl& baseUrl, const HFMTexture& hfmTexture);
|
||||||
|
graphics::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const HFMTexture& hfmTexture,
|
||||||
|
image::TextureUsage::Type type, MapChannel channel);
|
||||||
|
graphics::TextureMapPointer fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel);
|
||||||
|
|
||||||
|
Transform _albedoTransform;
|
||||||
|
Transform _lightmapTransform;
|
||||||
|
vec2 _lightmapParams;
|
||||||
|
|
||||||
|
bool _isOriginal { true };
|
||||||
|
};
|
||||||
|
|
||||||
|
class NetworkMaterialResource : public Resource {
|
||||||
|
public:
|
||||||
|
NetworkMaterialResource(const QUrl& url);
|
||||||
|
|
||||||
|
QString getType() const override { return "NetworkMaterial"; }
|
||||||
|
|
||||||
|
virtual void downloadFinished(const QByteArray& data) override;
|
||||||
|
|
||||||
|
typedef struct ParsedMaterials {
|
||||||
|
uint version { 1 };
|
||||||
|
std::vector<std::string> names;
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<NetworkMaterial>> networkMaterials;
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
version = 1;
|
||||||
|
names.clear();
|
||||||
|
networkMaterials.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
} ParsedMaterials;
|
||||||
|
|
||||||
|
ParsedMaterials parsedMaterials;
|
||||||
|
|
||||||
|
static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl);
|
||||||
|
static std::pair<std::string, std::shared_ptr<NetworkMaterial>> parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB);
|
||||||
|
};
|
||||||
|
|
||||||
|
using NetworkMaterialResourcePointer = QSharedPointer<NetworkMaterialResource>;
|
||||||
|
|
||||||
|
class MaterialCache : public ResourceCache {
|
||||||
|
public:
|
||||||
|
static MaterialCache& instance();
|
||||||
|
|
||||||
|
NetworkMaterialResourcePointer getMaterial(const QUrl& url);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QSharedPointer<Resource> createResource(const QUrl& url) override;
|
||||||
|
QSharedPointer<Resource> createResourceCopy(const QSharedPointer<Resource>& resource) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
//
|
||||||
|
// Created by Sam Gondelman on 2/7/2019
|
||||||
|
// Copyright 2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "MaterialNetworkingLogging.h"
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(materialnetworking, "hifi.gpu-material-network")
|
|
@ -0,0 +1,11 @@
|
||||||
|
//
|
||||||
|
// Created by Sam Gondelman on 2/7/2019
|
||||||
|
// Copyright 2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(materialnetworking)
|
|
@ -44,7 +44,7 @@
|
||||||
#include <Profile.h>
|
#include <Profile.h>
|
||||||
|
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
#include "ModelNetworkingLogging.h"
|
#include "MaterialNetworkingLogging.h"
|
||||||
#include "NetworkingConstants.h"
|
#include "NetworkingConstants.h"
|
||||||
#include <Trace.h>
|
#include <Trace.h>
|
||||||
#include <StatTracker.h>
|
#include <StatTracker.h>
|
||||||
|
@ -938,7 +938,7 @@ void NetworkTexture::handleFinishedInitialLoad() {
|
||||||
cache::FilePointer file;
|
cache::FilePointer file;
|
||||||
auto& ktxCache = textureCache->_ktxCache;
|
auto& ktxCache = textureCache->_ktxCache;
|
||||||
if (!memKtx || !(file = ktxCache->writeFile(data, KTXCache::Metadata(filename, length)))) {
|
if (!memKtx || !(file = ktxCache->writeFile(data, KTXCache::Metadata(filename, length)))) {
|
||||||
qCWarning(modelnetworking) << url << " failed to write cache file";
|
qCWarning(materialnetworking) << url << " failed to write cache file";
|
||||||
QMetaObject::invokeMethod(resource.data(), "setImage",
|
QMetaObject::invokeMethod(resource.data(), "setImage",
|
||||||
Q_ARG(gpu::TexturePointer, nullptr),
|
Q_ARG(gpu::TexturePointer, nullptr),
|
||||||
Q_ARG(int, 0),
|
Q_ARG(int, 0),
|
||||||
|
@ -1126,7 +1126,7 @@ void ImageReader::listSupportedImageFormats() {
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
std::call_once(once, []{
|
std::call_once(once, []{
|
||||||
auto supportedFormats = QImageReader::supportedImageFormats();
|
auto supportedFormats = QImageReader::supportedImageFormats();
|
||||||
qCDebug(modelnetworking) << "List of supported Image formats:" << supportedFormats.join(", ");
|
qCDebug(materialnetworking) << "List of supported Image formats:" << supportedFormats.join(", ");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1174,7 +1174,7 @@ void ImageReader::read() {
|
||||||
if (texture) {
|
if (texture) {
|
||||||
texture = textureCache->cacheTextureByHash(hash, texture);
|
texture = textureCache->cacheTextureByHash(hash, texture);
|
||||||
} else {
|
} else {
|
||||||
qCWarning(modelnetworking) << "Invalid cached KTX " << _url << " under hash " << hash.c_str() << ", recreating...";
|
qCWarning(materialnetworking) << "Invalid cached KTX " << _url << " under hash " << hash.c_str() << ", recreating...";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
set(TARGET_NAME model-baker)
|
set(TARGET_NAME model-baker)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
|
|
||||||
link_hifi_libraries(shared task gpu graphics hfm)
|
link_hifi_libraries(shared shaders task gpu graphics hfm material-networking)
|
||||||
|
include_hifi_library_headers(networking)
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#include "ModelBakerLogging.h"
|
#include "ModelBakerLogging.h"
|
||||||
|
|
||||||
|
#include <material-networking/MaterialCache.h>
|
||||||
|
|
||||||
void ApplyMaterialMappingTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) {
|
void ApplyMaterialMappingTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) {
|
||||||
const auto& materialsIn = input.get0();
|
const auto& materialsIn = input.get0();
|
||||||
const auto& mapping = input.get1();
|
const auto& mapping = input.get1();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
set(TARGET_NAME model-networking)
|
set(TARGET_NAME model-networking)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared shaders networking graphics fbx ktx image gl model-baker)
|
link_hifi_libraries(shared shaders networking graphics fbx material-networking model-baker)
|
||||||
include_hifi_library_headers(gpu)
|
|
||||||
include_hifi_library_headers(hfm)
|
include_hifi_library_headers(hfm)
|
||||||
include_hifi_library_headers(task)
|
include_hifi_library_headers(task)
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Sam Gondelman on 2/9/2018
|
|
||||||
// Copyright 2018 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
#ifndef hifi_MaterialCache_h
|
|
||||||
#define hifi_MaterialCache_h
|
|
||||||
|
|
||||||
#include <ResourceCache.h>
|
|
||||||
|
|
||||||
#include "glm/glm.hpp"
|
|
||||||
|
|
||||||
#include "ModelCache.h"
|
|
||||||
|
|
||||||
class NetworkMaterialResource : public Resource {
|
|
||||||
public:
|
|
||||||
NetworkMaterialResource(const QUrl& url);
|
|
||||||
|
|
||||||
QString getType() const override { return "NetworkMaterial"; }
|
|
||||||
|
|
||||||
virtual void downloadFinished(const QByteArray& data) override;
|
|
||||||
|
|
||||||
typedef struct ParsedMaterials {
|
|
||||||
uint version { 1 };
|
|
||||||
std::vector<std::string> names;
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<NetworkMaterial>> networkMaterials;
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
version = 1;
|
|
||||||
names.clear();
|
|
||||||
networkMaterials.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
} ParsedMaterials;
|
|
||||||
|
|
||||||
ParsedMaterials parsedMaterials;
|
|
||||||
|
|
||||||
static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl);
|
|
||||||
static std::pair<std::string, std::shared_ptr<NetworkMaterial>> parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB);
|
|
||||||
};
|
|
||||||
|
|
||||||
using NetworkMaterialResourcePointer = QSharedPointer<NetworkMaterialResource>;
|
|
||||||
|
|
||||||
class MaterialCache : public ResourceCache {
|
|
||||||
public:
|
|
||||||
static MaterialCache& instance();
|
|
||||||
|
|
||||||
NetworkMaterialResourcePointer getMaterial(const QUrl& url);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual QSharedPointer<Resource> createResource(const QUrl& url) override;
|
|
||||||
QSharedPointer<Resource> createResourceCopy(const QSharedPointer<Resource>& resource) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -556,310 +556,4 @@ void GeometryResourceWatcher::resourceRefreshed() {
|
||||||
// _instance.reset();
|
// _instance.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkMaterial::NetworkMaterial(const NetworkMaterial& m) :
|
|
||||||
Material(m),
|
|
||||||
_textures(m._textures),
|
|
||||||
_albedoTransform(m._albedoTransform),
|
|
||||||
_lightmapTransform(m._lightmapTransform),
|
|
||||||
_lightmapParams(m._lightmapParams),
|
|
||||||
_isOriginal(m._isOriginal)
|
|
||||||
{}
|
|
||||||
|
|
||||||
const QString NetworkMaterial::NO_TEXTURE = QString();
|
|
||||||
|
|
||||||
const QString& NetworkMaterial::getTextureName(MapChannel channel) {
|
|
||||||
if (_textures[channel].texture) {
|
|
||||||
return _textures[channel].name;
|
|
||||||
}
|
|
||||||
return NO_TEXTURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const HFMTexture& texture) {
|
|
||||||
if (texture.content.isEmpty()) {
|
|
||||||
// External file: search relative to the baseUrl, in case filename is relative
|
|
||||||
return baseUrl.resolved(QUrl(texture.filename));
|
|
||||||
} else {
|
|
||||||
// Inlined file: cache under the fbx file to avoid namespace clashes
|
|
||||||
// NOTE: We cannot resolve the path because filename may be an absolute path
|
|
||||||
assert(texture.filename.size() > 0);
|
|
||||||
auto baseUrlStripped = baseUrl.toDisplayString(QUrl::RemoveFragment | QUrl::RemoveQuery | QUrl::RemoveUserInfo);
|
|
||||||
if (texture.filename.at(0) == '/') {
|
|
||||||
return baseUrlStripped + texture.filename;
|
|
||||||
} else {
|
|
||||||
return baseUrlStripped + '/' + texture.filename;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const HFMTexture& hfmTexture,
|
|
||||||
image::TextureUsage::Type type, MapChannel channel) {
|
|
||||||
|
|
||||||
if (baseUrl.isEmpty()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto url = getTextureUrl(baseUrl, hfmTexture);
|
|
||||||
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, hfmTexture.content, hfmTexture.maxNumPixels);
|
|
||||||
_textures[channel] = Texture { hfmTexture.name, texture };
|
|
||||||
|
|
||||||
auto map = std::make_shared<graphics::TextureMap>();
|
|
||||||
if (texture) {
|
|
||||||
map->setTextureSource(texture->_textureSource);
|
|
||||||
}
|
|
||||||
map->setTextureTransform(hfmTexture.transform);
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel) {
|
|
||||||
auto textureCache = DependencyManager::get<TextureCache>();
|
|
||||||
if (textureCache && !url.isEmpty()) {
|
|
||||||
auto texture = textureCache->getTexture(url, type);
|
|
||||||
_textures[channel].texture = texture;
|
|
||||||
|
|
||||||
auto map = std::make_shared<graphics::TextureMap>();
|
|
||||||
if (texture) {
|
|
||||||
map->setTextureSource(texture->_textureSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::setAlbedoMap(const QUrl& url, bool useAlphaChannel) {
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
|
|
||||||
if (map) {
|
|
||||||
map->setUseAlphaChannel(useAlphaChannel);
|
|
||||||
setTextureMap(MapChannel::ALBEDO_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::setNormalMap(const QUrl& url, bool isBumpmap) {
|
|
||||||
auto map = fetchTextureMap(url, isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP);
|
|
||||||
if (map) {
|
|
||||||
setTextureMap(MapChannel::NORMAL_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::setRoughnessMap(const QUrl& url, bool isGloss) {
|
|
||||||
auto map = fetchTextureMap(url, isGloss ? image::TextureUsage::GLOSS_TEXTURE : image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
|
||||||
if (map) {
|
|
||||||
setTextureMap(MapChannel::ROUGHNESS_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::setMetallicMap(const QUrl& url, bool isSpecular) {
|
|
||||||
auto map = fetchTextureMap(url, isSpecular ? image::TextureUsage::SPECULAR_TEXTURE : image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
|
|
||||||
if (map) {
|
|
||||||
setTextureMap(MapChannel::METALLIC_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::setOcclusionMap(const QUrl& url) {
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
|
|
||||||
if (map) {
|
|
||||||
setTextureMap(MapChannel::OCCLUSION_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::setEmissiveMap(const QUrl& url) {
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
|
|
||||||
if (map) {
|
|
||||||
setTextureMap(MapChannel::EMISSIVE_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::setScatteringMap(const QUrl& url) {
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP);
|
|
||||||
if (map) {
|
|
||||||
setTextureMap(MapChannel::SCATTERING_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::setLightmapMap(const QUrl& url) {
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
|
||||||
if (map) {
|
|
||||||
//map->setTextureTransform(_lightmapTransform);
|
|
||||||
//map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
|
||||||
setTextureMap(MapChannel::LIGHTMAP_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkMaterial::NetworkMaterial(const HFMMaterial& material, const QUrl& textureBaseUrl) :
|
|
||||||
graphics::Material(*material._material),
|
|
||||||
_textures(MapChannel::NUM_MAP_CHANNELS)
|
|
||||||
{
|
|
||||||
_name = material.name.toStdString();
|
|
||||||
if (!material.albedoTexture.filename.isEmpty()) {
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.albedoTexture, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
|
|
||||||
if (map) {
|
|
||||||
_albedoTransform = material.albedoTexture.transform;
|
|
||||||
map->setTextureTransform(_albedoTransform);
|
|
||||||
|
|
||||||
if (!material.opacityTexture.filename.isEmpty()) {
|
|
||||||
if (material.albedoTexture.filename == material.opacityTexture.filename) {
|
|
||||||
// Best case scenario, just indicating that the albedo map contains transparency
|
|
||||||
// TODO: Different albedo/opacity maps are not currently supported
|
|
||||||
map->setUseAlphaChannel(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setTextureMap(MapChannel::ALBEDO_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!material.normalTexture.filename.isEmpty()) {
|
|
||||||
auto type = (material.normalTexture.isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE);
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.normalTexture, type, MapChannel::NORMAL_MAP);
|
|
||||||
setTextureMap(MapChannel::NORMAL_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!material.roughnessTexture.filename.isEmpty()) {
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.roughnessTexture, image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
|
||||||
setTextureMap(MapChannel::ROUGHNESS_MAP, map);
|
|
||||||
} else if (!material.glossTexture.filename.isEmpty()) {
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.glossTexture, image::TextureUsage::GLOSS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
|
||||||
setTextureMap(MapChannel::ROUGHNESS_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!material.metallicTexture.filename.isEmpty()) {
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.metallicTexture, image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
|
|
||||||
setTextureMap(MapChannel::METALLIC_MAP, map);
|
|
||||||
} else if (!material.specularTexture.filename.isEmpty()) {
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.specularTexture, image::TextureUsage::SPECULAR_TEXTURE, MapChannel::METALLIC_MAP);
|
|
||||||
setTextureMap(MapChannel::METALLIC_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!material.occlusionTexture.filename.isEmpty()) {
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.occlusionTexture, image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
|
|
||||||
if (map) {
|
|
||||||
map->setTextureTransform(material.occlusionTexture.transform);
|
|
||||||
}
|
|
||||||
setTextureMap(MapChannel::OCCLUSION_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!material.emissiveTexture.filename.isEmpty()) {
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.emissiveTexture, image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
|
|
||||||
setTextureMap(MapChannel::EMISSIVE_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!material.scatteringTexture.filename.isEmpty()) {
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.scatteringTexture, image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP);
|
|
||||||
setTextureMap(MapChannel::SCATTERING_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!material.lightmapTexture.filename.isEmpty()) {
|
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.lightmapTexture, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
|
||||||
if (map) {
|
|
||||||
_lightmapTransform = material.lightmapTexture.transform;
|
|
||||||
_lightmapParams = material.lightmapParams;
|
|
||||||
map->setTextureTransform(_lightmapTransform);
|
|
||||||
map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
|
||||||
}
|
|
||||||
setTextureMap(MapChannel::LIGHTMAP_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::setTextures(const QVariantMap& textureMap) {
|
|
||||||
_isOriginal = false;
|
|
||||||
|
|
||||||
const auto& albedoName = getTextureName(MapChannel::ALBEDO_MAP);
|
|
||||||
const auto& normalName = getTextureName(MapChannel::NORMAL_MAP);
|
|
||||||
const auto& roughnessName = getTextureName(MapChannel::ROUGHNESS_MAP);
|
|
||||||
const auto& metallicName = getTextureName(MapChannel::METALLIC_MAP);
|
|
||||||
const auto& occlusionName = getTextureName(MapChannel::OCCLUSION_MAP);
|
|
||||||
const auto& emissiveName = getTextureName(MapChannel::EMISSIVE_MAP);
|
|
||||||
const auto& lightmapName = getTextureName(MapChannel::LIGHTMAP_MAP);
|
|
||||||
const auto& scatteringName = getTextureName(MapChannel::SCATTERING_MAP);
|
|
||||||
|
|
||||||
if (!albedoName.isEmpty()) {
|
|
||||||
auto url = textureMap.contains(albedoName) ? textureMap[albedoName].toUrl() : QUrl();
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
|
|
||||||
if (map) {
|
|
||||||
map->setTextureTransform(_albedoTransform);
|
|
||||||
// when reassigning the albedo texture we also check for the alpha channel used as opacity
|
|
||||||
map->setUseAlphaChannel(true);
|
|
||||||
}
|
|
||||||
setTextureMap(MapChannel::ALBEDO_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!normalName.isEmpty()) {
|
|
||||||
auto url = textureMap.contains(normalName) ? textureMap[normalName].toUrl() : QUrl();
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP);
|
|
||||||
setTextureMap(MapChannel::NORMAL_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roughnessName.isEmpty()) {
|
|
||||||
auto url = textureMap.contains(roughnessName) ? textureMap[roughnessName].toUrl() : QUrl();
|
|
||||||
// FIXME: If passing a gloss map instead of a roughmap how do we know?
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
|
|
||||||
setTextureMap(MapChannel::ROUGHNESS_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!metallicName.isEmpty()) {
|
|
||||||
auto url = textureMap.contains(metallicName) ? textureMap[metallicName].toUrl() : QUrl();
|
|
||||||
// FIXME: If passing a specular map instead of a metallic how do we know?
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
|
|
||||||
setTextureMap(MapChannel::METALLIC_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!occlusionName.isEmpty()) {
|
|
||||||
auto url = textureMap.contains(occlusionName) ? textureMap[occlusionName].toUrl() : QUrl();
|
|
||||||
// FIXME: we need to handle the occlusion map transform here
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
|
|
||||||
setTextureMap(MapChannel::OCCLUSION_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!emissiveName.isEmpty()) {
|
|
||||||
auto url = textureMap.contains(emissiveName) ? textureMap[emissiveName].toUrl() : QUrl();
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
|
|
||||||
setTextureMap(MapChannel::EMISSIVE_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!scatteringName.isEmpty()) {
|
|
||||||
auto url = textureMap.contains(scatteringName) ? textureMap[scatteringName].toUrl() : QUrl();
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP);
|
|
||||||
setTextureMap(MapChannel::SCATTERING_MAP, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!lightmapName.isEmpty()) {
|
|
||||||
auto url = textureMap.contains(lightmapName) ? textureMap[lightmapName].toUrl() : QUrl();
|
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
|
||||||
if (map) {
|
|
||||||
map->setTextureTransform(_lightmapTransform);
|
|
||||||
map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
|
||||||
}
|
|
||||||
setTextureMap(MapChannel::LIGHTMAP_MAP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NetworkMaterial::isMissingTexture() {
|
|
||||||
for (auto& networkTexture : _textures) {
|
|
||||||
auto& texture = networkTexture.texture;
|
|
||||||
if (!texture) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Failed texture downloads need to be considered as 'loaded'
|
|
||||||
// or the object will never fade in
|
|
||||||
bool finished = texture->isFailed() || (texture->isLoaded() && texture->getGPUTexture() && texture->getGPUTexture()->isDefined());
|
|
||||||
if (!finished) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkMaterial::checkResetOpacityMap() {
|
|
||||||
// If material textures are loaded, check the material translucency
|
|
||||||
// FIXME: This should not be done here. The opacity map should already be reset in Material::setTextureMap.
|
|
||||||
// However, currently that code can be called before the albedo map is defined, so resetOpacityMap will fail.
|
|
||||||
// Geometry::areTexturesLoaded() is called repeatedly until it returns true, so we do the check here for now
|
|
||||||
const auto& albedoTexture = _textures[NetworkMaterial::MapChannel::ALBEDO_MAP];
|
|
||||||
if (albedoTexture.texture) {
|
|
||||||
resetOpacityMap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "ModelCache.moc"
|
#include "ModelCache.moc"
|
||||||
|
|
|
@ -15,17 +15,13 @@
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <ResourceCache.h>
|
#include <ResourceCache.h>
|
||||||
|
|
||||||
#include <graphics/Material.h>
|
|
||||||
#include <graphics/Asset.h>
|
#include <graphics/Asset.h>
|
||||||
|
|
||||||
#include "FBXSerializer.h"
|
#include "FBXSerializer.h"
|
||||||
#include "TextureCache.h"
|
#include <material-networking/MaterialCache.h>
|
||||||
|
#include <material-networking/TextureCache.h>
|
||||||
#include "ModelLoader.h"
|
#include "ModelLoader.h"
|
||||||
|
|
||||||
// Alias instead of derive to avoid copying
|
|
||||||
|
|
||||||
class NetworkTexture;
|
|
||||||
class NetworkMaterial;
|
|
||||||
class MeshPart;
|
class MeshPart;
|
||||||
|
|
||||||
class GeometryMappingResource;
|
class GeometryMappingResource;
|
||||||
|
@ -166,59 +162,6 @@ private:
|
||||||
ModelLoader _modelLoader;
|
ModelLoader _modelLoader;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetworkMaterial : public graphics::Material {
|
|
||||||
public:
|
|
||||||
using MapChannel = graphics::Material::MapChannel;
|
|
||||||
|
|
||||||
NetworkMaterial() : _textures(MapChannel::NUM_MAP_CHANNELS) {}
|
|
||||||
NetworkMaterial(const HFMMaterial& material, const QUrl& textureBaseUrl);
|
|
||||||
NetworkMaterial(const NetworkMaterial& material);
|
|
||||||
|
|
||||||
void setAlbedoMap(const QUrl& url, bool useAlphaChannel);
|
|
||||||
void setNormalMap(const QUrl& url, bool isBumpmap);
|
|
||||||
void setRoughnessMap(const QUrl& url, bool isGloss);
|
|
||||||
void setMetallicMap(const QUrl& url, bool isSpecular);
|
|
||||||
void setOcclusionMap(const QUrl& url);
|
|
||||||
void setEmissiveMap(const QUrl& url);
|
|
||||||
void setScatteringMap(const QUrl& url);
|
|
||||||
void setLightmapMap(const QUrl& url);
|
|
||||||
|
|
||||||
bool isMissingTexture();
|
|
||||||
void checkResetOpacityMap();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
friend class Geometry;
|
|
||||||
|
|
||||||
class Texture {
|
|
||||||
public:
|
|
||||||
QString name;
|
|
||||||
NetworkTexturePointer texture;
|
|
||||||
};
|
|
||||||
using Textures = std::vector<Texture>;
|
|
||||||
|
|
||||||
Textures _textures;
|
|
||||||
|
|
||||||
static const QString NO_TEXTURE;
|
|
||||||
const QString& getTextureName(MapChannel channel);
|
|
||||||
|
|
||||||
void setTextures(const QVariantMap& textureMap);
|
|
||||||
|
|
||||||
const bool& isOriginal() const { return _isOriginal; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Helpers for the ctors
|
|
||||||
QUrl getTextureUrl(const QUrl& baseUrl, const HFMTexture& hfmTexture);
|
|
||||||
graphics::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const HFMTexture& hfmTexture,
|
|
||||||
image::TextureUsage::Type type, MapChannel channel);
|
|
||||||
graphics::TextureMapPointer fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel);
|
|
||||||
|
|
||||||
Transform _albedoTransform;
|
|
||||||
Transform _lightmapTransform;
|
|
||||||
vec2 _lightmapParams;
|
|
||||||
|
|
||||||
bool _isOriginal { true };
|
|
||||||
};
|
|
||||||
|
|
||||||
class MeshPart {
|
class MeshPart {
|
||||||
public:
|
public:
|
||||||
MeshPart(int mesh, int part, int material) : meshID { mesh }, partID { part }, materialID { material } {}
|
MeshPart(int mesh, int part, int material) : meshID { mesh }, partID { part }, materialID { material } {}
|
||||||
|
|
|
@ -8,4 +8,4 @@
|
||||||
|
|
||||||
#include "ModelNetworkingLogging.h"
|
#include "ModelNetworkingLogging.h"
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(modelnetworking, "hifi.gpu-network")
|
Q_LOGGING_CATEGORY(modelnetworking, "hifi.gpu-model-network")
|
||||||
|
|
|
@ -7,6 +7,7 @@ include_hifi_library_headers(avatars)
|
||||||
include_hifi_library_headers(audio)
|
include_hifi_library_headers(audio)
|
||||||
include_hifi_library_headers(octree)
|
include_hifi_library_headers(octree)
|
||||||
include_hifi_library_headers(animation)
|
include_hifi_library_headers(animation)
|
||||||
|
include_hifi_library_headers(material-networking)
|
||||||
include_hifi_library_headers(model-networking)
|
include_hifi_library_headers(model-networking)
|
||||||
include_hifi_library_headers(image)
|
include_hifi_library_headers(image)
|
||||||
include_hifi_library_headers(ktx)
|
include_hifi_library_headers(ktx)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
set(TARGET_NAME procedural)
|
set(TARGET_NAME procedural)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared gpu shaders networking graphics model-networking ktx image)
|
link_hifi_libraries(shared gpu shaders networking graphics material-networking ktx image)
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
#include <gpu/Shader.h>
|
#include <gpu/Shader.h>
|
||||||
#include <gpu/Pipeline.h>
|
#include <gpu/Pipeline.h>
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
#include <model-networking/ShaderCache.h>
|
#include <material-networking/ShaderCache.h>
|
||||||
#include <model-networking/TextureCache.h>
|
#include <material-networking/TextureCache.h>
|
||||||
|
|
||||||
using UniformLambdas = std::list<std::function<void(gpu::Batch& batch)>>;
|
using UniformLambdas = std::list<std::function<void(gpu::Batch& batch)>>;
|
||||||
const size_t MAX_PROCEDURAL_TEXTURE_CHANNELS{ 4 };
|
const size_t MAX_PROCEDURAL_TEXTURE_CHANNELS{ 4 };
|
||||||
|
|
|
@ -3,7 +3,7 @@ set(TARGET_NAME render-utils)
|
||||||
# pull in the resources.qrc file
|
# pull in the resources.qrc file
|
||||||
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
||||||
setup_hifi_library(Gui Network Qml Quick Script)
|
setup_hifi_library(Gui Network Qml Quick Script)
|
||||||
link_hifi_libraries(shared task ktx gpu shaders graphics graphics-scripting model-networking render animation fbx image procedural)
|
link_hifi_libraries(shared task ktx gpu shaders graphics graphics-scripting material-networking model-networking render animation fbx image procedural)
|
||||||
include_hifi_library_headers(audio)
|
include_hifi_library_headers(audio)
|
||||||
include_hifi_library_headers(networking)
|
include_hifi_library_headers(networking)
|
||||||
include_hifi_library_headers(octree)
|
include_hifi_library_headers(octree)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <gpu/Context.h>
|
#include <gpu/Context.h>
|
||||||
#include <model-networking/TextureCache.h>
|
#include <material-networking/TextureCache.h>
|
||||||
#include <render/DrawTask.h>
|
#include <render/DrawTask.h>
|
||||||
#include <shaders/Shaders.h>
|
#include <shaders/Shaders.h>
|
||||||
#include <graphics/ShaderConstants.h>
|
#include <graphics/ShaderConstants.h>
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
// Compatibility
|
// Compatibility
|
||||||
#include <model-networking/TextureCache.h>
|
#include <material-networking/TextureCache.h>
|
||||||
|
|
|
@ -17,6 +17,6 @@ if (NOT ANDROID)
|
||||||
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
link_hifi_libraries(shared networking octree shaders gpu procedural graphics model-networking ktx recording avatars fbx hfm entities controllers animation audio physics image midi)
|
link_hifi_libraries(shared networking octree shaders gpu procedural graphics material-networking model-networking ktx recording avatars fbx hfm entities controllers animation audio physics image midi)
|
||||||
# ui includes gl, but link_hifi_libraries does not use transitive includes, so gl must be explicit
|
# ui includes gl, but link_hifi_libraries does not use transitive includes, so gl must be explicit
|
||||||
include_hifi_library_headers(gl)
|
include_hifi_library_headers(gl)
|
||||||
|
|
|
@ -11,7 +11,7 @@ if (WIN32 AND (NOT USE_GLES))
|
||||||
setup_hifi_plugin(Gui Qml Multimedia)
|
setup_hifi_plugin(Gui Qml Multimedia)
|
||||||
link_hifi_libraries(shared task gl qml networking controllers ui
|
link_hifi_libraries(shared task gl qml networking controllers ui
|
||||||
plugins display-plugins ui-plugins input-plugins script-engine
|
plugins display-plugins ui-plugins input-plugins script-engine
|
||||||
audio-client render-utils graphics shaders gpu render model-networking model-baker hfm fbx ktx image procedural ${PLATFORM_GL_BACKEND})
|
audio-client render-utils graphics shaders gpu render material-networking model-networking model-baker hfm fbx ktx image procedural ${PLATFORM_GL_BACKEND})
|
||||||
include_hifi_library_headers(octree)
|
include_hifi_library_headers(octree)
|
||||||
|
|
||||||
target_openvr()
|
target_openvr()
|
||||||
|
|
Loading…
Reference in a new issue