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

📄 core_graphics.cpp

📁 [游戏开发参考书-用DirectX编写RPG游戏]这是一个系列的丛书如果你都看并且懂的话你就可以你工作啦!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  if(MinX != NULL)
    *MinX *= XScale;
  if(MinY != NULL)
    *MinY *= YScale;
  if(MinZ != NULL)
    *MinZ *= ZScale;

  if(MaxX != NULL)
    *MaxX *= XScale;
  if(MaxY != NULL)
    *MaxY *= YScale;
  if(MaxZ != NULL)
    *MaxZ *= ZScale;

  if(Radius != NULL) {
    Length = (float)sqrt(XScale*XScale+YScale*YScale+ZScale*ZScale);
    (*Radius) *= Length;
  }

  return TRUE;
}

BOOL cObject::Update()
{
  // Update the world position
  m_Pos.Update(m_Graphics);

  return TRUE;
}

BOOL cObject::UpdateAnimation(unsigned long Time, BOOL Smooth)
{
  if(m_AnimationSet != NULL) {
    m_Mesh->GetParentFrame()->ResetMatrices();
    m_AnimationSet->Update(Time - m_StartTime, Smooth);
  }

  return TRUE;
}

BOOL cObject::AnimationComplete(unsigned long Time)
{
  if(m_AnimationSet == NULL)
    return TRUE;
  if((Time - m_StartTime) >= m_AnimationSet->m_Length)
    return TRUE;
  return FALSE;
}

BOOL cObject::Render()
{
  D3DXMATRIX Matrix;
  
  // Error checking
  if(m_Graphics == NULL || m_Mesh == NULL || m_Mesh->GetParentFrame() == NULL || m_Mesh->GetParentMesh() == NULL)
    return FALSE;

  // Update the object matrix
  Update();

  // Update the frame matrices
  D3DXMatrixIdentity(&Matrix);
  UpdateFrame(m_Mesh->GetParentFrame(), &Matrix);

  // Copy frame matrices to bone matrices
  m_Mesh->GetParentMesh()->CopyFrameToBoneMatrices();

  // Draw all frame meshes
  DrawFrame(m_Mesh->GetParentFrame());

  return TRUE;
}

void cObject::UpdateFrame(sFrame *Frame, D3DXMATRIX *Matrix)
{
  // Return if no more frames
  if(Frame == NULL)
    return;

  // Calculate frame matrix based on animation or not
  if(m_AnimationSet == NULL)
    D3DXMatrixMultiply(&Frame->m_matCombined, &Frame->m_matOriginal, Matrix);
  else
    D3DXMatrixMultiply(&Frame->m_matCombined, &Frame->m_matTransformed, Matrix);

  // Update child frames
  UpdateFrame(Frame->m_Child, &Frame->m_matCombined);

  // Update sibling frames
  UpdateFrame(Frame->m_Sibling, Matrix);
}

void cObject::DrawFrame(sFrame *Frame)
{
  sFrameMeshList *List;
  sMesh          *Mesh;
  D3DXMATRIX      matWorld;
  DWORD           i;

  if(Frame == NULL)
    return;

  if((List = Frame->m_MeshList) != NULL) {
    while(List != NULL) {

      // See if there's a mesh to draw
      if((Mesh = List->m_Mesh) != NULL) {

        // Generate the mesh if using bones and set world matrix
        if(Mesh->m_NumBones && Mesh->m_SkinMesh != NULL) {
          Mesh->m_SkinMesh->UpdateSkinnedMesh(Mesh->m_Matrices, Mesh->m_Mesh);

          // Set object world transformation
          m_Graphics->GetDeviceCOM()->SetTransform(D3DTS_WORLD, m_Pos.GetMatrix());
        } else {
          // Set the world transformation matrix for this frame
          D3DXMatrixMultiply(&matWorld, &Frame->m_matCombined, m_Pos.GetMatrix());
          m_Graphics->GetDeviceCOM()->SetTransform(D3DTS_WORLD, &matWorld);
        }

        // Loop through materials and draw the mesh
        for(i=0;i<Mesh->m_NumMaterials;i++) {
          // Don't draw materials with no alpha (0.0)
          if(Mesh->m_Materials[i].Diffuse.a != 0.0f) {
            m_Graphics->GetDeviceCOM()->SetMaterial(&Mesh->m_Materials[i]);
            m_Graphics->GetDeviceCOM()->SetTexture(0, Mesh->m_Textures[i]);

            // Enabled alpha blending based on material alpha
            if(Mesh->m_Materials[i].Diffuse.a != 1.0f)
              m_Graphics->EnableAlphaBlending(TRUE, D3DBLEND_SRCCOLOR, D3DBLEND_ONE);

            Mesh->m_Mesh->DrawSubset(i);

            // Disable alpha blending based on material alpha
            if(Mesh->m_Materials[i].Diffuse.a != 1.0f)
              m_Graphics->EnableAlphaBlending(FALSE);
          }
        }
      }

      // Next mesh in list
      List = List->m_Next;
    }
  }

  // Next child mesh
  DrawFrame(Frame->m_Child);
  DrawFrame(Frame->m_Sibling);
}

