mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-06-05 07:13:27 +00:00
Added HMDL outputting from blender intermediate
This commit is contained in:
parent
7c0206bd39
commit
db335e5d98
@ -503,8 +503,8 @@ void BlenderConnection::PyOutStream::linkBackground(const char* target,
|
||||
}
|
||||
|
||||
BlenderConnection::DataStream::Mesh::Mesh
|
||||
(BlenderConnection& conn, OutputMode outMode, int skinSlotCount, SurfProgFunc& surfProg)
|
||||
: outputMode(outMode), aabbMin(conn), aabbMax(conn)
|
||||
(BlenderConnection& conn, HMDLTopology topologyIn, int skinSlotCount, SurfProgFunc& surfProg)
|
||||
: topology(topologyIn), aabbMin(conn), aabbMax(conn)
|
||||
{
|
||||
uint32_t matSetCount;
|
||||
conn._readBuf(&matSetCount, 4);
|
||||
@ -587,12 +587,12 @@ BlenderConnection::DataStream::Mesh::Mesh
|
||||
{
|
||||
for (Surface& surf : surfaces)
|
||||
{
|
||||
std::vector<uint32_t>& bank = skinBanks.banks[surf.skinBankIdx];
|
||||
SkinBanks::Bank& bank = skinBanks.banks[surf.skinBankIdx];
|
||||
for (Surface::Vert& vert : surf.verts)
|
||||
{
|
||||
for (uint32_t i=0 ; i<bank.size() ; ++i)
|
||||
for (uint32_t i=0 ; i<bank.m_skinIdxs.size() ; ++i)
|
||||
{
|
||||
if (bank[i] == vert.iSkin)
|
||||
if (bank.m_skinIdxs[i] == vert.iSkin)
|
||||
{
|
||||
vert.iBankSkin = i;
|
||||
break;
|
||||
@ -706,7 +706,7 @@ BlenderConnection::DataStream::Mesh::Surface::Surface
|
||||
}
|
||||
|
||||
if (parent.boneNames.size())
|
||||
skinBankIdx = parent.skinBanks.addSurface(*this, skinSlotCount);
|
||||
skinBankIdx = parent.skinBanks.addSurface(parent, *this, skinSlotCount);
|
||||
}
|
||||
|
||||
BlenderConnection::DataStream::Mesh::Surface::Vert::Vert
|
||||
@ -730,27 +730,27 @@ static bool VertInBank(const std::vector<uint32_t>& bank, uint32_t sIdx)
|
||||
}
|
||||
|
||||
uint32_t BlenderConnection::DataStream::Mesh::SkinBanks::addSurface
|
||||
(const Surface& surf, int skinSlotCount)
|
||||
(const Mesh& mesh, const Surface& surf, int skinSlotCount)
|
||||
{
|
||||
if (banks.empty())
|
||||
addSkinBank(skinSlotCount);
|
||||
std::vector<uint32_t> toAdd;
|
||||
if (skinSlotCount > 0)
|
||||
toAdd.reserve(skinSlotCount);
|
||||
std::vector<std::vector<uint32_t>>::iterator bankIt = banks.begin();
|
||||
std::vector<Bank>::iterator bankIt = banks.begin();
|
||||
for (;;)
|
||||
{
|
||||
bool done = true;
|
||||
for (; bankIt != banks.end() ; ++bankIt)
|
||||
{
|
||||
std::vector<uint32_t>& bank = *bankIt;
|
||||
Bank& bank = *bankIt;
|
||||
done = true;
|
||||
for (const Surface::Vert& v : surf.verts)
|
||||
{
|
||||
if (!VertInBank(bank, v.iSkin) && !VertInBank(toAdd, v.iSkin))
|
||||
if (!VertInBank(bank.m_skinIdxs, v.iSkin) && !VertInBank(toAdd, v.iSkin))
|
||||
{
|
||||
toAdd.push_back(v.iSkin);
|
||||
if (skinSlotCount > 0 && bank.size() + toAdd.size() > skinSlotCount)
|
||||
if (skinSlotCount > 0 && bank.m_skinIdxs.size() + toAdd.size() > skinSlotCount)
|
||||
{
|
||||
toAdd.clear();
|
||||
done = false;
|
||||
@ -760,8 +760,7 @@ uint32_t BlenderConnection::DataStream::Mesh::SkinBanks::addSurface
|
||||
}
|
||||
if (toAdd.size())
|
||||
{
|
||||
for (uint32_t a : toAdd)
|
||||
bank.push_back(a);
|
||||
bank.addSkins(mesh, toAdd);
|
||||
toAdd.clear();
|
||||
}
|
||||
if (done)
|
||||
|
@ -21,13 +21,16 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "HECL/HECL.hpp"
|
||||
#include "HECL/HMDLMeta.hpp"
|
||||
#include <Athena/Types.hpp>
|
||||
#include <Athena/MemoryWriter.hpp>
|
||||
|
||||
namespace HECL
|
||||
{
|
||||
|
||||
extern LogVisor::LogModule BlenderLog;
|
||||
extern class BlenderConnection* SharedBlenderConnection;
|
||||
class HMDLBuffers;
|
||||
|
||||
class BlenderConnection
|
||||
{
|
||||
@ -374,11 +377,7 @@ public:
|
||||
/** Intermediate mesh representation prepared by blender from a single mesh object */
|
||||
struct Mesh
|
||||
{
|
||||
enum OutputMode
|
||||
{
|
||||
OutputTriangles,
|
||||
OutputTriStrips,
|
||||
} outputMode;
|
||||
enum HMDLTopology topology;
|
||||
|
||||
/* Cumulative AABB */
|
||||
Vector3f aabbMin;
|
||||
@ -436,6 +435,23 @@ public:
|
||||
uint32_t iBankSkin = -1;
|
||||
|
||||
Vert(BlenderConnection& conn, const Mesh& parent);
|
||||
|
||||
bool operator==(const Vert& other) const
|
||||
{
|
||||
if (iPos != other.iPos)
|
||||
return false;
|
||||
if (iNorm != other.iNorm)
|
||||
return false;
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
if (iColor[i] != other.iColor[i])
|
||||
return false;
|
||||
for (int i=0 ; i<8 ; ++i)
|
||||
if (iUv[i] != other.iUv[i])
|
||||
return false;
|
||||
if (iSkin != other.iSkin)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
std::vector<Vert> verts;
|
||||
|
||||
@ -445,33 +461,73 @@ public:
|
||||
|
||||
struct SkinBanks
|
||||
{
|
||||
std::vector<std::vector<uint32_t>> banks;
|
||||
std::vector<std::vector<uint32_t>>::iterator addSkinBank(int skinSlotCount)
|
||||
struct Bank
|
||||
{
|
||||
std::vector<uint32_t> m_skinIdxs;
|
||||
std::vector<uint32_t> m_boneIdxs;
|
||||
|
||||
void addSkins(const Mesh& parent, const std::vector<uint32_t>& skinIdxs)
|
||||
{
|
||||
for (uint32_t sidx : skinIdxs)
|
||||
{
|
||||
m_skinIdxs.push_back(sidx);
|
||||
for (const SkinBind& bind : parent.skins[sidx])
|
||||
{
|
||||
bool found = false;
|
||||
for (uint32_t bidx : m_boneIdxs)
|
||||
{
|
||||
if (bidx == bind.boneIdx)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
m_boneIdxs.push_back(bind.boneIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t lookupLocalBoneIdx(uint32_t boneIdx) const
|
||||
{
|
||||
for (size_t i=0 ; i<m_boneIdxs.size() ; ++i)
|
||||
if (m_boneIdxs[i] == boneIdx)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
std::vector<Bank> banks;
|
||||
std::vector<Bank>::iterator addSkinBank(int skinSlotCount)
|
||||
{
|
||||
banks.emplace_back();
|
||||
if (skinSlotCount > 0)
|
||||
banks.back().reserve(skinSlotCount);
|
||||
banks.back().m_skinIdxs.reserve(skinSlotCount);
|
||||
return banks.end() - 1;
|
||||
}
|
||||
uint32_t addSurface(const Surface& surf, int skinSlotCount);
|
||||
uint32_t addSurface(const Mesh& mesh, const Surface& surf, int skinSlotCount);
|
||||
} skinBanks;
|
||||
|
||||
using SurfProgFunc = std::function<void(int)>;
|
||||
Mesh(BlenderConnection& conn, OutputMode outMode, int skinSlotCount, SurfProgFunc& surfProg);
|
||||
Mesh(BlenderConnection& conn, HMDLTopology topology, int skinSlotCount, SurfProgFunc& surfProg);
|
||||
|
||||
Mesh getContiguousSkinningVersion() const;
|
||||
|
||||
/** Prepares mesh representation for indexed access on modern APIs.
|
||||
* Mesh must remain resident for accessing reference members
|
||||
*/
|
||||
HMDLBuffers getHMDLBuffers() const;
|
||||
};
|
||||
|
||||
|
||||
static const char* MeshOutputModeString(Mesh::OutputMode mode)
|
||||
static const char* MeshOutputModeString(HMDLTopology topology)
|
||||
{
|
||||
static const char* STRS[] = {"TRIANGLES", "TRISTRIPS"};
|
||||
return STRS[mode];
|
||||
return STRS[topology];
|
||||
}
|
||||
|
||||
|
||||
/** Compile mesh by context (MESH blends only) */
|
||||
Mesh compileMesh(Mesh::OutputMode outMode, int skinSlotCount=10,
|
||||
Mesh compileMesh(HMDLTopology topology, int skinSlotCount=10,
|
||||
Mesh::SurfProgFunc surfProg=[](int){})
|
||||
{
|
||||
if (m_parent->m_loadedType != TypeMesh)
|
||||
@ -480,7 +536,7 @@ public:
|
||||
|
||||
char req[128];
|
||||
snprintf(req, 128, "MESHCOMPILE %s %d",
|
||||
MeshOutputModeString(outMode), skinSlotCount);
|
||||
MeshOutputModeString(topology), skinSlotCount);
|
||||
m_parent->_writeLine(req);
|
||||
|
||||
char readBuf[256];
|
||||
@ -488,11 +544,11 @@ public:
|
||||
if (strcmp(readBuf, "OK"))
|
||||
BlenderLog.report(LogVisor::FatalError, "unable to cook mesh: %s", readBuf);
|
||||
|
||||
return Mesh(*m_parent, outMode, skinSlotCount, surfProg);
|
||||
return Mesh(*m_parent, topology, skinSlotCount, surfProg);
|
||||
}
|
||||
|
||||
/** Compile mesh by name (AREA blends only) */
|
||||
Mesh compileMesh(const std::string& name, Mesh::OutputMode outMode, int skinSlotCount=10,
|
||||
Mesh compileMesh(const std::string& name, HMDLTopology topology, int skinSlotCount=10,
|
||||
Mesh::SurfProgFunc surfProg=[](int){})
|
||||
{
|
||||
if (m_parent->m_loadedType != TypeArea)
|
||||
@ -501,7 +557,7 @@ public:
|
||||
|
||||
char req[128];
|
||||
snprintf(req, 128, "MESHCOMPILENAME %s %s %d", name.c_str(),
|
||||
MeshOutputModeString(outMode), skinSlotCount);
|
||||
MeshOutputModeString(topology), skinSlotCount);
|
||||
m_parent->_writeLine(req);
|
||||
|
||||
char readBuf[256];
|
||||
@ -509,11 +565,11 @@ public:
|
||||
if (strcmp(readBuf, "OK"))
|
||||
BlenderLog.report(LogVisor::FatalError, "unable to cook mesh '%s': %s", name.c_str(), readBuf);
|
||||
|
||||
return Mesh(*m_parent, outMode, skinSlotCount, surfProg);
|
||||
return Mesh(*m_parent, topology, skinSlotCount, surfProg);
|
||||
}
|
||||
|
||||
/** Compile all meshes into one (AREA blends only) */
|
||||
Mesh compileAllMeshes(Mesh::OutputMode outMode, int skinSlotCount=10, float maxOctantLength=5.0,
|
||||
Mesh compileAllMeshes(HMDLTopology topology, int skinSlotCount=10, float maxOctantLength=5.0,
|
||||
Mesh::SurfProgFunc surfProg=[](int){})
|
||||
{
|
||||
if (m_parent->m_loadedType != TypeArea)
|
||||
@ -522,7 +578,7 @@ public:
|
||||
|
||||
char req[128];
|
||||
snprintf(req, 128, "MESHCOMPILEALL %s %d %f",
|
||||
MeshOutputModeString(outMode),
|
||||
MeshOutputModeString(topology),
|
||||
skinSlotCount, maxOctantLength);
|
||||
m_parent->_writeLine(req);
|
||||
|
||||
@ -531,7 +587,7 @@ public:
|
||||
if (strcmp(readBuf, "OK"))
|
||||
BlenderLog.report(LogVisor::FatalError, "unable to cook all meshes: %s", readBuf);
|
||||
|
||||
return Mesh(*m_parent, outMode, skinSlotCount, surfProg);
|
||||
return Mesh(*m_parent, topology, skinSlotCount, surfProg);
|
||||
}
|
||||
|
||||
/** Intermediate actor representation prepared by blender from a single HECL actor blend */
|
||||
@ -651,6 +707,52 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class HMDLBuffers
|
||||
{
|
||||
public:
|
||||
struct Surface;
|
||||
private:
|
||||
friend struct BlenderConnection::DataStream::Mesh;
|
||||
HMDLBuffers(const HMDLMeta& meta,
|
||||
size_t vboSz, const std::vector<atUint32>& iboData,
|
||||
std::vector<Surface>&& surfaces,
|
||||
const BlenderConnection::DataStream::Mesh::SkinBanks& skinBanks)
|
||||
: m_metaSz(HECL_HMDL_META_SZ), m_metaData(new uint8_t[HECL_HMDL_META_SZ]),
|
||||
m_vboSz(vboSz), m_vboData(new uint8_t[vboSz]),
|
||||
m_iboSz(iboData.size()*4), m_iboData(new uint8_t[iboData.size()*4]),
|
||||
m_surfaces(std::move(surfaces)), m_skinBanks(skinBanks)
|
||||
{
|
||||
{
|
||||
Athena::io::MemoryWriter w(m_metaData.get(), HECL_HMDL_META_SZ);
|
||||
meta.write(w);
|
||||
}
|
||||
{
|
||||
Athena::io::MemoryWriter w(m_iboData.get(), m_iboSz);
|
||||
w.enumerateLittle(iboData);
|
||||
}
|
||||
}
|
||||
public:
|
||||
size_t m_metaSz;
|
||||
std::unique_ptr<uint8_t[]> m_metaData;
|
||||
size_t m_vboSz;
|
||||
std::unique_ptr<uint8_t[]> m_vboData;
|
||||
size_t m_iboSz;
|
||||
std::unique_ptr<uint8_t[]> m_iboData;
|
||||
|
||||
struct Surface
|
||||
{
|
||||
Surface(const BlenderConnection::DataStream::Mesh::Surface& origSurf,
|
||||
atUint32 start, atUint32 count)
|
||||
: m_origSurf(origSurf), m_start(start), m_count(count) {}
|
||||
const BlenderConnection::DataStream::Mesh::Surface& m_origSurf;
|
||||
atUint32 m_start;
|
||||
atUint32 m_count;
|
||||
};
|
||||
std::vector<Surface> m_surfaces;
|
||||
|
||||
const BlenderConnection::DataStream::Mesh::SkinBanks& m_skinBanks;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // BLENDERCONNECTION_HPP
|
||||
|
@ -25,6 +25,7 @@ bintoc(hecl_startup.c hecl_startup.blend HECL_STARTUP)
|
||||
add_library(HECLBlender
|
||||
BlenderConnection.cpp
|
||||
BlenderConnection.hpp
|
||||
HMDL.cpp
|
||||
hecl_blendershell.py
|
||||
hecl_blendershell.c
|
||||
zip_package.py
|
||||
|
121
hecl/blender/HMDL.cpp
Normal file
121
hecl/blender/HMDL.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
#include "BlenderConnection.hpp"
|
||||
|
||||
namespace HECL
|
||||
{
|
||||
|
||||
HMDLBuffers BlenderConnection::DataStream::Mesh::getHMDLBuffers() const
|
||||
{
|
||||
/* If skinned, compute max weight vec count */
|
||||
size_t weightCount = 0;
|
||||
for (const SkinBanks::Bank& bank : skinBanks.banks)
|
||||
weightCount = std::max(weightCount, bank.m_boneIdxs.size());
|
||||
size_t weightVecCount = weightCount / 4;
|
||||
if (weightCount % 4)
|
||||
++weightVecCount;
|
||||
|
||||
/* Prepare HMDL meta */
|
||||
HMDLMeta metaOut;
|
||||
metaOut.topology = topology;
|
||||
metaOut.vertStride = (3 + 3 + colorLayerCount + uvLayerCount * 2 + weightVecCount * 4) * 4;
|
||||
metaOut.colorCount = colorLayerCount;
|
||||
metaOut.uvCount = uvLayerCount;
|
||||
metaOut.weightCount = weightVecCount;
|
||||
|
||||
/* Total all verts from all surfaces (for ibo length) */
|
||||
size_t boundVerts = 0;
|
||||
for (const Surface& surf : surfaces)
|
||||
boundVerts += surf.verts.size();
|
||||
|
||||
/* Maintain unique vert pool for VBO */
|
||||
std::vector<std::pair<const Surface*, const Surface::Vert*>> vertPool;
|
||||
vertPool.reserve(boundVerts);
|
||||
|
||||
/* Target surfaces representation */
|
||||
std::vector<HMDLBuffers::Surface> outSurfaces;
|
||||
outSurfaces.reserve(surfaces.size());
|
||||
|
||||
/* Index buffer */
|
||||
std::vector<atUint32> iboData;
|
||||
iboData.reserve(boundVerts);
|
||||
|
||||
for (const Surface& surf : surfaces)
|
||||
{
|
||||
size_t iboStart = iboData.size();
|
||||
for (const Surface::Vert& v : surf.verts)
|
||||
{
|
||||
size_t ti = 0;
|
||||
bool found = false;
|
||||
for (const std::pair<const Surface*, const Surface::Vert*>& tv : vertPool)
|
||||
{
|
||||
if (v == *tv.second)
|
||||
{
|
||||
iboData.push_back(ti);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
++ti;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
iboData.push_back(vertPool.size());
|
||||
vertPool.emplace_back(&surf, &v);
|
||||
}
|
||||
}
|
||||
outSurfaces.emplace_back(surf, iboStart, iboData.size() - iboStart);
|
||||
}
|
||||
|
||||
metaOut.vertCount = vertPool.size();
|
||||
metaOut.indexCount = iboData.size();
|
||||
|
||||
size_t vboSz = metaOut.vertCount * metaOut.vertStride;
|
||||
HMDLBuffers ret(metaOut, vboSz, iboData, std::move(outSurfaces), skinBanks);
|
||||
Athena::io::MemoryWriter vboW(ret.m_vboData.get(), vboSz);
|
||||
for (const std::pair<const Surface*, const Surface::Vert*>& sv : vertPool)
|
||||
{
|
||||
const Surface& s = *sv.first;
|
||||
const Surface::Vert& v = *sv.second;
|
||||
|
||||
vboW.writeVec3fLittle(pos[v.iPos]);
|
||||
vboW.writeVec3fLittle(norm[v.iNorm]);
|
||||
|
||||
for (int i=0 ; i<colorLayerCount ; ++i)
|
||||
{
|
||||
const Vector3f& c = color[v.iColor[i]];
|
||||
vboW.writeUByte(std::max(0, std::min(255, int(c.val.vec[0] * 255))));
|
||||
vboW.writeUByte(std::max(0, std::min(255, int(c.val.vec[1] * 255))));
|
||||
vboW.writeUByte(std::max(0, std::min(255, int(c.val.vec[2] * 255))));
|
||||
vboW.writeUByte(255);
|
||||
}
|
||||
|
||||
for (int i=0 ; i<uvLayerCount ; ++i)
|
||||
vboW.writeVec2fLittle(uv[v.iUv[i]]);
|
||||
|
||||
if (weightVecCount)
|
||||
{
|
||||
const SkinBanks::Bank& bank = skinBanks.banks[s.skinBankIdx];
|
||||
const std::vector<SkinBind>& binds = skins[v.iSkin];
|
||||
auto it = bank.m_boneIdxs.cbegin();
|
||||
for (int i=0 ; i<weightVecCount ; ++i)
|
||||
{
|
||||
atVec4f vec = {};
|
||||
for (int j=0 ; j<4 ; ++j)
|
||||
{
|
||||
if (it == bank.m_boneIdxs.cend())
|
||||
break;
|
||||
for (const SkinBind& bind : binds)
|
||||
if (bind.boneIdx == *it)
|
||||
{
|
||||
vec.vec[j] = bind.weight;
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
vboW.writeVec4fLittle(vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
33
hecl/include/HECL/HMDLMeta.hpp
Normal file
33
hecl/include/HECL/HMDLMeta.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef HMDLMETA_HPP
|
||||
#define HMDLMETA_HPP
|
||||
|
||||
#include <HECL/HECL.hpp>
|
||||
#include <Athena/DNA.hpp>
|
||||
|
||||
namespace HECL
|
||||
{
|
||||
|
||||
enum HMDLTopology : atUint32
|
||||
{
|
||||
TopologyTriangles,
|
||||
TopologyTriStrips,
|
||||
};
|
||||
|
||||
#define HECL_HMDL_META_SZ 32
|
||||
|
||||
struct HMDLMeta : Athena::io::DNA<Athena::BigEndian>
|
||||
{
|
||||
DECL_DNA
|
||||
Value<atUint32> magic = SBIG('TACO');
|
||||
Value<HMDLTopology> topology;
|
||||
Value<atUint32> vertStride;
|
||||
Value<atUint32> vertCount;
|
||||
Value<atUint32> indexCount;
|
||||
Value<atUint32> colorCount;
|
||||
Value<atUint32> uvCount;
|
||||
Value<atUint32> weightCount;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HMDLMETA_HPP
|
@ -115,10 +115,14 @@ public:
|
||||
/**
|
||||
* @brief Integrated reader/constructor/container for HMDL data
|
||||
*/
|
||||
class HMDLData
|
||||
struct HMDLData
|
||||
{
|
||||
public:
|
||||
HMDLData(boo::IGraphicsDataFactory* factory, const void* data);
|
||||
boo::IGraphicsBufferS* m_vbo;
|
||||
boo::IGraphicsBufferS* m_ibo;
|
||||
boo::IVertexFormat* m_vtxFmt;
|
||||
|
||||
HMDLData(boo::IGraphicsDataFactory* factory,
|
||||
const void* metaData, const void* vbo, const void* ibo);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ if(WIN32)
|
||||
list(APPEND PLAT_SRCS winsupport.cpp ../include/HECL/winsupport.hpp)
|
||||
endif()
|
||||
|
||||
atdna(atdna_HMDLMeta.cpp ../include/HECL/HMDLMeta.hpp)
|
||||
atdna(atdna_Frontend.cpp ../include/HECL/Frontend.hpp)
|
||||
atdna(atdna_Runtime.cpp ../include/HECL/Runtime.hpp)
|
||||
|
||||
@ -15,6 +16,7 @@ add_library(HECLCommon
|
||||
ProjectPath.cpp
|
||||
WideStringConvert.cpp
|
||||
../include/HECL/HECL.hpp
|
||||
../include/HECL/HMDLMeta.hpp
|
||||
../include/HECL/Backend/Backend.hpp
|
||||
../include/HECL/Backend/GX.hpp
|
||||
../include/HECL/Backend/ProgrammableCommon.hpp
|
||||
@ -22,6 +24,7 @@ add_library(HECLCommon
|
||||
../include/HECL/Frontend.hpp
|
||||
../include/HECL/Database.hpp
|
||||
../include/HECL/Runtime.hpp
|
||||
atdna_HMDLMeta.cpp
|
||||
atdna_Frontend.cpp
|
||||
atdna_Runtime.cpp
|
||||
${PLAT_SRCS})
|
||||
|
@ -1,12 +1,58 @@
|
||||
#include "HECL/HMDLMeta.hpp"
|
||||
#include "HECL/Runtime.hpp"
|
||||
#include <Athena/MemoryReader.hpp>
|
||||
|
||||
namespace HECL
|
||||
{
|
||||
namespace Runtime
|
||||
{
|
||||
static LogVisor::LogModule Log("HMDL");
|
||||
|
||||
HMDLData::HMDLData(boo::IGraphicsDataFactory* factory, const void *data)
|
||||
HMDLData::HMDLData(boo::IGraphicsDataFactory* factory,
|
||||
const void* metaData, const void* vbo, const void* ibo)
|
||||
{
|
||||
HMDLMeta meta;
|
||||
{
|
||||
Athena::io::MemoryReader r((atUint8*)metaData, HECL_HMDL_META_SZ);
|
||||
meta.read(r);
|
||||
}
|
||||
if (meta.magic != FOURCC('TACO'))
|
||||
Log.report(LogVisor::FatalError, "invalid HMDL magic");
|
||||
|
||||
m_vbo = factory->newStaticBuffer(boo::BufferUseVertex, vbo, meta.vertStride, meta.vertCount);
|
||||
m_ibo = factory->newStaticBuffer(boo::BufferUseIndex, ibo, 4, meta.indexCount);
|
||||
|
||||
size_t elemCount = 2 + meta.colorCount + meta.uvCount + meta.weightCount;
|
||||
std::unique_ptr<boo::VertexElementDescriptor[]> vdescs(new boo::VertexElementDescriptor[elemCount]);
|
||||
for (size_t i=0 ; i<elemCount ; ++i)
|
||||
{
|
||||
vdescs[i].vertBuffer = m_vbo;
|
||||
vdescs[i].indexBuffer = m_ibo;
|
||||
}
|
||||
|
||||
vdescs[0].semantic = boo::VertexSemanticPosition;
|
||||
vdescs[1].semantic = boo::VertexSemanticNormal;
|
||||
size_t e = 2;
|
||||
|
||||
for (size_t i=0 ; i<meta.colorCount ; ++i, ++e)
|
||||
{
|
||||
vdescs[e].semantic = boo::VertexSemanticColor;
|
||||
vdescs[e].semanticIdx = i;
|
||||
}
|
||||
|
||||
for (size_t i=0 ; i<meta.uvCount ; ++i, ++e)
|
||||
{
|
||||
vdescs[e].semantic = boo::VertexSemanticUV;
|
||||
vdescs[e].semanticIdx = i;
|
||||
}
|
||||
|
||||
for (size_t i=0 ; i<meta.weightCount ; ++i, ++e)
|
||||
{
|
||||
vdescs[e].semantic = boo::VertexSemanticWeight;
|
||||
vdescs[e].semanticIdx = i;
|
||||
}
|
||||
|
||||
m_vtxFmt = factory->newVertexFormat(elemCount, vdescs.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user