SDKMESH2 export support for PBR materials

This commit is contained in:
Chuck Walbourn 2019-02-08 22:18:38 -08:00
Родитель 909a24e3f1
Коммит c250c3dd5e
9 изменённых файлов: 548 добавлений и 374 удалений

Просмотреть файл

@ -23,6 +23,7 @@
#pragma warning(pop)
#include "Mesh.h"
#include "SDKMesh.h"
#include <DirectXPackedVector.h>
#include <DirectXCollision.h>
@ -1861,350 +1862,8 @@ HRESULT Mesh::ExportToCMO(const wchar_t* szFileName, size_t nMaterials, const Ma
// SDKMESH
//======================================================================================
//--------------------------------------------------------------------------------------
// SDKMESH format is generated by the legacy DirectX SDK's Content Exporter and
// originally rendered by the DXUT helper class SDKMesh
//
// http://go.microsoft.com/fwlink/?LinkId=226208
//--------------------------------------------------------------------------------------
namespace DXUT
{
// .SDKMESH files
// SDKMESH_HEADER
// SDKMESH_VERTEX_BUFFER_HEADER header->VertexStreamHeadersOffset
// SDKMESH_INDEX_BUFFER_HEADER header->IndexStreamHeadersOffset
// SDKMESH_MESH header->MeshDataOffset
// SDKMESH_SUBSET header->SubsetDataOffset
// SDKMESH_FRAME header->FrameDataOffset
// SDKMESH_MATERIAL header->MaterialDataOffset
// [header->NonBufferDataSize]
// { [ header->NumVertexBuffers]
// VB data
// }
// { [ header->NumIndexBuffers]
// IB data
// }
// .SDDKANIM files
// SDKANIMATION_FILE_HEADER
// BYTE[] - Length of fileheader->AnimationDataSize
// .SDKMESH uses Direct3D 9 decls, but only a subset of these is ever generated by the legacy DirectX SDK Content Exporter
// D3DDECLUSAGE_POSITION / D3DDECLTYPE_FLOAT3
// (D3DDECLUSAGE_BLENDWEIGHT / D3DDECLTYPE_UBYTE4N
// D3DDECLUSAGE_BLENDINDICES / D3DDECLTYPE_UBYTE4)?
// (D3DDECLUSAGE_NORMAL / D3DDECLTYPE_FLOAT3 or D3DDECLTYPE_FLOAT16_4)?
// (D3DDECLUSAGE_COLOR / D3DDECLTYPE_D3DCOLOR)?
// (D3DDECLUSAGE_TEXCOORD / D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT2 or D3DDECLTYPE_FLOAT16_2, D3DDECLTYPE_FLOAT3 or D3DDECLTYPE_FLOAT16_4, D3DDECLTYPE_FLOAT4 or D3DDECLTYPE_FLOAT16_4)*
// (D3DDECLUSAGE_TANGENT / D3DDECLTYPE_FLOAT3 or D3DDECLTYPE_FLOAT16_4)?
// (D3DDECLUSAGE_BINORMAL / D3DDECLTYPE_FLOAT3 or D3DDECLTYPE_FLOAT16_4)?
enum D3DDECLUSAGE
{
D3DDECLUSAGE_POSITION = 0,
D3DDECLUSAGE_BLENDWEIGHT = 1,
D3DDECLUSAGE_BLENDINDICES = 2,
D3DDECLUSAGE_NORMAL = 3,
D3DDECLUSAGE_TEXCOORD = 5,
D3DDECLUSAGE_TANGENT = 6,
D3DDECLUSAGE_BINORMAL = 7,
D3DDECLUSAGE_COLOR = 10,
};
enum D3DDECLTYPE
{
D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.)
D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.)
D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.)
D3DDECLTYPE_FLOAT4 = 3, // 4D float
D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range
// Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte
D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0
D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)
D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1)
D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values
D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused.
};
#pragma pack(push,4)
struct D3DVERTEXELEMENT9
{
WORD Stream; // Stream index
WORD Offset; // Offset in the stream in bytes
BYTE Type; // Data type
BYTE Method; // Processing method
BYTE Usage; // Semantics
BYTE UsageIndex; // Semantic index
};
#pragma pack(pop)
//--------------------------------------------------------------------------------------
// Hard Defines for the various structures
//--------------------------------------------------------------------------------------
const uint32_t SDKMESH_FILE_VERSION = 101;
const uint32_t MAX_VERTEX_ELEMENTS = 32;
const uint32_t MAX_VERTEX_STREAMS = 16;
const uint32_t MAX_FRAME_NAME = 100;
const uint32_t MAX_MESH_NAME = 100;
const uint32_t MAX_SUBSET_NAME = 100;
const uint32_t MAX_MATERIAL_NAME = 100;
const uint32_t MAX_TEXTURE_NAME = MAX_PATH;
const uint32_t MAX_MATERIAL_PATH = MAX_PATH;
const uint32_t INVALID_FRAME = uint32_t(-1);
const uint32_t INVALID_MESH = uint32_t(-1);
const uint32_t INVALID_MATERIAL = uint32_t(-1);
const uint32_t INVALID_SUBSET = uint32_t(-1);
const uint32_t INVALID_ANIMATION_DATA = uint32_t(-1);
const uint32_t INVALID_SAMPLER_SLOT = uint32_t(-1);
const uint32_t ERROR_RESOURCE_VALUE = 1;
template<typename TYPE> bool IsErrorResource(TYPE data)
{
if ((TYPE)ERROR_RESOURCE_VALUE == data)
return true;
return false;
}
//--------------------------------------------------------------------------------------
// Enumerated Types. These will have mirrors in both D3D9 and D3D11
//--------------------------------------------------------------------------------------
enum SDKMESH_PRIMITIVE_TYPE
{
PT_TRIANGLE_LIST = 0,
PT_TRIANGLE_STRIP,
PT_LINE_LIST,
PT_LINE_STRIP,
PT_POINT_LIST,
PT_TRIANGLE_LIST_ADJ,
PT_TRIANGLE_STRIP_ADJ,
PT_LINE_LIST_ADJ,
PT_LINE_STRIP_ADJ,
PT_QUAD_PATCH_LIST,
PT_TRIANGLE_PATCH_LIST,
};
enum SDKMESH_INDEX_TYPE
{
IT_16BIT = 0,
IT_32BIT,
};
enum FRAME_TRANSFORM_TYPE
{
FTT_RELATIVE = 0,
FTT_ABSOLUTE, //This is not currently used but is here to support absolute transformations in the future
};
//--------------------------------------------------------------------------------------
// Structures.
//--------------------------------------------------------------------------------------
#pragma pack(push,8)
struct SDKMESH_HEADER
{
//Basic Info and sizes
UINT Version;
BYTE IsBigEndian;
UINT64 HeaderSize;
UINT64 NonBufferDataSize;
UINT64 BufferDataSize;
//Stats
UINT NumVertexBuffers;
UINT NumIndexBuffers;
UINT NumMeshes;
UINT NumTotalSubsets;
UINT NumFrames;
UINT NumMaterials;
//Offsets to Data
UINT64 VertexStreamHeadersOffset;
UINT64 IndexStreamHeadersOffset;
UINT64 MeshDataOffset;
UINT64 SubsetDataOffset;
UINT64 FrameDataOffset;
UINT64 MaterialDataOffset;
};
struct SDKMESH_VERTEX_BUFFER_HEADER
{
UINT64 NumVertices;
UINT64 SizeBytes;
UINT64 StrideBytes;
D3DVERTEXELEMENT9 Decl[MAX_VERTEX_ELEMENTS];
union
{
UINT64 DataOffset;
ID3D11Buffer* pVB11;
};
};
struct SDKMESH_INDEX_BUFFER_HEADER
{
UINT64 NumIndices;
UINT64 SizeBytes;
UINT IndexType;
union
{
UINT64 DataOffset;
ID3D11Buffer* pIB11;
};
};
struct SDKMESH_MESH
{
char Name[MAX_MESH_NAME];
BYTE NumVertexBuffers;
UINT VertexBuffers[MAX_VERTEX_STREAMS];
UINT IndexBuffer;
UINT NumSubsets;
UINT NumFrameInfluences; //aka bones
DirectX::XMFLOAT3 BoundingBoxCenter;
DirectX::XMFLOAT3 BoundingBoxExtents;
union
{
UINT64 SubsetOffset;
INT* pSubsets;
};
union
{
UINT64 FrameInfluenceOffset;
UINT* pFrameInfluences;
};
};
struct SDKMESH_SUBSET
{
char Name[MAX_SUBSET_NAME];
UINT MaterialID;
UINT PrimitiveType;
UINT64 IndexStart;
UINT64 IndexCount;
UINT64 VertexStart;
UINT64 VertexCount;
};
struct SDKMESH_FRAME
{
char Name[MAX_FRAME_NAME];
UINT Mesh;
UINT ParentFrame;
UINT ChildFrame;
UINT SiblingFrame;
DirectX::XMFLOAT4X4 Matrix;
UINT AnimationDataIndex; //Used to index which set of keyframes transforms this frame
};
struct SDKMESH_MATERIAL
{
char Name[MAX_MATERIAL_NAME];
// Use MaterialInstancePath
char MaterialInstancePath[MAX_MATERIAL_PATH];
// Or fall back to d3d8-type materials
char DiffuseTexture[MAX_TEXTURE_NAME];
char NormalTexture[MAX_TEXTURE_NAME];
char SpecularTexture[MAX_TEXTURE_NAME];
DirectX::XMFLOAT4 Diffuse;
DirectX::XMFLOAT4 Ambient;
DirectX::XMFLOAT4 Specular;
DirectX::XMFLOAT4 Emissive;
FLOAT Power;
union
{
UINT64 Force64_1; //Force the union to 64bits
ID3D11Texture2D* pDiffuseTexture11;
};
union
{
UINT64 Force64_2; //Force the union to 64bits
ID3D11Texture2D* pNormalTexture11;
};
union
{
UINT64 Force64_3; //Force the union to 64bits
ID3D11Texture2D* pSpecularTexture11;
};
union
{
UINT64 Force64_4; //Force the union to 64bits
ID3D11ShaderResourceView* pDiffuseRV11;
};
union
{
UINT64 Force64_5; //Force the union to 64bits
ID3D11ShaderResourceView* pNormalRV11;
};
union
{
UINT64 Force64_6; //Force the union to 64bits
ID3D11ShaderResourceView* pSpecularRV11;
};
};
struct SDKANIMATION_FILE_HEADER
{
UINT Version;
BYTE IsBigEndian;
UINT FrameTransformType;
UINT NumFrames;
UINT NumAnimationKeys;
UINT AnimationFPS;
UINT64 AnimationDataSize;
UINT64 AnimationDataOffset;
};
struct SDKANIMATION_DATA
{
DirectX::XMFLOAT3 Translation;
DirectX::XMFLOAT4 Orientation;
DirectX::XMFLOAT3 Scaling;
};
struct SDKANIMATION_FRAME_DATA
{
char FrameName[MAX_FRAME_NAME];
union
{
UINT64 DataOffset;
SDKANIMATION_DATA* pAnimationData;
};
};
#pragma pack(pop)
} // namespace
static_assert(sizeof(DXUT::D3DVERTEXELEMENT9) == 8, "Direct3D9 Decl structure size incorrect");
static_assert(sizeof(DXUT::SDKMESH_HEADER) == 104, "SDK Mesh structure size incorrect");
static_assert(sizeof(DXUT::SDKMESH_VERTEX_BUFFER_HEADER) == 288, "SDK Mesh structure size incorrect");
static_assert(sizeof(DXUT::SDKMESH_INDEX_BUFFER_HEADER) == 32, "SDK Mesh structure size incorrect");
static_assert(sizeof(DXUT::SDKMESH_MESH) == 224, "SDK Mesh structure size incorrect");
static_assert(sizeof(DXUT::SDKMESH_SUBSET) == 144, "SDK Mesh structure size incorrect");
static_assert(sizeof(DXUT::SDKMESH_FRAME) == 184, "SDK Mesh structure size incorrect");
static_assert(sizeof(DXUT::SDKMESH_MATERIAL) == 1256, "SDK Mesh structure size incorrect");
static_assert(sizeof(DXUT::SDKANIMATION_FILE_HEADER) == 40, "SDK Mesh structure size incorrect");
static_assert(sizeof(DXUT::SDKANIMATION_DATA) == 40, "SDK Mesh structure size incorrect");
static_assert(sizeof(DXUT::SDKANIMATION_FRAME_DATA) == 112, "SDK Mesh structure size incorrect");
//--------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT Mesh::ExportToSDKMESH(const wchar_t* szFileName, size_t nMaterials, const Material* materials, bool force32bit) const
HRESULT Mesh::ExportToSDKMESH(const wchar_t* szFileName, size_t nMaterials, const Material* materials, bool force32bit, bool version2) const
{
using namespace DXUT;
@ -2369,7 +2028,118 @@ HRESULT Mesh::ExportToSDKMESH(const wchar_t* szFileName, size_t nMaterials, cons
// Build materials buffer
std::unique_ptr<SDKMESH_MATERIAL[]> mats;
if (!nMaterials)
if (version2)
{
if (!nMaterials)
{
mats.reset(new (std::nothrow) SDKMESH_MATERIAL[1]);
if (!mats)
return E_OUTOFMEMORY;
auto mat2 = reinterpret_cast<SDKMESH_MATERIAL_V2*>(mats.get());
memset(mat2, 0, sizeof(SDKMESH_MATERIAL_V2));
strcpy_s(mat2->Name, "default");
mat2->Alpha = 1.f;
}
else
{
mats.reset(new (std::nothrow) SDKMESH_MATERIAL[nMaterials]);
if (!mats)
return E_OUTOFMEMORY;
for (size_t j = 0; j < nMaterials; ++j)
{
auto m0 = &materials[j];
auto m2 = reinterpret_cast<SDKMESH_MATERIAL_V2*>(&mats[j]);
memset(m2, 0, sizeof(SDKMESH_MATERIAL_V2));
if (!m0->name.empty())
{
int result = WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS,
m0->name.c_str(), -1,
m2->Name, MAX_MATERIAL_NAME, nullptr, FALSE);
if (!result)
{
*m2->Name = 0;
}
}
m2->Alpha = m0->alpha;
if (!m0->texture.empty())
{
int result = WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS,
m0->texture.c_str(), -1,
m2->AlbetoTexture, MAX_TEXTURE_NAME, nullptr, FALSE);
if (!result)
{
*m2->AlbetoTexture = 0;
}
}
// Derive other PBR texture names from base texture
{
char drive[_MAX_DRIVE] = {};
char dir[MAX_PATH] = {};
char fname[_MAX_FNAME] = {};
char ext[_MAX_EXT] = {};
_splitpath_s(m2->AlbetoTexture, drive, dir, fname, ext);
std::string basename = fname;
size_t pos = basename.find_last_of('_');
if (pos != std::string::npos)
{
basename = basename.substr(0, pos);
}
if (!basename.empty())
{
strcpy_s(fname, basename.c_str());
strcat_s(fname, "_normal");
_makepath_s(m2->NormalTexture, drive, dir, fname, ext);
strcpy_s(fname, basename.c_str());
strcat_s(fname, "_occlusionRoughnessMetallic");
_makepath_s(m2->RMATexture, drive, dir, fname, ext);
if (m0->emissiveColor.x > 0 || m0->emissiveColor.y > 0 || m0->emissiveColor.z > 0)
{
strcpy_s(fname, basename.c_str());
strcat_s(fname, "_emissive");
_makepath_s(m2->EmissiveTexture, drive, dir, fname, ext);
}
}
}
// Allow normal texture material property to override derived name
if (!m0->normalTexture.empty())
{
int result = WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS,
m0->normalTexture.c_str(), -1,
m2->NormalTexture, MAX_TEXTURE_NAME, nullptr, FALSE);
if (!result)
{
*m2->NormalTexture = 0;
}
}
// Allow emissive texture material property to override drived name
if (!m0->emissiveTexture.empty())
{
int result = WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS,
m0->emissiveTexture.c_str(), -1,
m2->EmissiveTexture, MAX_TEXTURE_NAME, nullptr, FALSE);
if (!result)
{
*m2->EmissiveTexture = 0;
}
}
}
}
}
else if (!nMaterials)
{
mats.reset(new (std::nothrow) SDKMESH_MATERIAL[1]);
if (!mats)
@ -2395,20 +2165,48 @@ HRESULT Mesh::ExportToSDKMESH(const wchar_t* szFileName, size_t nMaterials, cons
memset(m, 0, sizeof(SDKMESH_MATERIAL));
int result = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS,
m0->name.c_str(), -1,
m->Name, MAX_MATERIAL_NAME, nullptr, FALSE);
if (!result)
if (!m0->name.empty())
{
*m->Name = 0;
int result = WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS,
m0->name.c_str(), -1,
m->Name, MAX_MATERIAL_NAME, nullptr, FALSE);
if (!result)
{
*m->Name = 0;
}
}
result = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS,
m0->texture.c_str(), -1,
m->DiffuseTexture, MAX_TEXTURE_NAME, nullptr, FALSE);
if (!result)
if (!m0->texture.empty())
{
*m->DiffuseTexture = 0;
int result = WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS,
m0->texture.c_str(), -1,
m->DiffuseTexture, MAX_TEXTURE_NAME, nullptr, FALSE);
if (!result)
{
*m->DiffuseTexture = 0;
}
}
if (!m0->normalTexture.empty())
{
int result = WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS,
m0->normalTexture.c_str(), -1,
m->NormalTexture, MAX_TEXTURE_NAME, nullptr, FALSE);
if (!result)
{
*m->NormalTexture = 0;
}
}
if (!m0->specularTexture.empty())
{
int result = WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS,
m0->specularTexture.c_str(), -1,
m->SpecularTexture, MAX_TEXTURE_NAME, nullptr, FALSE);
if (!result)
{
*m->SpecularTexture = 0;
}
}
m->Diffuse.x = m0->diffuseColor.x;
@ -2489,7 +2287,7 @@ HRESULT Mesh::ExportToSDKMESH(const wchar_t* szFileName, size_t nMaterials, cons
// Write file header
SDKMESH_HEADER header = {};
header.Version = SDKMESH_FILE_VERSION;
header.Version = (version2) ? SDKMESH_FILE_VERSION_V2 : SDKMESH_FILE_VERSION;
header.IsBigEndian = 0;
header.NumVertexBuffers = 1;

Просмотреть файл

@ -105,6 +105,9 @@ public:
DirectX::XMFLOAT3 specularColor;
DirectX::XMFLOAT3 emissiveColor;
std::wstring texture;
std::wstring normalTexture;
std::wstring specularTexture;
std::wstring emissiveTexture;
Material() noexcept :
perVertexColor(false),
@ -142,7 +145,7 @@ public:
HRESULT ExportToVBO(_In_z_ const wchar_t* szFileName) const;
HRESULT ExportToCMO(_In_z_ const wchar_t* szFileName, _In_ size_t nMaterials, _In_reads_opt_(nMaterials) const Material* materials) const;
HRESULT ExportToSDKMESH(_In_z_ const wchar_t* szFileName, _In_ size_t nMaterials, _In_reads_opt_(nMaterials) const Material* materials, bool force32bit = false) const;
HRESULT ExportToSDKMESH(_In_z_ const wchar_t* szFileName, _In_ size_t nMaterials, _In_reads_opt_(nMaterials) const Material* materials, bool force32bit = false, bool version2 = false) const;
// Create mesh from file
static HRESULT CreateFromVBO(_In_z_ const wchar_t* szFileName, _Inout_ std::unique_ptr<Mesh>& result);

Просмотреть файл

@ -27,6 +27,28 @@
using namespace DirectX;
namespace
{
std::wstring ProcessTextureFileName(const wchar_t* inName, bool dds)
{
if (!inName || !*inName)
return std::wstring();
wchar_t txext[_MAX_EXT] = {};
wchar_t txfname[_MAX_FNAME] = {};
_wsplitpath_s(inName, nullptr, 0, nullptr, 0, txfname, _MAX_FNAME, txext, _MAX_EXT);
if (dds)
{
wcscpy_s(txext, L".dds");
}
wchar_t texture[_MAX_PATH] = {};
_wmakepath_s(texture, nullptr, nullptr, txfname, txext);
return std::wstring(texture);
}
}
HRESULT LoadFromOBJ(
const wchar_t* szFilename,
std::unique_ptr<Mesh>& inMesh,
@ -109,25 +131,16 @@ HRESULT LoadFromOBJ(
mtl.ambientColor = it->vAmbient;
mtl.diffuseColor = it->vDiffuse;
mtl.specularColor = (it->bSpecular) ? it->vSpecular : XMFLOAT3(0.f, 0.f, 0.f);
mtl.emissiveColor = XMFLOAT3(0.f, 0.f, 0.f);
mtl.emissiveColor = (it->bEmissive) ? it->vEmissive : XMFLOAT3(0.f, 0.f, 0.f);
wchar_t texture[_MAX_PATH] = {};
if (*it->strTexture)
mtl.texture = ProcessTextureFileName(it->strTexture, dds);
mtl.normalTexture = ProcessTextureFileName(it->strNormalTexture, dds);
mtl.specularTexture = ProcessTextureFileName(it->strSpecularTexture, dds);
if (it->bEmissive)
{
wchar_t txext[_MAX_EXT];
wchar_t txfname[_MAX_FNAME];
_wsplitpath_s(it->strTexture, nullptr, 0, nullptr, 0, txfname, _MAX_FNAME, txext, _MAX_EXT);
if (dds)
{
wcscpy_s(txext, L".dds");
}
_wmakepath_s(texture, nullptr, nullptr, txfname, txext);
mtl.emissiveTexture = ProcessTextureFileName(it->strEmissiveTexture, dds);
}
mtl.texture = texture;
inMaterial.push_back(mtl);
}
}

339
UVAtlasTool/SDKMesh.h Normal file
Просмотреть файл

@ -0,0 +1,339 @@
//--------------------------------------------------------------------------------------
// File: SDKMesh.h
//
// SDKMESH format is generated by the legacy DirectX SDK's Content Exporter and
// originally rendered by the DXUT helper class SDKMesh
//
// http://go.microsoft.com/fwlink/?LinkId=226208
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// http://go.microsoft.com/fwlink/?LinkId=248929
// http://go.microsoft.com/fwlink/?LinkID=615561
//--------------------------------------------------------------------------------------
#pragma once
namespace DXUT
{
// .SDKMESH files
// SDKMESH_HEADER
// SDKMESH_VERTEX_BUFFER_HEADER header->VertexStreamHeadersOffset
// SDKMESH_INDEX_BUFFER_HEADER header->IndexStreamHeadersOffset
// SDKMESH_MESH header->MeshDataOffset
// SDKMESH_SUBSET header->SubsetDataOffset
// SDKMESH_FRAME header->FrameDataOffset
// SDKMESH_MATERIAL header->MaterialDataOffset
// [header->NonBufferDataSize]
// { [ header->NumVertexBuffers]
// VB data
// }
// { [ header->NumIndexBuffers]
// IB data
// }
// .SDDKANIM files
// SDKANIMATION_FILE_HEADER
// uint8_t[] - Length of fileheader->AnimationDataSize
// .SDKMESH uses Direct3D 9 decls, but only a subset of these is ever generated by the legacy DirectX SDK Content Exporter
// D3DDECLUSAGE_POSITION / D3DDECLTYPE_FLOAT3
// (D3DDECLUSAGE_BLENDWEIGHT / D3DDECLTYPE_UBYTE4N
// D3DDECLUSAGE_BLENDINDICES / D3DDECLTYPE_UBYTE4)?
// (D3DDECLUSAGE_NORMAL / D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOAT16_4, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_UBYTE4N, or D3DDECLTYPE_DEC3N)?
// (D3DDECLUSAGE_COLOR / D3DDECLTYPE_D3DCOLOR)?
// (D3DDECLUSAGE_TEXCOORD / D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT2 or D3DDECLTYPE_FLOAT16_2, D3DDECLTYPE_FLOAT3 or D3DDECLTYPE_FLOAT16_4, D3DDECLTYPE_FLOAT4 or D3DDECLTYPE_FLOAT16_4)*
// (D3DDECLUSAGE_TANGENT / same as D3DDECLUSAGE_NORMAL)?
// (D3DDECLUSAGE_BINORMAL / same as D3DDECLUSAGE_NORMAL)?
enum D3DDECLUSAGE
{
D3DDECLUSAGE_POSITION = 0,
D3DDECLUSAGE_BLENDWEIGHT =1,
D3DDECLUSAGE_BLENDINDICES =2,
D3DDECLUSAGE_NORMAL =3,
D3DDECLUSAGE_TEXCOORD = 5,
D3DDECLUSAGE_TANGENT = 6,
D3DDECLUSAGE_BINORMAL = 7,
D3DDECLUSAGE_COLOR = 10,
};
enum D3DDECLTYPE
{
D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.)
D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.)
D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.)
D3DDECLTYPE_FLOAT4 = 3, // 4D float
D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range
// Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned uint8_t
D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0
D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
D3DDECLTYPE_DEC3N = 14, // 3D signed normalized (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1.)
// Note: There is no equivalent to D3DDECLTYPE_DEC3N (14) as a DXGI_FORMAT
D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1)
D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values
D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused.
// These are extensions for DXGI-based versions of Direct3D
D3DDECLTYPE_DXGI_R10G10B10A2_UNORM = 32 + DXGI_FORMAT_R10G10B10A2_UNORM,
D3DDECLTYPE_DXGI_R11G11B10_FLOAT = 32 + DXGI_FORMAT_R11G11B10_FLOAT,
D3DDECLTYPE_DXGI_R8G8B8A8_SNORM = 32 + DXGI_FORMAT_R8G8B8A8_SNORM,
};
#pragma pack(push,4)
struct D3DVERTEXELEMENT9
{
uint16_t Stream; // Stream index
uint16_t Offset; // Offset in the stream in bytes
uint8_t Type; // Data type
uint8_t Method; // Processing method
uint8_t Usage; // Semantics
uint8_t UsageIndex; // Semantic index
};
#pragma pack(pop)
//--------------------------------------------------------------------------------------
// Hard Defines for the various structures
//--------------------------------------------------------------------------------------
const uint32_t SDKMESH_FILE_VERSION = 101;
const uint32_t SDKMESH_FILE_VERSION_V2 = 200;
const uint32_t MAX_VERTEX_ELEMENTS = 32;
const uint32_t MAX_VERTEX_STREAMS = 16;
const uint32_t MAX_FRAME_NAME = 100;
const uint32_t MAX_MESH_NAME = 100;
const uint32_t MAX_SUBSET_NAME = 100;
const uint32_t MAX_MATERIAL_NAME = 100;
const uint32_t MAX_TEXTURE_NAME = MAX_PATH;
const uint32_t MAX_MATERIAL_PATH = MAX_PATH;
const uint32_t INVALID_FRAME = uint32_t(-1);
const uint32_t INVALID_MESH = uint32_t(-1);
const uint32_t INVALID_MATERIAL = uint32_t(-1);
const uint32_t INVALID_SUBSET = uint32_t(-1);
const uint32_t INVALID_ANIMATION_DATA = uint32_t(-1);
const uint32_t INVALID_SAMPLER_SLOT = uint32_t(-1);
const uint32_t ERROR_RESOURCE_VALUE = 1;
//--------------------------------------------------------------------------------------
// Enumerated Types.
//--------------------------------------------------------------------------------------
enum SDKMESH_PRIMITIVE_TYPE
{
PT_TRIANGLE_LIST = 0,
PT_TRIANGLE_STRIP,
PT_LINE_LIST,
PT_LINE_STRIP,
PT_POINT_LIST,
PT_TRIANGLE_LIST_ADJ,
PT_TRIANGLE_STRIP_ADJ,
PT_LINE_LIST_ADJ,
PT_LINE_STRIP_ADJ,
PT_QUAD_PATCH_LIST,
PT_TRIANGLE_PATCH_LIST,
};
enum SDKMESH_INDEX_TYPE
{
IT_16BIT = 0,
IT_32BIT,
};
enum FRAME_TRANSFORM_TYPE
{
FTT_RELATIVE = 0,
FTT_ABSOLUTE, //This is not currently used but is here to support absolute transformations in the future
};
//--------------------------------------------------------------------------------------
// Structures.
//--------------------------------------------------------------------------------------
#pragma pack(push,8)
struct SDKMESH_HEADER
{
//Basic Info and sizes
uint32_t Version;
uint8_t IsBigEndian;
uint64_t HeaderSize;
uint64_t NonBufferDataSize;
uint64_t BufferDataSize;
//Stats
uint32_t NumVertexBuffers;
uint32_t NumIndexBuffers;
uint32_t NumMeshes;
uint32_t NumTotalSubsets;
uint32_t NumFrames;
uint32_t NumMaterials;
//Offsets to Data
uint64_t VertexStreamHeadersOffset;
uint64_t IndexStreamHeadersOffset;
uint64_t MeshDataOffset;
uint64_t SubsetDataOffset;
uint64_t FrameDataOffset;
uint64_t MaterialDataOffset;
};
struct SDKMESH_VERTEX_BUFFER_HEADER
{
uint64_t NumVertices;
uint64_t SizeBytes;
uint64_t StrideBytes;
D3DVERTEXELEMENT9 Decl[MAX_VERTEX_ELEMENTS];
uint64_t DataOffset;
};
struct SDKMESH_INDEX_BUFFER_HEADER
{
uint64_t NumIndices;
uint64_t SizeBytes;
uint32_t IndexType;
uint64_t DataOffset;
};
struct SDKMESH_MESH
{
char Name[MAX_MESH_NAME];
uint8_t NumVertexBuffers;
uint32_t VertexBuffers[MAX_VERTEX_STREAMS];
uint32_t IndexBuffer;
uint32_t NumSubsets;
uint32_t NumFrameInfluences; //aka bones
DirectX::XMFLOAT3 BoundingBoxCenter;
DirectX::XMFLOAT3 BoundingBoxExtents;
union
{
uint64_t SubsetOffset;
INT* pSubsets;
};
union
{
uint64_t FrameInfluenceOffset;
uint32_t* pFrameInfluences;
};
};
struct SDKMESH_SUBSET
{
char Name[MAX_SUBSET_NAME];
uint32_t MaterialID;
uint32_t PrimitiveType;
uint64_t IndexStart;
uint64_t IndexCount;
uint64_t VertexStart;
uint64_t VertexCount;
};
struct SDKMESH_FRAME
{
char Name[MAX_FRAME_NAME];
uint32_t Mesh;
uint32_t ParentFrame;
uint32_t ChildFrame;
uint32_t SiblingFrame;
DirectX::XMFLOAT4X4 Matrix;
uint32_t AnimationDataIndex; //Used to index which set of keyframes transforms this frame
};
struct SDKMESH_MATERIAL
{
char Name[MAX_MATERIAL_NAME];
// Use MaterialInstancePath
char MaterialInstancePath[MAX_MATERIAL_PATH];
// Or fall back to d3d8-type materials
char DiffuseTexture[MAX_TEXTURE_NAME];
char NormalTexture[MAX_TEXTURE_NAME];
char SpecularTexture[MAX_TEXTURE_NAME];
DirectX::XMFLOAT4 Diffuse;
DirectX::XMFLOAT4 Ambient;
DirectX::XMFLOAT4 Specular;
DirectX::XMFLOAT4 Emissive;
float Power;
uint64_t Force64_1;
uint64_t Force64_2;
uint64_t Force64_3;
uint64_t Force64_4;
uint64_t Force64_5;
uint64_t Force64_6;
};
struct SDKMESH_MATERIAL_V2
{
char Name[MAX_MATERIAL_NAME];
// PBR materials
char RMATexture[MAX_TEXTURE_NAME];
char AlbetoTexture[MAX_TEXTURE_NAME];
char NormalTexture[MAX_TEXTURE_NAME];
char EmissiveTexture[MAX_TEXTURE_NAME];
float Alpha;
char Reserved[60];
uint64_t Force64_1;
uint64_t Force64_2;
uint64_t Force64_3;
uint64_t Force64_4;
uint64_t Force64_5;
uint64_t Force64_6;
};
struct SDKANIMATION_FILE_HEADER
{
uint32_t Version;
uint8_t IsBigEndian;
uint32_t FrameTransformType;
uint32_t NumFrames;
uint32_t NumAnimationKeys;
uint32_t AnimationFPS;
uint64_t AnimationDataSize;
uint64_t AnimationDataOffset;
};
struct SDKANIMATION_DATA
{
DirectX::XMFLOAT3 Translation;
DirectX::XMFLOAT4 Orientation;
DirectX::XMFLOAT3 Scaling;
};
struct SDKANIMATION_FRAME_DATA
{
char FrameName[MAX_FRAME_NAME];
uint64_t DataOffset;
};
#pragma pack(pop)
} // namespace
static_assert( sizeof(DXUT::D3DVERTEXELEMENT9) == 8, "Direct3D9 Decl structure size incorrect" );
static_assert( sizeof(DXUT::SDKMESH_HEADER)== 104, "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKMESH_VERTEX_BUFFER_HEADER) == 288, "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKMESH_INDEX_BUFFER_HEADER) == 32, "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKMESH_MESH) == 224, "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKMESH_SUBSET) == 144, "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKMESH_FRAME) == 184, "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKMESH_MATERIAL) == 1256, "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKMESH_MATERIAL_V2) == sizeof(DXUT::SDKMESH_MATERIAL), "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKANIMATION_FILE_HEADER) == 40, "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKANIMATION_DATA) == 40, "SDK Mesh structure size incorrect" );
static_assert( sizeof(DXUT::SDKANIMATION_FRAME_DATA) == 112, "SDK Mesh structure size incorrect" );

