Refactor NiTexturingProperty, load everything

macos_ci_fix
Alexei Kotov 1 year ago
parent 18e4af04b3
commit 080d7d2c13

@ -6,50 +6,61 @@
namespace Nif
{
void NiTextureTransform::read(NIFStream* nif)
{
nif->read(mOffset);
nif->read(mScale);
nif->read(mRotation);
mTransformMethod = static_cast<Method>(nif->get<uint32_t>());
nif->read(mOrigin);
}
void NiTexturingProperty::Texture::read(NIFStream* nif)
{
nif->read(inUse);
if (!inUse)
nif->read(mEnabled);
if (!mEnabled)
return;
texture.read(nif);
if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13))
mSourceTexture.read(nif);
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
{
clamp = nif->getInt();
nif->skip(4); // Filter mode. Ignoring because global filtering settings are more sensible
nif->read(mClamp);
nif->read(mFilter);
}
else
{
clamp = nif->getUShort() & 0xF;
uint16_t flags;
nif->read(flags);
mClamp = flags & 0xF;
mFilter = (flags >> 4) & 0xF;
}
// Max anisotropy. I assume we'll always only use the global anisotropy setting.
if (nif->getVersion() >= NIFStream::generateVersion(20, 5, 0, 4))
nif->getUShort();
nif->read(mMaxAnisotropy);
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
uvSet = nif->getUInt();
nif->read(mUVSet);
// Two PS2-specific shorts.
if (nif->getVersion() < NIFStream::generateVersion(10, 4, 0, 2))
// PS2 filtering settings
if (nif->getVersion() <= NIFStream::generateVersion(10, 4, 0, 1))
nif->skip(4);
if (nif->getVersion() <= NIFStream::generateVersion(4, 1, 0, 18))
nif->skip(2); // Unknown short
else if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
if (nif->getVersion() <= NIFStream::generateVersion(4, 1, 0, 12))
nif->skip(2); // Unknown
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
{
if (nif->get<bool>()) // Has texture transform
{
nif->getVector2(); // UV translation
nif->getVector2(); // UV scale
nif->getFloat(); // W axis rotation
nif->getUInt(); // Transform method
nif->getVector2(); // Texture rotation origin
}
nif->read(mHasTransform);
if (mHasTransform)
mTransform.read(nif);
}
}
void NiTexturingProperty::Texture::post(Reader& nif)
{
texture.post(nif);
mSourceTexture.post(nif);
}
void NiTexturingProperty::read(NIFStream* nif)
@ -58,37 +69,33 @@ namespace Nif
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD
|| nif->getVersion() >= NIFStream::generateVersion(20, 1, 0, 2))
flags = nif->getUShort();
nif->read(mFlags);
if (nif->getVersion() <= NIFStream::generateVersion(20, 1, 0, 1))
apply = nif->getUInt();
mApplyMode = static_cast<ApplyMode>(nif->get<uint32_t>());
unsigned int numTextures = nif->getUInt();
if (!numTextures)
return;
textures.resize(numTextures);
for (unsigned int i = 0; i < numTextures; i++)
mTextures.resize(nif->get<uint32_t>());
for (size_t i = 0; i < mTextures.size(); i++)
{
textures[i].read(nif);
if (i == 5 && textures[5].inUse) // Bump map settings
mTextures[i].read(nif);
if (i == 5 && mTextures[5].mEnabled)
{
envMapLumaBias = nif->getVector2();
bumpMapMatrix = nif->getVector4();
nif->read(mEnvMapLumaBias);
nif->read(mBumpMapMatrix);
}
else if (i == 7 && textures[7].inUse && nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
/*float parallaxOffset = */ nif->getFloat();
else if (i == 7 && mTextures[7].mEnabled && nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
nif->read(mParallaxOffset);
}
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
{
unsigned int numShaderTextures = nif->getUInt();
shaderTextures.resize(numShaderTextures);
for (unsigned int i = 0; i < numShaderTextures; i++)
mShaderTextures.resize(nif->get<uint32_t>());
mShaderIds.resize(mShaderTextures.size());
for (size_t i = 0; i < mShaderTextures.size(); i++)
{
shaderTextures[i].read(nif);
if (shaderTextures[i].inUse)
nif->getUInt(); // Unique identifier
mShaderTextures[i].read(nif);
if (mShaderTextures[i].mEnabled)
nif->read(mShaderIds[i]);
}
}
}
@ -97,10 +104,10 @@ namespace Nif
{
Property::post(nif);
for (size_t i = 0; i < textures.size(); i++)
textures[i].post(nif);
for (size_t i = 0; i < shaderTextures.size(); i++)
shaderTextures[i].post(nif);
for (Texture& tex : mTextures)
tex.post(nif);
for (Texture& tex : mShaderTextures)
tex.post(nif);
}
void BSSPParallaxParams::read(NIFStream* nif)

@ -10,53 +10,38 @@ namespace Nif
{
};
struct NiTexturingProperty : public Property
struct NiTextureTransform
{
unsigned short flags{ 0u };
// A sub-texture
struct Texture
enum class Method : uint32_t
{
/* Clamp mode
0 - clampS clampT
1 - clampS wrapT
2 - wrapS clampT
3 - wrapS wrapT
*/
bool inUse;
NiSourceTexturePtr texture;
// Back = inverse of mOrigin.
// FromMaya = inverse of the V axis with a positive translation along V of 1 unit.
MayaLegacy = 0, // mOrigin * mRotation * Back * mOffset * mScale
Max = 1, // mOrigin * mScale * mRotation * mOffset * Back
Maya = 2, // mOrigin * mRotation * Back * FromMaya * mOffset * mScale
};
unsigned int clamp, uvSet;
osg::Vec2f mOffset;
osg::Vec2f mScale;
float mRotation;
Method mTransformMethod;
osg::Vec2f mOrigin;
void read(NIFStream* nif);
void post(Reader& nif);
void read(NIFStream* nif);
};
bool wrapT() const { return clamp & 1; }
bool wrapS() const { return (clamp >> 1) & 1; }
struct NiTexturingProperty : public Property
{
enum class ApplyMode : uint32_t
{
Replace = 0,
Decal = 1,
Modulate = 2,
Hilight = 3, // PS2-specific?
Hilight2 = 4, // Used for Oblivion parallax
};
/* Apply mode:
0 - replace
1 - decal
2 - modulate
3 - hilight // These two are for PS2 only?
4 - hilight2
*/
unsigned int apply{ 0 };
/*
* The textures in this list are as follows:
*
* 0 - Base texture
* 1 - Dark texture
* 2 - Detail texture
* 3 - Gloss texture
* 4 - Glow texture
* 5 - Bump map texture
* 6 - Decal texture
*/
enum TextureType : uint32_t
enum TextureType
{
BaseTexture = 0,
DarkTexture = 1,
@ -67,11 +52,35 @@ namespace Nif
DecalTexture = 6,
};
std::vector<Texture> textures;
std::vector<Texture> shaderTextures;
// A sub-texture
struct Texture
{
bool mEnabled;
NiSourceTexturePtr mSourceTexture;
uint32_t mClamp;
uint32_t mFilter;
uint16_t mMaxAnisotropy;
uint32_t mUVSet;
bool mHasTransform;
NiTextureTransform mTransform;
void read(NIFStream* nif);
void post(Reader& nif);
bool wrapT() const { return mClamp & 1; }
bool wrapS() const { return mClamp & 2; }
};
uint16_t mFlags{ 0u };
ApplyMode mApplyMode{ ApplyMode::Modulate };
std::vector<Texture> mTextures;
std::vector<Texture> mShaderTextures;
std::vector<uint32_t> mShaderIds;
osg::Vec2f envMapLumaBias;
osg::Vec4f bumpMapMatrix;
osg::Vec2f mEnvMapLumaBias;
osg::Vec4f mBumpMapMatrix;
float mParallaxOffset;
void read(NIFStream* nif) override;
void post(Reader& nif) override;

@ -1827,9 +1827,9 @@ namespace NifOsg
// If this loop is changed such that the base texture isn't guaranteed to end up in texture unit 0, the
// shadow casting shader will need to be updated accordingly.
for (size_t i = 0; i < texprop->textures.size(); ++i)
for (size_t i = 0; i < texprop->mTextures.size(); ++i)
{
if (texprop->textures[i].inUse
if (texprop->mTextures[i].mEnabled
|| (i == Nif::NiTexturingProperty::BaseTexture && !texprop->mController.empty()))
{
switch (i)
@ -1854,10 +1854,10 @@ namespace NifOsg
unsigned int uvSet = 0;
// create a new texture, will later attempt to share using the SharedStateManager
osg::ref_ptr<osg::Texture2D> texture2d;
if (texprop->textures[i].inUse)
if (texprop->mTextures[i].mEnabled)
{
const Nif::NiTexturingProperty::Texture& tex = texprop->textures[i];
if (tex.texture.empty() && texprop->mController.empty())
const Nif::NiTexturingProperty::Texture& tex = texprop->mTextures[i];
if (tex.mSourceTexture.empty() && texprop->mController.empty())
{
if (i == 0)
Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName
@ -1865,9 +1865,9 @@ namespace NifOsg
continue;
}
if (!tex.texture.empty())
if (!tex.mSourceTexture.empty())
{
const Nif::NiSourceTexture* st = tex.texture.getPtr();
const Nif::NiSourceTexture* st = tex.mSourceTexture.getPtr();
osg::ref_ptr<osg::Image> image = handleSourceTexture(st, imageManager);
texture2d = new osg::Texture2D(image);
if (image)
@ -1878,7 +1878,7 @@ namespace NifOsg
handleTextureWrapping(texture2d, tex.wrapS(), tex.wrapT());
uvSet = tex.uvSet;
uvSet = tex.mUVSet;
}
else
{
@ -1926,10 +1926,10 @@ namespace NifOsg
// Bump maps offset the environment map.
// Set this texture to Off by default since we can't render it with the fixed-function pipeline
stateset->setTextureMode(texUnit, GL_TEXTURE_2D, osg::StateAttribute::OFF);
osg::Matrix2 bumpMapMatrix(texprop->bumpMapMatrix.x(), texprop->bumpMapMatrix.y(),
texprop->bumpMapMatrix.z(), texprop->bumpMapMatrix.w());
osg::Matrix2 bumpMapMatrix(texprop->mBumpMapMatrix.x(), texprop->mBumpMapMatrix.y(),
texprop->mBumpMapMatrix.z(), texprop->mBumpMapMatrix.w());
stateset->addUniform(new osg::Uniform("bumpMapMatrix", bumpMapMatrix));
stateset->addUniform(new osg::Uniform("envMapLumaBias", texprop->envMapLumaBias));
stateset->addUniform(new osg::Uniform("envMapLumaBias", texprop->mEnvMapLumaBias));
}
else if (i == Nif::NiTexturingProperty::GlossTexture)
{

Loading…
Cancel
Save