cAnimation::cAnimation()
{
  m_NumAnimations = 0;
  m_AnimationSet  = NULL;
}

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

BOOL cAnimation::Load(char *Filename, cMesh *MapMesh)
{
  IDirectXFile           *pDXFile = NULL;
  IDirectXFileEnumObject *pDXEnum = NULL;
  IDirectXFileData       *pDXData = NULL;
  
  // Free a prior animation
  Free();

  // Error checking
  if(Filename == NULL)
    return FALSE;

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

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

  ReleaseCOM(pDXEnum);
  ReleaseCOM(pDXFile);

  // Map the animation to the supplied mesh (if any)
  if(MapMesh != NULL)
    MapToMesh(MapMesh);

  return TRUE;
}

void cAnimation::ParseXFileData(IDirectXFileData *pDataObj, sAnimationSet *ParentAnim, sAnimation *CurrentAnim)
{
  IDirectXFileObject *pSubObj  = NULL;
  IDirectXFileData   *pSubData = NULL;
  IDirectXFileDataReference *pDataRef = NULL;
  const GUID      *Type = NULL;
  char            *Name = NULL;
  DWORD            Size;
  PBYTE           *DataPtr;

  DWORD            i;

  DWORD              KeyType, NumKeys, Time;
  sXFileRotateKey   *RotKey;
  sXFileScaleKey    *ScaleKey;
  sXFilePositionKey *PosKey;
  sXFileMatrixKey   *MatKey;

  sAnimationSet   *SubAnimSet = NULL;
  sAnimation      *SubAnim    = NULL;

  sAnimation      *Anim = NULL;
  sAnimationSet   *AnimSet = NULL;
  
  // 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 parent
  SubAnimSet = ParentAnim;
  SubAnim    = CurrentAnim;

  // Process the templates

  // Process an animation set
  if(*Type == TID_D3DRMAnimationSet) {
    // Create a animation set structure
    if((AnimSet = new sAnimationSet()) == NULL)
      return;

    // Set the name
    AnimSet->m_Name = Name;
    Name = NULL;

    // Link into the animation set list
    AnimSet->m_Next = m_AnimationSet;
    m_AnimationSet = AnimSet;

    // Set as new parent
    SubAnimSet = AnimSet;
  }

  // Process an animation
  if(*Type == TID_D3DRMAnimation && ParentAnim != NULL) {
    // Create an animation structure
    if((Anim = new sAnimation()) == NULL)
      return;

    // Set the name
    Anim->m_Name = Name;
    Name = NULL;

    // Link into the animation list
    Anim->m_Next = ParentAnim->m_Animation;
    ParentAnim->m_Animation = Anim;

    SubAnim = Anim;
  }

  // Process an animation key
  if(*Type == TID_D3DRMAnimationKey && CurrentAnim != NULL) {
    // Load in this animation's key data
    if(FAILED(pDataObj->GetData(NULL, &Size, (PVOID*)&DataPtr)))
      return;

    KeyType = ((DWORD*)DataPtr)[0];
    NumKeys = ((DWORD*)DataPtr)[1];

    switch(KeyType) {
      case 0:
        delete [] CurrentAnim->m_RotateKeys;
        if((CurrentAnim->m_RotateKeys = new sRotateKey[NumKeys]) == NULL)
          return;
        CurrentAnim->m_NumRotateKeys = NumKeys;
        RotKey = (sXFileRotateKey*)((char*)DataPtr + (sizeof(DWORD) * 2));
        for(i=0;i<NumKeys;i++) {
          CurrentAnim->m_RotateKeys[i].Time = RotKey->Time;
          CurrentAnim->m_RotateKeys[i].Quaternion.x = -RotKey->x;
          CurrentAnim->m_RotateKeys[i].Quaternion.y = -RotKey->y;
          CurrentAnim->m_RotateKeys[i].Quaternion.z = -RotKey->z;
          CurrentAnim->m_RotateKeys[i].Quaternion.w =  RotKey->w;

          if(RotKey->Time > ParentAnim->m_Length)
            ParentAnim->m_Length = RotKey->Time;

          RotKey += 1;
        }

        break;

      case 1: 
        delete [] CurrentAnim->m_ScaleKeys;
        if((CurrentAnim->m_ScaleKeys = new sScaleKey[NumKeys]) == NULL)
          return;
        CurrentAnim->m_NumScaleKeys = NumKeys;
        ScaleKey = (sXFileScaleKey*)((char*)DataPtr + (sizeof(DWORD) * 2));
        for(i=0;i<NumKeys;i++) {
          CurrentAnim->m_ScaleKeys[i].Time  = ScaleKey->Time;
          CurrentAnim->m_ScaleKeys[i].Scale = ScaleKey->Scale;

          if(ScaleKey->Time > ParentAnim->m_Length)
            ParentAnim->m_Length = ScaleKey->Time;

          ScaleKey += 1;
        }

        // Calculate the interpolation values
        if(NumKeys > 1) {
          for(i=0;i<NumKeys-1;i++) {
            CurrentAnim->m_ScaleKeys[i].ScaleInterpolation = CurrentAnim->m_ScaleKeys[i+1].Scale - CurrentAnim->m_ScaleKeys[i].Scale;
            Time = CurrentAnim->m_ScaleKeys[i+1].Time - CurrentAnim->m_ScaleKeys[i].Time;
            if(!Time)
              Time = 1;
            CurrentAnim->m_ScaleKeys[i].ScaleInterpolation /= (float)Time;
          }
        }

        break;
    
      case 2:
        delete [] CurrentAnim->m_PositionKeys;
        if((CurrentAnim->m_PositionKeys = new sPositionKey[NumKeys]) == NULL)
          return;
        CurrentAnim->m_NumPositionKeys = NumKeys;
        PosKey = (sXFilePositionKey*)((char*)DataPtr + (sizeof(DWORD) * 2));
        for(i=0;i<NumKeys;i++) {
          CurrentAnim->m_PositionKeys[i].Time = PosKey->Time;
          CurrentAnim->m_PositionKeys[i].Pos  = PosKey->Pos;

          if(PosKey->Time > ParentAnim->m_Length)
            ParentAnim->m_Length = PosKey->Time;

          PosKey += 1;
        }

        // Calculate the interpolation values
        if(NumKeys > 1) {
          for(i=0;i<NumKeys-1;i++) {
            CurrentAnim->m_PositionKeys[i].PosInterpolation = CurrentAnim->m_PositionKeys[i+1].Pos - CurrentAnim->m_PositionKeys[i].Pos;
            Time = CurrentAnim->m_PositionKeys[i+1].Time - CurrentAnim->m_PositionKeys[i].Time;
            if(!Time)
              Time = 1;
            CurrentAnim->m_PositionKeys[i].PosInterpolation /= (float)Time;
          }
        }

        break;

      case 4:
        delete [] CurrentAnim->m_MatrixKeys;
        if((CurrentAnim->m_MatrixKeys = new sMatrixKey[NumKeys]) == NULL)
          return;
        CurrentAnim->m_NumMatrixKeys = NumKeys;
        MatKey = (sXFileMatrixKey*)((char*)DataPtr + (sizeof(DWORD) * 2));
        for(i=0;i<NumKeys;i++) {
          CurrentAnim->m_MatrixKeys[i].Time   = MatKey->Time;
          CurrentAnim->m_MatrixKeys[i].Matrix = MatKey->Matrix;

          if(MatKey->Time > ParentAnim->m_Length)
            ParentAnim->m_Length = MatKey->Time;

          MatKey+=1;
        }

        // Calculate the interpolation matrices
        if(NumKeys > 1) {
          for(i=0;i<NumKeys-1;i++) {
            CurrentAnim->m_MatrixKeys[i].MatInterpolation = CurrentAnim->m_MatrixKeys[i+1].Matrix - CurrentAnim->m_MatrixKeys[i].Matrix;
            Time = CurrentAnim->m_MatrixKeys[i+1].Time - CurrentAnim->m_MatrixKeys[i].Time;
            if(!Time)
              Time = 1;
            CurrentAnim->m_MatrixKeys[i].MatInterpolation /= (float)Time;
          }
        }
        break;
    }
  }

  // Process animation options
  if(*Type == TID_D3DRMAnimationOptions && CurrentAnim != NULL) {
    // Load in this animation's options
    if(FAILED(pDataObj->GetData(NULL, &Size, (PVOID*)&DataPtr)))
      return;

    // Process looping information
    if(!((DWORD*)DataPtr)[0])
      CurrentAnim->m_Loop = TRUE;
    else
      CurrentAnim->m_Loop = FALSE;

    // Process linear information
    if(!((DWORD*)DataPtr)[1])
      CurrentAnim->m_Linear = FALSE;
    else
      CurrentAnim->m_Linear = TRUE;
  }

  // Process a frame reference
  if(*Type == TID_D3DRMFrame && CurrentAnim != NULL) {
    CurrentAnim->m_FrameName = Name;
    Name = NULL;

    // Don't enumerate child templates
    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, SubAnimSet, SubAnim);
        ReleaseCOM(pSubData);
      }
      ReleaseCOM(pDataRef);
    }

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

BOOL cAnimation::Free()
{
  delete m_AnimationSet;
  m_AnimationSet  = NULL;
  m_NumAnimations = 0;

  return TRUE;
}

BOOL cAnimation::IsLoaded()
{
  if(m_AnimationSet == NULL)
    return FALSE;
  return TRUE;
}

BOOL cAnimation::MapToMesh(cMesh *Mesh)
{
  sAnimationSet *AnimSet;
  sAnimation    *Anim;

  // Make sure there's a mesh to work with
  if(Mesh == NULL)
    return FALSE;

  // Assign links to frames by name
  if((AnimSet = m_AnimationSet) == NULL)
    return FALSE;

  // Scan through all animation sets
  while(AnimSet != NULL) {
    // Scan through all animations
    Anim = AnimSet->m_Animation;
    while(Anim != NULL) {
      // Find the matching frame from Mesh
      Anim->m_Frame = Mesh->GetFrame(Anim->m_FrameName);
      Anim = Anim->m_Next;
    }
    AnimSet = AnimSet->m_Next;
  }

  return TRUE;
}

long cAnimation::GetNumAnimations()
{
  return m_NumAnimations;
}

sAnimationSet *cAnimation::GetAnimationSet(char *Name)
{
  if(m_AnimationSet == NULL)
    return NULL;
  return m_AnimationSet->FindSet(Name);
}

BOOL cAnimation::SetLoop(BOOL ToLoop, char *Name)
{
  sAnimationSet *AnimSet;
  sAnimation    *Anim;

  if((AnimSet = GetAnimationSet(Name)) == NULL)
    return FALSE;

  Anim = AnimSet->m_Animation;
  while(Anim != NULL) {
    Anim->m_Loop = ToLoop;
    Anim = Anim->m_Next;
  }

  return TRUE;
}

unsigned long cAnimation::GetLength(char *Name)
{
  sAnimationSet *AnimSet;

  if((AnimSet = GetAnimationSet(Name)) == NULL)
    return 0;
  return AnimSet->m_Length;
}

cTexture::cTexture()
{
  m_Graphics = NULL;
  m_Texture = NULL;
  m_Width = m_Height = 0;
}

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

BOOL cTexture::Load(cGraphics *Graphics, char *Filename, DWORD Transparent, D3DFORMAT Format)
{
  Free();

⌨️ 快捷键说明

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