mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
Refactor NiTexturingProperty, load everything
This commit is contained in:
parent
18e4af04b3
commit
080d7d2c13
@ -6,50 +6,61 @@
|
|||||||
namespace Nif
|
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)
|
void NiTexturingProperty::Texture::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
nif->read(inUse);
|
nif->read(mEnabled);
|
||||||
if (!inUse)
|
if (!mEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
texture.read(nif);
|
if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13))
|
||||||
|
mSourceTexture.read(nif);
|
||||||
|
|
||||||
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
|
||||||
{
|
{
|
||||||
clamp = nif->getInt();
|
nif->read(mClamp);
|
||||||
nif->skip(4); // Filter mode. Ignoring because global filtering settings are more sensible
|
nif->read(mFilter);
|
||||||
}
|
}
|
||||||
else
|
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))
|
if (nif->getVersion() >= NIFStream::generateVersion(20, 5, 0, 4))
|
||||||
nif->getUShort();
|
nif->read(mMaxAnisotropy);
|
||||||
|
|
||||||
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
|
||||||
uvSet = nif->getUInt();
|
nif->read(mUVSet);
|
||||||
|
|
||||||
// Two PS2-specific shorts.
|
// PS2 filtering settings
|
||||||
if (nif->getVersion() < NIFStream::generateVersion(10, 4, 0, 2))
|
if (nif->getVersion() <= NIFStream::generateVersion(10, 4, 0, 1))
|
||||||
nif->skip(4);
|
nif->skip(4);
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(4, 1, 0, 18))
|
|
||||||
nif->skip(2); // Unknown short
|
if (nif->getVersion() <= NIFStream::generateVersion(4, 1, 0, 12))
|
||||||
else if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
nif->skip(2); // Unknown
|
||||||
|
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||||
{
|
{
|
||||||
if (nif->get<bool>()) // Has texture transform
|
nif->read(mHasTransform);
|
||||||
{
|
if (mHasTransform)
|
||||||
nif->getVector2(); // UV translation
|
mTransform.read(nif);
|
||||||
nif->getVector2(); // UV scale
|
|
||||||
nif->getFloat(); // W axis rotation
|
|
||||||
nif->getUInt(); // Transform method
|
|
||||||
nif->getVector2(); // Texture rotation origin
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiTexturingProperty::Texture::post(Reader& nif)
|
void NiTexturingProperty::Texture::post(Reader& nif)
|
||||||
{
|
{
|
||||||
texture.post(nif);
|
mSourceTexture.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiTexturingProperty::read(NIFStream* nif)
|
void NiTexturingProperty::read(NIFStream* nif)
|
||||||
@ -58,37 +69,33 @@ namespace Nif
|
|||||||
|
|
||||||
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD
|
||||||
|| nif->getVersion() >= NIFStream::generateVersion(20, 1, 0, 2))
|
|| nif->getVersion() >= NIFStream::generateVersion(20, 1, 0, 2))
|
||||||
flags = nif->getUShort();
|
nif->read(mFlags);
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(20, 1, 0, 1))
|
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();
|
mTextures.resize(nif->get<uint32_t>());
|
||||||
|
for (size_t i = 0; i < mTextures.size(); i++)
|
||||||
if (!numTextures)
|
|
||||||
return;
|
|
||||||
|
|
||||||
textures.resize(numTextures);
|
|
||||||
for (unsigned int i = 0; i < numTextures; i++)
|
|
||||||
{
|
{
|
||||||
textures[i].read(nif);
|
mTextures[i].read(nif);
|
||||||
if (i == 5 && textures[5].inUse) // Bump map settings
|
|
||||||
|
if (i == 5 && mTextures[5].mEnabled)
|
||||||
{
|
{
|
||||||
envMapLumaBias = nif->getVector2();
|
nif->read(mEnvMapLumaBias);
|
||||||
bumpMapMatrix = nif->getVector4();
|
nif->read(mBumpMapMatrix);
|
||||||
}
|
}
|
||||||
else if (i == 7 && textures[7].inUse && nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
|
else if (i == 7 && mTextures[7].mEnabled && nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
|
||||||
/*float parallaxOffset = */ nif->getFloat();
|
nif->read(mParallaxOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
||||||
{
|
{
|
||||||
unsigned int numShaderTextures = nif->getUInt();
|
mShaderTextures.resize(nif->get<uint32_t>());
|
||||||
shaderTextures.resize(numShaderTextures);
|
mShaderIds.resize(mShaderTextures.size());
|
||||||
for (unsigned int i = 0; i < numShaderTextures; i++)
|
for (size_t i = 0; i < mShaderTextures.size(); i++)
|
||||||
{
|
{
|
||||||
shaderTextures[i].read(nif);
|
mShaderTextures[i].read(nif);
|
||||||
if (shaderTextures[i].inUse)
|
if (mShaderTextures[i].mEnabled)
|
||||||
nif->getUInt(); // Unique identifier
|
nif->read(mShaderIds[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,10 +104,10 @@ namespace Nif
|
|||||||
{
|
{
|
||||||
Property::post(nif);
|
Property::post(nif);
|
||||||
|
|
||||||
for (size_t i = 0; i < textures.size(); i++)
|
for (Texture& tex : mTextures)
|
||||||
textures[i].post(nif);
|
tex.post(nif);
|
||||||
for (size_t i = 0; i < shaderTextures.size(); i++)
|
for (Texture& tex : mShaderTextures)
|
||||||
shaderTextures[i].post(nif);
|
tex.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSSPParallaxParams::read(NIFStream* nif)
|
void BSSPParallaxParams::read(NIFStream* nif)
|
||||||
|
@ -10,53 +10,38 @@ namespace Nif
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiTexturingProperty : public Property
|
struct NiTextureTransform
|
||||||
{
|
{
|
||||||
unsigned short flags{ 0u };
|
enum class Method : uint32_t
|
||||||
|
|
||||||
// A sub-texture
|
|
||||||
struct Texture
|
|
||||||
{
|
{
|
||||||
/* Clamp mode
|
// Back = inverse of mOrigin.
|
||||||
0 - clampS clampT
|
// FromMaya = inverse of the V axis with a positive translation along V of 1 unit.
|
||||||
1 - clampS wrapT
|
MayaLegacy = 0, // mOrigin * mRotation * Back * mOffset * mScale
|
||||||
2 - wrapS clampT
|
Max = 1, // mOrigin * mScale * mRotation * mOffset * Back
|
||||||
3 - wrapS wrapT
|
Maya = 2, // mOrigin * mRotation * Back * FromMaya * mOffset * mScale
|
||||||
*/
|
|
||||||
|
|
||||||
bool inUse;
|
|
||||||
NiSourceTexturePtr texture;
|
|
||||||
|
|
||||||
unsigned int clamp, uvSet;
|
|
||||||
|
|
||||||
void read(NIFStream* nif);
|
|
||||||
void post(Reader& nif);
|
|
||||||
|
|
||||||
bool wrapT() const { return clamp & 1; }
|
|
||||||
bool wrapS() const { return (clamp >> 1) & 1; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Apply mode:
|
osg::Vec2f mOffset;
|
||||||
0 - replace
|
osg::Vec2f mScale;
|
||||||
1 - decal
|
float mRotation;
|
||||||
2 - modulate
|
Method mTransformMethod;
|
||||||
3 - hilight // These two are for PS2 only?
|
osg::Vec2f mOrigin;
|
||||||
4 - hilight2
|
|
||||||
*/
|
|
||||||
unsigned int apply{ 0 };
|
|
||||||
|
|
||||||
/*
|
void read(NIFStream* nif);
|
||||||
* The textures in this list are as follows:
|
};
|
||||||
*
|
|
||||||
* 0 - Base texture
|
struct NiTexturingProperty : public Property
|
||||||
* 1 - Dark texture
|
{
|
||||||
* 2 - Detail texture
|
enum class ApplyMode : uint32_t
|
||||||
* 3 - Gloss texture
|
{
|
||||||
* 4 - Glow texture
|
Replace = 0,
|
||||||
* 5 - Bump map texture
|
Decal = 1,
|
||||||
* 6 - Decal texture
|
Modulate = 2,
|
||||||
*/
|
Hilight = 3, // PS2-specific?
|
||||||
enum TextureType : uint32_t
|
Hilight2 = 4, // Used for Oblivion parallax
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TextureType
|
||||||
{
|
{
|
||||||
BaseTexture = 0,
|
BaseTexture = 0,
|
||||||
DarkTexture = 1,
|
DarkTexture = 1,
|
||||||
@ -67,11 +52,35 @@ namespace Nif
|
|||||||
DecalTexture = 6,
|
DecalTexture = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Texture> textures;
|
// A sub-texture
|
||||||
std::vector<Texture> shaderTextures;
|
struct Texture
|
||||||
|
{
|
||||||
|
bool mEnabled;
|
||||||
|
NiSourceTexturePtr mSourceTexture;
|
||||||
|
uint32_t mClamp;
|
||||||
|
uint32_t mFilter;
|
||||||
|
uint16_t mMaxAnisotropy;
|
||||||
|
uint32_t mUVSet;
|
||||||
|
bool mHasTransform;
|
||||||
|
NiTextureTransform mTransform;
|
||||||
|
|
||||||
osg::Vec2f envMapLumaBias;
|
void read(NIFStream* nif);
|
||||||
osg::Vec4f bumpMapMatrix;
|
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 mEnvMapLumaBias;
|
||||||
|
osg::Vec4f mBumpMapMatrix;
|
||||||
|
float mParallaxOffset;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
void post(Reader& 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
|
// 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.
|
// 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()))
|
|| (i == Nif::NiTexturingProperty::BaseTexture && !texprop->mController.empty()))
|
||||||
{
|
{
|
||||||
switch (i)
|
switch (i)
|
||||||
@ -1854,10 +1854,10 @@ namespace NifOsg
|
|||||||
unsigned int uvSet = 0;
|
unsigned int uvSet = 0;
|
||||||
// create a new texture, will later attempt to share using the SharedStateManager
|
// create a new texture, will later attempt to share using the SharedStateManager
|
||||||
osg::ref_ptr<osg::Texture2D> texture2d;
|
osg::ref_ptr<osg::Texture2D> texture2d;
|
||||||
if (texprop->textures[i].inUse)
|
if (texprop->mTextures[i].mEnabled)
|
||||||
{
|
{
|
||||||
const Nif::NiTexturingProperty::Texture& tex = texprop->textures[i];
|
const Nif::NiTexturingProperty::Texture& tex = texprop->mTextures[i];
|
||||||
if (tex.texture.empty() && texprop->mController.empty())
|
if (tex.mSourceTexture.empty() && texprop->mController.empty())
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName
|
Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName
|
||||||
@ -1865,9 +1865,9 @@ namespace NifOsg
|
|||||||
continue;
|
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);
|
osg::ref_ptr<osg::Image> image = handleSourceTexture(st, imageManager);
|
||||||
texture2d = new osg::Texture2D(image);
|
texture2d = new osg::Texture2D(image);
|
||||||
if (image)
|
if (image)
|
||||||
@ -1878,7 +1878,7 @@ namespace NifOsg
|
|||||||
|
|
||||||
handleTextureWrapping(texture2d, tex.wrapS(), tex.wrapT());
|
handleTextureWrapping(texture2d, tex.wrapS(), tex.wrapT());
|
||||||
|
|
||||||
uvSet = tex.uvSet;
|
uvSet = tex.mUVSet;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1926,10 +1926,10 @@ namespace NifOsg
|
|||||||
// Bump maps offset the environment map.
|
// Bump maps offset the environment map.
|
||||||
// Set this texture to Off by default since we can't render it with the fixed-function pipeline
|
// 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);
|
stateset->setTextureMode(texUnit, GL_TEXTURE_2D, osg::StateAttribute::OFF);
|
||||||
osg::Matrix2 bumpMapMatrix(texprop->bumpMapMatrix.x(), texprop->bumpMapMatrix.y(),
|
osg::Matrix2 bumpMapMatrix(texprop->mBumpMapMatrix.x(), texprop->mBumpMapMatrix.y(),
|
||||||
texprop->bumpMapMatrix.z(), texprop->bumpMapMatrix.w());
|
texprop->mBumpMapMatrix.z(), texprop->mBumpMapMatrix.w());
|
||||||
stateset->addUniform(new osg::Uniform("bumpMapMatrix", bumpMapMatrix));
|
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)
|
else if (i == Nif::NiTexturingProperty::GlossTexture)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user