📄 direct3d.cpp
字号:
if(LastState != FALSE) {
LastState = FALSE;
pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
}
// Draw the mesh subset
pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,
pAttributes[i].VertexStart,
pAttributes[i].VertexCount,
pAttributes[i].FaceStart * 3,
pAttributes[i].FaceCount);
}
}
// Clear stream uses
pD3DDevice->SetStreamSource(0, NULL, 0, 0);
pD3DDevice->SetIndices(NULL);
// Free resources
ReleaseCOM(pVB);
ReleaseCOM(pIB);
delete [] pAttributes;
// Restore alpha blending states
if(LastState != OldAlphaState) {
pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, OldAlphaState);
pD3DDevice->SetRenderState(D3DRS_SRCBLEND, OldSrcBlend);
pD3DDevice->SetRenderState(D3DRS_DESTBLEND, OldDestBlend);
}
// Make sure to release the device object!
pD3DDevice->Release();
// Release vertex shader and declaration mapping
pD3DDevice->SetVertexShader(NULL);
pD3DDevice->SetVertexDeclaration(NULL);
return S_OK;
}
HRESULT DrawMeshes(D3DXMESHCONTAINER_EX *pMesh)
{
D3DXMESHCONTAINER_EX *MeshPtr = pMesh;
// Loop through all meshes in list
while(MeshPtr) {
// Draw mesh, returning on error
HRESULT hr = DrawMesh(MeshPtr);
if(FAILED(hr))
return hr;
// Go to next mesh
MeshPtr = (D3DXMESHCONTAINER_EX*)MeshPtr->pNextMeshContainer;
}
// Return success
return S_OK;
}
HRESULT DrawMeshes(D3DXMESHCONTAINER_EX *pMesh,
IDirect3DVertexShader9 *pShader,
IDirect3DVertexDeclaration9 *pDecl)
{
D3DXMESHCONTAINER_EX *MeshPtr = pMesh;
// Loop through all meshes in list
while(MeshPtr) {
// Draw mesh, returning on error
HRESULT hr = DrawMesh(MeshPtr, pShader, pDecl);
if(FAILED(hr))
return hr;
// Go to next mesh
MeshPtr = (D3DXMESHCONTAINER_EX*)MeshPtr->pNextMeshContainer;
}
// Return success
return S_OK;
}
///////////////////////////////////////////////////////////
//
// Generic .X parser class code
//
///////////////////////////////////////////////////////////
cXInternalParser::cXInternalParser()
{
m_pD3DDevice = NULL;
m_TexturePath = NULL;
m_Flags = 0;
m_RootMesh = NULL;
m_RootFrame = NULL;
}
cXInternalParser::~cXInternalParser()
{
delete m_RootMesh; m_RootMesh = NULL;
delete m_RootFrame; m_RootFrame = NULL;
}
BOOL cXInternalParser::Parse(char *Filename, void **Data)
{
IDirectXFile *pDXFile = NULL;
IDirectXFileEnumObject *pDXEnum = NULL;
IDirectXFileData *pDXData = NULL;
// Error checking
if(Filename == NULL)
return FALSE;
// Create the file object
if(FAILED(DirectXFileCreate(&pDXFile)))
return FALSE;
// Register the common templates
if(FAILED(pDXFile->RegisterTemplates( \
(LPVOID)D3DRM_XTEMPLATES, \
D3DRM_XTEMPLATE_BYTES))) {
pDXFile->Release();
return FALSE;
}
// Create an enumeration object
if(FAILED(pDXFile->CreateEnumObject((LPVOID)Filename, \
DXFILELOAD_FROMFILE, \
&pDXEnum))) {
pDXFile->Release();
return FALSE;
}
// Loop through all top-level objects, breaking on errors
BOOL ParseResult;
while(SUCCEEDED(pDXEnum->GetNextDataObject(&pDXData))) {
ParseResult = ParseObject(pDXData, NULL, 0, Data, FALSE);
ReleaseCOM(pDXData);
if(ParseResult == FALSE)
break;
}
// Release used COM objects
ReleaseCOM(pDXEnum);
ReleaseCOM(pDXFile);
return TRUE;
}
BOOL cXInternalParser::ParseObject(IDirectXFileData *pDataObj,
IDirectXFileData *pParentDataObj,
DWORD Depth,
void **Data, BOOL Reference)
{
const GUID *Type = GetObjectGUID(pDataObj);
// Process templates based on their type
// Build on to frame hierarchy (ony non-referenced frames)
if(*Type == TID_D3DRMFrame && Reference == FALSE && m_Flags & 2) {
// Allocate a frame
D3DXFRAME_EX *pFrame = new D3DXFRAME_EX();
// Get the frame's name (if any)
pFrame->Name = GetObjectName(pDataObj);
// Link frame into hierarchy
if(Data == NULL) {
// Link as sibling of root
pFrame->pFrameSibling = m_RootFrame;
m_RootFrame = pFrame; pFrame = NULL;
Data = (void**)&m_RootFrame;
} else {
// Link as child of supplied frame
D3DXFRAME_EX *pFramePtr = (D3DXFRAME_EX*)*Data;
pFrame->pFrameSibling = pFramePtr->pFrameFirstChild;
pFramePtr->pFrameFirstChild = pFrame; pFrame = NULL;
Data = (void**)&pFramePtr->pFrameFirstChild;
}
}
// Set a frame transformation matrix
if(*Type == TID_D3DRMFrameTransformMatrix && Reference == FALSE && m_Flags & 2 && Data) {
D3DXFRAME_EX *Frame = (D3DXFRAME_EX*)*Data;
if(Frame) {
Frame->TransformationMatrix = *(D3DXMATRIX*)GetObjectData(pDataObj, NULL);
Frame->matOriginal = Frame->TransformationMatrix;
}
}
// Load a mesh (skinned or regular)
if(*Type == TID_D3DRMMesh && m_Flags & 1) {
// Only load non-referenced skin meshes into memory
if(Reference == FALSE) {
// Load the mesh using the data object load method
D3DXMESHCONTAINER_EX *pMesh = NULL;
LoadMesh(&pMesh, m_pD3DDevice, pDataObj, m_TexturePath, m_NewFVF, m_LoadFlags);
// Link mesh to head of list of meshes
if(pMesh) {
pMesh->pNextMeshContainer = m_RootMesh;
m_RootMesh = pMesh; pMesh = NULL;
// Link mesh to frame if needed
if(Data) {
D3DXFRAME_EX *pFrame = (D3DXFRAME_EX*)*Data;
if(m_Flags & 2 && pFrame)
pFrame->pMeshContainer = m_RootMesh;
}
}
} else {
// If referenced, then check if wanting to link to frame
if(Data) {
D3DXFRAME_EX *pFrame = (D3DXFRAME_EX*)*Data;
if(m_Flags & 2 && m_RootMesh && pFrame) {
// Get name of mesh reference to link to
char *Name = GetObjectName(pDataObj);
if(Name) {
// Find matching mesh by name and store result
pFrame->pMeshContainer = m_RootMesh->Find(Name);
// Clear name
delete [] Name; Name = NULL;
}
}
}
}
}
// Parse child templates
return ParseChildObjects(pDataObj, Depth, Data, Reference);
}
BOOL cXInternalParser::ParseChildObjects(IDirectXFileData *pDataObj,
DWORD Depth, void **Data,
BOOL ForceReference)
{
IDirectXFileObject *pSubObj = NULL;
IDirectXFileData *pSubData = NULL;
IDirectXFileDataReference *pDataRef = NULL;
BOOL ParseResult = TRUE;
// Scan for embedded templates
while(SUCCEEDED(pDataObj->GetNextObject(&pSubObj))) {
// Process embedded references
if(SUCCEEDED(pSubObj->QueryInterface(
IID_IDirectXFileDataReference,
(void**)&pDataRef))) {
// Resolve the data object
if(SUCCEEDED(pDataRef->Resolve(&pSubData))) {
// Parse the object, remembering the return code
ParseResult = ParseObject(pSubData, pDataObj, Depth+1, Data, TRUE);
ReleaseCOM(pSubData);
}
ReleaseCOM(pDataRef);
// Return on parsing failure
if(ParseResult == FALSE)
return FALSE;
} else
// Process non-referenced embedded templates
if(SUCCEEDED(pSubObj->QueryInterface(
IID_IDirectXFileData,
(void**)&pSubData))) {
// Parse the object, remembering the return code
ParseResult = ParseObject(pSubData, pDataObj, Depth+1, Data, ForceReference);
ReleaseCOM(pSubData);
}
// Release the data object
ReleaseCOM(pSubObj);
// Return on parsing failure
if(ParseResult == FALSE)
return FALSE;
}
return TRUE;
}
const GUID *cXInternalParser::GetObjectGUID(IDirectXFileData *pDataObj)
{
const GUID *Type = NULL;
// Error checking
if(pDataObj == NULL)
return NULL;
// Get the template type
if(FAILED(pDataObj->GetType(&Type)))
return NULL;
return Type;
}
char *cXInternalParser::GetObjectName(IDirectXFileData *pDataObj)
{
char *Name = NULL;
DWORD Size = 0;
// Error checking
if(pDataObj == NULL)
return NULL;
// Get the template name (if any)
if(FAILED(pDataObj->GetName(NULL, &Size)))
return NULL;
// Allocate a name buffer and retrieve name
if(Size) {
if((Name = new char[Size]) != NULL)
pDataObj->GetName(Name, &Size);
}
return Name;
}
void *cXInternalParser::GetObjectData(IDirectXFileData *pDataObj,
DWORD *Size)
{
void *TemplateData = NULL;
DWORD TemplateSize = 0;
// Error checking
if(pDataObj == NULL)
return NULL;
// Get a data pointer to template
pDataObj->GetData(NULL, &TemplateSize, (PVOID*)&TemplateData);
// Save size if needed
if(Size != NULL)
*Size = TemplateSize;
return TemplateData;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -