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

📄 winmain.cpp

📁 [游戏开发参考书-用DirectX编写RPG游戏]这是一个系列的丛书如果你都看并且懂的话你就可以你工作啦!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  }

  // Display the scene
  g_pD3DDevice->Present(NULL, NULL, NULL, NULL);

  return TRUE;
}


sFrame *LoadFile(char *Filename)
{
  return ParseXFile(Filename);
}

sFrame *ParseXFile(char *Filename)
{
  IDirectXFile           *pDXFile = NULL;
  IDirectXFileEnumObject *pDXEnum = NULL;
  IDirectXFileData       *pDXData = NULL;
  sFrame                 *Frame;

  // Create the file object
  if(FAILED(DirectXFileCreate(&pDXFile)))
    return FALSE;

  // Register the 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;
  }

  // Allocate a frame that becomes root
  Frame = new sFrame();

  // Loop through all objects looking for the frames and meshes
  while(SUCCEEDED(pDXEnum->GetNextDataObject(&pDXData))) {
    ParseXFileData(pDXData, Frame);
    ReleaseCOM(pDXData);
  }

  // Release used COM objects
  ReleaseCOM(pDXEnum);
  ReleaseCOM(pDXFile);

  // Return root frame
  return Frame;
}

void ParseXFileData(IDirectXFileData *pDataObj, sFrame *ParentFrame)
{
  IDirectXFileObject *pSubObj  = NULL;
  IDirectXFileData   *pSubData = NULL;
  IDirectXFileDataReference *pDataRef = NULL;
  const GUID *Type = NULL;
  char       *Name = NULL;
  DWORD       Size;

  sFrame     *Frame = NULL;
  sFrame     *SubFrame = NULL;

  sMesh         *Mesh = NULL;
  ID3DXBuffer   *MaterialBuffer = NULL;
  D3DXMATERIAL  *Materials = NULL;
  ID3DXBuffer   *Adjacency = NULL;
  DWORD         *AdjacencyIn = NULL;
  DWORD         *AdjacencyOut = NULL;

  DWORD i;

  // Get the template type
  if(FAILED(pDataObj->GetType(&Type)))
    return;

  // Get the template name (if any)
  if(FAILED(pDataObj->GetName(NULL, &Size)))
    return;
  if(Size) {
    if((Name = new char[Size]) != NULL)
      pDataObj->GetName(Name, &Size);
  }

  // Give template a default name if none found
  if(Name == NULL) {
    if((Name = new char[9]) == NULL)
      return;
    strcpy(Name, "Template");
  }

  // Set sub frame
  SubFrame = ParentFrame;

  // Process the templates

  // Frame
  if(*Type == TID_D3DRMFrame) {
    // Create a new frame structure
    Frame = new sFrame();

    // Store the name
    Frame->m_Name = Name;
    Name = NULL;

    // Add to parent frame
    Frame->m_Sibling = ParentFrame->m_Child;
    ParentFrame->m_Child = Frame;

    // Set sub frame parent
    SubFrame = Frame;
  }

  // Load a mesh
  if(*Type == TID_D3DRMMesh) {
    // Create a new mesh structure
    Mesh = new sMesh();

    // Store the name
    Mesh->m_Name = Name;
    Name = NULL;

    // Load mesh data (as a skinned mesh)
    if(FAILED(D3DXLoadSkinMeshFromXof(pDataObj, 0,
                g_pD3DDevice,
                &Adjacency,
                &MaterialBuffer, &Mesh->m_NumMaterials, 
                &Mesh->m_BoneNames, &Mesh->m_BoneTransforms,
                &Mesh->m_SkinMesh))) {
      delete Mesh;
      return;
    }

    // Convert to regular mesh if no bones
    if(!(Mesh->m_NumBones = Mesh->m_SkinMesh->GetNumBones())) {
    
      // Convert to a regular mesh
      Mesh->m_SkinMesh->GetOriginalMesh(&Mesh->m_Mesh);
      ReleaseCOM(Mesh->m_SkinMesh);

    } else {

      // Get a pointer to bone matrices
      Mesh->m_BoneMatrices = (D3DXMATRIX*)Mesh->m_BoneTransforms->GetBufferPointer();

      // Allocate buffers for adjacency info
      AdjacencyIn  = (DWORD*)Adjacency->GetBufferPointer();
      AdjacencyOut = new DWORD[Mesh->m_SkinMesh->GetNumFaces() * 3];

      // Generate the skin mesh object
      if(FAILED(Mesh->m_SkinMesh->GenerateSkinnedMesh(
                  D3DXMESH_WRITEONLY, 0.0f, 
                  AdjacencyIn, AdjacencyOut, 
                  &Mesh->m_Mesh))) {
        // Convert to a regular mesh if error
        Mesh->m_SkinMesh->GetOriginalMesh(&Mesh->m_Mesh);
        ReleaseCOM(Mesh->m_SkinMesh);
        Mesh->m_NumBones = 0;
      }

      delete [] AdjacencyOut;
      ReleaseCOM(Adjacency);
    }

    // Load materials or create a default one if none
    if(!Mesh->m_NumMaterials) {
      // Create a default one
      Mesh->m_Materials = new D3DMATERIAL8[1];
      Mesh->m_Textures  = new LPDIRECT3DTEXTURE8[1];

      ZeroMemory(Mesh->m_Materials, sizeof(D3DMATERIAL8));
      Mesh->m_Materials[0].Diffuse.r = 1.0f;
      Mesh->m_Materials[0].Diffuse.g = 1.0f;
      Mesh->m_Materials[0].Diffuse.b = 1.0f;
      Mesh->m_Materials[0].Diffuse.a = 1.0f;
      Mesh->m_Materials[0].Ambient   = Mesh->m_Materials[0].Diffuse;
      Mesh->m_Materials[0].Specular  = Mesh->m_Materials[0].Diffuse;
      Mesh->m_Textures[0] = NULL;

      Mesh->m_NumMaterials = 1;
    } else {
      // Load the materials
      Materials = (D3DXMATERIAL*)MaterialBuffer->GetBufferPointer();
      Mesh->m_Materials = new D3DMATERIAL8[Mesh->m_NumMaterials];
      Mesh->m_Textures  = new LPDIRECT3DTEXTURE8[Mesh->m_NumMaterials];

      for(i=0;i<Mesh->m_NumMaterials;i++) {
        Mesh->m_Materials[i] = Materials[i].MatD3D;
        Mesh->m_Materials[i].Ambient = Mesh->m_Materials[i].Diffuse;
     
        // Build a texture path and load it
        if(FAILED(D3DXCreateTextureFromFile(g_pD3DDevice,
                                            Materials[i].pTextureFilename,
                                            &Mesh->m_Textures[i]))) {
          Mesh->m_Textures[i] = NULL;
        }
      }
    }
    ReleaseCOM(MaterialBuffer);

    // Link in mesh
    Mesh->m_Next = ParentFrame->m_Mesh;
    ParentFrame->m_Mesh = Mesh;
  }

  // Skip animation sets and animations
  if(*Type == TID_D3DRMAnimationSet || *Type == TID_D3DRMAnimation || *Type == TID_D3DRMAnimationKey) {
    delete [] Name;
    return;
  }

  // Release name buffer
  delete [] Name;

  // Scan for embedded templates
  while(SUCCEEDED(pDataObj->GetNextObject(&pSubObj))) {

    // Process embedded references
    if(SUCCEEDED(pSubObj->QueryInterface(IID_IDirectXFileDataReference, (void**)&pDataRef))) {
      if(SUCCEEDED(pDataRef->Resolve(&pSubData))) {
        ParseXFileData(pSubData, SubFrame);
        ReleaseCOM(pSubData);
      }
      ReleaseCOM(pDataRef);
    }

    // Process non-referenced embedded templates
    if(SUCCEEDED(pSubObj->QueryInterface(IID_IDirectXFileData, (void**)&pSubData))) {
      ParseXFileData(pSubData, SubFrame);
      ReleaseCOM(pSubData);
    }
    ReleaseCOM(pSubObj);
  }

  return;
}

