mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
feat: dump iw5 materials as json
This commit is contained in:
parent
7649e5d58f
commit
28a4fbd0d6
@ -9,6 +9,21 @@ namespace IW5
|
|||||||
public:
|
public:
|
||||||
static int StringTable_HashString(const char* str);
|
static int StringTable_HashString(const char* str);
|
||||||
|
|
||||||
|
static constexpr uint32_t R_HashString(const char* str, uint32_t hash)
|
||||||
|
{
|
||||||
|
for (const auto* pos = str; *pos; pos++)
|
||||||
|
{
|
||||||
|
hash = 33 * hash ^ (*pos | 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t R_HashString(const char* string)
|
||||||
|
{
|
||||||
|
return R_HashString(string, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
|
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
|
||||||
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
|
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
|
||||||
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
|
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
|
||||||
|
@ -675,6 +675,23 @@ namespace IW5
|
|||||||
gcc_align(8) uint64_t packed;
|
gcc_align(8) uint64_t packed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MaterialGameFlags
|
||||||
|
{
|
||||||
|
MTL_GAMEFLAG_1 = 0x1,
|
||||||
|
MTL_GAMEFLAG_2 = 0x2,
|
||||||
|
MTL_GAMEFLAG_4 = 0x4,
|
||||||
|
MTL_GAMEFLAG_8 = 0x8,
|
||||||
|
MTL_GAMEFLAG_10 = 0x10,
|
||||||
|
MTL_GAMEFLAG_20 = 0x20,
|
||||||
|
MTL_GAMEFLAG_40 = 0x40,
|
||||||
|
MTL_GAMEFLAG_80 = 0x80,
|
||||||
|
MTL_GAMEFLAG_100 = 0x100,
|
||||||
|
MTL_GAMEFLAG_200 = 0x200,
|
||||||
|
MTL_GAMEFLAG_400 = 0x400,
|
||||||
|
MTL_GAMEFLAG_800 = 0x800,
|
||||||
|
MTL_GAMEFLAG_1000 = 0x1000,
|
||||||
|
};
|
||||||
|
|
||||||
struct MaterialInfo
|
struct MaterialInfo
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
@ -737,13 +754,71 @@ namespace IW5
|
|||||||
water_t* water;
|
water_t* water;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TextureFilter
|
||||||
|
{
|
||||||
|
TEXTURE_FILTER_DISABLED = 0x0,
|
||||||
|
TEXTURE_FILTER_NEAREST = 0x1,
|
||||||
|
TEXTURE_FILTER_LINEAR = 0x2,
|
||||||
|
TEXTURE_FILTER_ANISO2X = 0x3,
|
||||||
|
TEXTURE_FILTER_ANISO4X = 0x4,
|
||||||
|
|
||||||
|
TEXTURE_FILTER_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SamplerStateBitsMipMap_e
|
||||||
|
{
|
||||||
|
SAMPLER_MIPMAP_ENUM_DISABLED,
|
||||||
|
SAMPLER_MIPMAP_ENUM_NEAREST,
|
||||||
|
SAMPLER_MIPMAP_ENUM_LINEAR,
|
||||||
|
|
||||||
|
SAMPLER_MIPMAP_ENUM_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SamplerStateBits_e
|
||||||
|
{
|
||||||
|
SAMPLER_FILTER_SHIFT = 0x0,
|
||||||
|
SAMPLER_FILTER_NEAREST = 0x1,
|
||||||
|
SAMPLER_FILTER_LINEAR = 0x2,
|
||||||
|
SAMPLER_FILTER_ANISO2X = 0x3,
|
||||||
|
SAMPLER_FILTER_ANISO4X = 0x4,
|
||||||
|
SAMPLER_FILTER_MASK = 0x7,
|
||||||
|
|
||||||
|
SAMPLER_MIPMAP_SHIFT = 0x3,
|
||||||
|
SAMPLER_MIPMAP_DISABLED = 0x0,
|
||||||
|
SAMPLER_MIPMAP_NEAREST = 0x8,
|
||||||
|
SAMPLER_MIPMAP_LINEAR = 0x10,
|
||||||
|
SAMPLER_MIPMAP_COUNT = 0x3,
|
||||||
|
SAMPLER_MIPMAP_MASK = 0x18,
|
||||||
|
|
||||||
|
SAMPLER_CLAMP_U_SHIFT = 0x5,
|
||||||
|
SAMPLER_CLAMP_V_SHIFT = 0x6,
|
||||||
|
SAMPLER_CLAMP_W_SHIFT = 0x7,
|
||||||
|
SAMPLER_CLAMP_U = 0x20,
|
||||||
|
SAMPLER_CLAMP_V = 0x40,
|
||||||
|
SAMPLER_CLAMP_W = 0x80,
|
||||||
|
SAMPLER_CLAMP_MASK = 0xE0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MaterialTextureDefSamplerState
|
||||||
|
{
|
||||||
|
unsigned char filter : 3;
|
||||||
|
unsigned char mipMap : 2;
|
||||||
|
unsigned char clampU : 1;
|
||||||
|
unsigned char clampV : 1;
|
||||||
|
unsigned char clampW : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef __zonecodegenerator
|
||||||
|
static_assert(sizeof(MaterialTextureDefSamplerState) == 1u);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct MaterialTextureDef
|
struct MaterialTextureDef
|
||||||
{
|
{
|
||||||
unsigned int nameHash;
|
unsigned int nameHash;
|
||||||
char nameStart;
|
char nameStart;
|
||||||
char nameEnd;
|
char nameEnd;
|
||||||
unsigned char samplerState;
|
MaterialTextureDefSamplerState samplerState;
|
||||||
unsigned char semantic;
|
unsigned char semantic; // TextureSemantic
|
||||||
MaterialTextureDefInfo u;
|
MaterialTextureDefInfo u;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -751,18 +826,161 @@ namespace IW5
|
|||||||
{
|
{
|
||||||
unsigned int nameHash;
|
unsigned int nameHash;
|
||||||
char name[12];
|
char name[12];
|
||||||
float literal[4];
|
vec4_t literal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum GfxBlend
|
||||||
|
{
|
||||||
|
GFXS_BLEND_DISABLED = 0x0,
|
||||||
|
GFXS_BLEND_ZERO = 0x1,
|
||||||
|
GFXS_BLEND_ONE = 0x2,
|
||||||
|
GFXS_BLEND_SRCCOLOR = 0x3,
|
||||||
|
GFXS_BLEND_INVSRCCOLOR = 0x4,
|
||||||
|
GFXS_BLEND_SRCALPHA = 0x5,
|
||||||
|
GFXS_BLEND_INVSRCALPHA = 0x6,
|
||||||
|
GFXS_BLEND_DESTALPHA = 0x7,
|
||||||
|
GFXS_BLEND_INVDESTALPHA = 0x8,
|
||||||
|
GFXS_BLEND_DESTCOLOR = 0x9,
|
||||||
|
GFXS_BLEND_INVDESTCOLOR = 0xA,
|
||||||
|
|
||||||
|
GFXS_BLEND_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GfxBlendOp
|
||||||
|
{
|
||||||
|
GFXS_BLENDOP_DISABLED = 0x0,
|
||||||
|
GFXS_BLENDOP_ADD = 0x1,
|
||||||
|
GFXS_BLENDOP_SUBTRACT = 0x2,
|
||||||
|
GFXS_BLENDOP_REVSUBTRACT = 0x3,
|
||||||
|
GFXS_BLENDOP_MIN = 0x4,
|
||||||
|
GFXS_BLENDOP_MAX = 0x5,
|
||||||
|
|
||||||
|
GFXS_BLENDOP_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GfxAlphaTest_e
|
||||||
|
{
|
||||||
|
GFXS_ALPHA_TEST_GT_0 = 1,
|
||||||
|
GFXS_ALPHA_TEST_LT_128 = 2,
|
||||||
|
GFXS_ALPHA_TEST_GE_128 = 3,
|
||||||
|
|
||||||
|
GFXS_ALPHA_TEST_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GfxCullFace_e
|
||||||
|
{
|
||||||
|
GFXS_CULL_NONE = 1,
|
||||||
|
GFXS_CULL_BACK = 2,
|
||||||
|
GFXS_CULL_FRONT = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GfxDepthTest_e
|
||||||
|
{
|
||||||
|
GFXS_DEPTHTEST_ALWAYS = 0,
|
||||||
|
GFXS_DEPTHTEST_LESS = 1,
|
||||||
|
GFXS_DEPTHTEST_EQUAL = 2,
|
||||||
|
GFXS_DEPTHTEST_LESSEQUAL = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GfxPolygonOffset_e
|
||||||
|
{
|
||||||
|
GFXS_POLYGON_OFFSET_0 = 0,
|
||||||
|
GFXS_POLYGON_OFFSET_1 = 1,
|
||||||
|
GFXS_POLYGON_OFFSET_2 = 2,
|
||||||
|
GFXS_POLYGON_OFFSET_SHADOWMAP = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GfxStencilOp
|
||||||
|
{
|
||||||
|
GFXS_STENCILOP_KEEP = 0x0,
|
||||||
|
GFXS_STENCILOP_ZERO = 0x1,
|
||||||
|
GFXS_STENCILOP_REPLACE = 0x2,
|
||||||
|
GFXS_STENCILOP_INCRSAT = 0x3,
|
||||||
|
GFXS_STENCILOP_DECRSAT = 0x4,
|
||||||
|
GFXS_STENCILOP_INVERT = 0x5,
|
||||||
|
GFXS_STENCILOP_INCR = 0x6,
|
||||||
|
GFXS_STENCILOP_DECR = 0x7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GfxStencilFunc
|
||||||
|
{
|
||||||
|
GFXS_STENCILFUNC_NEVER = 0x0,
|
||||||
|
GFXS_STENCILFUNC_LESS = 0x1,
|
||||||
|
GFXS_STENCILFUNC_EQUAL = 0x2,
|
||||||
|
GFXS_STENCILFUNC_LESSEQUAL = 0x3,
|
||||||
|
GFXS_STENCILFUNC_GREATER = 0x4,
|
||||||
|
GFXS_STENCILFUNC_NOTEQUAL = 0x5,
|
||||||
|
GFXS_STENCILFUNC_GREATEREQUAL = 0x6,
|
||||||
|
GFXS_STENCILFUNC_ALWAYS = 0x7
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GfxStateBitsLoadBitsStructured
|
||||||
|
{
|
||||||
|
// Byte 0
|
||||||
|
unsigned int srcBlendRgb : 4; // 0-3
|
||||||
|
unsigned int dstBlendRgb : 4; // 4-7
|
||||||
|
unsigned int blendOpRgb : 3; // 8-10
|
||||||
|
unsigned int alphaTestDisabled : 1; // 11
|
||||||
|
unsigned int alphaTest : 2; // 12-13
|
||||||
|
unsigned int cullFace : 2; // 14-15
|
||||||
|
unsigned int srcBlendAlpha : 4; // 16-19
|
||||||
|
unsigned int dstBlendAlpha : 4; // 20-23
|
||||||
|
unsigned int blendOpAlpha : 3; // 24-26
|
||||||
|
unsigned int colorWriteRgb : 1; // 27
|
||||||
|
unsigned int colorWriteAlpha : 1; // 28
|
||||||
|
unsigned int unused0 : 1; // 29
|
||||||
|
unsigned int gammaWrite : 1; // 30
|
||||||
|
unsigned int polymodeLine : 1; // 31
|
||||||
|
|
||||||
|
// Byte 1
|
||||||
|
unsigned int depthWrite : 1; // 0
|
||||||
|
unsigned int depthTestDisabled : 1; // 1
|
||||||
|
unsigned int depthTest : 2; // 2-3
|
||||||
|
unsigned int polygonOffset : 2; // 4-5
|
||||||
|
unsigned int stencilFrontEnabled : 1; // 6
|
||||||
|
unsigned int stencilBackEnabled : 1; // 7
|
||||||
|
unsigned int stencilFrontPass : 3; // 8-10
|
||||||
|
unsigned int stencilFrontFail : 3; // 11-13
|
||||||
|
unsigned int stencilFrontZFail : 3; // 14-16
|
||||||
|
unsigned int stencilFrontFunc : 3; // 17-19
|
||||||
|
unsigned int stencilBackPass : 3; // 20-22
|
||||||
|
unsigned int stencilBackFail : 3; // 23-25
|
||||||
|
unsigned int stencilBackZFail : 3; // 26-28
|
||||||
|
unsigned int stencilBackFunc : 3; // 29-31
|
||||||
|
};
|
||||||
|
|
||||||
|
union GfxStateBitsLoadBits
|
||||||
|
{
|
||||||
|
unsigned int raw[2];
|
||||||
|
GfxStateBitsLoadBitsStructured structured;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef __zonecodegenerator
|
||||||
|
static_assert(sizeof(GfxStateBitsLoadBits) == 8);
|
||||||
|
static_assert(sizeof(GfxStateBitsLoadBitsStructured) == 8);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct GfxStateBits
|
struct GfxStateBits
|
||||||
{
|
{
|
||||||
unsigned int loadBits[2];
|
GfxStateBitsLoadBits loadBits;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GfxCameraRegionType
|
||||||
|
{
|
||||||
|
CAMERA_REGION_LIT_OPAQUE = 0x0,
|
||||||
|
CAMERA_REGION_LIT_TRANS = 0x1,
|
||||||
|
CAMERA_REGION_EMISSIVE = 0x2,
|
||||||
|
CAMERA_REGION_DEPTH_HACK = 0x3,
|
||||||
|
CAMERA_REGION_LIGHT_MAP_OPAQUE = 0x4,
|
||||||
|
|
||||||
|
CAMERA_REGION_COUNT,
|
||||||
|
CAMERA_REGION_NONE = CAMERA_REGION_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
MaterialInfo info;
|
MaterialInfo info;
|
||||||
unsigned char stateBitsEntry[54];
|
char stateBitsEntry[54];
|
||||||
unsigned char textureCount;
|
unsigned char textureCount;
|
||||||
unsigned char constantCount;
|
unsigned char constantCount;
|
||||||
unsigned char stateBitsCount;
|
unsigned char stateBitsCount;
|
||||||
|
391
src/ObjCommon/Game/IW5/Material/JsonMaterial.h
Normal file
391
src/ObjCommon/Game/IW5/Material/JsonMaterial.h
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Game/IW5/IW5.h"
|
||||||
|
|
||||||
|
#include "Json/JsonExtension.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace IW5
|
||||||
|
{
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilOp,
|
||||||
|
{
|
||||||
|
{GFXS_STENCILOP_KEEP, "keep" },
|
||||||
|
{GFXS_STENCILOP_ZERO, "zero" },
|
||||||
|
{GFXS_STENCILOP_REPLACE, "replace"},
|
||||||
|
{GFXS_STENCILOP_INCRSAT, "incrsat"},
|
||||||
|
{GFXS_STENCILOP_DECRSAT, "decrsat"},
|
||||||
|
{GFXS_STENCILOP_INVERT, "invert" },
|
||||||
|
{GFXS_STENCILOP_INCR, "incr" },
|
||||||
|
{GFXS_STENCILOP_DECR, "decr" },
|
||||||
|
});
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilFunc,
|
||||||
|
{
|
||||||
|
{GFXS_STENCILFUNC_NEVER, "never" },
|
||||||
|
{GFXS_STENCILFUNC_LESS, "less" },
|
||||||
|
{GFXS_STENCILFUNC_EQUAL, "equal" },
|
||||||
|
{GFXS_STENCILFUNC_LESSEQUAL, "lessequal" },
|
||||||
|
{GFXS_STENCILFUNC_GREATER, "greater" },
|
||||||
|
{GFXS_STENCILFUNC_NOTEQUAL, "notequal" },
|
||||||
|
{GFXS_STENCILFUNC_GREATEREQUAL, "greaterequal"},
|
||||||
|
{GFXS_STENCILFUNC_ALWAYS, "always" },
|
||||||
|
});
|
||||||
|
|
||||||
|
class JsonStencil
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GfxStencilOp pass;
|
||||||
|
GfxStencilOp fail;
|
||||||
|
GfxStencilOp zfail;
|
||||||
|
GfxStencilFunc func;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStencil, pass, fail, zfail, func);
|
||||||
|
|
||||||
|
enum class JsonAlphaTest
|
||||||
|
{
|
||||||
|
INVALID,
|
||||||
|
DISABLED,
|
||||||
|
GT0,
|
||||||
|
LT128,
|
||||||
|
GE128
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(JsonAlphaTest,
|
||||||
|
{
|
||||||
|
{JsonAlphaTest::INVALID, nullptr },
|
||||||
|
{JsonAlphaTest::DISABLED, "disabled"},
|
||||||
|
{JsonAlphaTest::GT0, "gt0" },
|
||||||
|
{JsonAlphaTest::LT128, "lt128" },
|
||||||
|
{JsonAlphaTest::GE128, "ge128" }
|
||||||
|
});
|
||||||
|
|
||||||
|
enum class JsonCullFace
|
||||||
|
{
|
||||||
|
INVALID,
|
||||||
|
NONE,
|
||||||
|
BACK,
|
||||||
|
FRONT
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(
|
||||||
|
JsonCullFace,
|
||||||
|
{
|
||||||
|
{JsonCullFace::INVALID, nullptr},
|
||||||
|
{JsonCullFace::NONE, "none" },
|
||||||
|
{JsonCullFace::BACK, "back" },
|
||||||
|
{JsonCullFace::FRONT, "front"}
|
||||||
|
});
|
||||||
|
|
||||||
|
enum class JsonDepthTest
|
||||||
|
{
|
||||||
|
INVALID,
|
||||||
|
DISABLED,
|
||||||
|
ALWAYS,
|
||||||
|
LESS,
|
||||||
|
EQUAL,
|
||||||
|
LESS_EQUAL
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(JsonDepthTest,
|
||||||
|
{
|
||||||
|
{JsonDepthTest::INVALID, nullptr },
|
||||||
|
{JsonDepthTest::DISABLED, "disabled" },
|
||||||
|
{JsonDepthTest::ALWAYS, "always" },
|
||||||
|
{JsonDepthTest::LESS, "less" },
|
||||||
|
{JsonDepthTest::EQUAL, "equal" },
|
||||||
|
{JsonDepthTest::LESS_EQUAL, "less_equal"}
|
||||||
|
});
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlend,
|
||||||
|
{
|
||||||
|
{GFXS_BLEND_DISABLED, "disabled" },
|
||||||
|
{GFXS_BLEND_ZERO, "zero" },
|
||||||
|
{GFXS_BLEND_ONE, "one" },
|
||||||
|
{GFXS_BLEND_SRCCOLOR, "srccolor" },
|
||||||
|
{GFXS_BLEND_INVSRCCOLOR, "invsrccolor" },
|
||||||
|
{GFXS_BLEND_SRCALPHA, "srcalpha" },
|
||||||
|
{GFXS_BLEND_INVSRCALPHA, "invsrcalpha" },
|
||||||
|
{GFXS_BLEND_DESTALPHA, "destalpha" },
|
||||||
|
{GFXS_BLEND_INVDESTALPHA, "invdestalpha"},
|
||||||
|
{GFXS_BLEND_DESTCOLOR, "destcolor" },
|
||||||
|
{GFXS_BLEND_INVDESTCOLOR, "invdestcolor"},
|
||||||
|
});
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlendOp,
|
||||||
|
{
|
||||||
|
{GFXS_BLENDOP_DISABLED, "disabled" },
|
||||||
|
{GFXS_BLENDOP_ADD, "add" },
|
||||||
|
{GFXS_BLENDOP_SUBTRACT, "subtract" },
|
||||||
|
{GFXS_BLENDOP_REVSUBTRACT, "revsubtract"},
|
||||||
|
{GFXS_BLENDOP_MIN, "min" },
|
||||||
|
{GFXS_BLENDOP_MAX, "max" },
|
||||||
|
});
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(GfxPolygonOffset_e,
|
||||||
|
{
|
||||||
|
{GFXS_POLYGON_OFFSET_0, "offset0" },
|
||||||
|
{GFXS_POLYGON_OFFSET_1, "offset1" },
|
||||||
|
{GFXS_POLYGON_OFFSET_2, "offset2" },
|
||||||
|
{GFXS_POLYGON_OFFSET_SHADOWMAP, "offsetShadowmap"},
|
||||||
|
});
|
||||||
|
|
||||||
|
class JsonStateBitsTableEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GfxBlend srcBlendRgb;
|
||||||
|
GfxBlend dstBlendRgb;
|
||||||
|
GfxBlendOp blendOpRgb;
|
||||||
|
JsonAlphaTest alphaTest;
|
||||||
|
JsonCullFace cullFace;
|
||||||
|
GfxBlend srcBlendAlpha;
|
||||||
|
GfxBlend dstBlendAlpha;
|
||||||
|
GfxBlendOp blendOpAlpha;
|
||||||
|
bool colorWriteRgb;
|
||||||
|
bool colorWriteAlpha;
|
||||||
|
bool gammaWrite;
|
||||||
|
bool polymodeLine;
|
||||||
|
bool depthWrite;
|
||||||
|
JsonDepthTest depthTest;
|
||||||
|
GfxPolygonOffset_e polygonOffset;
|
||||||
|
std::optional<JsonStencil> stencilFront;
|
||||||
|
std::optional<JsonStencil> stencilBack;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStateBitsTableEntry,
|
||||||
|
srcBlendRgb,
|
||||||
|
dstBlendRgb,
|
||||||
|
blendOpRgb,
|
||||||
|
alphaTest,
|
||||||
|
cullFace,
|
||||||
|
srcBlendAlpha,
|
||||||
|
dstBlendAlpha,
|
||||||
|
blendOpAlpha,
|
||||||
|
colorWriteRgb,
|
||||||
|
colorWriteAlpha,
|
||||||
|
polymodeLine,
|
||||||
|
depthWrite,
|
||||||
|
depthWrite,
|
||||||
|
depthTest,
|
||||||
|
polygonOffset,
|
||||||
|
stencilFront,
|
||||||
|
stencilBack);
|
||||||
|
|
||||||
|
class JsonConstant
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::optional<std::string> name;
|
||||||
|
std::optional<std::string> nameFragment;
|
||||||
|
std::optional<unsigned> nameHash;
|
||||||
|
std::vector<float> literal;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void to_json(nlohmann::json& out, const JsonConstant& in)
|
||||||
|
{
|
||||||
|
if (in.name.has_value())
|
||||||
|
{
|
||||||
|
optional_to_json(out, "name", in.name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
optional_to_json(out, "nameFragment", in.nameFragment);
|
||||||
|
optional_to_json(out, "nameHash", in.nameHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
out["literal"] = in.literal;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void from_json(const nlohmann::json& in, JsonConstant& out)
|
||||||
|
{
|
||||||
|
optional_from_json(in, "name", out.name);
|
||||||
|
optional_from_json(in, "nameFragment", out.nameFragment);
|
||||||
|
optional_from_json(in, "nameHash", out.nameHash);
|
||||||
|
in.at("literal").get_to(out.literal);
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(TextureFilter,
|
||||||
|
{
|
||||||
|
{TEXTURE_FILTER_DISABLED, "disabled"},
|
||||||
|
{TEXTURE_FILTER_NEAREST, "nearest" },
|
||||||
|
{TEXTURE_FILTER_LINEAR, "linear" },
|
||||||
|
{TEXTURE_FILTER_ANISO2X, "aniso2x" },
|
||||||
|
{TEXTURE_FILTER_ANISO4X, "aniso4x" },
|
||||||
|
});
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(SamplerStateBitsMipMap_e,
|
||||||
|
{
|
||||||
|
{SAMPLER_MIPMAP_ENUM_DISABLED, "disabled"},
|
||||||
|
{SAMPLER_MIPMAP_ENUM_NEAREST, "nearest" },
|
||||||
|
{SAMPLER_MIPMAP_ENUM_LINEAR, "linear" },
|
||||||
|
});
|
||||||
|
|
||||||
|
class JsonSamplerState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextureFilter filter;
|
||||||
|
SamplerStateBitsMipMap_e mipMap;
|
||||||
|
bool clampU;
|
||||||
|
bool clampV;
|
||||||
|
bool clampW;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonSamplerState, filter, mipMap, clampU, clampV, clampW);
|
||||||
|
|
||||||
|
class JsonComplex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float real;
|
||||||
|
float imag;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonComplex, real, imag);
|
||||||
|
|
||||||
|
class JsonWater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float floatTime;
|
||||||
|
int m;
|
||||||
|
int n;
|
||||||
|
std::string h0;
|
||||||
|
std::string wTerm;
|
||||||
|
float lx;
|
||||||
|
float lz;
|
||||||
|
float gravity;
|
||||||
|
float windvel;
|
||||||
|
std::array<float, 2> winddir;
|
||||||
|
float amplitude;
|
||||||
|
std::array<float, 4> codeConstant;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWater, floatTime, m, n, h0, wTerm, lx, lz, gravity, windvel, winddir, amplitude, codeConstant);
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(TextureSemantic,
|
||||||
|
{
|
||||||
|
{TS_2D, "2D" },
|
||||||
|
{TS_FUNCTION, "function" },
|
||||||
|
{TS_COLOR_MAP, "colorMap" },
|
||||||
|
{TS_DETAIL_MAP, "detailMap" },
|
||||||
|
{TS_UNUSED_2, "unused2" },
|
||||||
|
{TS_NORMAL_MAP, "normalMap" },
|
||||||
|
{TS_UNUSED_3, "unused3" },
|
||||||
|
{TS_UNUSED_4, "unused4" },
|
||||||
|
{TS_SPECULAR_MAP, "specularMap" },
|
||||||
|
{TS_UNUSED_5, "unused5" },
|
||||||
|
{TS_UNUSED_6, "unused6" },
|
||||||
|
{TS_WATER_MAP, "waterMap" },
|
||||||
|
{TS_DISPLACEMENT_MAP, "displacementMap"},
|
||||||
|
});
|
||||||
|
|
||||||
|
class JsonTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::optional<std::string> name;
|
||||||
|
std::optional<unsigned> nameHash;
|
||||||
|
std::optional<std::string> nameStart;
|
||||||
|
std::optional<std::string> nameEnd;
|
||||||
|
TextureSemantic semantic;
|
||||||
|
JsonSamplerState samplerState;
|
||||||
|
std::string image;
|
||||||
|
std::optional<JsonWater> water;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void to_json(nlohmann::json& out, const JsonTexture& in)
|
||||||
|
{
|
||||||
|
if (in.name.has_value())
|
||||||
|
{
|
||||||
|
optional_to_json(out, "name", in.name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
optional_to_json(out, "nameHash", in.nameHash);
|
||||||
|
optional_to_json(out, "nameStart", in.nameStart);
|
||||||
|
optional_to_json(out, "nameEnd", in.nameEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
out["semantic"] = in.semantic;
|
||||||
|
out["samplerState"] = in.samplerState;
|
||||||
|
out["image"] = in.image;
|
||||||
|
optional_to_json(out, "water", in.water);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void from_json(const nlohmann::json& in, JsonTexture& out)
|
||||||
|
{
|
||||||
|
optional_from_json(in, "name", out.name);
|
||||||
|
optional_from_json(in, "nameHash", out.nameHash);
|
||||||
|
optional_from_json(in, "nameStart", out.nameStart);
|
||||||
|
optional_from_json(in, "nameEnd", out.nameEnd);
|
||||||
|
in.at("semantic").get_to(out.semantic);
|
||||||
|
in.at("samplerState").get_to(out.samplerState);
|
||||||
|
in.at("image").get_to(out.image);
|
||||||
|
optional_from_json(in, "water", out.water);
|
||||||
|
};
|
||||||
|
|
||||||
|
class JsonTextureAtlas
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint8_t rows;
|
||||||
|
uint8_t columns;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonTextureAtlas, rows, columns);
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(MaterialGameFlags,
|
||||||
|
{
|
||||||
|
{MTL_GAMEFLAG_1, "1" },
|
||||||
|
{MTL_GAMEFLAG_2, "2" },
|
||||||
|
{MTL_GAMEFLAG_4, "4" },
|
||||||
|
{MTL_GAMEFLAG_8, "8" },
|
||||||
|
{MTL_GAMEFLAG_10, "10" },
|
||||||
|
{MTL_GAMEFLAG_20, "20" },
|
||||||
|
{MTL_GAMEFLAG_40, "40" },
|
||||||
|
{MTL_GAMEFLAG_80, "80" },
|
||||||
|
{MTL_GAMEFLAG_100, "100" },
|
||||||
|
{MTL_GAMEFLAG_200, "200" },
|
||||||
|
{MTL_GAMEFLAG_400, "400" },
|
||||||
|
{MTL_GAMEFLAG_800, "800" },
|
||||||
|
{MTL_GAMEFLAG_1000, "1000"},
|
||||||
|
});
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(GfxCameraRegionType,
|
||||||
|
{
|
||||||
|
{CAMERA_REGION_LIT_OPAQUE, "litOpaque" },
|
||||||
|
{CAMERA_REGION_LIT_TRANS, "litTrans" },
|
||||||
|
{CAMERA_REGION_EMISSIVE, "emissive" },
|
||||||
|
{CAMERA_REGION_DEPTH_HACK, "depthHack" },
|
||||||
|
{CAMERA_REGION_LIGHT_MAP_OPAQUE, "lightMapOpaque"},
|
||||||
|
{CAMERA_REGION_NONE, "none" },
|
||||||
|
});
|
||||||
|
|
||||||
|
class JsonMaterial
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<MaterialGameFlags> gameFlags;
|
||||||
|
unsigned sortKey;
|
||||||
|
std::optional<JsonTextureAtlas> textureAtlas;
|
||||||
|
unsigned surfaceTypeBits;
|
||||||
|
std::vector<int8_t> stateBitsEntry;
|
||||||
|
unsigned stateFlags;
|
||||||
|
GfxCameraRegionType cameraRegion;
|
||||||
|
std::string techniqueSet;
|
||||||
|
std::vector<JsonTexture> textures;
|
||||||
|
std::vector<JsonConstant> constants;
|
||||||
|
std::vector<JsonStateBitsTableEntry> stateBits;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterial,
|
||||||
|
gameFlags,
|
||||||
|
sortKey,
|
||||||
|
textureAtlas,
|
||||||
|
surfaceTypeBits,
|
||||||
|
stateBitsEntry,
|
||||||
|
stateFlags,
|
||||||
|
cameraRegion,
|
||||||
|
techniqueSet,
|
||||||
|
textures,
|
||||||
|
constants,
|
||||||
|
stateBits);
|
||||||
|
} // namespace IW5
|
48
src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperMaterial.cpp
Normal file
48
src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperMaterial.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include "AssetDumperMaterial.h"
|
||||||
|
|
||||||
|
#include "Game/IW5/Material/JsonMaterialWriter.h"
|
||||||
|
#include "Game/IW5/Material/MaterialConstantZoneState.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <format>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
|
using namespace IW5;
|
||||||
|
|
||||||
|
std::string AssetDumperMaterial::GetFileNameForAsset(const std::string& assetName)
|
||||||
|
{
|
||||||
|
std::string sanitizedFileName(assetName);
|
||||||
|
if (sanitizedFileName[0] == '*')
|
||||||
|
{
|
||||||
|
std::ranges::replace(sanitizedFileName, '*', '_');
|
||||||
|
const auto parenthesisPos = sanitizedFileName.find('(');
|
||||||
|
if (parenthesisPos != std::string::npos)
|
||||||
|
sanitizedFileName.erase(parenthesisPos);
|
||||||
|
sanitizedFileName = "generated/" + sanitizedFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::format("materials/{}.json", sanitizedFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetDumperMaterial::ShouldDump(XAssetInfo<Material>* asset)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfo<Material>* asset)
|
||||||
|
{
|
||||||
|
const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset->m_name));
|
||||||
|
|
||||||
|
if (!assetFile)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DumpMaterialAsJson(*assetFile, asset->Asset(), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetDumperMaterial::DumpPool(AssetDumpingContext& context, AssetPool<Material>* pool)
|
||||||
|
{
|
||||||
|
auto* materialConstantState = context.GetZoneAssetDumperState<MaterialConstantZoneState>();
|
||||||
|
materialConstantState->ExtractNamesFromZone();
|
||||||
|
|
||||||
|
AbstractAssetDumper::DumpPool(context, pool);
|
||||||
|
}
|
21
src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperMaterial.h
Normal file
21
src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperMaterial.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
|
#include "Game/IW5/IW5.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace IW5
|
||||||
|
{
|
||||||
|
class AssetDumperMaterial final : public AbstractAssetDumper<Material>
|
||||||
|
{
|
||||||
|
static std::string GetFileNameForAsset(const std::string& assetName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool ShouldDump(XAssetInfo<Material>* asset) override;
|
||||||
|
void DumpAsset(AssetDumpingContext& context, XAssetInfo<Material>* asset) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void DumpPool(AssetDumpingContext& context, AssetPool<Material>* pool) override;
|
||||||
|
};
|
||||||
|
} // namespace IW5
|
293
src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.cpp
Normal file
293
src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.cpp
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
#include "JsonMaterialWriter.h"
|
||||||
|
|
||||||
|
#include "Game/IW5/CommonIW5.h"
|
||||||
|
#include "Game/IW5/Material/JsonMaterial.h"
|
||||||
|
#include "Impl/Base64.h"
|
||||||
|
#include "MaterialConstantZoneState.h"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
using namespace IW5;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class JsonDumper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JsonDumper(AssetDumpingContext& context, std::ostream& stream)
|
||||||
|
: m_stream(stream),
|
||||||
|
m_material_constants(*context.GetZoneAssetDumperState<MaterialConstantZoneState>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dump(const Material* material) const
|
||||||
|
{
|
||||||
|
JsonMaterial jsonMaterial;
|
||||||
|
CreateJsonMaterial(jsonMaterial, *material);
|
||||||
|
json jRoot = jsonMaterial;
|
||||||
|
|
||||||
|
jRoot["_type"] = "material";
|
||||||
|
jRoot["_game"] = "iw5";
|
||||||
|
jRoot["_version"] = 1;
|
||||||
|
|
||||||
|
m_stream << std::setw(4) << jRoot << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char* AssetName(const char* input)
|
||||||
|
{
|
||||||
|
if (input && input[0] == ',')
|
||||||
|
return &input[1];
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateJsonGameFlags(JsonMaterial& jMaterial, const unsigned gameFlags)
|
||||||
|
{
|
||||||
|
jMaterial.gameFlags.clear();
|
||||||
|
for (auto i = 0u; i < sizeof(gameFlags) * 8u; i++)
|
||||||
|
{
|
||||||
|
const auto flag = static_cast<MaterialGameFlags>(1 << i);
|
||||||
|
|
||||||
|
if (gameFlags & flag)
|
||||||
|
jMaterial.gameFlags.emplace_back(flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateJsonSamplerState(JsonSamplerState& jSamplerState, const MaterialTextureDefSamplerState& samplerState)
|
||||||
|
{
|
||||||
|
jSamplerState.filter = static_cast<TextureFilter>(samplerState.filter);
|
||||||
|
jSamplerState.mipMap = static_cast<SamplerStateBitsMipMap_e>(samplerState.mipMap);
|
||||||
|
jSamplerState.clampU = samplerState.clampU;
|
||||||
|
jSamplerState.clampV = samplerState.clampV;
|
||||||
|
jSamplerState.clampW = samplerState.clampW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateJsonWater(JsonWater& jWater, const water_t& water)
|
||||||
|
{
|
||||||
|
jWater.floatTime = water.writable.floatTime;
|
||||||
|
jWater.m = water.M;
|
||||||
|
jWater.n = water.N;
|
||||||
|
jWater.lx = water.Lx;
|
||||||
|
jWater.lz = water.Lz;
|
||||||
|
jWater.gravity = water.gravity;
|
||||||
|
jWater.windvel = water.windvel;
|
||||||
|
jWater.winddir[0] = water.winddir[0];
|
||||||
|
jWater.winddir[1] = water.winddir[1];
|
||||||
|
jWater.amplitude = water.amplitude;
|
||||||
|
jWater.codeConstant[0] = water.codeConstant[0];
|
||||||
|
jWater.codeConstant[1] = water.codeConstant[1];
|
||||||
|
jWater.codeConstant[2] = water.codeConstant[2];
|
||||||
|
jWater.codeConstant[3] = water.codeConstant[3];
|
||||||
|
|
||||||
|
if (water.H0)
|
||||||
|
{
|
||||||
|
const auto count = water.M * water.N;
|
||||||
|
jWater.h0 = base64::EncodeBase64(water.H0, sizeof(complex_s) * count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (water.wTerm)
|
||||||
|
{
|
||||||
|
const auto count = water.M * water.N;
|
||||||
|
jWater.wTerm = base64::EncodeBase64(water.wTerm, sizeof(float) * count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateJsonTexture(JsonTexture& jTextureDef, const MaterialTextureDef& textureDef) const
|
||||||
|
{
|
||||||
|
std::string textureDefName;
|
||||||
|
if (m_material_constants.GetTextureDefName(textureDef.nameHash, textureDefName))
|
||||||
|
{
|
||||||
|
jTextureDef.name = textureDefName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jTextureDef.nameHash = textureDef.nameHash;
|
||||||
|
jTextureDef.nameStart = std::string(1u, textureDef.nameStart);
|
||||||
|
jTextureDef.nameEnd = std::string(1u, textureDef.nameEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
jTextureDef.semantic = static_cast<TextureSemantic>(textureDef.semantic);
|
||||||
|
|
||||||
|
CreateJsonSamplerState(jTextureDef.samplerState, textureDef.samplerState);
|
||||||
|
|
||||||
|
if (textureDef.semantic == TS_WATER_MAP)
|
||||||
|
{
|
||||||
|
if (textureDef.u.water)
|
||||||
|
{
|
||||||
|
const auto& water = *textureDef.u.water;
|
||||||
|
if (water.image && water.image->name)
|
||||||
|
jTextureDef.image = AssetName(water.image->name);
|
||||||
|
|
||||||
|
JsonWater jWater;
|
||||||
|
CreateJsonWater(jWater, water);
|
||||||
|
|
||||||
|
jTextureDef.water = std::move(jWater);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (textureDef.u.image && textureDef.u.image->name)
|
||||||
|
jTextureDef.image = AssetName(textureDef.u.image->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateJsonConstant(JsonConstant& jConstantDef, const MaterialConstantDef& constantDef) const
|
||||||
|
{
|
||||||
|
const auto fragmentLength = strnlen(constantDef.name, std::extent_v<decltype(MaterialConstantDef::name)>);
|
||||||
|
const std::string nameFragment(constantDef.name, fragmentLength);
|
||||||
|
std::string knownConstantName;
|
||||||
|
|
||||||
|
if (fragmentLength < std::extent_v<decltype(MaterialConstantDef::name)> || Common::R_HashString(nameFragment.c_str(), 0) == constantDef.nameHash)
|
||||||
|
{
|
||||||
|
jConstantDef.name = nameFragment;
|
||||||
|
}
|
||||||
|
else if (m_material_constants.GetConstantName(constantDef.nameHash, knownConstantName))
|
||||||
|
{
|
||||||
|
jConstantDef.name = knownConstantName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jConstantDef.nameHash = constantDef.nameHash;
|
||||||
|
jConstantDef.nameFragment = nameFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
jConstantDef.literal = std::vector({
|
||||||
|
constantDef.literal.x,
|
||||||
|
constantDef.literal.y,
|
||||||
|
constantDef.literal.z,
|
||||||
|
constantDef.literal.w,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateJsonStencil(JsonStencil& jStencil, const unsigned pass, const unsigned fail, const unsigned zFail, const unsigned func)
|
||||||
|
{
|
||||||
|
jStencil.pass = static_cast<GfxStencilOp>(pass);
|
||||||
|
jStencil.fail = static_cast<GfxStencilOp>(fail);
|
||||||
|
jStencil.zfail = static_cast<GfxStencilOp>(zFail);
|
||||||
|
jStencil.func = static_cast<GfxStencilFunc>(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateJsonStateBitsTableEntry(JsonStateBitsTableEntry& jStateBitsTableEntry, const GfxStateBits& stateBitsTableEntry)
|
||||||
|
{
|
||||||
|
const auto& structured = stateBitsTableEntry.loadBits.structured;
|
||||||
|
|
||||||
|
jStateBitsTableEntry.srcBlendRgb = static_cast<GfxBlend>(structured.srcBlendRgb);
|
||||||
|
jStateBitsTableEntry.dstBlendRgb = static_cast<GfxBlend>(structured.dstBlendRgb);
|
||||||
|
jStateBitsTableEntry.blendOpRgb = static_cast<GfxBlendOp>(structured.blendOpRgb);
|
||||||
|
|
||||||
|
assert(structured.alphaTestDisabled || structured.alphaTest == GFXS_ALPHA_TEST_GT_0 || structured.alphaTest == GFXS_ALPHA_TEST_LT_128
|
||||||
|
|| structured.alphaTest == GFXS_ALPHA_TEST_GE_128);
|
||||||
|
if (structured.alphaTestDisabled)
|
||||||
|
jStateBitsTableEntry.alphaTest = JsonAlphaTest::DISABLED;
|
||||||
|
else if (structured.alphaTest == GFXS_ALPHA_TEST_GT_0)
|
||||||
|
jStateBitsTableEntry.alphaTest = JsonAlphaTest::GT0;
|
||||||
|
else if (structured.alphaTest == GFXS_ALPHA_TEST_LT_128)
|
||||||
|
jStateBitsTableEntry.alphaTest = JsonAlphaTest::LT128;
|
||||||
|
else if (structured.alphaTest == GFXS_ALPHA_TEST_GE_128)
|
||||||
|
jStateBitsTableEntry.alphaTest = JsonAlphaTest::GE128;
|
||||||
|
else
|
||||||
|
jStateBitsTableEntry.alphaTest = JsonAlphaTest::INVALID;
|
||||||
|
|
||||||
|
assert(structured.cullFace == GFXS_CULL_NONE || structured.cullFace == GFXS_CULL_BACK || structured.cullFace == GFXS_CULL_FRONT);
|
||||||
|
if (structured.cullFace == GFXS_CULL_NONE)
|
||||||
|
jStateBitsTableEntry.cullFace = JsonCullFace::NONE;
|
||||||
|
else if (structured.cullFace == GFXS_CULL_BACK)
|
||||||
|
jStateBitsTableEntry.cullFace = JsonCullFace::BACK;
|
||||||
|
else if (structured.cullFace == GFXS_CULL_FRONT)
|
||||||
|
jStateBitsTableEntry.cullFace = JsonCullFace::FRONT;
|
||||||
|
else
|
||||||
|
jStateBitsTableEntry.cullFace = JsonCullFace::INVALID;
|
||||||
|
|
||||||
|
jStateBitsTableEntry.srcBlendAlpha = static_cast<GfxBlend>(structured.srcBlendAlpha);
|
||||||
|
jStateBitsTableEntry.dstBlendAlpha = static_cast<GfxBlend>(structured.dstBlendAlpha);
|
||||||
|
jStateBitsTableEntry.blendOpAlpha = static_cast<GfxBlendOp>(structured.blendOpAlpha);
|
||||||
|
jStateBitsTableEntry.colorWriteRgb = structured.colorWriteRgb;
|
||||||
|
jStateBitsTableEntry.colorWriteAlpha = structured.colorWriteAlpha;
|
||||||
|
jStateBitsTableEntry.gammaWrite = structured.gammaWrite;
|
||||||
|
jStateBitsTableEntry.polymodeLine = structured.polymodeLine;
|
||||||
|
jStateBitsTableEntry.depthWrite = structured.depthWrite;
|
||||||
|
|
||||||
|
assert(structured.depthTestDisabled || structured.depthTest == GFXS_DEPTHTEST_ALWAYS || structured.depthTest == GFXS_DEPTHTEST_LESS
|
||||||
|
|| structured.depthTest == GFXS_DEPTHTEST_EQUAL || structured.depthTest == GFXS_DEPTHTEST_LESSEQUAL);
|
||||||
|
if (structured.depthTestDisabled)
|
||||||
|
jStateBitsTableEntry.depthTest = JsonDepthTest::DISABLED;
|
||||||
|
else if (structured.depthTest == GFXS_DEPTHTEST_ALWAYS)
|
||||||
|
jStateBitsTableEntry.depthTest = JsonDepthTest::ALWAYS;
|
||||||
|
else if (structured.depthTest == GFXS_DEPTHTEST_LESS)
|
||||||
|
jStateBitsTableEntry.depthTest = JsonDepthTest::LESS;
|
||||||
|
else if (structured.depthTest == GFXS_DEPTHTEST_EQUAL)
|
||||||
|
jStateBitsTableEntry.depthTest = JsonDepthTest::EQUAL;
|
||||||
|
else if (structured.depthTest == GFXS_DEPTHTEST_LESSEQUAL)
|
||||||
|
jStateBitsTableEntry.depthTest = JsonDepthTest::LESS_EQUAL;
|
||||||
|
else
|
||||||
|
jStateBitsTableEntry.depthTest = JsonDepthTest::INVALID;
|
||||||
|
|
||||||
|
jStateBitsTableEntry.polygonOffset = static_cast<GfxPolygonOffset_e>(structured.polygonOffset);
|
||||||
|
|
||||||
|
if (structured.stencilFrontEnabled)
|
||||||
|
{
|
||||||
|
JsonStencil jStencilFront;
|
||||||
|
CreateJsonStencil(
|
||||||
|
jStencilFront, structured.stencilFrontPass, structured.stencilFrontFail, structured.stencilFrontZFail, structured.stencilFrontFunc);
|
||||||
|
jStateBitsTableEntry.stencilFront = jStencilFront;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (structured.stencilBackEnabled)
|
||||||
|
{
|
||||||
|
JsonStencil jStencilBack;
|
||||||
|
CreateJsonStencil(
|
||||||
|
jStencilBack, structured.stencilBackPass, structured.stencilBackFail, structured.stencilBackZFail, structured.stencilBackFunc);
|
||||||
|
jStateBitsTableEntry.stencilBack = jStencilBack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateJsonMaterial(JsonMaterial& jMaterial, const Material& material) const
|
||||||
|
{
|
||||||
|
CreateJsonGameFlags(jMaterial, material.info.gameFlags);
|
||||||
|
jMaterial.sortKey = material.info.sortKey;
|
||||||
|
|
||||||
|
jMaterial.textureAtlas = JsonTextureAtlas();
|
||||||
|
jMaterial.textureAtlas->rows = material.info.textureAtlasRowCount;
|
||||||
|
jMaterial.textureAtlas->columns = material.info.textureAtlasColumnCount;
|
||||||
|
|
||||||
|
jMaterial.surfaceTypeBits = material.info.surfaceTypeBits;
|
||||||
|
|
||||||
|
jMaterial.stateBitsEntry.resize(std::extent_v<decltype(Material::stateBitsEntry)>);
|
||||||
|
for (auto i = 0u; i < std::extent_v<decltype(Material::stateBitsEntry)>; i++)
|
||||||
|
jMaterial.stateBitsEntry[i] = material.stateBitsEntry[i];
|
||||||
|
|
||||||
|
jMaterial.stateFlags = material.stateFlags;
|
||||||
|
jMaterial.cameraRegion = static_cast<GfxCameraRegionType>(material.cameraRegion);
|
||||||
|
|
||||||
|
if (material.techniqueSet && material.techniqueSet->name)
|
||||||
|
jMaterial.techniqueSet = AssetName(material.techniqueSet->name);
|
||||||
|
|
||||||
|
jMaterial.textures.resize(material.textureCount);
|
||||||
|
for (auto i = 0u; i < material.textureCount; i++)
|
||||||
|
CreateJsonTexture(jMaterial.textures[i], material.textureTable[i]);
|
||||||
|
|
||||||
|
jMaterial.constants.resize(material.constantCount);
|
||||||
|
for (auto i = 0u; i < material.constantCount; i++)
|
||||||
|
CreateJsonConstant(jMaterial.constants[i], material.constantTable[i]);
|
||||||
|
|
||||||
|
jMaterial.stateBits.resize(material.stateBitsCount);
|
||||||
|
for (auto i = 0u; i < material.stateBitsCount; i++)
|
||||||
|
CreateJsonStateBitsTableEntry(jMaterial.stateBits[i], material.stateBitsTable[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& m_stream;
|
||||||
|
const MaterialConstantZoneState& m_material_constants;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace IW5
|
||||||
|
{
|
||||||
|
void DumpMaterialAsJson(std::ostream& stream, const Material* material, AssetDumpingContext& context)
|
||||||
|
{
|
||||||
|
const JsonDumper dumper(context, stream);
|
||||||
|
dumper.Dump(material);
|
||||||
|
}
|
||||||
|
} // namespace IW5
|
11
src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.h
Normal file
11
src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Dumping/AssetDumpingContext.h"
|
||||||
|
#include "Game/IW5/IW5.h"
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace IW5
|
||||||
|
{
|
||||||
|
void DumpMaterialAsJson(std::ostream& stream, const Material* material, AssetDumpingContext& context);
|
||||||
|
} // namespace IW5
|
236
src/ObjWriting/Game/IW5/Material/MaterialConstantZoneState.cpp
Normal file
236
src/ObjWriting/Game/IW5/Material/MaterialConstantZoneState.cpp
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
#include "MaterialConstantZoneState.h"
|
||||||
|
|
||||||
|
#include "Game/IW5/CommonIW5.h"
|
||||||
|
#include "Game/IW5/GameAssetPoolIW5.h"
|
||||||
|
#include "Game/IW5/GameIW5.h"
|
||||||
|
#include "ObjWriting.h"
|
||||||
|
|
||||||
|
namespace IW5
|
||||||
|
{
|
||||||
|
const char* KNOWN_CONSTANT_NAMES[]{
|
||||||
|
"worldViewProjectionMatrix",
|
||||||
|
"worldViewMatrix2",
|
||||||
|
"worldViewMatrix1",
|
||||||
|
"worldViewMatrix",
|
||||||
|
"worldOutdoorLookupMatrix",
|
||||||
|
"worldMatrix",
|
||||||
|
"waterColor",
|
||||||
|
"viewportDimensions",
|
||||||
|
"viewProjectionMatrix",
|
||||||
|
"uvScale",
|
||||||
|
"uvAnimParms",
|
||||||
|
"thermalColorOffset",
|
||||||
|
"sunShadowmapPixelAdjust",
|
||||||
|
"ssaoParms",
|
||||||
|
"spotShadowmapPixelAdjust",
|
||||||
|
"shadowmapSwitchPartition",
|
||||||
|
"shadowmapScale",
|
||||||
|
"shadowmapPolygonOffset",
|
||||||
|
"shadowLookupMatrix",
|
||||||
|
"renderTargetSize",
|
||||||
|
"renderSourceSize",
|
||||||
|
"projectionMatrix",
|
||||||
|
"playlistPopulationParams",
|
||||||
|
"pixelCostFracs",
|
||||||
|
"pixelCostDecode",
|
||||||
|
"particleCloudSparkColor2",
|
||||||
|
"particleCloudSparkColor1",
|
||||||
|
"particleCloudSparkColor0",
|
||||||
|
"particleCloudMatrix2",
|
||||||
|
"particleCloudMatrix1",
|
||||||
|
"particleCloudMatrix",
|
||||||
|
"particleCloudColor",
|
||||||
|
"outdoorFeatherParms",
|
||||||
|
"oceanUVAnimParmPaintedFoam",
|
||||||
|
"oceanUVAnimParmOctave2",
|
||||||
|
"oceanUVAnimParmOctave1",
|
||||||
|
"oceanUVAnimParmOctave0",
|
||||||
|
"oceanUVAnimParmFoam",
|
||||||
|
"oceanUVAnimParmDetail1",
|
||||||
|
"oceanUVAnimParmDetail0",
|
||||||
|
"oceanScrollParms",
|
||||||
|
"oceanMiscParms",
|
||||||
|
"oceanFoamParms",
|
||||||
|
"oceanAmplitude",
|
||||||
|
"materialColor",
|
||||||
|
"lightprobeAmbient",
|
||||||
|
"lightingLookupScale",
|
||||||
|
"lightSpotFactors",
|
||||||
|
"lightSpotDir",
|
||||||
|
"lightSpecular",
|
||||||
|
"lightPosition",
|
||||||
|
"lightFalloffPlacement",
|
||||||
|
"lightDiffuse",
|
||||||
|
"inverseWorldViewMatrix",
|
||||||
|
"inverseViewProjectionMatrix",
|
||||||
|
"inverseTransposeWorldViewMatrix",
|
||||||
|
"heatMapDetail",
|
||||||
|
"glowSetup",
|
||||||
|
"glowApply",
|
||||||
|
"gameTime",
|
||||||
|
"fullscreenDistortion",
|
||||||
|
"fogSunDir",
|
||||||
|
"fogSunConsts",
|
||||||
|
"fogSunColorLinear",
|
||||||
|
"fogSunColorGamma",
|
||||||
|
"fogConsts",
|
||||||
|
"fogColorLinear",
|
||||||
|
"fogColorGamma",
|
||||||
|
"flagParms",
|
||||||
|
"filterTap",
|
||||||
|
"featherParms",
|
||||||
|
"falloffParms",
|
||||||
|
"falloffEndColor",
|
||||||
|
"falloffBeginColor",
|
||||||
|
"fadeEffect",
|
||||||
|
"eyeOffsetParms",
|
||||||
|
"eyeOffset",
|
||||||
|
"envMapParms",
|
||||||
|
"dustTint",
|
||||||
|
"dustParms",
|
||||||
|
"dustEyeParms",
|
||||||
|
"dofRowDelta",
|
||||||
|
"dofLerpScale",
|
||||||
|
"dofLerpBias",
|
||||||
|
"dofEquationViewModelAndFarBlur",
|
||||||
|
"dofEquationScene",
|
||||||
|
"distortionScale",
|
||||||
|
"detailScale",
|
||||||
|
"depthFromClip",
|
||||||
|
"debugBumpmap",
|
||||||
|
"colorTintQuadraticDelta",
|
||||||
|
"colorTintDelta",
|
||||||
|
"colorTintBase",
|
||||||
|
"colorSaturationR",
|
||||||
|
"colorSaturationG",
|
||||||
|
"colorSaturationB",
|
||||||
|
"colorObjMin",
|
||||||
|
"colorObjMax",
|
||||||
|
"colorMatrixR",
|
||||||
|
"colorMatrixG",
|
||||||
|
"colorMatrixB",
|
||||||
|
"colorBias",
|
||||||
|
"codeMeshArg",
|
||||||
|
"clipSpaceLookupScale",
|
||||||
|
"clipSpaceLookupOffset",
|
||||||
|
"baseLightingCoords",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* KNOWN_TEXTURE_DEF_NAMES[]{
|
||||||
|
"attenuation",
|
||||||
|
"attenuationSampler",
|
||||||
|
"cinematicA",
|
||||||
|
"cinematicASampler",
|
||||||
|
"cinematicCb",
|
||||||
|
"cinematicCbSampler",
|
||||||
|
"cinematicCr",
|
||||||
|
"cinematicCrSampler",
|
||||||
|
"cinematicY",
|
||||||
|
"cinematicYSampler",
|
||||||
|
"colorMap",
|
||||||
|
"colorMap1",
|
||||||
|
"colorMap2",
|
||||||
|
"colorMapPostSun",
|
||||||
|
"colorMapPostSunSampler",
|
||||||
|
"colorMapSampler",
|
||||||
|
"colorMapSampler1",
|
||||||
|
"colorMapSampler2",
|
||||||
|
"cucoloris",
|
||||||
|
"cucolorisSampler",
|
||||||
|
"detailMap",
|
||||||
|
"detailMapSampler",
|
||||||
|
"dust",
|
||||||
|
"dustSampler",
|
||||||
|
"fadeMap",
|
||||||
|
"fadeMapSampler",
|
||||||
|
"floatZ",
|
||||||
|
"floatZSampler",
|
||||||
|
"grainMap",
|
||||||
|
"grainMapSampler",
|
||||||
|
"halfParticleColor",
|
||||||
|
"halfParticleColorSampler",
|
||||||
|
"halfParticleDepth",
|
||||||
|
"halfParticleDepthSampler",
|
||||||
|
"heatmap",
|
||||||
|
"heatmapSampler",
|
||||||
|
"lightmapPrimary",
|
||||||
|
"lightmapSamplerPrimary",
|
||||||
|
"lightmapSamplerSecondary",
|
||||||
|
"lightmapSecondary",
|
||||||
|
"lookupMap",
|
||||||
|
"lookupMapSampler",
|
||||||
|
"modelLighting",
|
||||||
|
"modelLightingSampler",
|
||||||
|
"normalMap",
|
||||||
|
"normalMapSampler",
|
||||||
|
"oceanColorRamp",
|
||||||
|
"oceanColorRampSampler",
|
||||||
|
"oceanDetailNormal",
|
||||||
|
"oceanDetailNormalSampler",
|
||||||
|
"oceanDisplacement",
|
||||||
|
"oceanDisplacementSampler",
|
||||||
|
"oceanEnv",
|
||||||
|
"oceanEnvSampler",
|
||||||
|
"oceanFoam",
|
||||||
|
"oceanFoamSampler",
|
||||||
|
"oceanHeightNormal",
|
||||||
|
"oceanHeightNormalSampler",
|
||||||
|
"oceanPaintedFoam",
|
||||||
|
"oceanPaintedFoamSampler",
|
||||||
|
"outdoorMap",
|
||||||
|
"outdoorMapSampler",
|
||||||
|
"population",
|
||||||
|
"populationSampler",
|
||||||
|
"reflectionProbe",
|
||||||
|
"reflectionProbeSampler",
|
||||||
|
"shadowmapSamplerSpot",
|
||||||
|
"shadowmapSamplerSun",
|
||||||
|
"shadowmapSpot",
|
||||||
|
"shadowmapSun",
|
||||||
|
"skyMap",
|
||||||
|
"skyMapSampler",
|
||||||
|
"specularMap",
|
||||||
|
"specularMapSampler",
|
||||||
|
"ssao",
|
||||||
|
"ssaoSampler",
|
||||||
|
"worldMap",
|
||||||
|
"worldMapSampler",
|
||||||
|
};
|
||||||
|
|
||||||
|
void MaterialConstantZoneState::ExtractNamesFromZoneInternal()
|
||||||
|
{
|
||||||
|
for (const auto* zone : g_GameIW5.GetZones())
|
||||||
|
{
|
||||||
|
const auto* iw5AssetPools = dynamic_cast<const GameAssetPoolIW5*>(zone->m_pools.get());
|
||||||
|
if (!iw5AssetPools)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const auto* vertexShaderAsset : *iw5AssetPools->m_material_vertex_shader)
|
||||||
|
{
|
||||||
|
const auto* vertexShader = vertexShaderAsset->Asset();
|
||||||
|
if (ShouldDumpFromStruct(vertexShader))
|
||||||
|
ExtractNamesFromShader(vertexShader->prog.loadDef.program, static_cast<size_t>(vertexShader->prog.loadDef.programSize) * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto* pixelShaderAsset : *iw5AssetPools->m_material_pixel_shader)
|
||||||
|
{
|
||||||
|
const auto* pixelShader = pixelShaderAsset->Asset();
|
||||||
|
if (ShouldDumpFromStruct(pixelShader))
|
||||||
|
ExtractNamesFromShader(pixelShader->prog.loadDef.program, static_cast<size_t>(pixelShader->prog.loadDef.programSize) * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialConstantZoneState::AddStaticKnownNames()
|
||||||
|
{
|
||||||
|
for (const auto* knownConstantName : KNOWN_CONSTANT_NAMES)
|
||||||
|
AddConstantName(knownConstantName);
|
||||||
|
for (const auto* knownTextureDefName : KNOWN_TEXTURE_DEF_NAMES)
|
||||||
|
AddTextureDefName(knownTextureDefName);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned MaterialConstantZoneState::HashString(const std::string& str)
|
||||||
|
{
|
||||||
|
return Common::R_HashString(str.c_str());
|
||||||
|
}
|
||||||
|
} // namespace IW5
|
16
src/ObjWriting/Game/IW5/Material/MaterialConstantZoneState.h
Normal file
16
src/ObjWriting/Game/IW5/Material/MaterialConstantZoneState.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Material/AbstractMaterialConstantZoneState.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace IW5
|
||||||
|
{
|
||||||
|
class MaterialConstantZoneState final : public AbstractMaterialConstantZoneStateDx9
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void ExtractNamesFromZoneInternal() override;
|
||||||
|
void AddStaticKnownNames() override;
|
||||||
|
unsigned HashString(const std::string& str) override;
|
||||||
|
};
|
||||||
|
} // namespace IW5
|
@ -5,6 +5,7 @@
|
|||||||
#include "AssetDumpers/AssetDumperLeaderboardDef.h"
|
#include "AssetDumpers/AssetDumperLeaderboardDef.h"
|
||||||
#include "AssetDumpers/AssetDumperLoadedSound.h"
|
#include "AssetDumpers/AssetDumperLoadedSound.h"
|
||||||
#include "AssetDumpers/AssetDumperLocalizeEntry.h"
|
#include "AssetDumpers/AssetDumperLocalizeEntry.h"
|
||||||
|
#include "AssetDumpers/AssetDumperMaterial.h"
|
||||||
#include "AssetDumpers/AssetDumperMenuDef.h"
|
#include "AssetDumpers/AssetDumperMenuDef.h"
|
||||||
#include "AssetDumpers/AssetDumperMenuList.h"
|
#include "AssetDumpers/AssetDumperMenuList.h"
|
||||||
#include "AssetDumpers/AssetDumperRawFile.h"
|
#include "AssetDumpers/AssetDumperRawFile.h"
|
||||||
@ -39,7 +40,7 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const
|
|||||||
// DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts, ASSET_TYPE_XANIMPARTS)
|
// DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts, ASSET_TYPE_XANIMPARTS)
|
||||||
// DUMP_ASSET_POOL(AssetDumperXModelSurfs, m_xmodel_surfs, ASSET_TYPE_XMODEL_SURFS)
|
// DUMP_ASSET_POOL(AssetDumperXModelSurfs, m_xmodel_surfs, ASSET_TYPE_XMODEL_SURFS)
|
||||||
DUMP_ASSET_POOL(AssetDumperXModel, m_xmodel, ASSET_TYPE_XMODEL)
|
DUMP_ASSET_POOL(AssetDumperXModel, m_xmodel, ASSET_TYPE_XMODEL)
|
||||||
// DUMP_ASSET_POOL(AssetDumperMaterial, m_material, ASSET_TYPE_MATERIAL)
|
DUMP_ASSET_POOL(AssetDumperMaterial, m_material, ASSET_TYPE_MATERIAL)
|
||||||
// DUMP_ASSET_POOL(AssetDumperMaterialPixelShader, m_material_pixel_shader, ASSET_TYPE_PIXELSHADER)
|
// DUMP_ASSET_POOL(AssetDumperMaterialPixelShader, m_material_pixel_shader, ASSET_TYPE_PIXELSHADER)
|
||||||
// DUMP_ASSET_POOL(AssetDumperMaterialVertexShader, m_material_vertex_shader, ASSET_TYPE_VERTEXSHADER)
|
// DUMP_ASSET_POOL(AssetDumperMaterialVertexShader, m_material_vertex_shader, ASSET_TYPE_VERTEXSHADER)
|
||||||
// DUMP_ASSET_POOL(AssetDumperMaterialVertexDeclaration, m_material_vertex_decl, ASSET_TYPE_VERTEXDECL)
|
// DUMP_ASSET_POOL(AssetDumperMaterialVertexDeclaration, m_material_vertex_decl, ASSET_TYPE_VERTEXDECL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user