⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 direct3d.cpp

📁 用DirectX制作高级动画-[Advanced.Animation.with.DirectX]
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        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 + -