Просмотреть файл

@ -68,6 +68,7 @@ enum OPTIONS
OPT_IMT_TEXFILE,
OPT_IMT_VERTEX,
OPT_SDKMESH,
OPT_SDKMESH_V2,
OPT_CMO,
OPT_VBO,
OPT_OUTPUTFILE,
@ -143,6 +144,7 @@ const SValue g_pOptions [] =
{ L"iv", OPT_IMT_VERTEX },
{ L"o", OPT_OUTPUTFILE },
{ L"sdkmesh", OPT_SDKMESH },
{ L"sdkmesh2", OPT_SDKMESH_V2 },
{ L"cmo", OPT_CMO },
{ L"vbo", OPT_VBO },
{ L"cw", OPT_CLOCKWISE },
@ -292,6 +294,12 @@ namespace
wprintf(L"Usage: uvatlas <options> <files>\n");
wprintf(L"\n");
wprintf(L" Input file type must be Wavefront OBJ\n\n");
wprintf(L" Output file type:\n");
wprintf(L" -sdkmesh DirectX SDK .sdkmesh format (default)\n");
wprintf(L" -sdkmesh2 .sdkmesh format version 2 (PBR materials)\n");
wprintf(L" -cmo Visual Studio Content Pipeline .cmo format\n");
wprintf(L" -vbo Vertex Buffer Object (.vbo) format\n\n");
wprintf(L" -r wildcard filename search is recursive\n");
wprintf(L" -q <level> sets quality level to DEFAULT, FAST or QUALITY\n");
wprintf(L" -n <number> maximum number of charts to generate (def: 0)\n");
@ -311,7 +319,6 @@ namespace
wprintf(
L" -iv <channel> calculate IMT using per-vertex data\n"
L" NORMAL, COLOR, TEXCOORD\n");
wprintf(L" -sdkmesh|-cmo|-vbo output file type\n");
wprintf(L" -nodds prevents extension renaming in exported materials\n");
wprintf(L" -flip reverse winding of faces\n");
wprintf(L" -flipu inverts the u texcoords\n");
@ -578,11 +585,16 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
break;
case OPT_SDKMESH:
case OPT_SDKMESH_V2:
if (dwOptions & ((DWORD64(1) << OPT_VBO) | (DWORD64(1) << OPT_CMO)))
{
wprintf(L"Can only use one of sdkmesh, cmo, or vbo\n");
return 1;
}
if (dwOption == OPT_SDKMESH_V2)
{
dwOptions |= (DWORD64(1) << OPT_SDKMESH);
}
break;
case OPT_CMO:
@ -1230,7 +1242,8 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
hr = inMesh->ExportToSDKMESH(
outputPath,
inMaterial.size(), inMaterial.empty() ? nullptr : inMaterial.data(),
(dwOptions & (DWORD64(1) << OPT_FORCE_32BIT_IB)) ? true : false);
(dwOptions & (DWORD64(1) << OPT_FORCE_32BIT_IB)) ? true : false,
(dwOptions & (DWORD64(1) << OPT_SDKMESH_V2)) ? true : false);
}
else if (!_wcsicmp(outputExt, L".cmo"))
{
@ -1289,7 +1302,11 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
}
else if (!_wcsicmp(outputExt, L".sdkmesh"))
{
hr = inMesh->ExportToSDKMESH(outputPath, inMaterial.size(), inMaterial.empty() ? nullptr : inMaterial.data());
hr = inMesh->ExportToSDKMESH(
outputPath,
inMaterial.size(), inMaterial.empty() ? nullptr : inMaterial.data(),
(dwOptions & (DWORD64(1) << OPT_FORCE_32BIT_IB)) ? true : false,
(dwOptions & (DWORD64(1) << OPT_SDKMESH_V2)) ? true : false);
}
else if (!_wcsicmp(outputExt, L".cmo"))
{

Просмотреть файл

@ -313,6 +313,7 @@
<ClCompile Include="Mesh.cpp" />
<ClInclude Include="..\..\DirectXMesh\Utilities\WaveFrontReader.h" />
<CLInclude Include="Mesh.h" />
<ClInclude Include="SDKMesh.h" />
</ItemGroup>
<ItemGroup>
</ItemGroup>

Просмотреть файл

@ -21,6 +21,7 @@
<ClInclude Include="..\..\DirectXMesh\Utilities\WaveFrontReader.h">
<Filter>Wavefront OBJ</Filter>
</ClInclude>
<ClInclude Include="SDKMesh.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="UVAtlas.rc">

Просмотреть файл

@ -332,6 +332,7 @@
<ClCompile Include="Mesh.cpp" />
<ClInclude Include="..\..\DirectXMesh\Utilities\WaveFrontReader.h" />
<CLInclude Include="Mesh.h" />
<ClInclude Include="SDKMesh.h" />
</ItemGroup>
<ItemGroup>
</ItemGroup>

Просмотреть файл

@ -21,6 +21,7 @@
<ClInclude Include="..\..\DirectXMesh\Utilities\WaveFrontReader.h">
<Filter>Wavefront OBJ</Filter>
</ClInclude>
<ClInclude Include="SDKMesh.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="UVAtlas.rc">