void DrawFrame(sFrame *Frame)
{
  sMesh *Mesh;
  D3DXMATRIX *Matrices;
  DWORD i;

  // Return if no frame
  if(Frame == NULL)
    return;
  
  // Draw meshes if any in frame
  if((Mesh = Frame->m_Mesh) != NULL) {

    // Generate mesh from skinned mesh to draw with
    if(Mesh->m_SkinMesh != NULL) {
      // Allocate an array of matrices to orient bones
      Matrices = new D3DXMATRIX[Mesh->m_NumBones];

      // Set all bones orientation to identity
      for(i=0;i<Mesh->m_NumBones;i++)
        D3DXMatrixIdentity(&Matrices[i]);

      // Update skinned mesh
      Mesh->m_SkinMesh->UpdateSkinnedMesh(Matrices, Mesh->m_Mesh);

      // Render the mesh
      for(i=0;i<Mesh->m_NumMaterials;i++) {
        g_pD3DDevice->SetMaterial(&Mesh->m_Materials[i]);
        g_pD3DDevice->SetTexture(0, Mesh->m_Textures[i]);
        Mesh->m_Mesh->DrawSubset(i);
      }

      // Free array of matrices
      delete [] Matrices;
    }

    // Go to next mesh
    Mesh = Mesh->m_Next;
  }

  // Draw child frames
  DrawFrame(Frame->m_Child);

  // Draw sibling frames
  DrawFrame(Frame->m_Sibling);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -