mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-31 10:20:13 +00:00
Merge branch 'master' of https://github.com/zinnschlag/openmw into graphics
Conflicts: components/nifogre/ogre_nif_loader.cpp
This commit is contained in:
commit
b82ee4872d
@ -297,7 +297,7 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
|||||||
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
|
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
|
||||||
|
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
if (NOT WIN32 AND NOT APPLE)
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
||||||
"${OpenMW_BINARY_DIR}/openmw.desktop")
|
"${OpenMW_BINARY_DIR}/openmw.desktop")
|
||||||
endif()
|
endif()
|
||||||
|
@ -112,8 +112,8 @@ void Cell::load(ESMReader &esm, MWWorld::ESMStore &store)
|
|||||||
// instead.
|
// instead.
|
||||||
if (mData.mFlags & QuasiEx)
|
if (mData.mFlags & QuasiEx)
|
||||||
mRegion = esm.getHNOString("RGNN");
|
mRegion = esm.getHNOString("RGNN");
|
||||||
else
|
else if (esm.isNextSub("AMBI"))
|
||||||
esm.getHNT(mAmbi, "AMBI", 16);
|
esm.getHT(mAmbi);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -126,7 +126,7 @@ void Cell::load(ESMReader &esm, MWWorld::ESMStore &store)
|
|||||||
if (esm.isNextSub("NAM0")) {
|
if (esm.isNextSub("NAM0")) {
|
||||||
esm.getHT(mNAM0);
|
esm.getHT(mNAM0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// preload moved references
|
// preload moved references
|
||||||
while (esm.isNextSub("MVRF")) {
|
while (esm.isNextSub("MVRF")) {
|
||||||
CellRef ref;
|
CellRef ref;
|
||||||
@ -135,7 +135,7 @@ void Cell::load(ESMReader &esm, MWWorld::ESMStore &store)
|
|||||||
|
|
||||||
MWWorld::Store<ESM::Cell> &cStore = const_cast<MWWorld::Store<ESM::Cell>&>(store.get<ESM::Cell>());
|
MWWorld::Store<ESM::Cell> &cStore = const_cast<MWWorld::Store<ESM::Cell>&>(store.get<ESM::Cell>());
|
||||||
ESM::Cell *cellAlt = const_cast<ESM::Cell*>(cStore.searchOrCreate(cMRef.mTarget[0], cMRef.mTarget[1]));
|
ESM::Cell *cellAlt = const_cast<ESM::Cell*>(cStore.searchOrCreate(cMRef.mTarget[0], cMRef.mTarget[1]));
|
||||||
|
|
||||||
// Get regular moved reference data. Adapted from CellStore::loadRefs. Maybe we can optimize the following
|
// Get regular moved reference data. Adapted from CellStore::loadRefs. Maybe we can optimize the following
|
||||||
// implementation when the oher implementation works as well.
|
// implementation when the oher implementation works as well.
|
||||||
getNextRef(esm, ref);
|
getNextRef(esm, ref);
|
||||||
@ -143,7 +143,7 @@ void Cell::load(ESMReader &esm, MWWorld::ESMStore &store)
|
|||||||
|
|
||||||
std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase),
|
std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase),
|
||||||
(int(*)(int)) std::tolower);
|
(int(*)(int)) std::tolower);
|
||||||
|
|
||||||
// Add data required to make reference appear in the correct cell.
|
// Add data required to make reference appear in the correct cell.
|
||||||
// We should not need to test for duplicates, as this part of the code is pre-cell merge.
|
// We should not need to test for duplicates, as this part of the code is pre-cell merge.
|
||||||
mMovedRefs.push_back(cMRef);
|
mMovedRefs.push_back(cMRef);
|
||||||
@ -186,7 +186,7 @@ void Cell::save(ESMWriter &esm)
|
|||||||
if (mMapColor != 0)
|
if (mMapColor != 0)
|
||||||
esm.writeHNT("NAM5", mMapColor);
|
esm.writeHNT("NAM5", mMapColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNAM0 != 0)
|
if (mNAM0 != 0)
|
||||||
esm.writeHNT("NAM0", mNAM0);
|
esm.writeHNT("NAM0", mNAM0);
|
||||||
}
|
}
|
||||||
@ -226,7 +226,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
|
|||||||
|
|
||||||
esm.getHNT(ref.mRefnum, "FRMR");
|
esm.getHNT(ref.mRefnum, "FRMR");
|
||||||
ref.mRefID = esm.getHNString("NAME");
|
ref.mRefID = esm.getHNString("NAME");
|
||||||
|
|
||||||
// Identify references belonging to a parent file and adapt the ID accordingly.
|
// Identify references belonging to a parent file and adapt the ID accordingly.
|
||||||
int local = (ref.mRefnum & 0xff000000) >> 24;
|
int local = (ref.mRefnum & 0xff000000) >> 24;
|
||||||
size_t global = esm.getIndex() + 1;
|
size_t global = esm.getIndex() + 1;
|
||||||
@ -249,7 +249,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
|
|||||||
// missing
|
// missing
|
||||||
ref.mScale = 1.0;
|
ref.mScale = 1.0;
|
||||||
esm.getHNOT(ref.mScale, "XSCL");
|
esm.getHNOT(ref.mScale, "XSCL");
|
||||||
|
|
||||||
// TODO: support loading references from saves, there are tons of keys not recognized yet.
|
// TODO: support loading references from saves, there are tons of keys not recognized yet.
|
||||||
// The following is just an incomplete list.
|
// The following is just an incomplete list.
|
||||||
if (esm.isNextSub("ACTN"))
|
if (esm.isNextSub("ACTN"))
|
||||||
@ -266,7 +266,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
|
|||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
else if (esm.isNextSub("CRED")) // ???
|
else if (esm.isNextSub("CRED")) // ???
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
||||||
ref.mOwner = esm.getHNOString("ANAM");
|
ref.mOwner = esm.getHNOString("ANAM");
|
||||||
ref.mGlob = esm.getHNOString("BNAM");
|
ref.mGlob = esm.getHNOString("BNAM");
|
||||||
ref.mSoul = esm.getHNOString("XSOL");
|
ref.mSoul = esm.getHNOString("XSOL");
|
||||||
@ -305,7 +305,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
|
|||||||
esm.getHNOT(ref.mFltv, "FLTV");
|
esm.getHNOT(ref.mFltv, "FLTV");
|
||||||
|
|
||||||
esm.getHNOT(ref.mPos, "DATA", 24);
|
esm.getHNOT(ref.mPos, "DATA", 24);
|
||||||
|
|
||||||
// Number of references in the cell? Maximum once in each cell,
|
// Number of references in the cell? Maximum once in each cell,
|
||||||
// but not always at the beginning, and not always right. In other
|
// but not always at the beginning, and not always right. In other
|
||||||
// words, completely useless.
|
// words, completely useless.
|
||||||
@ -318,7 +318,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
|
|||||||
esm.getHT(ref.mNam0);
|
esm.getHT(ref.mNam0);
|
||||||
//esm.getHNOT(NAM0, "NAM0");
|
//esm.getHNOT(NAM0, "NAM0");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esm.isNextSub("DELE")) {
|
if (esm.isNextSub("DELE")) {
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
ref.mDeleted = 2; // Deleted, will not respawn.
|
ref.mDeleted = 2; // Deleted, will not respawn.
|
||||||
@ -333,7 +333,7 @@ bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref)
|
|||||||
{
|
{
|
||||||
esm.getHT(mref.mRefnum);
|
esm.getHT(mref.mRefnum);
|
||||||
esm.getHNOT(mref.mTarget, "CNDT");
|
esm.getHNOT(mref.mTarget, "CNDT");
|
||||||
|
|
||||||
// Identify references belonging to a parent file and adapt the ID accordingly.
|
// Identify references belonging to a parent file and adapt the ID accordingly.
|
||||||
int local = (mref.mRefnum & 0xff000000) >> 24;
|
int local = (mref.mRefnum & 0xff000000) >> 24;
|
||||||
size_t global = esm.getIndex() + 1;
|
size_t global = esm.getIndex() + 1;
|
||||||
|
@ -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
|
||||||
@ -682,6 +676,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())
|
||||||
@ -713,59 +708,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)
|
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
|
||||||
|
if (result.first)
|
||||||
{
|
{
|
||||||
// The 237 alpha flags are by far the most common. Check
|
alphaFlags = (1<<9) | (6<<10); /* alpha_rejection enabled, greater_equal */
|
||||||
// NiAlphaProperty in nif/property.h if you need to decode
|
alphaTest = result.second;
|
||||||
// other values. 237 basically means normal transparencly.
|
}
|
||||||
if (alphaFlags == 237)
|
|
||||||
{
|
if((alphaFlags&1))
|
||||||
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
|
{
|
||||||
if (result.first)
|
std::string blend_mode;
|
||||||
{
|
blend_mode += getBlendFactor((alphaFlags>>1)&0xf);
|
||||||
instance->setProperty("alpha_rejection",
|
blend_mode += " ";
|
||||||
sh::makeProperty<sh::StringValue>(new sh::StringValue("greater_equal " + boost::lexical_cast<std::string>(result.second))));
|
blend_mode += getBlendFactor((alphaFlags>>5)&0xf);
|
||||||
}
|
|
||||||
else
|
instance->setProperty("depth_write", sh::makeProperty(new sh::StringValue("off")));
|
||||||
{
|
instance->setProperty("scene_blend", sh::makeProperty(new sh::StringValue(blend_mode)));
|
||||||
// Enable transparency
|
|
||||||
instance->setProperty("scene_blend", sh::makeProperty<sh::StringValue>(new sh::StringValue("alpha_blend")));
|
|
||||||
instance->setProperty("depth_write", sh::makeProperty<sh::StringValue>(new sh::StringValue("off")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
warn("Unhandled alpha setting for texture " + texName);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
instance->getMaterial ()->setShadowCasterMaterial ("openmw_shadowcaster_noalpha");
|
instance->getMaterial()->setShadowCasterMaterial("openmw_shadowcaster_noalpha");
|
||||||
|
|
||||||
sh::Factory::getInstance ()._ensureMaterial (matname, "Default");
|
if((alphaFlags>>9)&1)
|
||||||
|
|
||||||
// As of yet UNTESTED code from Chris:
|
|
||||||
/*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)
|
|
||||||
pass->setAlphaRejectSettings(getTestMode((alphaFlags>>10)&0x7),
|
|
||||||
alphaTest);
|
|
||||||
|
|
||||||
pass->setTransparentSortingEnabled(!((alphaFlags>>13)&1));
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
instance->setProperty("transparent_sorting", sh::makeProperty(new sh::StringValue(((alphaFlags>>13)&1) ?
|
||||||
|
"off" : "on")));
|
||||||
|
|
||||||
return matname;
|
return matname;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user