1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-04 15:45:34 +00:00

Properly handle NiAlphaProperty values

This commit is contained in:
Chris Robinson 2013-02-26 15:24:20 -08:00
parent 70b6b68005
commit b4b20622c6

View file

@ -492,49 +492,43 @@ bool createSkeleton(const std::string &name, const std::string &group, const Nif
NIFSkeletonLoader::LoaderMap NIFSkeletonLoader::sLoaders; NIFSkeletonLoader::LoaderMap NIFSkeletonLoader::sLoaders;
// Conversion of blend / test mode from NIF -> OGRE. // Conversion of blend / test mode from NIF
// Not in use yet, so let's comment it out. static const char *getBlendFactor(int mode)
/*
static SceneBlendFactor getBlendFactor(int mode)
{ {
switch(mode) switch(mode)
{ {
case 0: return SBF_ONE; case 0: return "one";
case 1: return SBF_ZERO; case 1: return "zero";
case 2: return SBF_SOURCE_COLOUR; case 2: return "src_colour";
case 3: return SBF_ONE_MINUS_SOURCE_COLOUR; case 3: return "one_minus_src_colour";
case 4: return SBF_DEST_COLOUR; case 4: return "dest_colour";
case 5: return SBF_ONE_MINUS_DEST_COLOUR; case 5: return "one_minus_dest_colour";
case 6: return SBF_SOURCE_ALPHA; case 6: return "src_alpha";
case 7: return SBF_ONE_MINUS_SOURCE_ALPHA; case 7: return "one_minus_src_alpha";
case 8: return SBF_DEST_ALPHA; case 8: return "dest_alpha";
case 9: return SBF_ONE_MINUS_DEST_ALPHA; case 9: return "one_minus_dest_alpha";
// [Comment from Chris Robinson:] Can't handle this mode? :/ case 10: return "src_alpha_saturate";
// case 10: return SBF_SOURCE_ALPHA_SATURATE;
default:
return SBF_SOURCE_ALPHA;
} }
std::cerr<< "Unexpected blend mode: "<<mode <<std::endl;
return "src_alpha";
} }
static const char *getTestMode(int mode)
// This is also unused
static CompareFunction getTestMode(int mode)
{ {
switch(mode) switch(mode)
{ {
case 0: return CMPF_ALWAYS_PASS; case 0: return "always_pass";
case 1: return CMPF_LESS; case 1: return "less";
case 2: return CMPF_EQUAL; case 2: return "equal";
case 3: return CMPF_LESS_EQUAL; case 3: return "less_equal";
case 4: return CMPF_GREATER; case 4: return "greater";
case 5: return CMPF_NOT_EQUAL; case 5: return "not_equal";
case 6: return CMPF_GREATER_EQUAL; case 6: return "greater_equal";
case 7: return CMPF_ALWAYS_FAIL; case 7: return "always_fail";
default:
return CMPF_ALWAYS_PASS;
} }
std::cerr<< "Unexpected test mode: "<<mode <<std::endl;
return "less_equal";
} }
*/
class NIFMaterialLoader { class NIFMaterialLoader {
@ -567,8 +561,8 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
Ogre::Vector3 emissive(0.0f); Ogre::Vector3 emissive(0.0f);
float glossiness = 0.0f; float glossiness = 0.0f;
float alpha = 1.0f; float alpha = 1.0f;
int alphaFlags = -1; int alphaFlags = 0;
// ubyte alphaTest = 0; int alphaTest = 0;
Ogre::String texName; Ogre::String texName;
bool vertexColour = (shape->data->colors.size() != 0); bool vertexColour = (shape->data->colors.size() != 0);
@ -640,7 +634,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
if (a) if (a)
{ {
alphaFlags = a->flags; alphaFlags = a->flags;
// alphaTest = a->data.threshold; alphaTest = a->data.threshold;
} }
// Material // Material
@ -674,6 +668,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
boost::hash_combine(h, texName); boost::hash_combine(h, texName);
boost::hash_combine(h, vertexColour); boost::hash_combine(h, vertexColour);
boost::hash_combine(h, alphaFlags); boost::hash_combine(h, alphaFlags);
boost::hash_combine(h, alphaTest);
std::map<size_t,std::string>::iterator itr = MaterialMap.find(h); std::map<size_t,std::string>::iterator itr = MaterialMap.find(h);
if (itr != MaterialMap.end()) if (itr != MaterialMap.end())
@ -705,57 +700,37 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
instance->setProperty ("has_vertex_colour", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(true))); instance->setProperty ("has_vertex_colour", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(true)));
// Add transparency if NiAlphaProperty was present // Add transparency if NiAlphaProperty was present
if (alphaFlags != -1)
{
// The 237 alpha flags are by far the most common. Check
// NiAlphaProperty in nif/property.h if you need to decode
// other values. 237 basically means normal transparencly.
if (alphaFlags == 237)
{
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName); NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
if (result.first) if (result.first)
{ {
instance->setProperty("alpha_rejection", alphaFlags = (1<<9) | (6<<10); /* alpha_rejection enabled, greater_equal */
sh::makeProperty<sh::StringValue>(new sh::StringValue("greater_equal " + boost::lexical_cast<std::string>(result.second)))); alphaTest = result.second;
} }
else
if((alphaFlags&1))
{ {
// Enable transparency std::string blend_mode;
instance->setProperty("scene_blend", sh::makeProperty<sh::StringValue>(new sh::StringValue("alpha_blend"))); blend_mode += getBlendFactor((alphaFlags>>1)&0xf);
instance->setProperty("depth_write", sh::makeProperty<sh::StringValue>(new sh::StringValue("off"))); blend_mode += " ";
} blend_mode += getBlendFactor((alphaFlags>>5)&0xf);
instance->setProperty("depth_write", sh::makeProperty(new sh::StringValue("off")));
instance->setProperty("scene_blend", sh::makeProperty(new sh::StringValue(blend_mode)));
} }
else else
warn("Unhandled alpha setting for texture " + texName); instance->getMaterial()->setShadowCasterMaterial("openmw_shadowcaster_noalpha");
}
else
instance->getMaterial ()->setShadowCasterMaterial ("openmw_shadowcaster_noalpha");
// As of yet UNTESTED code from Chris: if((alphaFlags>>9)&1)
/*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL);
pass->setDepthCheckEnabled(true);
// Add transparency if NiAlphaProperty was present
if (alphaFlags != -1)
{ {
std::cout << "Alpha flags set!" << endl; std::string reject;
if ((alphaFlags&1)) reject += getTestMode((alphaFlags>>10)&0x7);
{ reject += " ";
pass->setDepthWriteEnabled(false); reject += Ogre::StringConverter::toString(alphaTest);
pass->setSceneBlending(getBlendFactor((alphaFlags>>1)&0xf), instance->setProperty("alpha_rejection", sh::makeProperty(new sh::StringValue(reject)));
getBlendFactor((alphaFlags>>5)&0xf));
} }
else
pass->setDepthWriteEnabled(true);
if ((alphaFlags>>9)&1) instance->setProperty("transparent_sorting", sh::makeProperty(new sh::StringValue(((alphaFlags>>13)&1) ?
pass->setAlphaRejectSettings(getTestMode((alphaFlags>>10)&0x7), "off" : "on")));
alphaTest);
pass->setTransparentSortingEnabled(!((alphaFlags>>13)&1));
}
*/
return matname; return matname;
} }