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

📄 core_graphics.cpp

📁 [游戏开发参考书-用DirectX编写RPG游戏]这是一个系列的丛书如果你都看并且懂的话你就可以你工作啦!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    while(Mesh != NULL) {
      if(Mesh->m_SkinMesh != NULL) {
        Matrix = new D3DXMATRIX[Mesh->m_NumBones];
        for(i=0;i<Mesh->m_NumBones;i++)
          D3DXMatrixIdentity(&Matrix[i]);
        Mesh->m_SkinMesh->UpdateSkinnedMesh(Matrix, Mesh->m_Mesh);
        delete [] Matrix;
      }
      Mesh = Mesh->m_Next;
    }
  }

  // Calculate bounding box and sphere
  if((Mesh = m_Meshes) != NULL) {
    while(Mesh != NULL) {
      m_Min.x = min(m_Min.x, Mesh->m_Min.x);
      m_Min.y = min(m_Min.y, Mesh->m_Min.y);
      m_Min.z = min(m_Min.z, Mesh->m_Min.z);
      m_Max.x = max(m_Max.x, Mesh->m_Max.x);
      m_Max.y = max(m_Max.y, Mesh->m_Max.y);
      m_Max.z = max(m_Max.z, Mesh->m_Max.z);
      m_Radius = max(m_Radius, Mesh->m_Radius);

      Mesh = Mesh->m_Next;
    }
  }

  return TRUE;
}

void cMesh::ParseXFileData(IDirectXFileData *pDataObj, sFrame *ParentFrame, char *TexturePath)
{
  IDirectXFileObject *pSubObj  = NULL;
  IDirectXFileData   *pSubData = NULL;
  IDirectXFileDataReference *pDataRef = NULL;
  const GUID *Type = NULL;
  char       *Name = NULL;
  DWORD       Size;
  sFrame     *SubFrame = NULL;
  char        Path[MAX_PATH];

  sFrame     *Frame = NULL;
  D3DXMATRIX *FrameMatrix = NULL;

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

  DWORD i;
  BYTE  **Ptr;

  // 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, "$NoName$");
  }

  // 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_Parent = ParentFrame;
    Frame->m_Sibling = ParentFrame->m_Child;
    ParentFrame->m_Child = Frame;

    // Increase frame count
    m_NumFrames++;

    // Set sub frame parent
    SubFrame = Frame;
  }

  // Frame transformation matrix
  if(*Type == TID_D3DRMFrameTransformMatrix) {
    if(FAILED(pDataObj->GetData(NULL, &Size, (PVOID*)&FrameMatrix)))
      return;
    ParentFrame->m_matOriginal = *FrameMatrix;
  }

  // Mesh
  if(*Type == TID_D3DRMMesh) {
    // See if mesh already loaded
    if(m_Meshes == NULL || m_Meshes->FindMesh(Name) == NULL) {
      // Create a new mesh structure
      Mesh = new sMesh();

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

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

      // Calculate the bounding box and sphere
      if(SUCCEEDED(Mesh->m_SkinMesh->LockVertexBuffer(D3DLOCK_READONLY, (BYTE**)&Ptr))) {
        D3DXComputeBoundingBox((void*)Ptr, Mesh->m_SkinMesh->GetNumVertices(), Mesh->m_SkinMesh->GetFVF(), &Mesh->m_Min, &Mesh->m_Max);
        D3DXComputeBoundingSphere((void*)Ptr, Mesh->m_SkinMesh->GetNumVertices(), Mesh->m_SkinMesh->GetFVF(), &D3DXVECTOR3(0.0f,0.0f,0.0f), &Mesh->m_Radius);
        Mesh->m_SkinMesh->UnlockVertexBuffer();
      }

      // 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 {
        // Create the bone matrix array and clear it out
        Mesh->m_Matrices = new D3DXMATRIX[Mesh->m_NumBones];
        for(i=0;i<Mesh->m_NumBones;i++)
          D3DXMatrixIdentity(&Mesh->m_Matrices[i]);

        // Create the frame mapping matrix array and clear out
        Mesh->m_FrameMatrices = new D3DXMATRIX*[Mesh->m_NumBones];
        for(i=0;i<Mesh->m_NumBones;i++)
          Mesh->m_FrameMatrices[i] = NULL;

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

        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
          sprintf(Path, "%s%s", TexturePath, Materials[i].pTextureFilename);
          if(FAILED(D3DXCreateTextureFromFile(m_Graphics->GetDeviceCOM(),
                                              Path,
                                              &Mesh->m_Textures[i]))) {
            Mesh->m_Textures[i] = NULL;
          }
        }
      }
      ReleaseCOM(MaterialBuffer);

      // link in mesh
      Mesh->m_Next = m_Meshes;
      m_Meshes = Mesh;
      m_NumMeshes++;
    } else {
      // Find mesh in list
      Mesh = m_Meshes->FindMesh(Name);
    }

    // Add mesh to frame 
    if(Mesh != NULL)
      ParentFrame->AddMesh(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, TexturePath);
        ReleaseCOM(pSubData);
      }
      ReleaseCOM(pDataRef);
    }

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

  return;
}

