From f1212dfa7363f01d40d2b595a911f483fc8f15a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Garc=C3=ADa=20Li=C3=B1=C3=A1n?= Date: Thu, 3 Dec 2020 18:36:56 +0100 Subject: [PATCH] Initial support for texture arrays in Effects --- simgear/scene/material/TextureBuilder.cxx | 75 +++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/simgear/scene/material/TextureBuilder.cxx b/simgear/scene/material/TextureBuilder.cxx index 70ad0a08..3535ab40 100644 --- a/simgear/scene/material/TextureBuilder.cxx +++ b/simgear/scene/material/TextureBuilder.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -745,6 +746,80 @@ TextureBuilder::Registrar installCubeMap("cubemap", new CubeMapBuilder); } +typedef map Tex2DArraySignature; + +Tex2DArraySignature makeTex2DArraySignature(Effect *effect, + const SGPropertyNode *props) +{ + Tex2DArraySignature signature; + const PropertyList images = props->getChildren("image"); + for (const auto &image : images) { + const SGPropertyNode *real_prop = getEffectPropertyNode(effect, image); + signature[image->getIndex()] = real_prop->getStringValue(); + } + return signature; +} + +class Texture2DArrayBuilder : public TextureBuilder +{ +public: + Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*, + const SGReaderWriterOptions* options); +protected: + typedef map> TexMap; + TexMap texMap; +}; + +Texture* Texture2DArrayBuilder::build(Effect* effect, Pass* pass, + const SGPropertyNode* props, + const SGReaderWriterOptions* options) +{ + Tex2DArraySignature signature = makeTex2DArraySignature(effect, props); + + auto itr = texMap.find(signature); + ref_ptr tex; + + if (itr != texMap.end() && itr->second.lock(tex)) + return tex.release(); + + tex = new osg::Texture2DArray; + + osgDB::ReaderWriter::ReadResult result; + SGReaderWriterOptions* wOpts = (SGReaderWriterOptions*)options; + SGReaderWriterOptions::LoadOriginHint origLOH = wOpts->getLoadOriginHint(); + wOpts->setLoadOriginHint(SGReaderWriterOptions::LoadOriginHint::ORIGIN_EFFECTS); + + for (const auto &pair : signature) { + osg::ref_ptr image; + result = osgDB::readRefImageFile(pair.second, options); + if (result.success()) + image = result.getImage(); + + if (image.valid()) { + tex->setImage(pair.first, image); + } else { + SG_LOG(SG_INPUT, SG_ALERT, "failed to load effect texture file '" + << pair.second << "'"); + return nullptr; + } + } + + wOpts->setLoadOriginHint(origLOH); + + // TODO: Filtering, wrap-mode, etc. should be configurable + + if (itr == texMap.end()) + texMap[signature] = tex; + else + itr->second = tex; // update existing + return tex.release(); +} + +namespace { +TextureBuilder::Registrar install2DArray("2d-array", new Texture2DArrayBuilder); +} + + class Texture3DBuilder : public TextureBuilder { public: