Load vertex decl asset

This commit is contained in:
Jan 2022-04-10 19:39:26 +02:00
parent e0bcf7aff0
commit 99c7ebbe9b
9 changed files with 174 additions and 13 deletions

View File

@ -78,6 +78,23 @@ namespace IW4
"texcoord[7]", "texcoord[7]",
}; };
static_assert(std::extent_v<decltype(materialStreamDestinationNames)> == STREAM_DST_COUNT); static_assert(std::extent_v<decltype(materialStreamDestinationNames)> == STREAM_DST_COUNT);
static const char* materialStreamDestinationAbbreviation[]
{
"p",
"n",
"c0",
"c1",
"d",
"t0",
"t1",
"t2",
"t3",
"t4",
"t5",
"t6",
"t7",
};
static_assert(std::extent_v<decltype(materialStreamDestinationAbbreviation)> == STREAM_DST_COUNT);
static const char* materialStreamSourceNames[] static const char* materialStreamSourceNames[]
{ {
@ -92,6 +109,19 @@ namespace IW4
"normalTransform[1]" "normalTransform[1]"
}; };
static_assert(std::extent_v<decltype(materialStreamSourceNames)> == STREAM_SRC_COUNT); static_assert(std::extent_v<decltype(materialStreamSourceNames)> == STREAM_SRC_COUNT);
static const char* materialStreamSourceAbbreviation[]
{
"p",
"c",
"t0",
"n",
"t",
"t1",
"t2",
"n0",
"n1"
};
static_assert(std::extent_v<decltype(materialStreamSourceAbbreviation)> == STREAM_SRC_COUNT);
inline CodeSamplerSource s_lightmapSamplers[] inline CodeSamplerSource s_lightmapSamplers[]
{ {

View File

@ -91,12 +91,14 @@ namespace IW4
std::unique_ptr<d3d9::ShaderInfo> m_pixel_shader_info; std::unique_ptr<d3d9::ShaderInfo> m_pixel_shader_info;
MaterialVertexDeclaration m_vertex_decl; MaterialVertexDeclaration m_vertex_decl;
XAssetInfo<MaterialVertexDeclaration>* m_vertex_decl_asset;
std::vector<MaterialShaderArgument> m_arguments; std::vector<MaterialShaderArgument> m_arguments;
Pass() Pass()
: m_vertex_shader(nullptr), : m_vertex_shader(nullptr),
m_pixel_shader(nullptr), m_pixel_shader(nullptr),
m_vertex_decl{} m_vertex_decl{},
m_vertex_decl_asset(nullptr)
{ {
} }
}; };
@ -109,7 +111,6 @@ namespace IW4
m_manager(manager), m_manager(manager),
m_zone_state(zoneState) m_zone_state(zoneState)
{ {
m_passes.emplace_back();
} }
void AcceptNextPass() override void AcceptNextPass() override
@ -117,6 +118,50 @@ namespace IW4
m_passes.emplace_back(); m_passes.emplace_back();
} }
bool AutoCreateVertexShaderArguments(std::string& string)
{
return true;
}
bool AutoCreatePixelShaderArguments(std::string& string)
{
return true;
}
void AllocateVertexDecl()
{
assert(!m_passes.empty());
auto& pass = m_passes.at(m_passes.size() - 1);
std::sort(std::begin(pass.m_vertex_decl.routing.data), std::begin(pass.m_vertex_decl.routing.data) + pass.m_vertex_decl.streamCount,
[](const MaterialStreamRouting& r1, const MaterialStreamRouting& r2)
{
return r1.source < r2.source;
});
std::ostringstream ss;
for(auto i = 0u; i < pass.m_vertex_decl.streamCount; i++)
{
const auto& stream = pass.m_vertex_decl.routing.data[i];
assert(stream.source < std::extent_v<decltype(materialStreamSourceAbbreviation)>);
assert(stream.dest < std::extent_v<decltype(materialStreamDestinationAbbreviation)>);
ss << materialStreamSourceAbbreviation[stream.source] << materialStreamDestinationAbbreviation[stream.dest];
}
pass.m_vertex_decl_asset = reinterpret_cast<XAssetInfo<MaterialVertexDeclaration>*>(m_manager->LoadDependency(ASSET_TYPE_VERTEXDECL, ss.str()));
}
bool AcceptEndPass(std::string& errorMessage) override
{
if (!AutoCreateVertexShaderArguments(errorMessage) || !AutoCreatePixelShaderArguments(errorMessage))
return false;
AllocateVertexDecl();
return true;
}
void AcceptStateMap(const std::string& stateMapName) override void AcceptStateMap(const std::string& stateMapName) override
{ {
// TODO: State maps currently are not used // TODO: State maps currently are not used

View File

@ -1,9 +1,11 @@
#include "AssetLoaderVertexDecl.h" #include "AssetLoaderVertexDecl.h"
#include <cstring> #include <cstring>
#include <iostream>
#include "ObjLoading.h" #include "ObjLoading.h"
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
#include "Game/IW4/TechsetConstantsIW4.h"
#include "Pool/GlobalAssetPool.h" #include "Pool/GlobalAssetPool.h"
using namespace IW4; using namespace IW4;
@ -15,3 +17,79 @@ void* AssetLoaderVertexDecl::CreateEmptyAsset(const std::string& assetName, Memo
vertexDecl->name = memory->Dup(assetName.c_str()); vertexDecl->name = memory->Dup(assetName.c_str());
return vertexDecl; return vertexDecl;
} }
bool AssetLoaderVertexDecl::CanLoadFromRaw() const
{
return true;
}
bool AssetLoaderVertexDecl::NextAbbreviation(const std::string& assetName, std::string& abbreviation, size_t& offset)
{
if (offset >= assetName.size())
return false;
if (offset + 1 < assetName.size() && isdigit(assetName[offset + 1]))
{
abbreviation = std::string(assetName, offset, 2);
offset += 2;
}
else
{
abbreviation = std::string(assetName, offset, 1);
offset += 1;
}
return true;
}
bool AssetLoaderVertexDecl::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
{
MaterialVertexDeclaration decl{};
size_t currentOffset = 0u;
std::string sourceAbbreviation;
while (NextAbbreviation(assetName, sourceAbbreviation, currentOffset))
{
if(decl.streamCount >= std::extent_v<decltype(MaterialVertexStreamRouting::data)>)
{
std::cout << "Failed to add vertex decl stream. Too many abbreviations: " << assetName << "\n";
return false;
}
std::string destinationAbbreviation;
if (!NextAbbreviation(assetName, destinationAbbreviation, currentOffset))
{
std::cout << "Failed to detect vertex decl destination abbreviation: " << assetName << "\n";
return false;
}
const auto foundSourceAbbreviation = std::find(std::begin(materialStreamSourceAbbreviation), std::end(materialStreamSourceAbbreviation), sourceAbbreviation);
if (foundSourceAbbreviation == std::end(materialStreamSourceAbbreviation))
{
std::cout << "Unknown vertex decl source abbreviation: " << sourceAbbreviation << "\n";
return false;
}
const auto foundDestinationAbbreviation = std::find(std::begin(materialStreamDestinationAbbreviation), std::end(materialStreamDestinationAbbreviation), destinationAbbreviation);
if (foundDestinationAbbreviation == std::end(materialStreamDestinationAbbreviation))
{
std::cout << "Unknown vertex decl destination abbreviation: " << destinationAbbreviation << "\n";
return false;
}
const auto sourceIndex = static_cast<MaterialStreamStreamSource_e>(foundSourceAbbreviation - std::begin(materialStreamSourceAbbreviation));
const auto destinationIndex = static_cast<MaterialStreamDestination_e>(foundDestinationAbbreviation - std::begin(materialStreamDestinationAbbreviation));
decl.routing.data[decl.streamCount].source = sourceIndex;
decl.routing.data[decl.streamCount].dest = destinationIndex;
decl.hasOptionalSource = decl.hasOptionalSource || sourceIndex >= STREAM_SRC_OPTIONAL_BEGIN;
decl.streamCount++;
}
decl.name = memory->Dup(assetName.c_str());
auto* allocatedDecl = memory->Create<MaterialVertexDeclaration>(decl);
manager->AddAsset(ASSET_TYPE_VERTEXDECL, assetName, allocatedDecl);
return true;
}

View File

@ -8,7 +8,12 @@ namespace IW4
{ {
class AssetLoaderVertexDecl final : public BasicAssetLoader<ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration> class AssetLoaderVertexDecl final : public BasicAssetLoader<ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration>
{ {
static bool NextAbbreviation(const std::string& assetName, std::string& abbreviation, size_t& offset);
public: public:
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
_NODISCARD bool CanLoadFromRaw() const override;
bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
}; };
} }

View File

@ -26,9 +26,6 @@ namespace techset
assert(state->m_in_pass == false); assert(state->m_in_pass == false);
state->m_in_pass = true; state->m_in_pass = true;
if (state->m_before_first_pass)
state->m_before_first_pass = false;
else
state->m_acceptor->AcceptNextPass(); state->m_acceptor->AcceptNextPass();
} }
}; };

View File

@ -11,13 +11,15 @@ namespace techset
{ {
class SequenceEndPass final : public TechniqueParser::sequence_t class SequenceEndPass final : public TechniqueParser::sequence_t
{ {
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
public: public:
SequenceEndPass() SequenceEndPass()
{ {
const SimpleMatcherFactory create(this); const SimpleMatcherFactory create(this);
AddMatchers({ AddMatchers({
create.Char('}') create.Char('}').Capture(CAPTURE_FIRST_TOKEN)
}); });
} }
@ -25,6 +27,11 @@ namespace techset
void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override void ProcessMatch(TechniqueParserState* state, SequenceResult<SimpleParserValue>& result) const override
{ {
assert(state->m_in_pass == true); assert(state->m_in_pass == true);
std::string errorMessage;
if(!state->m_acceptor->AcceptEndPass(errorMessage))
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), errorMessage);
state->m_in_pass = false; state->m_in_pass = false;
} }
}; };

View File

@ -6,7 +6,6 @@ using namespace techset;
TechniqueParserState::TechniqueParserState(ITechniqueDefinitionAcceptor* acceptor) TechniqueParserState::TechniqueParserState(ITechniqueDefinitionAcceptor* acceptor)
: m_acceptor(acceptor), : m_acceptor(acceptor),
m_before_first_pass(true),
m_in_pass(false), m_in_pass(false),
m_in_shader(false), m_in_shader(false),
m_current_shader(ShaderSelector::VERTEX_SHADER) m_current_shader(ShaderSelector::VERTEX_SHADER)

View File

@ -9,7 +9,6 @@ namespace techset
public: public:
ITechniqueDefinitionAcceptor* const m_acceptor; ITechniqueDefinitionAcceptor* const m_acceptor;
bool m_before_first_pass;
bool m_in_pass; bool m_in_pass;
bool m_in_shader; bool m_in_shader;
ShaderSelector m_current_shader; ShaderSelector m_current_shader;

View File

@ -74,6 +74,7 @@ namespace techset
ITechniqueDefinitionAcceptor& operator=(ITechniqueDefinitionAcceptor&& other) noexcept = default; ITechniqueDefinitionAcceptor& operator=(ITechniqueDefinitionAcceptor&& other) noexcept = default;
virtual void AcceptNextPass() = 0; virtual void AcceptNextPass() = 0;
virtual bool AcceptEndPass(std::string& errorMessage) = 0;
virtual void AcceptStateMap(const std::string& stateMapName) = 0; virtual void AcceptStateMap(const std::string& stateMapName) = 0;