void cMesh::MapFramesToBones(sFrame *Frame)
{
  sMesh *Mesh;
  DWORD i;
  char **Name;

  // Return if no more frames to map
  if(Frame == NULL || Frame->m_Name == NULL)
    return;

  // Scan through meshes looking for bone matches
  Mesh = m_Meshes;
  while(Mesh != NULL) {
    if(Mesh->m_NumBones && Mesh->m_BoneNames != NULL && Mesh->m_Matrices != NULL && Mesh->m_FrameMatrices != NULL) {
      Name = (char**)Mesh->m_BoneNames->GetBufferPointer();
      for(i=0;i<Mesh->m_NumBones;i++) {
        if(!strcmp(Frame->m_Name, Name[i])) {
          Mesh->m_FrameMatrices[i] = &Frame->m_matCombined;
          break;
        }
      }
    }
    Mesh = Mesh->m_Next;
  }

  // Scan through child frames
  MapFramesToBones(Frame->m_Child);

  // Scan through sibling frames
  MapFramesToBones(Frame->m_Sibling);
}

BOOL cMesh::Free()
{
  m_Graphics = NULL;
 
  m_NumMeshes = 0;
  delete m_Meshes;
  m_Meshes = NULL;

  m_NumFrames = 0;
  delete m_Frames;
  m_Frames = NULL;

  m_Min.x = m_Min.y = m_Min.z = m_Max.x = m_Max.y = m_Max.z = 0.0f;
  m_Radius = 0.0f;

  return TRUE;
}

BOOL cMesh::IsLoaded()
{
  if(m_Meshes != NULL && m_Frames != NULL)
    return TRUE;
  return FALSE;
}

long cMesh::GetNumFrames()
{
  return m_NumFrames;
}

sFrame *cMesh::GetParentFrame()
{
  return m_Frames;
}

sFrame *cMesh::GetFrame(char *Name)
{
  if(m_Frames == NULL)
    return NULL;
  return m_Frames->FindFrame(Name);
}

long cMesh::GetNumMeshes()
{
  return m_NumMeshes;
}

sMesh *cMesh::GetParentMesh()
{
  return m_Meshes;
}

sMesh *cMesh::GetMesh(char *Name)
{
  if(m_Meshes == NULL)
    return NULL;
  return m_Meshes->FindMesh(Name);
}

BOOL cMesh::GetBounds(float *MinX, float *MinY, float *MinZ, float *MaxX, float *MaxY, float *MaxZ, float *Radius)
{
  if(MinX != NULL)
    *MinX = m_Min.x;
  if(MinY != NULL)
    *MinY = m_Min.y;
  if(MinZ != NULL)
    *MinZ = m_Min.z;

  if(MaxX != NULL)
    *MaxX = m_Max.x;
  if(MaxY != NULL)
    *MaxY = m_Max.y;
  if(MaxZ != NULL)
    *MaxZ = m_Max.z;

  if(Radius != NULL)
    *Radius = m_Radius;

  return TRUE;
}

cObject::cObject()
{
  m_Graphics       = NULL;
  m_Mesh           = NULL;
  m_AnimationSet   = NULL;
}

cObject::~cObject()
{
  Free();
}

BOOL cObject::Create(cGraphics *Graphics, cMesh *Mesh)
{
  if((m_Graphics = Graphics) == NULL)
    return FALSE;
  m_Mesh = Mesh;

  Move(0.0f, 0.0f, 0.0f);
  Rotate(0.0f, 0.0f, 0.0f);
  Scale(1.0f, 1.0f, 1.0f);

  return TRUE;
}

