mirror of https://github.com/AxioDL/metaforce.git
Lots of bug fixes (Windows still needs some fixes)
This commit is contained in:
parent
5e88b99769
commit
15d60493f2
|
@ -1664,9 +1664,10 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
|
||||||
struct MaterialPool
|
struct MaterialPool
|
||||||
{
|
{
|
||||||
std::vector<const Mesh::Material*> materials;
|
std::vector<const Mesh::Material*> materials;
|
||||||
size_t addMaterial(const Mesh::Material& mat)
|
size_t addMaterial(const Mesh::Material& mat, bool& newMat)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
|
newMat = false;
|
||||||
for (const Mesh::Material* testMat : materials)
|
for (const Mesh::Material* testMat : materials)
|
||||||
{
|
{
|
||||||
if (mat == *testMat)
|
if (mat == *testMat)
|
||||||
|
@ -1674,6 +1675,7 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
|
||||||
++ret;
|
++ret;
|
||||||
}
|
}
|
||||||
materials.push_back(&mat);
|
materials.push_back(&mat);
|
||||||
|
newMat = true;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} matPool;
|
} matPool;
|
||||||
|
@ -1696,9 +1698,10 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
|
||||||
|
|
||||||
for (const Mesh::Material& mat : mesh.materialSets[0])
|
for (const Mesh::Material& mat : mesh.materialSets[0])
|
||||||
{
|
{
|
||||||
size_t idx = matPool.addMaterial(mat);
|
bool newMat;
|
||||||
|
size_t idx = matPool.addMaterial(mat, newMat);
|
||||||
meshToGlobalMats.push_back(idx);
|
meshToGlobalMats.push_back(idx);
|
||||||
if (idx < matPool.materials.size() - 1)
|
if (!newMat)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const hecl::ProjectPath& path : mat.texs)
|
for (const hecl::ProjectPath& path : mat.texs)
|
||||||
|
@ -1736,6 +1739,7 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
|
||||||
|
|
||||||
/* Iterate meshes */
|
/* Iterate meshes */
|
||||||
auto matIt = surfToGlobalMats.cbegin();
|
auto matIt = surfToGlobalMats.cbegin();
|
||||||
|
int meshIdx = 0;
|
||||||
for (const Mesh& mesh : meshes)
|
for (const Mesh& mesh : meshes)
|
||||||
{
|
{
|
||||||
zeus::CTransform meshXf(mesh.sceneXf.val);
|
zeus::CTransform meshXf(mesh.sceneXf.val);
|
||||||
|
|
|
@ -322,7 +322,7 @@ bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template bool WriteCRSM<UniqueID32>(const CRSM<UniqueID32>& crsm, const hecl::ProjectPath& outPath);
|
template bool WriteCRSM<UniqueID32>(const CRSM<UniqueID32>& crsm, const hecl::ProjectPath& outPath);
|
||||||
|
|
|
@ -133,7 +133,7 @@ bool WriteDGRP(const DGRP<IDType>& dgrp, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template bool WriteDGRP<UniqueID32>(const DGRP<UniqueID32>& dgrp, const hecl::ProjectPath& outPath);
|
template bool WriteDGRP<UniqueID32>(const DGRP<UniqueID32>& dgrp, const hecl::ProjectPath& outPath);
|
||||||
|
|
|
@ -82,7 +82,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size_t binarySize(size_t __isz) const
|
size_t binarySize(size_t __isz) const
|
||||||
{return __isz + 4;}
|
{return __isz + 16;}
|
||||||
};
|
};
|
||||||
|
|
||||||
using FourCC = hecl::FourCC;
|
using FourCC = hecl::FourCC;
|
||||||
|
|
|
@ -404,7 +404,7 @@ bool WriteDPSM(const DPSM<IDType>& dpsm, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template bool WriteDPSM<UniqueID32>(const DPSM<UniqueID32>& dpsm, const hecl::ProjectPath& outPath);
|
template bool WriteDPSM<UniqueID32>(const DPSM<UniqueID32>& dpsm, const hecl::ProjectPath& outPath);
|
||||||
|
|
|
@ -421,7 +421,7 @@ bool WriteELSM(const ELSM<IDType>& elsm, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template bool WriteELSM<UniqueID32>(const ELSM<UniqueID32>& gpsm, const hecl::ProjectPath& outPath);
|
template bool WriteELSM<UniqueID32>(const ELSM<UniqueID32>& gpsm, const hecl::ProjectPath& outPath);
|
||||||
|
|
|
@ -565,7 +565,7 @@ bool WriteFONT(const FONT<IDType>& font, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template bool WriteFONT<UniqueID32>(const FONT<UniqueID32>& font, const hecl::ProjectPath& outPath);
|
template bool WriteFONT<UniqueID32>(const FONT<UniqueID32>& font, const hecl::ProjectPath& outPath);
|
||||||
|
|
|
@ -1007,7 +1007,7 @@ bool WriteFSM2(const FSM2<IDType>& fsm2, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template bool WriteFSM2<UniqueID32>(const FSM2<UniqueID32>& fsm2, const hecl::ProjectPath& outPath);
|
template bool WriteFSM2<UniqueID32>(const FSM2<UniqueID32>& fsm2, const hecl::ProjectPath& outPath);
|
||||||
|
|
|
@ -144,14 +144,10 @@ static void MakeLeaf(const ColMesh& mesh, const std::vector<int>& index, Node& n
|
||||||
n.right.reset();
|
n.right.reset();
|
||||||
n.isLeaf = true;
|
n.isLeaf = true;
|
||||||
n.leafData = std::make_unique<typename Node::LeafData>();
|
n.leafData = std::make_unique<typename Node::LeafData>();
|
||||||
n.leafData->edgeIndexCount = atUint32(index.size() * 3);
|
n.leafData->triangleIndexCount = atUint32(index.size());
|
||||||
n.leafData->edgeIndices.reserve(n.leafData->edgeIndexCount);
|
n.leafData->triangleIndices.reserve(n.leafData->triangleIndexCount);
|
||||||
for (int i : index)
|
for (int i : index)
|
||||||
{
|
n.leafData->triangleIndices.push_back(i);
|
||||||
const ColMesh::Triangle& T = mesh.trianges[i];
|
|
||||||
for (int j = 0; j < 3; ++j)
|
|
||||||
n.leafData->edgeIndices.push_back(T.edges[j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Node>
|
template <typename Node>
|
||||||
|
|
|
@ -1390,7 +1390,7 @@ bool WriteGPSM(const GPSM<IDType>& gpsm, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template bool WriteGPSM<UniqueID32>(const GPSM<UniqueID32>& gpsm, const hecl::ProjectPath& outPath);
|
template bool WriteGPSM<UniqueID32>(const GPSM<UniqueID32>& gpsm, const hecl::ProjectPath& outPath);
|
||||||
|
|
|
@ -523,7 +523,7 @@ bool WriteSWSH(const SWSH<IDType>& swsh, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template bool WriteSWSH<UniqueID32>(const SWSH<UniqueID32>& swsh, const hecl::ProjectPath& outPath);
|
template bool WriteSWSH<UniqueID32>(const SWSH<UniqueID32>& swsh, const hecl::ProjectPath& outPath);
|
||||||
|
|
|
@ -16,7 +16,7 @@ bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -660,7 +660,7 @@ bool WriteWPSM(const WPSM<IDType>& wpsm, const hecl::ProjectPath& outPath)
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template bool WriteWPSM<UniqueID32>(const WPSM<UniqueID32>& wpsm, const hecl::ProjectPath& outPath);
|
template bool WriteWPSM<UniqueID32>(const WPSM<UniqueID32>& wpsm, const hecl::ProjectPath& outPath);
|
||||||
|
|
|
@ -135,7 +135,9 @@ CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& i
|
||||||
if (bone->children.size())
|
if (bone->children.size())
|
||||||
{
|
{
|
||||||
int curId = 4;
|
int curId = 4;
|
||||||
RecursiveAddArmatureBone(armature, armature.getChild(bone, 0), 3, curId, idMap, nameMap);
|
const Armature::Bone* child;
|
||||||
|
for (size_t i=0 ; (child = armature.getChild(bone, i)) ; ++i)
|
||||||
|
RecursiveAddArmatureBone(armature, child, 3, curId, idMap, nameMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
bones.emplace_back();
|
bones.emplace_back();
|
||||||
|
|
|
@ -53,9 +53,9 @@ struct DCLN : BigDNA
|
||||||
struct LeafData : BigDNA
|
struct LeafData : BigDNA
|
||||||
{
|
{
|
||||||
DECL_DNA
|
DECL_DNA
|
||||||
Value<atUint32> edgeIndexCount;
|
Value<atUint32> triangleIndexCount;
|
||||||
Vector<atUint16, DNA_COUNT(edgeIndexCount)> edgeIndices;
|
Vector<atUint16, DNA_COUNT(triangleIndexCount)> triangleIndices;
|
||||||
size_t getMemoryUsage() const { return (((edgeIndices.size() * 2) + 16) + 3) & ~3; }
|
size_t getMemoryUsage() const { return (((triangleIndices.size() * 2) + 16) + 3) & ~3; }
|
||||||
};
|
};
|
||||||
|
|
||||||
Value<atVec4f> xf[3];
|
Value<atVec4f> xf[3];
|
||||||
|
@ -234,6 +234,10 @@ struct DCLN : BigDNA
|
||||||
|
|
||||||
athena::io::FileWriter w(outPath.getAbsolutePath());
|
athena::io::FileWriter w(outPath.getAbsolutePath());
|
||||||
dcln.write(w);
|
dcln.write(w);
|
||||||
|
int64_t rem = w.position() % 32;
|
||||||
|
if (rem)
|
||||||
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
|
w.writeUByte(0xff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <hecl/ClientProcess.hpp>
|
||||||
|
#include <athena/MemoryReader.hpp>
|
||||||
#include "MREA.hpp"
|
#include "MREA.hpp"
|
||||||
#include "SCLY.hpp"
|
#include "SCLY.hpp"
|
||||||
#include "PATH.hpp"
|
#include "PATH.hpp"
|
||||||
|
@ -167,8 +169,17 @@ bool MREA::Extract(const SpecBase& dataSpec,
|
||||||
rs.seek(secStart + head.secSizes[curSec++], athena::Begin);
|
rs.seek(secStart + head.secSizes[curSec++], athena::Begin);
|
||||||
|
|
||||||
/* Dump VISI entities */
|
/* Dump VISI entities */
|
||||||
|
secStart = rs.position();
|
||||||
if (head.secSizes[curSec] && rs.readUint32Big() == 'VISI')
|
if (head.secSizes[curSec] && rs.readUint32Big() == 'VISI')
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
rs.seek(secStart, athena::Begin);
|
||||||
|
auto visiData = rs.readUBytes(head.secSizes[curSec]);
|
||||||
|
athena::io::FileWriter visiOut(outPath.getWithExtension(_S(".visi"), true).getAbsolutePath());
|
||||||
|
visiOut.writeUBytes(visiData.get(), head.secSizes[curSec]);
|
||||||
|
rs.seek(secStart + 4, athena::Begin);
|
||||||
|
}
|
||||||
|
|
||||||
athena::io::YAMLDocWriter visiWriter("VISI");
|
athena::io::YAMLDocWriter visiWriter("VISI");
|
||||||
if (auto __vec = visiWriter.enterSubVector("entities"))
|
if (auto __vec = visiWriter.enterSubVector("entities"))
|
||||||
{
|
{
|
||||||
|
@ -447,6 +458,8 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
|
||||||
if (auto __vec = r.enterSubVector("entities", entityCount))
|
if (auto __vec = r.enterSubVector("entities", entityCount))
|
||||||
{
|
{
|
||||||
entities.reserve(entityCount);
|
entities.reserve(entityCount);
|
||||||
|
for (size_t i=0 ; i<entityCount ; ++i)
|
||||||
|
{
|
||||||
uint16_t entityId = r.readUint16(nullptr);
|
uint16_t entityId = r.readUint16(nullptr);
|
||||||
for (const SCLY::ScriptLayer& layer : sclyData.layers)
|
for (const SCLY::ScriptLayer& layer : sclyData.layers)
|
||||||
{
|
{
|
||||||
|
@ -455,15 +468,51 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
|
||||||
if ((obj->id & 0xffff) == entityId)
|
if ((obj->id & 0xffff) == entityId)
|
||||||
{
|
{
|
||||||
zeus::CAABox entAABB = obj->getVISIAABB(btok);
|
zeus::CAABox entAABB = obj->getVISIAABB(btok);
|
||||||
if (entAABB.min.x < entAABB.max.x)
|
if (!entAABB.invalid())
|
||||||
entities.emplace_back(entityId, entAABB);
|
entities.emplace_back(entityId, entAABB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if pre-generated visi exists, recycle if able
|
||||||
|
hecl::ProjectPath preVisiPath = inPath.getWithExtension(_S(".visi"), true);
|
||||||
|
if (preVisiPath.getPathType() == hecl::ProjectPath::Type::File)
|
||||||
|
{
|
||||||
|
athena::io::FileReader preVisiReader(preVisiPath.getAbsolutePath());
|
||||||
|
atUint64 preVisiLen = preVisiReader.length();
|
||||||
|
if (preVisiLen > 26)
|
||||||
|
{
|
||||||
|
auto preVisiData = preVisiReader.readUBytes(preVisiLen);
|
||||||
|
athena::io::MemoryReader preVisiDataReader(preVisiData.get(), preVisiLen);
|
||||||
|
|
||||||
|
atUint32 preVisiFourCC = preVisiDataReader.readUint32Big();
|
||||||
|
atUint32 preVisiVersion = preVisiDataReader.readUint32Big();
|
||||||
|
preVisiDataReader.readBool();
|
||||||
|
preVisiDataReader.readBool();
|
||||||
|
atUint32 preFeatureCount = preVisiDataReader.readUint32Big();
|
||||||
|
atUint32 preLightsCount = preVisiDataReader.readUint32Big();
|
||||||
|
atUint32 preLayer2LightCount = preVisiDataReader.readUint32Big();
|
||||||
|
atUint32 preEntityCount = preVisiDataReader.readUint32Big();
|
||||||
|
|
||||||
|
if (preVisiFourCC == 'VISI' && preVisiVersion == 2 &&
|
||||||
|
preFeatureCount == meshes.size() + entities.size() &&
|
||||||
|
preLightsCount == lightsVisi[0].size() + lightsVisi[1].size() &&
|
||||||
|
preLayer2LightCount == lightsVisi[1].size() &&
|
||||||
|
preEntityCount == entities.size())
|
||||||
|
{
|
||||||
|
secs.emplace_back(preVisiLen, 0);
|
||||||
|
memcpy(secs.back().data(), preVisiData.get(), preVisiLen);
|
||||||
|
visiGood = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!visiGood)
|
||||||
|
{
|
||||||
hecl::ProjectPath visiIntOut = outPath.getWithExtension(_S(".visiint"));
|
hecl::ProjectPath visiIntOut = outPath.getWithExtension(_S(".visiint"));
|
||||||
hecl::ProjectPath visiIn = outPath.getWithExtension(_S(".visi"));
|
hecl::ProjectPath visiIn = inPath.getWithExtension(_S(".visi"));
|
||||||
athena::io::FileWriter w(visiIntOut.getAbsolutePath());
|
athena::io::FileWriter w(visiIntOut.getAbsolutePath());
|
||||||
w.writeUint32Big(meshes.size());
|
w.writeUint32Big(meshes.size());
|
||||||
for (const DNACMDL::Mesh& mesh : meshes)
|
for (const DNACMDL::Mesh& mesh : meshes)
|
||||||
|
@ -509,9 +558,12 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
VisiGenPath += _S(".exe");
|
VisiGenPath += _S(".exe");
|
||||||
#endif
|
#endif
|
||||||
|
char thrIdx[16];
|
||||||
|
snprintf(thrIdx, 16, "%d", hecl::ClientProcess::GetThreadWorkerIdx());
|
||||||
const hecl::SystemChar* args[] = {VisiGenPath.c_str(),
|
const hecl::SystemChar* args[] = {VisiGenPath.c_str(),
|
||||||
visiIntOut.getAbsolutePath().c_str(),
|
visiIntOut.getAbsolutePath().c_str(),
|
||||||
visiIn.getAbsolutePath().c_str(),
|
visiIn.getAbsolutePath().c_str(),
|
||||||
|
thrIdx,
|
||||||
nullptr};
|
nullptr};
|
||||||
if (0 == hecl::RunProcess(VisiGenPath.c_str(), args))
|
if (0 == hecl::RunProcess(VisiGenPath.c_str(), args))
|
||||||
{
|
{
|
||||||
|
@ -523,6 +575,7 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!visiGood)
|
if (!visiGood)
|
||||||
secs.emplace_back(4, 0);
|
secs.emplace_back(4, 0);
|
||||||
|
|
||||||
|
@ -578,7 +631,7 @@ bool MREA::CookPath(const hecl::ProjectPath& outPath,
|
||||||
int64_t rem = w.position() % 32;
|
int64_t rem = w.position() % 32;
|
||||||
if (rem)
|
if (rem)
|
||||||
for (int64_t i=0 ; i<32-rem ; ++i)
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
w.writeBytes((atInt8*)"\xff", 1);
|
w.writeUByte(0xff);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,26 @@ makeProj:
|
||||||
m_mainMP1.emplace(m_factoryMP1, m_objStore, m_vm.m_mainBooFactory,
|
m_mainMP1.emplace(m_factoryMP1, m_objStore, m_vm.m_mainBooFactory,
|
||||||
m_vm.m_mainCommandQueue, m_vm.m_renderTex);
|
m_vm.m_mainCommandQueue, m_vm.m_renderTex);
|
||||||
m_vm.InitMP1(*m_mainMP1);
|
m_vm.InitMP1(*m_mainMP1);
|
||||||
m_vm.BuildTestPART();
|
|
||||||
|
// precook
|
||||||
|
m_precooking = true;
|
||||||
|
std::vector<SObjectTag> nonMlvls;
|
||||||
|
std::vector<SObjectTag> mlvls;
|
||||||
|
mlvls.reserve(8);
|
||||||
|
m_factoryMP1.EnumerateResources([this, &nonMlvls, &mlvls](const SObjectTag& tag)
|
||||||
|
{
|
||||||
|
if (tag.type == FOURCC('CMDL') || tag.type == FOURCC('MREA'))
|
||||||
|
m_factoryMP1.CookResourceAsync(tag);
|
||||||
|
else if (tag.type != FOURCC('MLVL'))
|
||||||
|
nonMlvls.push_back(tag);
|
||||||
|
else // (tag.type == FOURCC('MLVL'))
|
||||||
|
mlvls.push_back(tag);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
for (const SObjectTag& tag : nonMlvls)
|
||||||
|
m_factoryMP1.CookResourceAsync(tag);
|
||||||
|
for (const SObjectTag& tag : mlvls)
|
||||||
|
m_factoryMP1.CookResourceAsync(tag);
|
||||||
|
|
||||||
if (needsSave)
|
if (needsSave)
|
||||||
saveProject();
|
saveProject();
|
||||||
|
@ -182,6 +201,14 @@ bool ProjectManager::saveProject()
|
||||||
|
|
||||||
void ProjectManager::mainUpdate()
|
void ProjectManager::mainUpdate()
|
||||||
{
|
{
|
||||||
|
if (m_precooking)
|
||||||
|
{
|
||||||
|
if (!m_factoryMP1.IsBusy())
|
||||||
|
m_precooking = false;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_mainMP1)
|
if (m_mainMP1)
|
||||||
{
|
{
|
||||||
if (m_mainMP1->Proc())
|
if (m_mainMP1->Proc())
|
||||||
|
@ -194,6 +221,9 @@ void ProjectManager::mainUpdate()
|
||||||
|
|
||||||
void ProjectManager::mainDraw()
|
void ProjectManager::mainDraw()
|
||||||
{
|
{
|
||||||
|
if (m_precooking)
|
||||||
|
return;
|
||||||
|
|
||||||
if (m_mainMP1)
|
if (m_mainMP1)
|
||||||
m_mainMP1->Draw();
|
m_mainMP1->Draw();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ class ProjectManager
|
||||||
ProjectResourceFactoryMP1 m_factoryMP1;
|
ProjectResourceFactoryMP1 m_factoryMP1;
|
||||||
ProjectResourcePool m_objStore;
|
ProjectResourcePool m_objStore;
|
||||||
std::experimental::optional<MP1::CMain> m_mainMP1;
|
std::experimental::optional<MP1::CMain> m_mainMP1;
|
||||||
|
bool m_precooking = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ProjectManager* g_SharedManager;
|
static ProjectManager* g_SharedManager;
|
||||||
|
|
|
@ -548,18 +548,23 @@ void ProjectResourceFactoryBase::AsyncTask::CookComplete()
|
||||||
xc_targetDataRawPtr,
|
xc_targetDataRawPtr,
|
||||||
x14_resSize, x14_resOffset);
|
x14_resSize, x14_resOffset);
|
||||||
}
|
}
|
||||||
else
|
else if (xc_targetDataPtr || xc_targetObjPtr)
|
||||||
{
|
{
|
||||||
x10_loadBuffer.reset(new u8[x14_resSize]);
|
x10_loadBuffer.reset(new u8[x14_resSize]);
|
||||||
m_bufTransaction = m_parent.m_clientProc.addBufferTransaction(m_cookedPath,
|
m_bufTransaction = m_parent.m_clientProc.addBufferTransaction(m_cookedPath,
|
||||||
x10_loadBuffer.get(),
|
x10_loadBuffer.get(),
|
||||||
x14_resSize, x14_resOffset);
|
x14_resSize, x14_resOffset);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Skip buffer transaction if no target pointers set */
|
||||||
|
m_complete = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectResourceFactoryBase::AsyncTask::AsyncPump()
|
bool ProjectResourceFactoryBase::AsyncTask::AsyncPump()
|
||||||
{
|
{
|
||||||
if (m_failed)
|
if (m_failed || m_complete)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (m_bufTransaction)
|
if (m_bufTransaction)
|
||||||
|
@ -581,14 +586,49 @@ bool ProjectResourceFactoryBase::AsyncTask::AsyncPump()
|
||||||
|
|
||||||
void ProjectResourceFactoryBase::AsyncTask::WaitForComplete()
|
void ProjectResourceFactoryBase::AsyncTask::WaitForComplete()
|
||||||
{
|
{
|
||||||
using ItType = std::unordered_map<SObjectTag, std::shared_ptr<AsyncTask>>::iterator;
|
using ItType = std::unordered_map<SObjectTag,
|
||||||
ItType search = m_parent.m_asyncLoadList.find(x0_tag);
|
std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator;
|
||||||
if (search == m_parent.m_asyncLoadList.end())
|
ItType search = m_parent.m_asyncLoadMap.find(x0_tag);
|
||||||
|
if (search == m_parent.m_asyncLoadMap.end())
|
||||||
return;
|
return;
|
||||||
for (ItType tmp = search ; !m_parent.AsyncPumpTask(tmp) ; tmp = search)
|
for (ItType tmp = search ; !m_parent.AsyncPumpTask(tmp) ; tmp = search)
|
||||||
{std::this_thread::sleep_for(std::chrono::milliseconds(2));}
|
{std::this_thread::sleep_for(std::chrono::milliseconds(2));}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using AsyncTask = ProjectResourceFactoryBase::AsyncTask;
|
||||||
|
|
||||||
|
std::shared_ptr<AsyncTask>
|
||||||
|
ProjectResourceFactoryBase::_AddTask(const std::shared_ptr<AsyncTask>& ptr)
|
||||||
|
{
|
||||||
|
m_asyncLoadMap.insert({ptr->x0_tag, m_asyncLoadList.insert(m_asyncLoadList.end(), ptr)});
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<std::shared_ptr<AsyncTask>>::iterator
|
||||||
|
ProjectResourceFactoryBase::_RemoveTask(std::list<std::shared_ptr<AsyncTask>>::iterator it)
|
||||||
|
{
|
||||||
|
m_asyncLoadMap.erase((*it)->x0_tag);
|
||||||
|
return m_asyncLoadList.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<SObjectTag, std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator
|
||||||
|
ProjectResourceFactoryBase::_RemoveTask(std::unordered_map<SObjectTag,
|
||||||
|
std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator it)
|
||||||
|
{
|
||||||
|
if (it != m_asyncLoadMap.end())
|
||||||
|
{
|
||||||
|
m_asyncLoadList.erase(it->second);
|
||||||
|
return m_asyncLoadMap.erase(it);
|
||||||
|
}
|
||||||
|
return it;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<SObjectTag, std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator
|
||||||
|
ProjectResourceFactoryBase::_RemoveTask(const SObjectTag& tag)
|
||||||
|
{
|
||||||
|
return _RemoveTask(m_asyncLoadMap.find(tag));
|
||||||
|
};
|
||||||
|
|
||||||
bool ProjectResourceFactoryBase::WaitForTagReady(const urde::SObjectTag& tag,
|
bool ProjectResourceFactoryBase::WaitForTagReady(const urde::SObjectTag& tag,
|
||||||
const hecl::ProjectPath*& pathOut)
|
const hecl::ProjectPath*& pathOut)
|
||||||
{
|
{
|
||||||
|
@ -687,17 +727,17 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
|
||||||
const hecl::ProjectPath* resPath = nullptr;
|
const hecl::ProjectPath* resPath = nullptr;
|
||||||
if (!WaitForTagReady(tag, resPath))
|
if (!WaitForTagReady(tag, resPath))
|
||||||
return {};
|
return {};
|
||||||
auto asyncSearch = m_asyncLoadList.find(tag);
|
auto asyncSearch = m_asyncLoadMap.find(tag);
|
||||||
if (asyncSearch != m_asyncLoadList.end())
|
if (asyncSearch != m_asyncLoadMap.end())
|
||||||
{
|
{
|
||||||
/* Async spinloop */
|
/* Async spinloop */
|
||||||
AsyncTask& task = *asyncSearch->second;
|
AsyncTask& task = **asyncSearch->second;
|
||||||
task.EnsurePath(task.x0_tag, *resPath);
|
task.EnsurePath(task.x0_tag, *resPath);
|
||||||
|
|
||||||
/* Pump load pipeline (cooking if needed) */
|
/* Pump load pipeline (cooking if needed) */
|
||||||
while (!task.AsyncPump()) {std::this_thread::sleep_for(std::chrono::milliseconds(2));}
|
while (!task.AsyncPump()) {std::this_thread::sleep_for(std::chrono::milliseconds(2));}
|
||||||
|
|
||||||
if (task.m_complete)
|
if (task.m_complete && task.x10_loadBuffer)
|
||||||
{
|
{
|
||||||
/* Load complete, build resource */
|
/* Load complete, build resource */
|
||||||
std::unique_ptr<IObj> newObj;
|
std::unique_ptr<IObj> newObj;
|
||||||
|
@ -714,16 +754,23 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
|
||||||
|
|
||||||
*task.xc_targetObjPtr = newObj.get();
|
*task.xc_targetObjPtr = newObj.get();
|
||||||
Log.report(logvisor::Warning, "spin-built %.4s %08X",
|
Log.report(logvisor::Warning, "spin-built %.4s %08X",
|
||||||
task.x0_tag.type.toString().c_str(),
|
task.x0_tag.type.toString().c_str(), u32(task.x0_tag.id.Value()));
|
||||||
u32(task.x0_tag.id.Value()));
|
|
||||||
|
|
||||||
m_asyncLoadList.erase(asyncSearch);
|
_RemoveTask(asyncSearch);
|
||||||
return newObj;
|
return newObj;
|
||||||
}
|
}
|
||||||
|
else if (task.m_complete)
|
||||||
|
{
|
||||||
|
Log.report(logvisor::Error, "unable to spin-build %.4s %08X; Resource requested as cook-only",
|
||||||
|
task.x0_tag.type.toString().c_str(), u32(task.x0_tag.id.Value()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Log.report(logvisor::Error, "unable to spin-build %.4s %08X",
|
Log.report(logvisor::Error, "unable to spin-build %.4s %08X",
|
||||||
task.x0_tag.type.toString().c_str(),
|
task.x0_tag.type.toString().c_str(), u32(task.x0_tag.id.Value()));
|
||||||
u32(task.x0_tag.id.Value()));
|
}
|
||||||
m_asyncLoadList.erase(asyncSearch);
|
|
||||||
|
_RemoveTask(asyncSearch);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,16 +778,15 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
|
||||||
return BuildSync(tag, *resPath, paramXfer, selfRef);
|
return BuildSync(tag, *resPath, paramXfer, selfRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
|
std::shared_ptr<AsyncTask>
|
||||||
ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag,
|
ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag,
|
||||||
const urde::CVParamTransfer& paramXfer,
|
const urde::CVParamTransfer& paramXfer,
|
||||||
urde::IObj** objOut,
|
urde::IObj** objOut,
|
||||||
CObjectReference* selfRef)
|
CObjectReference* selfRef)
|
||||||
{
|
{
|
||||||
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
|
if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end())
|
||||||
return {};
|
return {};
|
||||||
return m_asyncLoadList.emplace(std::make_pair(tag,
|
return _AddTask(std::make_unique<AsyncTask>(*this, tag, objOut, paramXfer, selfRef));
|
||||||
std::make_unique<AsyncTask>(*this, tag, objOut, paramXfer, selfRef))).first->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectResourceFactoryBase::BuildAsync(const urde::SObjectTag& tag,
|
void ProjectResourceFactoryBase::BuildAsync(const urde::SObjectTag& tag,
|
||||||
|
@ -772,40 +818,37 @@ u32 ProjectResourceFactoryBase::ResourceSize(const SObjectTag& tag)
|
||||||
return fr->length();
|
return fr->length();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
|
std::shared_ptr<AsyncTask>
|
||||||
ProjectResourceFactoryBase::LoadResourceAsync(const urde::SObjectTag& tag,
|
ProjectResourceFactoryBase::LoadResourceAsync(const urde::SObjectTag& tag,
|
||||||
std::unique_ptr<u8[]>& target)
|
std::unique_ptr<u8[]>& target)
|
||||||
{
|
{
|
||||||
if (!tag.id.IsValid())
|
if (!tag.id.IsValid())
|
||||||
Log.report(logvisor::Fatal, "attempted to access null id");
|
Log.report(logvisor::Fatal, "attempted to access null id");
|
||||||
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
|
if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end())
|
||||||
return {};
|
return {};
|
||||||
return m_asyncLoadList.emplace(std::make_pair(tag,
|
return _AddTask(std::make_shared<AsyncTask>(*this, tag, target));
|
||||||
std::make_shared<AsyncTask>(*this, tag, target))).first->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
|
std::shared_ptr<AsyncTask>
|
||||||
ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag,
|
ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag,
|
||||||
u32 size, u32 off,
|
u32 size, u32 off,
|
||||||
std::unique_ptr<u8[]>& target)
|
std::unique_ptr<u8[]>& target)
|
||||||
{
|
{
|
||||||
if (!tag.id.IsValid())
|
if (!tag.id.IsValid())
|
||||||
Log.report(logvisor::Fatal, "attempted to access null id");
|
Log.report(logvisor::Fatal, "attempted to access null id");
|
||||||
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
|
if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end())
|
||||||
return {};
|
return {};
|
||||||
return m_asyncLoadList.emplace(std::make_pair(tag,
|
return _AddTask(std::make_shared<AsyncTask>(*this, tag, target, size, off));
|
||||||
std::make_shared<AsyncTask>(*this, tag, target, size, off))).first->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
|
std::shared_ptr<AsyncTask>
|
||||||
ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, u8* target)
|
ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, u8* target)
|
||||||
{
|
{
|
||||||
if (!tag.id.IsValid())
|
if (!tag.id.IsValid())
|
||||||
Log.report(logvisor::Fatal, "attempted to access null id");
|
Log.report(logvisor::Fatal, "attempted to access null id");
|
||||||
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
|
if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end())
|
||||||
return {};
|
return {};
|
||||||
return m_asyncLoadList.emplace(std::make_pair(tag,
|
return _AddTask(std::make_shared<AsyncTask>(*this, tag, target, size, off));
|
||||||
std::make_shared<AsyncTask>(*this, tag, target, size, off))).first->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<u8[]> ProjectResourceFactoryBase::LoadResourceSync(const urde::SObjectTag& tag)
|
std::unique_ptr<u8[]> ProjectResourceFactoryBase::LoadResourceSync(const urde::SObjectTag& tag)
|
||||||
|
@ -847,9 +890,19 @@ std::unique_ptr<u8[]> ProjectResourceFactoryBase::LoadResourcePartSync(const urd
|
||||||
return fr->readUBytes(sz);
|
return fr->readUBytes(sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<AsyncTask>
|
||||||
|
ProjectResourceFactoryBase::CookResourceAsync(const urde::SObjectTag& tag)
|
||||||
|
{
|
||||||
|
if (!tag.id.IsValid())
|
||||||
|
Log.report(logvisor::Fatal, "attempted to access null id");
|
||||||
|
if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end())
|
||||||
|
return {};
|
||||||
|
return _AddTask(std::make_shared<AsyncTask>(*this, tag));
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectResourceFactoryBase::CancelBuild(const urde::SObjectTag& tag)
|
void ProjectResourceFactoryBase::CancelBuild(const urde::SObjectTag& tag)
|
||||||
{
|
{
|
||||||
m_asyncLoadList.erase(tag);
|
_RemoveTask(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectResourceFactoryBase::CanBuild(const urde::SObjectTag& tag)
|
bool ProjectResourceFactoryBase::CanBuild(const urde::SObjectTag& tag)
|
||||||
|
@ -961,12 +1014,12 @@ void ProjectResourceFactoryBase::EnumerateNamedResources(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectResourceFactoryBase::AsyncPumpTask(
|
template <typename ItType>
|
||||||
std::unordered_map<SObjectTag, std::shared_ptr<AsyncTask>>::iterator& it)
|
bool ProjectResourceFactoryBase::AsyncPumpTask(ItType& it)
|
||||||
{
|
{
|
||||||
/* Ensure requested resource is in the index */
|
/* Ensure requested resource is in the index */
|
||||||
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
||||||
AsyncTask& task = *it->second;
|
AsyncTask& task = _GetAsyncTask(it);
|
||||||
auto search = m_tagToPath.find(task.x0_tag);
|
auto search = m_tagToPath.find(task.x0_tag);
|
||||||
if (search == m_tagToPath.end())
|
if (search == m_tagToPath.end())
|
||||||
{
|
{
|
||||||
|
@ -974,7 +1027,7 @@ bool ProjectResourceFactoryBase::AsyncPumpTask(
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Error, _S("unable to find async load resource (%s, %08X)"),
|
Log.report(logvisor::Error, _S("unable to find async load resource (%s, %08X)"),
|
||||||
task.x0_tag.type.toString().c_str(), task.x0_tag.id);
|
task.x0_tag.type.toString().c_str(), task.x0_tag.id);
|
||||||
it = m_asyncLoadList.erase(it);
|
it = _RemoveTask(it);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1025,13 +1078,19 @@ bool ProjectResourceFactoryBase::AsyncPumpTask(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it = m_asyncLoadList.erase(it);
|
it = _RemoveTask(it);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template bool ProjectResourceFactoryBase::AsyncPumpTask<std::list<std::shared_ptr<AsyncTask>>::iterator>(
|
||||||
|
std::list<std::shared_ptr<AsyncTask>>::iterator& it);
|
||||||
|
template bool ProjectResourceFactoryBase::AsyncPumpTask<std::unordered_map<SObjectTag,
|
||||||
|
std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator>(
|
||||||
|
std::unordered_map<SObjectTag, std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator& it);
|
||||||
|
|
||||||
void ProjectResourceFactoryBase::AsyncIdle()
|
void ProjectResourceFactoryBase::AsyncIdle()
|
||||||
{
|
{
|
||||||
/* Consume completed transactions, they will be processed this cycle at the latest */
|
/* Consume completed transactions, they will be processed this cycle at the latest */
|
||||||
|
|
|
@ -60,6 +60,10 @@ public:
|
||||||
IObj** ptr, const CVParamTransfer& xfer, CObjectReference* selfRef)
|
IObj** ptr, const CVParamTransfer& xfer, CObjectReference* selfRef)
|
||||||
: m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer), m_selfRef(selfRef) {}
|
: m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer), m_selfRef(selfRef) {}
|
||||||
|
|
||||||
|
/* Cook only */
|
||||||
|
AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag)
|
||||||
|
: m_parent(parent), x0_tag(tag) {}
|
||||||
|
|
||||||
void EnsurePath(const urde::SObjectTag& tag,
|
void EnsurePath(const urde::SObjectTag& tag,
|
||||||
const hecl::ProjectPath& path);
|
const hecl::ProjectPath& path);
|
||||||
void CookComplete();
|
void CookComplete();
|
||||||
|
@ -85,7 +89,27 @@ protected:
|
||||||
std::mutex m_backgroundIndexMutex;
|
std::mutex m_backgroundIndexMutex;
|
||||||
bool m_backgroundRunning = false;
|
bool m_backgroundRunning = false;
|
||||||
|
|
||||||
std::unordered_map<SObjectTag, std::shared_ptr<AsyncTask>> m_asyncLoadList;
|
std::list<std::shared_ptr<AsyncTask>> m_asyncLoadList;
|
||||||
|
std::unordered_map<SObjectTag, std::list<std::shared_ptr<AsyncTask>>::iterator> m_asyncLoadMap;
|
||||||
|
std::shared_ptr<AsyncTask>
|
||||||
|
_AddTask(const std::shared_ptr<AsyncTask>& ptr);
|
||||||
|
std::list<std::shared_ptr<AsyncTask>>::iterator
|
||||||
|
_RemoveTask(std::list<std::shared_ptr<AsyncTask>>::iterator it);
|
||||||
|
std::unordered_map<SObjectTag, std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator
|
||||||
|
_RemoveTask(std::unordered_map<SObjectTag,
|
||||||
|
std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator it);
|
||||||
|
std::unordered_map<SObjectTag, std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator
|
||||||
|
_RemoveTask(const SObjectTag& tag);
|
||||||
|
|
||||||
|
static AsyncTask& _GetAsyncTask(std::list<std::shared_ptr<AsyncTask>>::iterator it)
|
||||||
|
{
|
||||||
|
return **it;
|
||||||
|
}
|
||||||
|
static AsyncTask& _GetAsyncTask(
|
||||||
|
std::unordered_map<SObjectTag, std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator it)
|
||||||
|
{
|
||||||
|
return **it->second;
|
||||||
|
}
|
||||||
|
|
||||||
bool WaitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut);
|
bool WaitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut);
|
||||||
bool
|
bool
|
||||||
|
@ -141,9 +165,13 @@ public:
|
||||||
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
|
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
|
||||||
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);
|
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);
|
||||||
|
|
||||||
bool AsyncPumpTask(std::unordered_map<SObjectTag, std::shared_ptr<AsyncTask>>::iterator& it);
|
std::shared_ptr<AsyncTask> CookResourceAsync(const urde::SObjectTag& tag);
|
||||||
|
|
||||||
|
template <typename ItType>
|
||||||
|
bool AsyncPumpTask(ItType& it);
|
||||||
void AsyncIdle();
|
void AsyncIdle();
|
||||||
void Shutdown() { CancelBackgroundIndex(); }
|
void Shutdown() { CancelBackgroundIndex(); }
|
||||||
|
bool IsBusy() const { return m_asyncLoadMap.size() != 0; }
|
||||||
|
|
||||||
SObjectTag TagFromPath(const hecl::SystemChar* path) const
|
SObjectTag TagFromPath(const hecl::SystemChar* path) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,8 +25,11 @@ using YAMLNode = athena::io::YAMLNode;
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
void ViewManager::BuildTestPART()
|
void ViewManager::InitMP1(MP1::CMain& main)
|
||||||
{
|
{
|
||||||
|
main.Init(m_fileStoreManager, m_mainWindow.get(), m_voiceEngine.get(), *m_amuseAllocWrapper);
|
||||||
|
main.WarmupShaders();
|
||||||
|
|
||||||
m_testGameView.reset(new TestGameView(*this, m_viewResources, *m_rootView));
|
m_testGameView.reset(new TestGameView(*this, m_viewResources, *m_rootView));
|
||||||
|
|
||||||
m_rootView->accessContentViews().clear();
|
m_rootView->accessContentViews().clear();
|
||||||
|
@ -34,12 +37,6 @@ void ViewManager::BuildTestPART()
|
||||||
m_rootView->updateSize();
|
m_rootView->updateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewManager::InitMP1(MP1::CMain& main)
|
|
||||||
{
|
|
||||||
main.Init(m_fileStoreManager, m_mainWindow.get(), m_voiceEngine.get(), *m_amuseAllocWrapper);
|
|
||||||
main.WarmupShaders();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewManager::TestGameView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
void ViewManager::TestGameView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||||
{
|
{
|
||||||
specter::View::resized(root, sub);
|
specter::View::resized(root, sub);
|
||||||
|
@ -48,7 +45,6 @@ void ViewManager::TestGameView::resized(const boo::SWindowRect& root, const boo:
|
||||||
|
|
||||||
void ViewManager::TestGameView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
void ViewManager::TestGameView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||||
{
|
{
|
||||||
gfxQ->clearTarget(true, true);
|
|
||||||
m_vm.m_projManager.mainDraw();
|
m_vm.m_projManager.mainDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,6 @@ class ViewManager : public specter::IViewManager
|
||||||
unsigned m_editorFrames = 120;
|
unsigned m_editorFrames = 120;
|
||||||
void FadeInEditors() {m_editorFrames = 0;}
|
void FadeInEditors() {m_editorFrames = 0;}
|
||||||
|
|
||||||
void BuildTestPART();
|
|
||||||
void InitMP1(MP1::CMain& main);
|
void InitMP1(MP1::CMain& main);
|
||||||
|
|
||||||
Space* m_deferSplit = nullptr;
|
Space* m_deferSplit = nullptr;
|
||||||
|
|
|
@ -28,7 +28,7 @@ void CMapArea::PostConstruct()
|
||||||
{
|
{
|
||||||
x38_moStart = x44_buf.get();
|
x38_moStart = x44_buf.get();
|
||||||
x3c_vertexStart = x38_moStart + (x28_mappableObjCount * 0x50);
|
x3c_vertexStart = x38_moStart + (x28_mappableObjCount * 0x50);
|
||||||
x40_surfaceStart = x40_surfaceStart + (x2c_vertexCount * 12);
|
x40_surfaceStart = x3c_vertexStart + (x2c_vertexCount * 12);
|
||||||
|
|
||||||
m_mappableObjects.reserve(x28_mappableObjCount);
|
m_mappableObjects.reserve(x28_mappableObjCount);
|
||||||
for (u32 i = 0, j=0 ; i<x28_mappableObjCount ; ++i, j += 0x50)
|
for (u32 i = 0, j=0 ; i<x28_mappableObjCount ; ++i, j += 0x50)
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace urde
|
||||||
CMapUniverse::CMapUniverse(CInputStream& in, u32 version)
|
CMapUniverse::CMapUniverse(CInputStream& in, u32 version)
|
||||||
: x0_hexagonId(in.readUint32Big())
|
: x0_hexagonId(in.readUint32Big())
|
||||||
{
|
{
|
||||||
x4_hexagonToken = g_SimplePool->GetObj({'MAPA', x0_hexagonId});
|
x4_hexagonToken = g_SimplePool->GetObj({FOURCC('MAPA'), x0_hexagonId});
|
||||||
u32 count = in.readUint32Big();
|
u32 count = in.readUint32Big();
|
||||||
x10_worldDatas.reserve(count);
|
x10_worldDatas.reserve(count);
|
||||||
for (u32 i = 0 ; i<count ; ++i)
|
for (u32 i = 0 ; i<count ; ++i)
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
void Lock() { x0_area.Lock(); }
|
void Lock() { x0_area.Lock(); }
|
||||||
void Unlock() { x0_area.Unlock(); }
|
void Unlock() { x0_area.Unlock(); }
|
||||||
bool IsLoaded() const { return x0_area.IsLoaded(); }
|
bool IsLoaded() const { return x0_area.IsLoaded(); }
|
||||||
const CMapArea* GetMapArea() const { return x0_area.IsLoaded() ? x0_area.GetObj() : nullptr; }
|
const CMapArea* GetMapArea() const { return x0_area.GetObj(); }
|
||||||
const CMapAreaData* GetNextMapAreaData() const { return x14_next; }
|
const CMapAreaData* GetNextMapAreaData() const { return x14_next; }
|
||||||
EMapAreaList GetContainingList() const { return x10_list; }
|
EMapAreaList GetContainingList() const { return x10_list; }
|
||||||
CMapAreaData* NextMapAreaData() { return x14_next; }
|
CMapAreaData* NextMapAreaData() { return x14_next; }
|
||||||
|
|
|
@ -127,6 +127,8 @@ IObj* CToken::GetObj()
|
||||||
}
|
}
|
||||||
CToken& CToken::operator=(const CToken& other)
|
CToken& CToken::operator=(const CToken& other)
|
||||||
{
|
{
|
||||||
|
Unlock();
|
||||||
|
RemoveRef();
|
||||||
x0_objRef = other.x0_objRef;
|
x0_objRef = other.x0_objRef;
|
||||||
if (x0_objRef)
|
if (x0_objRef)
|
||||||
{
|
{
|
||||||
|
|
|
@ -166,7 +166,7 @@ bool CAreaOctTree::Node::LineTestInternal(const zeus::CLine& line, const CMateri
|
||||||
float tf1 = lT;
|
float tf1 = lT;
|
||||||
float tf2 = hT;
|
float tf2 = hT;
|
||||||
if (BoxLineTest(child.GetBoundingBox(), line, tf1, tf2))
|
if (BoxLineTest(child.GetBoundingBox(), line, tf1, tf2))
|
||||||
if (!LineTestInternal(line, filter, tf1, tf2, maxT, vec))
|
if (!child.LineTestInternal(line, filter, tf1, tf2, maxT, vec))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -201,7 +201,7 @@ bool CAreaOctTree::Node::LineTestInternal(const zeus::CLine& line, const CMateri
|
||||||
{
|
{
|
||||||
Node child = GetChild(r26b);
|
Node child = GetChild(r26b);
|
||||||
if (child.x20_nodeType != ETreeType::Invalid)
|
if (child.x20_nodeType != ETreeType::Invalid)
|
||||||
if (!LineTestInternal(line, filter, f21, f22, maxT, vec))
|
if (!child.LineTestInternal(line, filter, f21, f22, maxT, vec))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (i < idx.first)
|
if (i < idx.first)
|
||||||
|
@ -306,7 +306,7 @@ void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMate
|
||||||
float tf1 = lT;
|
float tf1 = lT;
|
||||||
float tf2 = hT;
|
float tf2 = hT;
|
||||||
if (BoxLineTest(child.GetBoundingBox(), line, tf1, tf2))
|
if (BoxLineTest(child.GetBoundingBox(), line, tf1, tf2))
|
||||||
LineTestExInternal(line, filter, tmpRes[i], tf1, tf2, maxT, vec);
|
child.LineTestExInternal(line, filter, tmpRes[i], tf1, tf2, maxT, vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tmpRes[0].x10_surface && !tmpRes[1].x10_surface)
|
if (!tmpRes[0].x10_surface && !tmpRes[1].x10_surface)
|
||||||
|
@ -425,12 +425,12 @@ void CAreaOctTree::Node::LineTestExInternal(const zeus::CLine& line, const CMate
|
||||||
{
|
{
|
||||||
if (i >= 0)
|
if (i >= 0)
|
||||||
selector ^= 1 << r19[i];
|
selector ^= 1 << r19[i];
|
||||||
float hiT = (i < r17-1) ? hiT = r20[r19[i+1]] : hiT = hT;
|
float hiT = (i < r17-1) ? r20[r19[i+1]] : hT;
|
||||||
if (hiT > lowT && loT <= hiT)
|
if (hiT > lowT && loT <= hiT)
|
||||||
{
|
{
|
||||||
Node child = GetChild(selector);
|
Node child = GetChild(selector);
|
||||||
if (child.x20_nodeType != ETreeType::Invalid)
|
if (child.x20_nodeType != ETreeType::Invalid)
|
||||||
LineTestExInternal(line, filter, res, loT, hiT, maxT, vec);
|
child.LineTestExInternal(line, filter, res, loT, hiT, maxT, vec);
|
||||||
if (res.x10_surface)
|
if (res.x10_surface)
|
||||||
if (res.x3c_t > highT)
|
if (res.x3c_t > highT)
|
||||||
res = SRayResult();
|
res = SRayResult();
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "RetroTypes.hpp"
|
#include "RetroTypes.hpp"
|
||||||
#include "zeus/CTransform.hpp"
|
#include "zeus/CTransform.hpp"
|
||||||
#include "zeus/CAABox.hpp"
|
#include "zeus/CAABox.hpp"
|
||||||
|
#include "hecl/Runtime.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -21,9 +22,21 @@ class CMetroidModelInstance
|
||||||
zeus::CAABox x34_aabb;
|
zeus::CAABox x34_aabb;
|
||||||
std::vector<CBooSurface> m_surfaces;
|
std::vector<CBooSurface> m_surfaces;
|
||||||
std::unique_ptr<CBooModel> m_instance;
|
std::unique_ptr<CBooModel> m_instance;
|
||||||
|
hecl::HMDLMeta m_hmdlMeta;
|
||||||
|
std::vector<std::shared_ptr<hecl::Runtime::ShaderPipelines>> m_shaders;
|
||||||
public:
|
public:
|
||||||
CMetroidModelInstance() = default;
|
CMetroidModelInstance() = default;
|
||||||
CMetroidModelInstance(CMetroidModelInstance&&) = default;
|
CMetroidModelInstance(CMetroidModelInstance&&) = default;
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
x0_visorFlags = 0;
|
||||||
|
x4_xf = {};
|
||||||
|
x34_aabb = {};
|
||||||
|
m_surfaces.clear();
|
||||||
|
m_instance.reset();
|
||||||
|
m_hmdlMeta = {};
|
||||||
|
m_shaders.clear();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,11 @@ public:
|
||||||
int m_matSetIdx;
|
int m_matSetIdx;
|
||||||
SShader(int idx) : m_matSetIdx(idx) {}
|
SShader(int idx) : m_matSetIdx(idx) {}
|
||||||
void UnlockTextures();
|
void UnlockTextures();
|
||||||
|
std::shared_ptr<hecl::Runtime::ShaderPipelines>
|
||||||
|
BuildShader(const hecl::HMDLMeta& meta, const MaterialSet::Material& mat);
|
||||||
|
void BuildShaders(const hecl::HMDLMeta& meta,
|
||||||
|
std::vector<std::shared_ptr<hecl::Runtime::ShaderPipelines>>& shaders);
|
||||||
|
void BuildShaders(const hecl::HMDLMeta& meta) { BuildShaders(meta, m_shaders); }
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ESurfaceSelection
|
enum class ESurfaceSelection
|
||||||
|
@ -101,7 +106,8 @@ private:
|
||||||
CBooModel* m_next = nullptr;
|
CBooModel* m_next = nullptr;
|
||||||
CBooModel* m_prev = nullptr;
|
CBooModel* m_prev = nullptr;
|
||||||
size_t m_uniUpdateCount = 0;
|
size_t m_uniUpdateCount = 0;
|
||||||
TLockedToken<CModel> m_model;
|
TToken<CModel> m_modelTok;
|
||||||
|
CModel* m_model;
|
||||||
std::vector<CBooSurface>* x0_surfaces;
|
std::vector<CBooSurface>* x0_surfaces;
|
||||||
const MaterialSet* x4_matSet;
|
const MaterialSet* x4_matSet;
|
||||||
int m_matSetIdx = -1;
|
int m_matSetIdx = -1;
|
||||||
|
@ -161,9 +167,11 @@ private:
|
||||||
static float g_TransformedTime2;
|
static float g_TransformedTime2;
|
||||||
static CBooModel* g_LastModelCached;
|
static CBooModel* g_LastModelCached;
|
||||||
|
|
||||||
|
static bool g_DummyTextures;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~CBooModel();
|
~CBooModel();
|
||||||
CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
|
CBooModel(TToken<CModel>& token, CModel* parent, std::vector<CBooSurface>* surfaces, SShader& shader,
|
||||||
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
|
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
|
||||||
const zeus::CAABox& aabb, u8 renderMask,
|
const zeus::CAABox& aabb, u8 renderMask,
|
||||||
int numInsts, boo::ITexture* txtrOverrides[8]);
|
int numInsts, boo::ITexture* txtrOverrides[8]);
|
||||||
|
@ -178,6 +186,8 @@ public:
|
||||||
void ActivateLights(const std::vector<CLight>& lights);
|
void ActivateLights(const std::vector<CLight>& lights);
|
||||||
void DisableAllLights();
|
void DisableAllLights();
|
||||||
void RemapMaterialData(SShader& shader);
|
void RemapMaterialData(SShader& shader);
|
||||||
|
void RemapMaterialData(SShader& shader,
|
||||||
|
const std::vector<std::shared_ptr<hecl::Runtime::ShaderPipelines>>& pipelines);
|
||||||
bool TryLockTextures() const;
|
bool TryLockTextures() const;
|
||||||
void UnlockTextures() const;
|
void UnlockTextures() const;
|
||||||
void SyncLoadTextures() const;
|
void SyncLoadTextures() const;
|
||||||
|
@ -197,6 +207,9 @@ public:
|
||||||
const CPoseAsTransforms* pose) const;
|
const CPoseAsTransforms* pose) const;
|
||||||
void DrawFlat(ESurfaceSelection sel, EExtendedShader extendedIdx) const;
|
void DrawFlat(ESurfaceSelection sel, EExtendedShader extendedIdx) const;
|
||||||
|
|
||||||
|
void LockParent() { m_modelTok.Lock(); }
|
||||||
|
void UnlockParent() { m_modelTok.Unlock(); }
|
||||||
|
|
||||||
|
|
||||||
const MaterialSet::Material& GetMaterialByIndex(int idx) const
|
const MaterialSet::Material& GetMaterialByIndex(int idx) const
|
||||||
{
|
{
|
||||||
|
@ -220,6 +233,8 @@ public:
|
||||||
static zeus::CTransform g_shadowTexXf;
|
static zeus::CTransform g_shadowTexXf;
|
||||||
static void EnableShadowMaps(boo::ITexture* map, const zeus::CTransform& texXf);
|
static void EnableShadowMaps(boo::ITexture* map, const zeus::CTransform& texXf);
|
||||||
static void DisableShadowMaps();
|
static void DisableShadowMaps();
|
||||||
|
|
||||||
|
static void SetDummyTextures(bool b) { g_DummyTextures = true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CModel
|
class CModel
|
||||||
|
@ -258,7 +273,9 @@ public:
|
||||||
const zeus::CAABox& GetAABB() const {return m_aabb;}
|
const zeus::CAABox& GetAABB() const {return m_aabb;}
|
||||||
CBooModel& GetInstance() {return *x28_modelInst;}
|
CBooModel& GetInstance() {return *x28_modelInst;}
|
||||||
const CBooModel& GetInstance() const {return *x28_modelInst;}
|
const CBooModel& GetInstance() const {return *x28_modelInst;}
|
||||||
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts, boo::ITexture* txtrOverrides[8] = nullptr);
|
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts,
|
||||||
|
boo::ITexture* txtrOverrides[8] = nullptr,
|
||||||
|
bool lockParent = true);
|
||||||
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
|
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
|
||||||
|
|
||||||
size_t GetPoolVertexOffset(size_t idx) const;
|
size_t GetPoolVertexOffset(size_t idx) const;
|
||||||
|
|
|
@ -46,6 +46,8 @@ void CBooModel::KillCachedViewDepState()
|
||||||
g_LastModelCached = nullptr;
|
g_LastModelCached = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CBooModel::g_DummyTextures = false;
|
||||||
|
|
||||||
zeus::CVector3f CBooModel::g_ReflectViewPos = {};
|
zeus::CVector3f CBooModel::g_ReflectViewPos = {};
|
||||||
|
|
||||||
static const zeus::CMatrix4f ReflectBaseMtx =
|
static const zeus::CMatrix4f ReflectBaseMtx =
|
||||||
|
@ -146,13 +148,13 @@ CBooModel::~CBooModel()
|
||||||
g_FirstModel = m_next;
|
g_FirstModel = m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBooModel::CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
|
CBooModel::CBooModel(TToken<CModel>& token, CModel* parent, std::vector<CBooSurface>* surfaces, SShader& shader,
|
||||||
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
|
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
|
||||||
const zeus::CAABox& aabb, u8 renderMask,
|
const zeus::CAABox& aabb, u8 renderMask,
|
||||||
int numInsts, boo::ITexture* txtrOverrides[8])
|
int numInsts, boo::ITexture* txtrOverrides[8])
|
||||||
: m_model(token), x0_surfaces(surfaces), x4_matSet(&shader.m_matSet), m_matSetIdx(shader.m_matSetIdx),
|
: m_modelTok(token), m_model(parent), x0_surfaces(surfaces), x4_matSet(&shader.m_matSet),
|
||||||
m_pipelines(&shader.m_shaders), x1c_textures(shader.x0_textures), x20_aabb(aabb),
|
m_matSetIdx(shader.m_matSetIdx), m_pipelines(&shader.m_shaders), x1c_textures(shader.x0_textures),
|
||||||
x40_24_texturesLoaded(false), x40_25_modelVisible(0), x41_mask(renderMask),
|
x20_aabb(aabb), x40_24_texturesLoaded(false), x40_25_modelVisible(0), x41_mask(renderMask),
|
||||||
m_staticVtxFmt(vtxFmt), m_staticVbo(vbo), m_staticIbo(ibo)
|
m_staticVtxFmt(vtxFmt), m_staticVbo(vbo), m_staticIbo(ibo)
|
||||||
{
|
{
|
||||||
if (txtrOverrides)
|
if (txtrOverrides)
|
||||||
|
@ -224,7 +226,7 @@ boo::IVertexFormat* CBooModel::ModelInstance::GetBooVtxFmt(const CBooModel& mode
|
||||||
|
|
||||||
CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
{
|
{
|
||||||
if (!x40_24_texturesLoaded)
|
if (!x40_24_texturesLoaded && !g_DummyTextures)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (m_instances.size() >= 256)
|
if (m_instances.size() >= 256)
|
||||||
|
@ -233,7 +235,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
ModelInstance& newInst = m_instances.back();
|
ModelInstance& newInst = m_instances.back();
|
||||||
size_t skinBankCount = 0;
|
size_t skinBankCount = 0;
|
||||||
size_t weightVecCount = 0;
|
size_t weightVecCount = 0;
|
||||||
if (const CModel* model = m_model.GetObj())
|
if (const CModel* model = m_model)
|
||||||
{
|
{
|
||||||
skinBankCount = model->m_hmdlMeta.bankCount;
|
skinBankCount = model->m_hmdlMeta.bankCount;
|
||||||
weightVecCount = model->m_hmdlMeta.weightCount;
|
weightVecCount = model->m_hmdlMeta.weightCount;
|
||||||
|
@ -276,6 +278,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Animated UV transform matrices */
|
/* Animated UV transform matrices */
|
||||||
|
size_t matCount = x4_matSet->materials.size();
|
||||||
for (const MaterialSet::Material& mat : x4_matSet->materials)
|
for (const MaterialSet::Material& mat : x4_matSet->materials)
|
||||||
{
|
{
|
||||||
size_t thisSz = ROUND_UP_256(/*mat.uvAnims.size()*/ 8 * (sizeof(zeus::CMatrix4f) * 2));
|
size_t thisSz = ROUND_UP_256(/*mat.uvAnims.size()*/ 8 * (sizeof(zeus::CMatrix4f) * 2));
|
||||||
|
@ -341,6 +344,10 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
{
|
{
|
||||||
texs[texCount++] = overtex;
|
texs[texCount++] = overtex;
|
||||||
}
|
}
|
||||||
|
else if (g_DummyTextures)
|
||||||
|
{
|
||||||
|
texs[texCount++] = g_Renderer->x220_sphereRamp;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TCachedToken<CTexture>& tex = x1c_textures[idx];
|
TCachedToken<CTexture>& tex = x1c_textures[idx];
|
||||||
|
@ -472,6 +479,17 @@ void CBooModel::RemapMaterialData(SShader& shader)
|
||||||
m_instances.clear();
|
m_instances.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBooModel::RemapMaterialData(SShader& shader,
|
||||||
|
const std::vector<std::shared_ptr<hecl::Runtime::ShaderPipelines>>& pipelines)
|
||||||
|
{
|
||||||
|
x4_matSet = &shader.m_matSet;
|
||||||
|
m_matSetIdx = shader.m_matSetIdx;
|
||||||
|
x1c_textures = shader.x0_textures;
|
||||||
|
m_pipelines = &pipelines;
|
||||||
|
x40_24_texturesLoaded = false;
|
||||||
|
m_instances.clear();
|
||||||
|
}
|
||||||
|
|
||||||
bool CBooModel::TryLockTextures() const
|
bool CBooModel::TryLockTextures() const
|
||||||
{
|
{
|
||||||
if (!x40_24_texturesLoaded)
|
if (!x40_24_texturesLoaded)
|
||||||
|
@ -614,15 +632,12 @@ void CBooModel::WarmupDrawSurface(const CBooSurface& surf) const
|
||||||
return;
|
return;
|
||||||
const ModelInstance& inst = m_instances[m_uniUpdateCount-1];
|
const ModelInstance& inst = m_instances[m_uniUpdateCount-1];
|
||||||
|
|
||||||
for (const std::vector<boo::IShaderDataBinding*>& extendeds : inst.m_shaderDataBindings)
|
for (boo::IShaderDataBinding* binding : inst.m_shaderDataBindings[surf.selfIdx])
|
||||||
{
|
|
||||||
for (boo::IShaderDataBinding* binding : extendeds)
|
|
||||||
{
|
{
|
||||||
CGraphics::SetShaderDataBinding(binding);
|
CGraphics::SetShaderDataBinding(binding);
|
||||||
CGraphics::DrawArrayIndexed(surf.m_data.idxStart, std::min(u32(3), surf.m_data.idxCount));
|
CGraphics::DrawArrayIndexed(surf.m_data.idxStart, std::min(u32(3), surf.m_data.idxCount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimation& anim)
|
void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimation& anim)
|
||||||
{
|
{
|
||||||
|
@ -816,7 +831,7 @@ boo::IGraphicsBufferD* CBooModel::UpdateUniformData(const CModelFlags& flags,
|
||||||
{
|
{
|
||||||
size_t skinBankCount = 0;
|
size_t skinBankCount = 0;
|
||||||
size_t weightVecCount = 0;
|
size_t weightVecCount = 0;
|
||||||
if (const CModel* model = m_model.GetObj())
|
if (const CModel* model = m_model)
|
||||||
{
|
{
|
||||||
skinBankCount = model->m_hmdlMeta.bankCount;
|
skinBankCount = model->m_hmdlMeta.bankCount;
|
||||||
weightVecCount = model->m_hmdlMeta.weightCount;
|
weightVecCount = model->m_hmdlMeta.weightCount;
|
||||||
|
@ -1024,13 +1039,44 @@ static const u8* MemoryFromPartData(const u8*& dataCur, const u32*& secSizeCur)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx, int subInsts, boo::ITexture* txtrOverrides[8])
|
std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx, int subInsts,
|
||||||
|
boo::ITexture* txtrOverrides[8],
|
||||||
|
bool lockParent)
|
||||||
{
|
{
|
||||||
if (shaderIdx >= x18_matSets.size())
|
if (shaderIdx >= x18_matSets.size())
|
||||||
shaderIdx = 0;
|
shaderIdx = 0;
|
||||||
return std::make_unique<CBooModel>(m_selfToken, &x8_surfaces, x18_matSets[shaderIdx],
|
auto ret = std::make_unique<CBooModel>(m_selfToken, this, &x8_surfaces, x18_matSets[shaderIdx],
|
||||||
m_staticVtxFmt, m_staticVbo, m_ibo,
|
m_staticVtxFmt, m_staticVbo, m_ibo,
|
||||||
m_aabb, (m_flags & 0x2) != 0, subInsts, txtrOverrides);
|
m_aabb, (m_flags & 0x2) != 0, subInsts, txtrOverrides);
|
||||||
|
if (lockParent)
|
||||||
|
ret->LockParent();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<hecl::Runtime::ShaderPipelines>
|
||||||
|
CBooModel::SShader::BuildShader(const hecl::HMDLMeta& meta, const MaterialSet::Material& mat)
|
||||||
|
{
|
||||||
|
hecl::Backend::ReflectionType reflectionType;
|
||||||
|
if (mat.flags.samusReflectionIndirectTexture())
|
||||||
|
reflectionType = hecl::Backend::ReflectionType::Indirect;
|
||||||
|
else if (mat.flags.samusReflection())
|
||||||
|
reflectionType = hecl::Backend::ReflectionType::Simple;
|
||||||
|
else
|
||||||
|
reflectionType = hecl::Backend::ReflectionType::None;
|
||||||
|
hecl::Runtime::ShaderTag tag(mat.heclIr,
|
||||||
|
meta.colorCount, meta.uvCount, meta.weightCount,
|
||||||
|
meta.weightCount * 4, 8, boo::Primitive(meta.topology),
|
||||||
|
reflectionType, true, true, true);
|
||||||
|
return CModelShaders::g_ModelShaders->buildExtendedShader
|
||||||
|
(tag, mat.heclIr, "CMDL", *CGraphics::g_BooFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBooModel::SShader::BuildShaders(const hecl::HMDLMeta& meta,
|
||||||
|
std::vector<std::shared_ptr<hecl::Runtime::ShaderPipelines>>& shaders)
|
||||||
|
{
|
||||||
|
shaders.reserve(m_matSet.materials.size());
|
||||||
|
for (const MaterialSet::Material& mat : m_matSet.materials)
|
||||||
|
shaders.push_back(BuildShader(meta, mat));
|
||||||
}
|
}
|
||||||
|
|
||||||
CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* store, CObjectReference* selfRef)
|
CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* store, CObjectReference* selfRef)
|
||||||
|
@ -1072,25 +1118,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
|
||||||
const u8* surfInfo = MemoryFromPartData(dataCur, secSizeCur);
|
const u8* surfInfo = MemoryFromPartData(dataCur, secSizeCur);
|
||||||
|
|
||||||
for (CBooModel::SShader& matSet : x18_matSets)
|
for (CBooModel::SShader& matSet : x18_matSets)
|
||||||
{
|
matSet.BuildShaders(m_hmdlMeta);
|
||||||
matSet.m_shaders.reserve(matSet.m_matSet.materials.size());
|
|
||||||
for (const MaterialSet::Material& mat : matSet.m_matSet.materials)
|
|
||||||
{
|
|
||||||
hecl::Backend::ReflectionType reflectionType;
|
|
||||||
if (mat.flags.samusReflectionIndirectTexture())
|
|
||||||
reflectionType = hecl::Backend::ReflectionType::Indirect;
|
|
||||||
else if (mat.flags.samusReflection())
|
|
||||||
reflectionType = hecl::Backend::ReflectionType::Simple;
|
|
||||||
else
|
|
||||||
reflectionType = hecl::Backend::ReflectionType::None;
|
|
||||||
hecl::Runtime::ShaderTag tag(mat.heclIr,
|
|
||||||
m_hmdlMeta.colorCount, m_hmdlMeta.uvCount, m_hmdlMeta.weightCount,
|
|
||||||
m_hmdlMeta.weightCount * 4, 8, boo::Primitive(m_hmdlMeta.topology),
|
|
||||||
reflectionType, true, true, true);
|
|
||||||
matSet.m_shaders.push_back(CModelShaders::g_ModelShaders->buildExtendedShader
|
|
||||||
(tag, mat.heclIr, "CMDL", *CGraphics::g_BooFactory));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
|
@ -1131,7 +1159,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
|
||||||
const float* aabbPtr = reinterpret_cast<const float*>(data.get() + 0xc);
|
const float* aabbPtr = reinterpret_cast<const float*>(data.get() + 0xc);
|
||||||
m_aabb = zeus::CAABox(hecl::SBig(aabbPtr[0]), hecl::SBig(aabbPtr[1]), hecl::SBig(aabbPtr[2]),
|
m_aabb = zeus::CAABox(hecl::SBig(aabbPtr[0]), hecl::SBig(aabbPtr[1]), hecl::SBig(aabbPtr[2]),
|
||||||
hecl::SBig(aabbPtr[3]), hecl::SBig(aabbPtr[4]), hecl::SBig(aabbPtr[5]));
|
hecl::SBig(aabbPtr[3]), hecl::SBig(aabbPtr[4]), hecl::SBig(aabbPtr[5]));
|
||||||
x28_modelInst = MakeNewInstance(0, 1);
|
x28_modelInst = MakeNewInstance(0, 1, nullptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::SShader::UnlockTextures()
|
void CBooModel::SShader::UnlockTextures()
|
||||||
|
@ -1228,6 +1256,7 @@ void CModel::ApplyVerticesCPU(boo::IGraphicsBufferD* vertBuf,
|
||||||
|
|
||||||
void CModel::_WarmupShaders()
|
void CModel::_WarmupShaders()
|
||||||
{
|
{
|
||||||
|
CBooModel::SetDummyTextures(true);
|
||||||
CBooModel::EnableShadowMaps(g_Renderer->x220_sphereRamp, zeus::CTransform::Identity());
|
CBooModel::EnableShadowMaps(g_Renderer->x220_sphereRamp, zeus::CTransform::Identity());
|
||||||
CGraphics::CProjectionState backupProj = CGraphics::GetProjectionState();
|
CGraphics::CProjectionState backupProj = CGraphics::GetProjectionState();
|
||||||
zeus::CTransform backupViewPoint = CGraphics::g_ViewMatrix;
|
zeus::CTransform backupViewPoint = CGraphics::g_ViewMatrix;
|
||||||
|
@ -1239,7 +1268,6 @@ void CModel::_WarmupShaders()
|
||||||
for (CBooModel::SShader& shader : x18_matSets)
|
for (CBooModel::SShader& shader : x18_matSets)
|
||||||
{
|
{
|
||||||
GetInstance().RemapMaterialData(shader);
|
GetInstance().RemapMaterialData(shader);
|
||||||
GetInstance().SyncLoadTextures();
|
|
||||||
GetInstance().UpdateUniformData(defaultFlags, nullptr, nullptr);
|
GetInstance().UpdateUniformData(defaultFlags, nullptr, nullptr);
|
||||||
GetInstance().WarmupDrawSurfaces();
|
GetInstance().WarmupDrawSurfaces();
|
||||||
}
|
}
|
||||||
|
@ -1247,6 +1275,7 @@ void CModel::_WarmupShaders()
|
||||||
CGraphics::SetViewPointMatrix(backupViewPoint);
|
CGraphics::SetViewPointMatrix(backupViewPoint);
|
||||||
CGraphics::SetModelMatrix(backupModel);
|
CGraphics::SetModelMatrix(backupModel);
|
||||||
CBooModel::DisableShadowMaps();
|
CBooModel::DisableShadowMaps();
|
||||||
|
CBooModel::SetDummyTextures(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel::WarmupShaders(const SObjectTag& cmdlTag)
|
void CModel::WarmupShaders(const SObjectTag& cmdlTag)
|
||||||
|
|
|
@ -28,7 +28,7 @@ static const char* VS =
|
||||||
"{\n"
|
"{\n"
|
||||||
" VertToFrag vtf;\n"
|
" VertToFrag vtf;\n"
|
||||||
" vtf.color = bu.color;\n"
|
" vtf.color = bu.color;\n"
|
||||||
" vtf.pos = bu.xf * vec4(v.posIn.xyz, 1.0);\n"
|
" vtf.pos = bu.xf * float4(v.posIn.xyz, 1.0);\n"
|
||||||
" return vtf;\n"
|
" return vtf;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ class CModelShaders
|
||||||
{
|
{
|
||||||
friend class CModel;
|
friend class CModel;
|
||||||
hecl::Runtime::ShaderCacheManager m_shaderCache;
|
hecl::Runtime::ShaderCacheManager m_shaderCache;
|
||||||
static std::experimental::optional<CModelShaders> g_ModelShaders;
|
|
||||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensions(boo::IGraphicsDataFactory::Platform plat);
|
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensions(boo::IGraphicsDataFactory::Platform plat);
|
||||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat);
|
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat);
|
||||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat);
|
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat);
|
||||||
|
@ -42,6 +41,8 @@ class CModelShaders
|
||||||
static const hecl::Backend::TextureInfo BallFadeTextures[];
|
static const hecl::Backend::TextureInfo BallFadeTextures[];
|
||||||
static const hecl::Backend::TextureInfo WorldShadowTextures[];
|
static const hecl::Backend::TextureInfo WorldShadowTextures[];
|
||||||
public:
|
public:
|
||||||
|
static std::experimental::optional<CModelShaders> g_ModelShaders;
|
||||||
|
|
||||||
struct Light
|
struct Light
|
||||||
{
|
{
|
||||||
zeus::CVector3f pos;
|
zeus::CVector3f pos;
|
||||||
|
|
|
@ -248,15 +248,7 @@ CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat)
|
||||||
hecl::Backend::BlendFactor::SrcAlpha,
|
hecl::Backend::BlendFactor::SrcAlpha,
|
||||||
hecl::Backend::BlendFactor::InvSrcAlpha,
|
hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::ZTest::Equal,
|
hecl::Backend::ZTest::Equal,
|
||||||
false, false, false, true);
|
false, false, false, true, true);
|
||||||
|
|
||||||
/* MorphBall shadow shading */
|
|
||||||
ext.registerExtensionSlot({}, {MBShadowPostGLSL, "MBShadowPostFunc"},
|
|
||||||
3, MBShadowBlockNames, 3, BallFadeTextures,
|
|
||||||
hecl::Backend::BlendFactor::SrcAlpha,
|
|
||||||
hecl::Backend::BlendFactor::InvSrcAlpha,
|
|
||||||
hecl::Backend::ZTest::Equal,
|
|
||||||
false, false, false, true);
|
|
||||||
|
|
||||||
/* World shadow shading (modified lighting) */
|
/* World shadow shading (modified lighting) */
|
||||||
ext.registerExtensionSlot({LightingShadowGLSL, "LightingShadowFunc"}, {MainPostGLSL, "MainPostFunc"},
|
ext.registerExtensionSlot({LightingShadowGLSL, "LightingShadowFunc"}, {MainPostGLSL, "MainPostFunc"},
|
||||||
|
|
|
@ -231,7 +231,7 @@ CModelShaders::GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat)
|
||||||
hecl::Backend::BlendFactor::SrcAlpha,
|
hecl::Backend::BlendFactor::SrcAlpha,
|
||||||
hecl::Backend::BlendFactor::InvSrcAlpha,
|
hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::ZTest::Equal,
|
hecl::Backend::ZTest::Equal,
|
||||||
false, false, false, true);
|
false, false, false, true, true);
|
||||||
|
|
||||||
/* World shadow shading (modified lighting) */
|
/* World shadow shading (modified lighting) */
|
||||||
ext.registerExtensionSlot({LightingShadowHLSL, "LightingShadowFunc"}, {MainPostHLSL, "MainPostFunc"},
|
ext.registerExtensionSlot({LightingShadowHLSL, "LightingShadowFunc"}, {MainPostHLSL, "MainPostFunc"},
|
||||||
|
|
|
@ -126,7 +126,7 @@ static const char* ThermalPostMetal =
|
||||||
" float4 tmulColor;\n"
|
" float4 tmulColor;\n"
|
||||||
" float4 addColor;\n"
|
" float4 addColor;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"static float4 ThermalPostFunc(thread VertToFrag& vtf, constant ThermalUniform& lu, texture2d<float> extTex7, float4 colorIn)\n"
|
"static float4 EXTThermalPostFunc(thread VertToFrag& vtf, constant ThermalUniform& lu, texture2d<float> extTex7, float4 colorIn)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return float4(extTex7.sample(samp, vtf.extTcgs0).rrr * lu.tmulColor.rgb + lu.addColor.rgb, 1.0);\n"
|
" return float4(extTex7.sample(samp, vtf.extTcgs0).rrr * lu.tmulColor.rgb + lu.addColor.rgb, 1.0);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
@ -149,7 +149,7 @@ static const char* MBShadowPostMetal =
|
||||||
" float4 shadowUp;\n"
|
" float4 shadowUp;\n"
|
||||||
" float shadowId;\n"
|
" float shadowId;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"static float4 MBShadowPostFunc(thread VertToFrag& vtf, constant MBShadowUniform& su,\n"
|
"static float4 EXTMBShadowPostFunc(thread VertToFrag& vtf, constant MBShadowUniform& su,\n"
|
||||||
" texture2d<float> extTex0, texture2d<float> extTex1, texture2d<float> extTex2, float4 colorIn)\n"
|
" texture2d<float> extTex0, texture2d<float> extTex1, texture2d<float> extTex2, float4 colorIn)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float idTexel = extTex0.sample(samp, vtf.extTcgs0).a;\n"
|
" float idTexel = extTex0.sample(samp, vtf.extTcgs0).a;\n"
|
||||||
|
@ -179,7 +179,7 @@ CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat
|
||||||
false, false, false, true);
|
false, false, false, true);
|
||||||
|
|
||||||
/* Thermal Visor shading */
|
/* Thermal Visor shading */
|
||||||
ext.registerExtensionSlot({}, {ThermalPostMetal, "ThermalPostFunc"}, 1, ThermalBlockNames,
|
ext.registerExtensionSlot({}, {ThermalPostMetal, "EXTThermalPostFunc"}, 1, ThermalBlockNames,
|
||||||
1, ThermalTextures, hecl::Backend::BlendFactor::One,
|
1, ThermalTextures, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
|
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
|
||||||
false, false, false, true);
|
false, false, false, true);
|
||||||
|
@ -233,12 +233,12 @@ CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat
|
||||||
false, true, true, false);
|
false, true, true, false);
|
||||||
|
|
||||||
/* MorphBall shadow shading */
|
/* MorphBall shadow shading */
|
||||||
ext.registerExtensionSlot({}, {MBShadowPostMetal, "MBShadowPostFunc"},
|
ext.registerExtensionSlot({}, {MBShadowPostMetal, "EXTMBShadowPostFunc"},
|
||||||
1, MBShadowBlockNames, 3, BallFadeTextures,
|
1, MBShadowBlockNames, 3, BallFadeTextures,
|
||||||
hecl::Backend::BlendFactor::SrcAlpha,
|
hecl::Backend::BlendFactor::SrcAlpha,
|
||||||
hecl::Backend::BlendFactor::InvSrcAlpha,
|
hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::ZTest::Equal,
|
hecl::Backend::ZTest::Equal,
|
||||||
false, false, false, true);
|
false, false, false, true, true);
|
||||||
|
|
||||||
/* World shadow shading (modified lighting) */
|
/* World shadow shading (modified lighting) */
|
||||||
ext.registerExtensionSlot({LightingShadowMetal, "EXTLightingShadowFunc"}, {MainPostMetal, "MainPostFunc"},
|
ext.registerExtensionSlot({LightingShadowMetal, "EXTLightingShadowFunc"}, {MainPostMetal, "MainPostFunc"},
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct OGLParticleSwooshDataBindingFactory : TShader<CParticleSwooshShaders>::ID
|
||||||
CSwooshDescription* desc = gen.GetDesc();
|
CSwooshDescription* desc = gen.GetDesc();
|
||||||
|
|
||||||
CUVElement* texr = desc->x3c_TEXR.get();
|
CUVElement* texr = desc->x3c_TEXR.get();
|
||||||
boo::ITexture* textures[] = {texr->GetValueTexture(0).GetObj()->GetBooTexture()};
|
boo::ITexture* textures[] = {texr ? texr->GetValueTexture(0).GetObj()->GetBooTexture() : nullptr};
|
||||||
|
|
||||||
const boo::VertexElementDescriptor VtxFmt[] =
|
const boo::VertexElementDescriptor VtxFmt[] =
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,7 +71,7 @@ struct D3DParticleSwooshDataBindingFactory : TShader<CParticleSwooshShaders>::ID
|
||||||
CSwooshDescription* desc = gen.GetDesc();
|
CSwooshDescription* desc = gen.GetDesc();
|
||||||
|
|
||||||
CUVElement* texr = desc->x3c_TEXR.get();
|
CUVElement* texr = desc->x3c_TEXR.get();
|
||||||
boo::ITexture* textures[] = {texr->GetValueTexture(0).GetObj()->GetBooTexture()};
|
boo::ITexture* textures[] = {texr ? texr->GetValueTexture(0).GetObj()->GetBooTexture() : nullptr};
|
||||||
|
|
||||||
boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf};
|
boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf};
|
||||||
gen.m_dataBind = ctx.newShaderDataBinding(shaders.m_pipeline, CParticleSwooshShaders::m_vtxFormat,
|
gen.m_dataBind = ctx.newShaderDataBinding(shaders.m_pipeline, CParticleSwooshShaders::m_vtxFormat,
|
||||||
|
|
|
@ -77,7 +77,7 @@ struct MetalParticleSwooshDataBindingFactory : TShader<CParticleSwooshShaders>::
|
||||||
CSwooshDescription* desc = gen.GetDesc();
|
CSwooshDescription* desc = gen.GetDesc();
|
||||||
|
|
||||||
CUVElement* texr = desc->x3c_TEXR.get();
|
CUVElement* texr = desc->x3c_TEXR.get();
|
||||||
boo::ITexture* textures[] = {texr->GetValueTexture(0).GetObj()->GetBooTexture()};
|
boo::ITexture* textures[] = {texr ? texr->GetValueTexture(0).GetObj()->GetBooTexture() : nullptr};
|
||||||
|
|
||||||
boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf};
|
boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf};
|
||||||
gen.m_dataBind = ctx.newShaderDataBinding(shaders.m_pipeline, CParticleSwooshShaders::m_vtxFormat,
|
gen.m_dataBind = ctx.newShaderDataBinding(shaders.m_pipeline, CParticleSwooshShaders::m_vtxFormat,
|
||||||
|
|
|
@ -116,9 +116,9 @@ static const char* BlurVS =
|
||||||
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant PhazonSuitBlurUniform& psu [[ buffer(2) ]])\n"
|
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant PhazonSuitBlurUniform& psu [[ buffer(2) ]])\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" VertToFrag vtf;\n"
|
" VertToFrag vtf;\n"
|
||||||
" vtf.uv = uvIn.xy;\n"
|
" vtf.uv = v.uvIn.xy;\n"
|
||||||
" vtf.blurDir = blurDir.xy;\n"
|
" vtf.blurDir = psu.blurDir.xy;\n"
|
||||||
" vtf.position = float4(posIn.xyz, 1.0);\n"
|
" vtf.position = float4(v.posIn.xyz, 1.0);\n"
|
||||||
" return vtf;\n"
|
" return vtf;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
|
|
@ -270,6 +270,21 @@ void CMain::InitializeSubsystems(const hecl::Runtime::FileStoreManager& storeMgr
|
||||||
CGBASupport::Initialize();
|
CGBASupport::Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMain::MemoryCardInitializePump()
|
||||||
|
{
|
||||||
|
if (!g_MemoryCardSys)
|
||||||
|
{
|
||||||
|
std::unique_ptr<CMemoryCardSys>& memSys = x128_globalObjects.x0_memoryCardSys;
|
||||||
|
if (!memSys)
|
||||||
|
memSys.reset(new CMemoryCardSys());
|
||||||
|
if (memSys->InitializePump())
|
||||||
|
{
|
||||||
|
g_MemoryCardSys = memSys.get();
|
||||||
|
g_GameState->InitializeMemoryStates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CMain::FillInAssetIDs()
|
void CMain::FillInAssetIDs()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -326,6 +341,7 @@ void CMain::WarmupShaders()
|
||||||
if (m_warmupTags.size())
|
if (m_warmupTags.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_needsWarmupClear = true;
|
||||||
size_t modelCount = 0;
|
size_t modelCount = 0;
|
||||||
g_ResFactory->EnumerateResources([&](const SObjectTag& tag)
|
g_ResFactory->EnumerateResources([&](const SObjectTag& tag)
|
||||||
{
|
{
|
||||||
|
@ -376,6 +392,11 @@ void CMain::Draw()
|
||||||
// Warmup cycle overrides draw
|
// Warmup cycle overrides draw
|
||||||
if (m_warmupTags.size())
|
if (m_warmupTags.size())
|
||||||
{
|
{
|
||||||
|
if (m_needsWarmupClear)
|
||||||
|
{
|
||||||
|
CGraphics::g_BooMainCommandQueue->clearTarget(true, true);
|
||||||
|
m_needsWarmupClear = false;
|
||||||
|
}
|
||||||
auto startTime = std::chrono::steady_clock::now();
|
auto startTime = std::chrono::steady_clock::now();
|
||||||
while (m_warmupIt != m_warmupTags.end())
|
while (m_warmupIt != m_warmupTags.end())
|
||||||
{
|
{
|
||||||
|
@ -400,6 +421,7 @@ void CMain::Draw()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGraphics::g_BooMainCommandQueue->clearTarget(true, true);
|
||||||
x164_archSupport->Draw();
|
x164_archSupport->Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -243,6 +243,7 @@ private:
|
||||||
// Warmup state
|
// Warmup state
|
||||||
std::vector<SObjectTag> m_warmupTags;
|
std::vector<SObjectTag> m_warmupTags;
|
||||||
std::vector<SObjectTag>::iterator m_warmupIt;
|
std::vector<SObjectTag>::iterator m_warmupIt;
|
||||||
|
bool m_needsWarmupClear = false;
|
||||||
|
|
||||||
void InitializeSubsystems(const hecl::Runtime::FileStoreManager& storeMgr);
|
void InitializeSubsystems(const hecl::Runtime::FileStoreManager& storeMgr);
|
||||||
|
|
||||||
|
@ -269,20 +270,7 @@ public:
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
boo::IWindow* GetMainWindow() const;
|
boo::IWindow* GetMainWindow() const;
|
||||||
|
|
||||||
void MemoryCardInitializePump()
|
void MemoryCardInitializePump();
|
||||||
{
|
|
||||||
if (!g_MemoryCardSys)
|
|
||||||
{
|
|
||||||
std::unique_ptr<CMemoryCardSys>& memSys = x128_globalObjects.x0_memoryCardSys;
|
|
||||||
if (!memSys)
|
|
||||||
memSys.reset(new CMemoryCardSys());
|
|
||||||
if (memSys->InitializePump())
|
|
||||||
{
|
|
||||||
g_MemoryCardSys = memSys.get();
|
|
||||||
g_GameState->InitializeMemoryStates();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckReset() { return false; }
|
bool CheckReset() { return false; }
|
||||||
bool CheckTerminate() { return false; }
|
bool CheckTerminate() { return false; }
|
||||||
|
|
|
@ -168,13 +168,13 @@ namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
TCastToPtr<T>::TCastToPtr(CEntity* p) { p->Accept(*this); }
|
TCastToPtr<T>::TCastToPtr(CEntity* p) { if (p) p->Accept(*this); else ptr = nullptr; }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
TCastToPtr<T>::TCastToPtr(CEntity& p) { p.Accept(*this); }
|
TCastToPtr<T>::TCastToPtr(CEntity& p) { p.Accept(*this); }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
TCastToPtr<T>& TCastToPtr<T>::operator=(CEntity* p) { p->Accept(*this); return *this; }
|
TCastToPtr<T>& TCastToPtr<T>::operator=(CEntity* p) { if (p) p->Accept(*this); else ptr = nullptr; return *this; }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
TCastToPtr<T>& TCastToPtr<T>::operator=(CEntity& p) { p.Accept(*this); return *this; }
|
TCastToPtr<T>& TCastToPtr<T>::operator=(CEntity& p) { p.Accept(*this); return *this; }
|
||||||
|
|
|
@ -414,16 +414,16 @@ CGameArea::CGameArea(CInputStream& in, int idx, int mlvlVersion)
|
||||||
CGameArea::CGameArea(CAssetId mreaId)
|
CGameArea::CGameArea(CAssetId mreaId)
|
||||||
: x84_mrea(mreaId)
|
: x84_mrea(mreaId)
|
||||||
{
|
{
|
||||||
while (StartStreamingMainArea()) {}
|
while (StartStreamingMainArea())
|
||||||
|
|
||||||
for (auto& req : xf8_loadTransactions)
|
for (auto& req : xf8_loadTransactions)
|
||||||
req->WaitForComplete();
|
req->WaitForComplete();
|
||||||
|
|
||||||
MREAHeader header = VerifyHeader();
|
MREAHeader header = VerifyHeader();
|
||||||
x12c_postConstructed->x4c_insts.reserve(header.modelCount);
|
x12c_postConstructed->x4c_insts.resize(header.modelCount);
|
||||||
|
|
||||||
FillInStaticGeometry();
|
FillInStaticGeometry(false);
|
||||||
|
|
||||||
|
CBooModel::SetDummyTextures(true);
|
||||||
CBooModel::EnableShadowMaps(g_Renderer->x220_sphereRamp, zeus::CTransform::Identity());
|
CBooModel::EnableShadowMaps(g_Renderer->x220_sphereRamp, zeus::CTransform::Identity());
|
||||||
CGraphics::CProjectionState backupProj = CGraphics::GetProjectionState();
|
CGraphics::CProjectionState backupProj = CGraphics::GetProjectionState();
|
||||||
zeus::CTransform backupViewPoint = CGraphics::g_ViewMatrix;
|
zeus::CTransform backupViewPoint = CGraphics::g_ViewMatrix;
|
||||||
|
@ -434,7 +434,6 @@ CGameArea::CGameArea(CAssetId mreaId)
|
||||||
for (CMetroidModelInstance& inst : x12c_postConstructed->x4c_insts)
|
for (CMetroidModelInstance& inst : x12c_postConstructed->x4c_insts)
|
||||||
{
|
{
|
||||||
CGraphics::SetModelMatrix(zeus::CTransform::Translate(-inst.x34_aabb.center()));
|
CGraphics::SetModelMatrix(zeus::CTransform::Translate(-inst.x34_aabb.center()));
|
||||||
inst.m_instance->SyncLoadTextures();
|
|
||||||
inst.m_instance->UpdateUniformData(defaultFlags, nullptr, nullptr);
|
inst.m_instance->UpdateUniformData(defaultFlags, nullptr, nullptr);
|
||||||
inst.m_instance->WarmupDrawSurfaces();
|
inst.m_instance->WarmupDrawSurfaces();
|
||||||
}
|
}
|
||||||
|
@ -442,6 +441,7 @@ CGameArea::CGameArea(CAssetId mreaId)
|
||||||
CGraphics::SetViewPointMatrix(backupViewPoint);
|
CGraphics::SetViewPointMatrix(backupViewPoint);
|
||||||
CGraphics::SetModelMatrix(backupModel);
|
CGraphics::SetModelMatrix(backupModel);
|
||||||
CBooModel::DisableShadowMaps();
|
CBooModel::DisableShadowMaps();
|
||||||
|
CBooModel::SetDummyTextures(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameArea::IGetScriptingMemoryAlways() const
|
bool CGameArea::IGetScriptingMemoryAlways() const
|
||||||
|
@ -932,7 +932,7 @@ void CGameArea::PostConstructArea()
|
||||||
u32 sec = 3;
|
u32 sec = 3;
|
||||||
|
|
||||||
/* Models */
|
/* Models */
|
||||||
x12c_postConstructed->x4c_insts.reserve(header.modelCount);
|
x12c_postConstructed->x4c_insts.resize(header.modelCount);
|
||||||
for (u32 i=0 ; i<header.modelCount ; ++i)
|
for (u32 i=0 ; i<header.modelCount ; ++i)
|
||||||
{
|
{
|
||||||
u32 surfCount = hecl::SBig(*reinterpret_cast<const u32*>((secIt+4)->first));
|
u32 surfCount = hecl::SBig(*reinterpret_cast<const u32*>((secIt+4)->first));
|
||||||
|
@ -1051,26 +1051,28 @@ void CGameArea::PostConstructArea()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameArea::FillInStaticGeometry()
|
void CGameArea::FillInStaticGeometry(bool textures)
|
||||||
{
|
{
|
||||||
x12c_postConstructed->x4c_insts.clear();
|
if (!x12c_postConstructed->x4c_insts.empty())
|
||||||
|
for (CMetroidModelInstance& inst : x12c_postConstructed->x4c_insts)
|
||||||
|
inst.Clear();
|
||||||
|
|
||||||
/* Materials */
|
/* Materials */
|
||||||
|
CBooModel::SShader& matSet = x12c_postConstructed->m_materialSet;
|
||||||
auto secIt = m_resolvedBufs.begin() + 2;
|
auto secIt = m_resolvedBufs.begin() + 2;
|
||||||
{
|
{
|
||||||
athena::io::MemoryReader r(secIt->first, secIt->second);
|
athena::io::MemoryReader r(secIt->first, secIt->second);
|
||||||
x12c_postConstructed->m_materialSet.m_matSet.read(r);
|
matSet.m_matSet.read(r);
|
||||||
|
if (textures)
|
||||||
|
CBooModel::MakeTexturesFromMats(matSet.m_matSet, matSet.x0_textures, *g_SimplePool);
|
||||||
++secIt;
|
++secIt;
|
||||||
}
|
}
|
||||||
|
|
||||||
x12c_postConstructed->m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
x12c_postConstructed->m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
/* Models */
|
/* Models */
|
||||||
for (u32 i=0 ; i<x12c_postConstructed->x4c_insts.capacity() ; ++i)
|
for (CMetroidModelInstance& inst : x12c_postConstructed->x4c_insts)
|
||||||
{
|
{
|
||||||
x12c_postConstructed->x4c_insts.emplace_back();
|
|
||||||
CMetroidModelInstance& inst = x12c_postConstructed->x4c_insts.back();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
DataSpec::DNAMP1::MREA::MeshHeader header;
|
DataSpec::DNAMP1::MREA::MeshHeader header;
|
||||||
athena::io::MemoryReader r(secIt->first, secIt->second);
|
athena::io::MemoryReader r(secIt->first, secIt->second);
|
||||||
|
@ -1081,30 +1083,31 @@ void CGameArea::FillInStaticGeometry()
|
||||||
++secIt;
|
++secIt;
|
||||||
}
|
}
|
||||||
|
|
||||||
hecl::HMDLMeta hmdlMeta;
|
|
||||||
{
|
{
|
||||||
athena::io::MemoryReader r(secIt->first, secIt->second);
|
athena::io::MemoryReader r(secIt->first, secIt->second);
|
||||||
hmdlMeta.read(r);
|
inst.m_hmdlMeta.read(r);
|
||||||
}
|
}
|
||||||
++secIt;
|
++secIt;
|
||||||
|
|
||||||
boo::IGraphicsBufferS* vbo;
|
boo::IGraphicsBufferS* vbo;
|
||||||
boo::IGraphicsBufferS* ibo;
|
boo::IGraphicsBufferS* ibo;
|
||||||
boo::IVertexFormat* vtxFmt;
|
boo::IVertexFormat* vtxFmt;
|
||||||
vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, secIt->first, hmdlMeta.vertStride, hmdlMeta.vertCount);
|
vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, secIt->first, inst.m_hmdlMeta.vertStride,
|
||||||
|
inst.m_hmdlMeta.vertCount);
|
||||||
++secIt;
|
++secIt;
|
||||||
ibo = ctx.newStaticBuffer(boo::BufferUse::Index, secIt->first, 4, hmdlMeta.indexCount);
|
ibo = ctx.newStaticBuffer(boo::BufferUse::Index, secIt->first, 4, inst.m_hmdlMeta.indexCount);
|
||||||
++secIt;
|
++secIt;
|
||||||
vtxFmt = hecl::Runtime::HMDLData::NewVertexFormat(ctx, hmdlMeta, vbo, ibo);
|
vtxFmt = hecl::Runtime::HMDLData::NewVertexFormat(ctx, inst.m_hmdlMeta, vbo, ibo);
|
||||||
|
|
||||||
u32 surfCount = hecl::SBig(*reinterpret_cast<const u32*>(secIt->first));
|
u32 surfCount = hecl::SBig(*reinterpret_cast<const u32*>(secIt->first));
|
||||||
inst.m_surfaces.reserve(surfCount);
|
inst.m_surfaces.reserve(surfCount);
|
||||||
|
inst.m_shaders.resize(matSet.m_matSet.materials.size());
|
||||||
++secIt;
|
++secIt;
|
||||||
for (u32 i=0 ; i<surfCount ; ++i)
|
for (u32 j=0 ; j<surfCount ; ++j)
|
||||||
{
|
{
|
||||||
inst.m_surfaces.emplace_back();
|
inst.m_surfaces.emplace_back();
|
||||||
CBooSurface& surf = inst.m_surfaces.back();
|
CBooSurface& surf = inst.m_surfaces.back();
|
||||||
surf.selfIdx = i;
|
surf.selfIdx = j;
|
||||||
athena::io::MemoryReader r(secIt->first, secIt->second);
|
athena::io::MemoryReader r(secIt->first, secIt->second);
|
||||||
surf.m_data.read(r);
|
surf.m_data.read(r);
|
||||||
++secIt;
|
++secIt;
|
||||||
|
@ -1112,13 +1115,24 @@ void CGameArea::FillInStaticGeometry()
|
||||||
|
|
||||||
TToken<CModel> nullModel;
|
TToken<CModel> nullModel;
|
||||||
inst.m_instance = std::make_unique<CBooModel>
|
inst.m_instance = std::make_unique<CBooModel>
|
||||||
(nullModel, &inst.m_surfaces, x12c_postConstructed->m_materialSet, vtxFmt, vbo, ibo,
|
(nullModel, nullptr, &inst.m_surfaces, matSet, vtxFmt, vbo, ibo,
|
||||||
inst.x34_aabb, inst.x0_visorFlags, 1, nullptr);
|
inst.x34_aabb, inst.x0_visorFlags, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (CMetroidModelInstance& inst : x12c_postConstructed->x4c_insts)
|
||||||
|
{
|
||||||
|
for (CBooSurface& surf : inst.m_surfaces)
|
||||||
|
{
|
||||||
|
auto& shad = inst.m_shaders[surf.m_data.matIdx];
|
||||||
|
if (!shad)
|
||||||
|
shad = matSet.BuildShader(inst.m_hmdlMeta, matSet.m_matSet.materials[surf.m_data.matIdx]);
|
||||||
|
}
|
||||||
|
inst.m_instance->RemapMaterialData(matSet, inst.m_shaders);
|
||||||
|
}
|
||||||
|
|
||||||
x12c_postConstructed->x1108_25_modelsConstructed = true;
|
x12c_postConstructed->x1108_25_modelsConstructed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -340,7 +340,7 @@ public:
|
||||||
void LoadScriptObjects(CStateManager& mgr);
|
void LoadScriptObjects(CStateManager& mgr);
|
||||||
std::pair<const u8*, u32> GetLayerScriptBuffer(int layer);
|
std::pair<const u8*, u32> GetLayerScriptBuffer(int layer);
|
||||||
void PostConstructArea();
|
void PostConstructArea();
|
||||||
void FillInStaticGeometry();
|
void FillInStaticGeometry(bool textures = true);
|
||||||
void VerifyTokenList(CStateManager& stateMgr);
|
void VerifyTokenList(CStateManager& stateMgr);
|
||||||
void ClearTokenList();
|
void ClearTokenList();
|
||||||
u32 GetPreConstructedSize() const;
|
u32 GetPreConstructedSize() const;
|
||||||
|
|
|
@ -364,7 +364,7 @@ public:
|
||||||
if (size > base::x0_size)
|
if (size > base::x0_size)
|
||||||
{
|
{
|
||||||
for (size_t i = base::x0_size; i < size; ++i)
|
for (size_t i = base::x0_size; i < size; ++i)
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(i)))) T;
|
::new (static_cast<void*>(std::addressof(base::_value(i)))) T();
|
||||||
base::x0_size = size;
|
base::x0_size = size;
|
||||||
}
|
}
|
||||||
else if (size < base::x0_size)
|
else if (size < base::x0_size)
|
||||||
|
@ -428,7 +428,7 @@ class prereserved_vector : public _reserved_vector_base<T, N>
|
||||||
void _init()
|
void _init()
|
||||||
{
|
{
|
||||||
for (auto& i : base::x4_data)
|
for (auto& i : base::x4_data)
|
||||||
::new (static_cast<void*>(std::addressof(i._value))) T;
|
::new (static_cast<void*>(std::addressof(i._value))) T();
|
||||||
}
|
}
|
||||||
void _deinit()
|
void _deinit()
|
||||||
{
|
{
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit f949aabf5c4632df97746c273cab27a1ea1bffe4
|
Subproject commit 84393676f125f87c443b770738b552015998228d
|
|
@ -59,20 +59,29 @@ static void UpdatePercent(float percent)
|
||||||
VISIRenderer* m_renderer;
|
VISIRenderer* m_renderer;
|
||||||
NSWindow* m_window;
|
NSWindow* m_window;
|
||||||
NSOpenGLView* m_glView;
|
NSOpenGLView* m_glView;
|
||||||
|
int m_instanceIdx;
|
||||||
}
|
}
|
||||||
- (id)initWithRenderer:(VISIRenderer*)renderer;
|
- (id)initWithRenderer:(VISIRenderer*)renderer instIdx:(int)instIdx;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
- (id)initWithRenderer:(VISIRenderer*)renderer
|
- (id)initWithRenderer:(VISIRenderer*)renderer instIdx:(int)instIdx
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
m_renderer = renderer;
|
m_renderer = renderer;
|
||||||
|
m_instanceIdx = instIdx;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification*)notification
|
- (void)applicationDidFinishLaunching:(NSNotification*)notification
|
||||||
{
|
{
|
||||||
NSRect cRect = NSMakeRect(100, 100, 768, 512);
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
if (m_instanceIdx != -1)
|
||||||
|
{
|
||||||
|
x = (m_instanceIdx & 1) != 0;
|
||||||
|
y = (m_instanceIdx & 2) != 0;
|
||||||
|
}
|
||||||
|
NSRect cRect = NSMakeRect(x * 768, y * 534, 768, 512);
|
||||||
m_window = [[NSWindow alloc] initWithContentRect:cRect
|
m_window = [[NSWindow alloc] initWithContentRect:cRect
|
||||||
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable
|
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable
|
||||||
backing:NSBackingStoreBuffered
|
backing:NSBackingStoreBuffered
|
||||||
|
@ -109,12 +118,15 @@ int main(int argc, const char** argv)
|
||||||
logvisor::RegisterConsoleLogger();
|
logvisor::RegisterConsoleLogger();
|
||||||
atSetExceptionHandler(AthenaExc);
|
atSetExceptionHandler(AthenaExc);
|
||||||
VISIRenderer renderer(argc, argv);
|
VISIRenderer renderer(argc, argv);
|
||||||
|
int instIdx = -1;
|
||||||
|
if (argc > 3)
|
||||||
|
instIdx = atoi(argv[3]);
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
[[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular];
|
[[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
|
||||||
/* Delegate (OS X callbacks) */
|
/* Delegate (OS X callbacks) */
|
||||||
AppDelegate* appDelegate = [[AppDelegate alloc] initWithRenderer:&renderer];
|
AppDelegate* appDelegate = [[AppDelegate alloc] initWithRenderer:&renderer instIdx:instIdx];
|
||||||
[[NSApplication sharedApplication] setDelegate:appDelegate];
|
[[NSApplication sharedApplication] setDelegate:appDelegate];
|
||||||
[[NSApplication sharedApplication] run];
|
[[NSApplication sharedApplication] run];
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,10 @@ int wmain(int argc, const hecl::SystemChar** argv)
|
||||||
VISIRenderer renderer(argc, argv);
|
VISIRenderer renderer(argc, argv);
|
||||||
s_Renderer = &renderer;
|
s_Renderer = &renderer;
|
||||||
|
|
||||||
|
int instIdx = -1;
|
||||||
|
if (argc > 3)
|
||||||
|
instIdx = _wtoi(argv[3]);
|
||||||
|
|
||||||
WNDCLASS wndClass =
|
WNDCLASS wndClass =
|
||||||
{
|
{
|
||||||
CS_NOCLOSE,
|
CS_NOCLOSE,
|
||||||
|
@ -74,8 +78,16 @@ int wmain(int argc, const hecl::SystemChar** argv)
|
||||||
RECT clientRect = {0, 0, 768, 512};
|
RECT clientRect = {0, 0, 768, 512};
|
||||||
AdjustWindowRect(&clientRect, dwStyle, FALSE);
|
AdjustWindowRect(&clientRect, dwStyle, FALSE);
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
if (instIdx != -1)
|
||||||
|
{
|
||||||
|
x = (instIdx & 1) != 0;
|
||||||
|
y = (instIdx & 2) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
HWND window = CreateWindowW(L"VISIGenWindow", L"VISIGen", dwStyle,
|
HWND window = CreateWindowW(L"VISIGenWindow", L"VISIGen", dwStyle,
|
||||||
100, 100,
|
x, y,
|
||||||
clientRect.right - clientRect.left,
|
clientRect.right - clientRect.left,
|
||||||
clientRect.bottom - clientRect.top,
|
clientRect.bottom - clientRect.top,
|
||||||
NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL);
|
||||||
|
|
|
@ -194,7 +194,19 @@ int main(int argc, const char** argv)
|
||||||
swa.border_pixmap = 0;
|
swa.border_pixmap = 0;
|
||||||
swa.event_mask = 0;
|
swa.event_mask = 0;
|
||||||
|
|
||||||
windowId = XCreateWindow(xDisp, screen->root, 0, 0, 768, 512, 10,
|
int instIdx = -1;
|
||||||
|
if (argc > 3)
|
||||||
|
instIdx = atoi(argv[3]);
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
if (instIdx != -1)
|
||||||
|
{
|
||||||
|
x = (instIdx & 1) != 0;
|
||||||
|
y = (instIdx & 2) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
windowId = XCreateWindow(xDisp, screen->root, x, y, 768, 512, 10,
|
||||||
CopyFromParent, CopyFromParent, selectedVisual,
|
CopyFromParent, CopyFromParent, selectedVisual,
|
||||||
CWBorderPixel | CWEventMask | CWColormap, &swa);
|
CWBorderPixel | CWEventMask | CWColormap, &swa);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
#include "VISIBuilder.hpp"
|
#include "VISIBuilder.hpp"
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define VISI_MAX_LEVEL 10
|
#define VISI_MAX_LEVEL 10
|
||||||
#define VISI_MIN_LENGTH 8.0
|
#define VISI_MIN_LENGTH 8.0
|
||||||
|
|
||||||
|
@ -31,8 +36,8 @@ const VISIBuilder::Leaf& VISIBuilder::PVSRenderCache::GetLeaf(const zeus::CVecto
|
||||||
{
|
{
|
||||||
const VISIRenderer::RGBA8& pixel = RGBABuf[i];
|
const VISIRenderer::RGBA8& pixel = RGBABuf[i];
|
||||||
uint32_t id = (pixel.b << 16) | (pixel.g << 8) | pixel.r;
|
uint32_t id = (pixel.b << 16) | (pixel.g << 8) | pixel.r;
|
||||||
if (id != 0xffffff)
|
if (id != 0)
|
||||||
leafOut->setBit(id);
|
leafOut->setBit(id - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto setBitLambda = [&](int idx) { leafOut->setBit(idx); };
|
auto setBitLambda = [&](int idx) { leafOut->setBit(idx); };
|
||||||
|
@ -51,16 +56,16 @@ const VISIBuilder::Leaf& VISIBuilder::PVSRenderCache::GetLeaf(const zeus::CVecto
|
||||||
void VISIBuilder::Progress::report(int divisions)
|
void VISIBuilder::Progress::report(int divisions)
|
||||||
{
|
{
|
||||||
m_prog += 1.f / divisions;
|
m_prog += 1.f / divisions;
|
||||||
printf(" %g%% \r", m_prog * 100.f);
|
//printf(" %g%% \r", m_prog * 100.f);
|
||||||
fflush(stdout);
|
//fflush(stdout);
|
||||||
if (m_updatePercent)
|
if (m_updatePercent)
|
||||||
m_updatePercent(m_prog);
|
m_updatePercent(m_prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VISIBuilder::Node::buildChildren(int level, int divisions, const zeus::CAABox& curAabb,
|
void VISIBuilder::Node::buildChildren(int level, int divisions, const zeus::CAABox& curAabb,
|
||||||
PVSRenderCache& rc, Progress& prog, const bool& terminate)
|
PVSRenderCache& rc, Progress& prog, const std::function<bool()>& terminate)
|
||||||
{
|
{
|
||||||
if (terminate)
|
if (terminate())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Recurse in while building node structure
|
// Recurse in while building node structure
|
||||||
|
@ -316,9 +321,10 @@ std::vector<uint8_t> VISIBuilder::build(const zeus::CAABox& fullAabb,
|
||||||
renderCache.m_lightMetaBit = featureCount;
|
renderCache.m_lightMetaBit = featureCount;
|
||||||
|
|
||||||
Progress prog(updatePercent);
|
Progress prog(updatePercent);
|
||||||
bool& terminate = renderCache.m_renderer.m_terminate;
|
pid_t parentPid = getppid();
|
||||||
|
auto terminate = [this, parentPid]() { return renderCache.m_renderer.m_terminate || kill(parentPid, 0); };
|
||||||
rootNode.buildChildren(0, 1, fullAabb, renderCache, prog, terminate);
|
rootNode.buildChildren(0, 1, fullAabb, renderCache, prog, terminate);
|
||||||
if (terminate)
|
if (terminate())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
// Lights cache their CPVSVisSet result enum as 2 bits
|
// Lights cache their CPVSVisSet result enum as 2 bits
|
||||||
|
@ -365,7 +371,6 @@ std::vector<uint8_t> VISIBuilder::build(const zeus::CAABox& fullAabb,
|
||||||
|
|
||||||
w.seekAlign32();
|
w.seekAlign32();
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
Log.report(logvisor::Info, "Finished!");
|
Log.report(logvisor::Info, "Finished!");
|
||||||
return dataOut;
|
return dataOut;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ struct VISIBuilder
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
|
|
||||||
void buildChildren(int level, int divisions, const zeus::CAABox& curAabb,
|
void buildChildren(int level, int divisions, const zeus::CAABox& curAabb,
|
||||||
PVSRenderCache& rc, Progress& prog, const bool& terminate);
|
PVSRenderCache& rc, Progress& prog, const std::function<bool()>& terminate);
|
||||||
void calculateSizesAndOffs(size_t& cur, size_t leafSz);
|
void calculateSizesAndOffs(size_t& cur, size_t leafSz);
|
||||||
void writeNodes(athena::io::MemoryWriter& w, size_t leafBytes) const;
|
void writeNodes(athena::io::MemoryWriter& w, size_t leafBytes) const;
|
||||||
|
|
||||||
|
|
|
@ -110,8 +110,6 @@ bool VISIRenderer::SetupShaders()
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_aabbIBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_aabbIBO);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 20 * 4, AABBIdxs, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 20 * 4, AABBIdxs, GL_STATIC_DRAW);
|
||||||
|
|
||||||
glGenQueries(1, &m_query);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +136,7 @@ std::vector<VISIRenderer::Model::Vert> VISIRenderer::AABBToVerts(const zeus::CAA
|
||||||
|
|
||||||
static zeus::CColor ColorForIndex(int i)
|
static zeus::CColor ColorForIndex(int i)
|
||||||
{
|
{
|
||||||
|
i += 1;
|
||||||
return zeus::CColor((i & 0xff) / 255.f,
|
return zeus::CColor((i & 0xff) / 255.f,
|
||||||
((i >> 8) & 0xff) / 255.f,
|
((i >> 8) & 0xff) / 255.f,
|
||||||
((i >> 16) & 0xff) / 255.f,
|
((i >> 16) & 0xff) / 255.f,
|
||||||
|
@ -202,6 +201,11 @@ bool VISIRenderer::SetupVertexBuffersAndFormats()
|
||||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Model::Vert), (void*)16);
|
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Model::Vert), (void*)16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_queryCount = m_models.size() + m_entities.size() + m_lights.size();
|
||||||
|
m_queries.reset(new GLuint[m_queryCount]);
|
||||||
|
m_queryBools.reset(new bool[m_queryCount]);
|
||||||
|
glGenQueries(GLsizei(m_queryCount), m_queries.get());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +281,7 @@ void VISIRenderer::RenderPVSOpaque(RGBA8* bufOut, const zeus::CVector3f& pos, bo
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glClearColor(1.f, 1.f, 1.f, 1.f);
|
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
for (int j=0 ; j<6 ; ++j)
|
for (int j=0 ; j<6 ; ++j)
|
||||||
|
@ -297,26 +301,6 @@ void VISIRenderer::RenderPVSOpaque(RGBA8* bufOut, const zeus::CVector3f& pos, bo
|
||||||
zeus::CFrustum frustum;
|
zeus::CFrustum frustum;
|
||||||
frustum.updatePlanes(mv, g_Proj);
|
frustum.updatePlanes(mv, g_Proj);
|
||||||
|
|
||||||
// Fill depth buffer with backfaces initially
|
|
||||||
glCullFace(GL_FRONT);
|
|
||||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
||||||
|
|
||||||
for (const Model& model : m_models)
|
|
||||||
{
|
|
||||||
if (!frustum.aabbFrustumTest(model.aabb))
|
|
||||||
continue;
|
|
||||||
glBindVertexArray(model.vao);
|
|
||||||
for (const Model::Surface& surf : model.surfaces)
|
|
||||||
{
|
|
||||||
// Non-transparents first
|
|
||||||
if (!surf.transparent)
|
|
||||||
glDrawElements(model.topology, surf.count, GL_UNSIGNED_INT,
|
|
||||||
reinterpret_cast<void*>(uintptr_t(surf.first * 4)));
|
|
||||||
else
|
|
||||||
needTransparent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw frontfaces
|
// Draw frontfaces
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
@ -362,6 +346,8 @@ void VISIRenderer::RenderPVSTransparent(const std::function<void(int)>& passFunc
|
||||||
zeus::CFrustum frustum;
|
zeus::CFrustum frustum;
|
||||||
frustum.updatePlanes(mv, g_Proj);
|
frustum.updatePlanes(mv, g_Proj);
|
||||||
|
|
||||||
|
memset(m_queryBools.get(), 0, m_queryCount);
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (const Model& model : m_models)
|
for (const Model& model : m_models)
|
||||||
{
|
{
|
||||||
|
@ -371,23 +357,29 @@ void VISIRenderer::RenderPVSTransparent(const std::function<void(int)>& passFunc
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
glBindVertexArray(model.vao);
|
glBindVertexArray(model.vao);
|
||||||
|
glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, m_queries[idx]);
|
||||||
|
m_queryBools[idx] = true;
|
||||||
for (const Model::Surface& surf : model.surfaces)
|
for (const Model::Surface& surf : model.surfaces)
|
||||||
{
|
{
|
||||||
// transparents
|
// transparents
|
||||||
if (surf.transparent)
|
if (surf.transparent)
|
||||||
{
|
|
||||||
glBeginQuery(GL_ANY_SAMPLES_PASSED, m_query);
|
|
||||||
glDrawElements(model.topology, surf.count, GL_UNSIGNED_INT,
|
glDrawElements(model.topology, surf.count, GL_UNSIGNED_INT,
|
||||||
reinterpret_cast<void*>(uintptr_t(surf.first * 4)));
|
reinterpret_cast<void*>(uintptr_t(surf.first * 4)));
|
||||||
glEndQuery(GL_ANY_SAMPLES_PASSED);
|
|
||||||
GLint res;
|
|
||||||
glGetQueryObjectiv(m_query, GL_QUERY_RESULT, &res);
|
|
||||||
if (res)
|
|
||||||
passFunc(idx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i=0 ; i<idx ; ++i)
|
||||||
|
{
|
||||||
|
if (m_queryBools[i])
|
||||||
|
{
|
||||||
|
GLint res;
|
||||||
|
glGetQueryObjectiv(m_queries[i], GL_QUERY_RESULT, &res);
|
||||||
|
if (res)
|
||||||
|
passFunc(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,6 +406,8 @@ void VISIRenderer::RenderPVSEntitiesAndLights(const std::function<void(int)>& pa
|
||||||
zeus::CFrustum frustum;
|
zeus::CFrustum frustum;
|
||||||
frustum.updatePlanes(mv, g_Proj);
|
frustum.updatePlanes(mv, g_Proj);
|
||||||
|
|
||||||
|
memset(m_queryBools.get(), 0, m_queryCount);
|
||||||
|
|
||||||
int idx = m_models.size();
|
int idx = m_models.size();
|
||||||
for (const Entity& ent : m_entities)
|
for (const Entity& ent : m_entities)
|
||||||
{
|
{
|
||||||
|
@ -423,36 +417,56 @@ void VISIRenderer::RenderPVSEntitiesAndLights(const std::function<void(int)>& pa
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
glBindVertexArray(ent.vao);
|
glBindVertexArray(ent.vao);
|
||||||
glBeginQuery(GL_ANY_SAMPLES_PASSED, m_query);
|
m_queryBools[idx] = true;
|
||||||
|
glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, m_queries[idx]);
|
||||||
glDrawElements(GL_TRIANGLE_STRIP, 20, GL_UNSIGNED_INT, 0);
|
glDrawElements(GL_TRIANGLE_STRIP, 20, GL_UNSIGNED_INT, 0);
|
||||||
glEndQuery(GL_ANY_SAMPLES_PASSED);
|
glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Light& light : m_lights)
|
||||||
|
{
|
||||||
|
if (!frustum.pointFrustumTest(light.point))
|
||||||
|
{
|
||||||
|
++idx;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
glBindVertexArray(light.vao);
|
||||||
|
m_queryBools[idx] = true;
|
||||||
|
glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, m_queries[idx]);
|
||||||
|
glDrawArrays(GL_POINTS, 0, 1);
|
||||||
|
glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = m_models.size();
|
||||||
|
for (const Entity& ent : m_entities)
|
||||||
|
{
|
||||||
|
if (m_queryBools[idx])
|
||||||
|
{
|
||||||
GLint res;
|
GLint res;
|
||||||
glGetQueryObjectiv(m_query, GL_QUERY_RESULT, &res);
|
glGetQueryObjectiv(m_queries[idx], GL_QUERY_RESULT, &res);
|
||||||
if (res)
|
if (res)
|
||||||
passFunc(idx);
|
passFunc(idx);
|
||||||
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lightIdx = 0;
|
int lightIdx = 0;
|
||||||
for (const Light& light : m_lights)
|
for (const Light& light : m_lights)
|
||||||
{
|
{
|
||||||
if (!frustum.pointFrustumTest(light.point))
|
if (m_queryBools[idx])
|
||||||
{
|
{
|
||||||
++lightIdx;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
glBindVertexArray(light.vao);
|
|
||||||
glBeginQuery(GL_ANY_SAMPLES_PASSED, m_query);
|
|
||||||
glDrawArrays(GL_POINTS, 0, 1);
|
|
||||||
glEndQuery(GL_ANY_SAMPLES_PASSED);
|
|
||||||
GLint res;
|
GLint res;
|
||||||
glGetQueryObjectiv(m_query, GL_QUERY_RESULT, &res);
|
glGetQueryObjectiv(m_queries[idx], GL_QUERY_RESULT, &res);
|
||||||
EPVSVisSetState state = m_totalAABB.pointInside(light.point) ?
|
EPVSVisSetState state = m_totalAABB.pointInside(light.point) ?
|
||||||
EPVSVisSetState::EndOfTree : EPVSVisSetState::OutOfBounds;
|
EPVSVisSetState::EndOfTree : EPVSVisSetState::OutOfBounds;
|
||||||
if (res && state == EPVSVisSetState::EndOfTree)
|
if (res && state == EPVSVisSetState::EndOfTree)
|
||||||
state = EPVSVisSetState::NodeFound;
|
state = EPVSVisSetState::NodeFound;
|
||||||
lightPassFunc(lightIdx, state);
|
lightPassFunc(lightIdx, state);
|
||||||
|
}
|
||||||
++lightIdx;
|
++lightIdx;
|
||||||
|
++idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,9 @@ class VISIRenderer
|
||||||
std::vector<Light> m_lights;
|
std::vector<Light> m_lights;
|
||||||
bool SetupVertexBuffersAndFormats();
|
bool SetupVertexBuffersAndFormats();
|
||||||
|
|
||||||
GLuint m_query;
|
size_t m_queryCount;
|
||||||
|
std::unique_ptr<GLuint[]> m_queries;
|
||||||
|
std::unique_ptr<bool[]> m_queryBools;
|
||||||
|
|
||||||
FPercent m_updatePercent;
|
FPercent m_updatePercent;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue