X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Fmaterial%2FTextureBuilder.cxx;h=d60e767d1dffc80afc506facbcfecfcd60c97d2c;hb=0d419aba8a1ea9c67b1982f4d68fe1fe7bd79033;hp=a924b95571055057d3e378b86ff0ba10ad7a439a;hpb=2e71b64de1d937e2b7c34dd4a2365be455d0b82a;p=simgear.git diff --git a/simgear/scene/material/TextureBuilder.cxx b/simgear/scene/material/TextureBuilder.cxx index a924b955..d60e767d 100644 --- a/simgear/scene/material/TextureBuilder.cxx +++ b/simgear/scene/material/TextureBuilder.cxx @@ -29,12 +29,14 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -50,13 +52,14 @@ using namespace osg; using namespace effect; TexEnvCombine* buildTexEnvCombine(Effect* effect, - const SGPropertyNode* envProp); + const SGPropertyNode* envProp, + const SGReaderWriterXMLOptions* options); TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp); // Hack to force inclusion of TextureBuilder.cxx in library osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type, const SGPropertyNode*props, - const osgDB::ReaderWriter::Options* + const SGReaderWriterXMLOptions* options) { return EffectBuilder::buildFromType(effect, type, props, options); @@ -93,12 +96,12 @@ TexEnv* buildTexEnv(Effect* effect, const SGPropertyNode* prop) if (colorProp) env->setColor(toOsg(colorProp->getValue())); return env; - } +} void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, - const osgDB::ReaderWriter::Options* options) + const SGReaderWriterXMLOptions* options) { if (!isAttributeActive(effect, prop)) return; @@ -129,7 +132,9 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass, options); } catch (BuilderException& e) { - SG_LOG(SG_INPUT, SG_ALERT, "No image file for texture, using white "); + SG_LOG(SG_INPUT, SG_ALERT, "No image file, " + << "maybe the reader did not set the filename attribute, " + << "using white on " << pass->getName()); texture = StateAttributeFactory::instance()->getWhiteTexture(); } pass->setTextureAttributeAndModes(unit, texture); @@ -141,7 +146,8 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass, } const SGPropertyNode* combineProp = prop->getChild("texenv-combine"); TexEnvCombine* combiner = 0; - if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp)))) + if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp, + options)))) pass->setTextureAttributeAndModes(unit, combiner); const SGPropertyNode* tgenProp = prop->getChild("texgen"); TexGen* tgen = 0; @@ -177,7 +183,7 @@ EffectPropertyMap wrapModes(wrapModesInit); TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props, - const osgDB::ReaderWriter::Options* options, + const SGReaderWriterXMLOptions* options, const string& texType) { Texture::FilterMode minFilter = Texture::LINEAR_MIPMAP_LINEAR; @@ -213,7 +219,7 @@ TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props, } void setAttrs(const TexTuple& attrs, Texture* tex, - const osgDB::ReaderWriter::Options* options) + const SGReaderWriterXMLOptions* options) { const string& imageName = attrs.get<0>(); if (imageName.empty()) { @@ -253,7 +259,7 @@ class TexBuilder : public TextureBuilder public: TexBuilder(const string& texType) : _type(texType) {} Texture* build(Effect* effect, const SGPropertyNode*, - const osgDB::ReaderWriter::Options* options); + const SGReaderWriterXMLOptions* options); protected: typedef map > TexMap; TexMap texMap; @@ -262,7 +268,7 @@ protected: template Texture* TexBuilder::build(Effect* effect, const SGPropertyNode* props, - const osgDB::ReaderWriter::Options* options) + const SGReaderWriterXMLOptions* options) { TexTuple attrs = makeTexTuple(effect, props, options, _type); typename TexMap::iterator itr = texMap.find(attrs); @@ -286,11 +292,11 @@ class WhiteTextureBuilder : public TextureBuilder { public: Texture* build(Effect* effect, const SGPropertyNode*, - const osgDB::ReaderWriter::Options* options); + const SGReaderWriterXMLOptions* options); }; Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*, - const osgDB::ReaderWriter::Options* options) + const SGReaderWriterXMLOptions* options) { return StateAttributeFactory::instance()->getWhiteTexture(); } @@ -304,11 +310,11 @@ class TransparentTextureBuilder : public TextureBuilder { public: Texture* build(Effect* effect, const SGPropertyNode*, - const osgDB::ReaderWriter::Options* options); + const SGReaderWriterXMLOptions* options); }; Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*, - const osgDB::ReaderWriter::Options* options) + const SGReaderWriterXMLOptions* options) { return StateAttributeFactory::instance()->getTransparentTexture(); } @@ -368,14 +374,14 @@ class NoiseBuilder : public TextureBuilder { public: Texture* build(Effect* effect, const SGPropertyNode*, - const osgDB::ReaderWriter::Options* options); + const SGReaderWriterXMLOptions* options); protected: typedef map > NoiseMap; NoiseMap _noises; }; Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props, - const osgDB::ReaderWriter::Options* options) + const SGReaderWriterXMLOptions* options) { int texSize = 64; const SGPropertyNode* sizeProp = getEffectPropertyChild(effect, props, @@ -401,6 +407,114 @@ namespace TextureBuilder::Registrar installNoise("noise", new NoiseBuilder); } + +// Image names for all sides +typedef boost::tuple CubeMapTuple; + +CubeMapTuple makeCubeMapTuple(Effect* effect, const SGPropertyNode* props) +{ + const SGPropertyNode* ep = 0; + + string positive_x; + if ((ep = getEffectPropertyChild(effect, props, "positive-x"))) + positive_x = ep->getStringValue(); + string negative_x; + if ((ep = getEffectPropertyChild(effect, props, "negative-x"))) + negative_x = ep->getStringValue(); + string positive_y; + if ((ep = getEffectPropertyChild(effect, props, "positive-y"))) + positive_y = ep->getStringValue(); + string negative_y; + if ((ep = getEffectPropertyChild(effect, props, "negative-y"))) + negative_y = ep->getStringValue(); + string positive_z; + if ((ep = getEffectPropertyChild(effect, props, "positive-z"))) + positive_z = ep->getStringValue(); + string negative_z; + if ((ep = getEffectPropertyChild(effect, props, "negative-z"))) + negative_z = ep->getStringValue(); + return CubeMapTuple(positive_x, negative_x, positive_y, negative_y, positive_z, negative_z); +} + + +class CubeMapBuilder : public TextureBuilder +{ +public: + Texture* build(Effect* effect, const SGPropertyNode*, + const SGReaderWriterXMLOptions* options); +protected: + typedef map > CubeMap; + CubeMap _cubemaps; +}; + +Texture* CubeMapBuilder::build(Effect* effect, const SGPropertyNode* props, + const SGReaderWriterXMLOptions* options) +{ + // First check that there is a tag + const SGPropertyNode* texturesProp = getEffectPropertyChild(effect, props, "images"); + if (!texturesProp) { + throw BuilderException("no for cube map"); + return NULL; // This is redundant + } + + CubeMapTuple _tuple = makeCubeMapTuple(effect, texturesProp); + + CubeMap::iterator itr = _cubemaps.find(_tuple); + if (itr != _cubemaps.end()) + return itr->second.get(); + + TextureCubeMap* cubeTexture = new osg::TextureCubeMap; + + // TODO: Read these from effect file? Maybe these are sane for all cuebmaps? + cubeTexture->setFilter(osg::Texture3D::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR); + cubeTexture->setFilter(osg::Texture3D::MAG_FILTER, osg::Texture::LINEAR); + cubeTexture->setWrap(osg::Texture3D::WRAP_S, osg::Texture::CLAMP_TO_EDGE); + cubeTexture->setWrap(osg::Texture3D::WRAP_T, osg::Texture::CLAMP_TO_EDGE); + cubeTexture->setWrap(osg::Texture3D::WRAP_R, osg::Texture::CLAMP_TO_EDGE); + + osgDB::ReaderWriter::ReadResult result = + osgDB::Registry::instance()->readImage(_tuple.get<0>(), options); + if(result.success()) { + osg::Image* image = result.getImage(); + cubeTexture->setImage(TextureCubeMap::POSITIVE_X, image); + } + result = osgDB::Registry::instance()->readImage(_tuple.get<1>(), options); + if(result.success()) { + osg::Image* image = result.getImage(); + cubeTexture->setImage(TextureCubeMap::NEGATIVE_X, image); + } + result = osgDB::Registry::instance()->readImage(_tuple.get<2>(), options); + if(result.success()) { + osg::Image* image = result.getImage(); + cubeTexture->setImage(TextureCubeMap::POSITIVE_Y, image); + } + result = osgDB::Registry::instance()->readImage(_tuple.get<3>(), options); + if(result.success()) { + osg::Image* image = result.getImage(); + cubeTexture->setImage(TextureCubeMap::NEGATIVE_Y, image); + } + result = osgDB::Registry::instance()->readImage(_tuple.get<4>(), options); + if(result.success()) { + osg::Image* image = result.getImage(); + cubeTexture->setImage(TextureCubeMap::POSITIVE_Z, image); + } + result = osgDB::Registry::instance()->readImage(_tuple.get<5>(), options); + if(result.success()) { + osg::Image* image = result.getImage(); + cubeTexture->setImage(TextureCubeMap::NEGATIVE_Z, image); + } + + _cubemaps[_tuple] = cubeTexture; + + return cubeTexture; +} + +namespace { +TextureBuilder::Registrar installCubeMap("cubemap", new CubeMapBuilder); +} + + + EffectNameValue combineParamInit[] = { {"replace", TexEnvCombine::REPLACE}, @@ -443,7 +557,8 @@ EffectNameValue opParamInit[] = EffectPropertyMap operandParams(opParamInit); -TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp) +TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp, + const SGReaderWriterXMLOptions* options) { if (!isAttributeActive(effect, envProp)) return 0; @@ -538,7 +653,8 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp) const SGPropertyNode* colorNode = envProp->getChild("constant-color"); if (colorNode) initFromParameters(effect, colorNode, result, - &TexEnvCombine::setConstantColor, colorFields); + &TexEnvCombine::setConstantColor, colorFields, + options); return result; } @@ -568,7 +684,6 @@ TexGen* buildTexGen(Effect* effect, const SGPropertyNode* tgenProp) if (!isAttributeActive(effect, tgenProp)) return 0; TexGen* result = new TexGen; - const SGPropertyNode* p = 0; TexGen::Mode mode = TexGen::OBJECT_LINEAR; findAttr(tgenModes, getEffectPropertyChild(effect, tgenProp, "mode"), mode); result->setMode(mode);