BOOL cObject::Free()
{
  m_Graphics     = NULL;
  m_Mesh         = NULL;
  m_AnimationSet = NULL;

  return TRUE;
}

BOOL cObject::EnableBillboard(BOOL Enable)
{
  m_Pos.EnableBillboard(Enable);
  return TRUE;
}

BOOL cObject::AttachToObject(cObject *Object, char *FrameName)
{
  sFrame *Frame;

  if(Object == NULL || Object->m_Mesh == NULL) {
    m_Pos.SetCombineMatrix1(NULL);
    m_Pos.SetCombineMatrix2(NULL);
  } else {
    Frame = Object->m_Mesh->GetFrame(FrameName);
    if(Frame == NULL) {
      m_Pos.SetCombineMatrix1(NULL);
      m_Pos.SetCombineMatrix2(NULL);
    } else {
      m_Pos.SetCombineMatrix1(&Frame->m_matCombined);
      m_Pos.SetCombineMatrix2(Object->m_Pos.GetMatrix());
    }
  }

  return TRUE;
}

BOOL cObject::Move(float XPos, float YPos, float ZPos)
{
  return m_Pos.Move(XPos, YPos, ZPos);
}

BOOL cObject::MoveRel(float XAdd, float YAdd, float ZAdd)
{
  return m_Pos.MoveRel(XAdd, YAdd, ZAdd);
}

BOOL cObject::Rotate(float XRot, float YRot, float ZRot)
{
  return m_Pos.Rotate(XRot, YRot, ZRot);
}

BOOL cObject::RotateRel(float XAdd, float YAdd, float ZAdd)
{
  return m_Pos.RotateRel(XAdd, YAdd, ZAdd);
}

BOOL cObject::Scale(float XScale, float YScale, float ZScale)
{
  return m_Pos.Scale(XScale, YScale, ZScale);
}

BOOL cObject::ScaleRel(float XAdd, float YAdd, float ZAdd)
{
  return m_Pos.ScaleRel(XAdd, YAdd, ZAdd);
}

D3DXMATRIX *cObject::GetMatrix()
{
  return m_Pos.GetMatrix(); 
}

BOOL cObject::SetMesh(cMesh *Mesh)
{
  m_Mesh = Mesh;

  return TRUE;
}

cMesh *cObject::GetMesh()
{
  return m_Mesh;
}

BOOL cObject::SetAnimation(cAnimation *Animation, char *Name, unsigned long StartTime)
{
  m_StartTime = StartTime;
  if(Animation == NULL)
    m_AnimationSet = NULL;
  else
    m_AnimationSet = Animation->GetAnimationSet(Name);

  return TRUE;
}

char *cObject::GetAnimation()
{
  if(m_AnimationSet == NULL)
    return NULL;
  return m_AnimationSet->m_Name;
}

BOOL cObject::ResetAnimation(unsigned long StartTime)
{
  m_StartTime = StartTime;
  return TRUE;
}

float cObject::GetXPos()
{
  return m_Pos.GetXPos();
}

float cObject::GetYPos()
{
  return m_Pos.GetYPos();
}

float cObject::GetZPos()
{
  return m_Pos.GetZPos();
}

float cObject::GetXRotation()
{
  return m_Pos.GetXRotation();
}

float cObject::GetYRotation()
{
  return m_Pos.GetYRotation();
}

float cObject::GetZRotation()
{
  return m_Pos.GetZRotation();
}

float cObject::GetXScale()
{
  return m_Pos.GetXScale();
}

float cObject::GetYScale()
{
  return m_Pos.GetYScale();
}

float cObject::GetZScale()
{
  return m_Pos.GetZScale();
}

BOOL cObject::GetBounds(float *MinX, float *MinY, float *MinZ, float *MaxX, float *MaxY, float *MaxZ, float *Radius)
{
  float Length, XScale, YScale, ZScale;

  if(m_Mesh == NULL)
    return FALSE;

  m_Mesh->GetBounds(MinX, MinY, MinZ, MaxX, MaxY, MaxZ, Radius);

  // Scale bounds
  XScale = m_Pos.GetXScale();
  YScale = m_Pos.GetYScale();
  ZScale = m_Pos.GetZScale();

⌨️ 快捷键说明

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