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

📄 winmain.cpp

📁 用DirectX制作高级动画-[Advanced.Animation.with.DirectX]
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
  Make sure you have the /J compiler switch in your project settings!
  The /J switch ensures chars are unsigned by default.
*/

#include <windows.h>
#include <stdio.h>
#include "d3d9.h"
#include "d3dx9.h"
#include "resource.h"
#include "MD2.h"
#include "MS3D.h"

// Window class
char g_szClass[] = "MESHCONV";

// Open/save filename structures and buffers
OPENFILENAME g_ofn, g_sfn;
char g_MD2Filename[MAX_PATH];
char g_MS3DFilename[MAX_PATH];
char g_XFilename[MAX_PATH];
char g_TextureFilename[MAX_PATH];

// Function prototypes
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow);
long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

BOOL ConvertMD2(char *SrcFilename, char *TextureFilename, char *DestFilename);
BOOL ConvertMS3D(char *SrcFilename, char *DestFilename);
void WriteFrame(sMS3DBoneContainer *Bone, FILE *fp, DWORD Indent, BOOL Close);
void CombineTransformation(sMS3DBoneContainer *Bone, D3DXMATRIX *Matrix);
void CreateYawPitchRollRotationMatrix(D3DXMATRIX *matRotation,
                                      float Yaw, float Pitch, float Roll);

// Application //////////////////////////////////////////////////////
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow)
{
  WNDCLASS wc;
  MSG      Msg;

  // Register window class
  wc.style         = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc   = WindowProc;
  wc.cbClsExtra    = 0;
  wc.cbWndExtra    = DLGWINDOWEXTRA;
  wc.hInstance     = hInst;
  wc.hIcon         = LoadIcon(hInst, IDI_APPLICATION);
  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  wc.lpszMenuName  = NULL;
  wc.lpszClassName = g_szClass;
  RegisterClass(&wc);

  // Create the dialog box window and show it
  HWND hWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_CONVERSION), 0, NULL);
  UpdateWindow(hWnd);
  ShowWindow(hWnd, nCmdShow);

  // Setup open filename data structure
  ZeroMemory(&g_ofn, sizeof(OPENFILENAME));
  g_ofn.lStructSize   = sizeof(OPENFILENAME);
  g_ofn.hInstance     = hInst;
  g_ofn.hwndOwner     = hWnd;
  g_ofn.nMaxFile      = MAX_PATH;
  g_ofn.nMaxFileTitle = MAX_PATH;
  g_ofn.Flags         = OFN_HIDEREADONLY;

  // Setup save filename data structure
  ZeroMemory(&g_sfn, sizeof(OPENFILENAME));
  g_sfn.lStructSize   = sizeof(OPENFILENAME);
  g_sfn.hInstance     = hInst;
  g_sfn.hwndOwner     = hWnd;
  g_sfn.nMaxFile      = MAX_PATH;
  g_sfn.nMaxFileTitle = MAX_PATH;
  g_sfn.Flags         = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
  g_sfn.lpstrDefExt   = "x";
  g_sfn.lpstrFile     = g_XFilename;
  g_sfn.lpstrTitle    = "Select .X file";
  g_sfn.lpstrFilter   = ".X files (*.X)\0*.x\0All files (*.*)\0*.*\0\0";

  // Clear filenames
  g_MD2Filename[0] = g_MS3DFilename[0] = g_XFilename[0] = 0;

  // Message loop
  while(GetMessage(&Msg, NULL, 0, 0)) {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
  }

  // Clean up
  UnregisterClass(g_szClass, hInst);

  return 0;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch(uMsg) {

    case WM_COMMAND:

      switch(LOWORD(wParam)) {

        // Convert .MD2 to .X
        case IDC_CONVERTMD2:

          // Get the source filename
          g_ofn.lpstrDefExt = "md2";
          g_ofn.lpstrFile   = g_MD2Filename;
          g_ofn.lpstrTitle  = "Select .MD2 file";
          g_ofn.lpstrFilter = ".MD2 files (*.MD2)\0*.md2\0All files (*.*)\0*.*\0\0";
          if(!GetOpenFileName(&g_ofn))
            break;

          // Get texture filename
          g_ofn.lpstrDefExt = "bmp";
          g_ofn.lpstrFile   = g_TextureFilename;
          g_ofn.lpstrTitle  = "Select texture file";
          g_ofn.lpstrFilter = ".bmp files (*.bmp)\0*.bmp\0All files (*.*)\0*.*\0\0";
          if(!GetOpenFileName(&g_ofn))
            break;

          // Get the destination filename
          if(!GetSaveFileName(&g_sfn))
            break;

          // Do file conversion
          if(ConvertMD2(g_MD2Filename, g_TextureFilename, g_XFilename) == TRUE)
            MessageBox(hWnd, "Conversion complete!", "Success", MB_OK);
          else
            MessageBox(hWnd, "Conversion failed!", "Failure", MB_OK);

          break;

        // Convert .MS3D to .X
        case IDC_CONVERTMS3D:

          // Get the source filename
          g_ofn.lpstrDefExt = "ms3d";
          g_ofn.lpstrFile   = g_MS3DFilename;
          g_ofn.lpstrTitle  = "Select .MS3D file";
          g_ofn.lpstrFilter = ".MS3D files (*.MS3D)\0*.ms3d\0All files (*.*)\0*.*\0\0";
          if(!GetOpenFileName(&g_ofn))
            break;

          // Get the destination filename
          if(!GetSaveFileName(&g_sfn))
            break;

          // Do file conversion
          if(ConvertMS3D(g_MS3DFilename, g_XFilename) == TRUE)
            MessageBox(hWnd, "Conversion complete!", "Success", MB_OK);
          else
            MessageBox(hWnd, "Conversion failed!", "Failure", MB_OK);

          break;

      }
      break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default: return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }

  return 0;
}

BOOL ConvertMD2(char *SrcFilename, char *TextureFilename, char *DestFilename)
{
  FILE *fp_in, *fp_out;

  sMD2Header        mdHeader;

  char             *mdFrame;
  sMD2Frame        *mdFramePtr;
  sMD2FrameVertex  *mdVertexPtr;

  sMD2TextureCoord *mdTextureCoords = NULL;
  sMD2Face         *mdFaces = NULL;

  char             *MeshNames = NULL;
  sMD2MeshVertex   *Vertices = NULL;
  unsigned short   *Indices = NULL;

  // Error checking
  if(!SrcFilename || !TextureFilename || !DestFilename)
    return FALSE;

  // Get pointer to local texture filename
  char *TextureFilenamePtr = strrchr(TextureFilename, '\\');
  if(!TextureFilenamePtr)
    TextureFilenamePtr = TextureFilename;
  else
    TextureFilenamePtr++;

  // Open the target file
  if((fp_out = fopen(DestFilename, "wb"))==NULL)
    return FALSE;

  // Write the target .X file header and templates
  fprintf(fp_out, "xof 0303txt 0032\r\n");
  fprintf(fp_out, "\r\n");
  fprintf(fp_out, "// This file was created with MeshConv (c) 2003 by Jim Adams\r\n");
  fprintf(fp_out, "\r\n");
  fprintf(fp_out, "template MorphAnimationKey\r\n");
  fprintf(fp_out, "{\r\n");
  fprintf(fp_out, "  <2746B58A-B375-4cc3-8D23-7D094D3C7C67>\r\n");
  fprintf(fp_out, "  DWORD  Time;        // Key's time\r\n");
  fprintf(fp_out, "  STRING MeshName;    // Mesh to use (name reference)\r\n");
  fprintf(fp_out, "}\r\n");
  fprintf(fp_out, "\r\n");
  fprintf(fp_out, "template MorphAnimationSet\r\n");
  fprintf(fp_out, "{\r\n");
  fprintf(fp_out, "  <0892DE81-915A-4f34-B503-F7C397CB9E06>\r\n");
  fprintf(fp_out, "  DWORD Loop;     // 0=don't loop, 1=loop\r\n");
  fprintf(fp_out, "  DWORD NumKeys;  // # keys in animation\r\n");
  fprintf(fp_out, "  array MorphAnimationKey Keys[NumKeys];\r\n");
  fprintf(fp_out, "}\r\n");
  fprintf(fp_out, "\r\n");

  // Open the source file
  if((fp_in = fopen(SrcFilename, "rb"))==NULL) {
    fclose(fp_out);
    return FALSE;
  }

  // Read the .MD2 file header and make sure it's valid
  fread(&mdHeader, 1, sizeof(sMD2Header), fp_in);
  if(mdHeader.Signature != 0x32504449 || mdHeader.Version != 8) {
    fclose(fp_in);
    fclose(fp_out);
    return FALSE;
  }

  /////////////////////////////////////////
  //
  // Parse model data
  //
  /////////////////////////////////////////

  // Load texture coordinates /////////////////////////////
  if(mdHeader.NumTextureCoords) {
    mdTextureCoords = new sMD2TextureCoord[mdHeader.NumTextureCoords];
    fseek(fp_in, mdHeader.OffsetTextureCoords, SEEK_SET);
    fread(mdTextureCoords, 1, mdHeader.NumTextureCoords * sizeof(sMD2TextureCoord), fp_in);
  }

  // Load face data ///////////////////////////////////////
  if(mdHeader.NumFaces) {
    mdFaces = new sMD2Face[mdHeader.NumFaces];
    fseek(fp_in, mdHeader.OffsetFaces, SEEK_SET);
    fread(mdFaces, 1, mdHeader.NumFaces * sizeof(sMD2Face), fp_in);
  }

  // Allocate a temporary frame structure
  mdFrame = new char[mdHeader.FrameSize];
  mdFramePtr = (sMD2Frame*)mdFrame;

  // Store mesh values in local variables
  DWORD NumVertices  = mdHeader.NumFaces * 3;
  DWORD NumFaces     = mdHeader.NumFaces;

  // Allocate vertex and index buffers
  Vertices = new sMD2MeshVertex[NumVertices];
  Indices  = new unsigned short[NumFaces*3];

  // Allocate space for mesh names
  MeshNames = new char[16 * mdHeader.NumFrames];

  // Jump to frame data in file and begin reading in each frame
  fseek(fp_in, mdHeader.OffsetFrames, SEEK_SET);
  for(DWORD i=0;i<mdHeader.NumFrames;i++) {

    // Read in the frame (mesh)
    fread(mdFrame, 1, mdHeader.FrameSize, fp_in);

    // Assign a simple name if none already assigned (rarely happens)
    if(!mdFramePtr->Name[0])
      sprintf(mdFramePtr->Name, "NoName%02lu", i);

    // Copy name into mesh name buffer
    memcpy(&MeshNames[16*i], mdFramePtr->Name, 16);

    // Loop and build vertex/index data
    DWORD Num = 0;
    for(DWORD j=0;j<NumFaces;j++) {

      // Three vertices per face
      for(DWORD k=0;k<3;k++) {

        // Get a pointer to the frame vertex structure
        mdVertexPtr = &mdFramePtr->Vertices[mdFaces[j].Indices[k]];

        // Calculate coordinates (note ordering and reversal of x)
        Vertices[Num].x = -((float)mdVertexPtr->Vertex[1] * mdFramePtr->Scale[1] + mdFramePtr->Translate[1]);
        Vertices[Num].y =   (float)mdVertexPtr->Vertex[2] * mdFramePtr->Scale[2] + mdFramePtr->Translate[2];
        Vertices[Num].z =   (float)mdVertexPtr->Vertex[0] * mdFramePtr->Scale[0] + mdFramePtr->Translate[0];

        // Calculate normals
        Vertices[Num].nx = -g_Quake2Normals[mdVertexPtr->LightNormal][1];
        Vertices[Num].ny =  g_Quake2Normals[mdVertexPtr->LightNormal][2];
        Vertices[Num].nz =  g_Quake2Normals[mdVertexPtr->LightNormal][0];

        // Calculate texture coordinates
        Vertices[Num].u = (float)mdTextureCoords[mdFaces[j].TextureCoords[k]].u / (float)mdHeader.SkinWidth;
        Vertices[Num].v = (float)mdTextureCoords[mdFaces[j].TextureCoords[k]].v / (float)mdHeader.SkinHeight;

        // Store face order
        Indices[Num] = (unsigned short)Num;

        // Go to next vertex
        Num++;
      }
    }

    // Write out mesh header
    fprintf(fp_out, "Mesh %s {\r\n", mdFramePtr->Name);

    // Write out # vertices and write out vertex coordinates
    fprintf(fp_out, "  %lu;\r\n", NumVertices);
    for(j=0;j<NumVertices;j++) {
      fprintf(fp_out, "  %06lf;%06lf;%06lf;", Vertices[j].x, Vertices[j].y, Vertices[j].z);
      if(j < (NumVertices-1))
        fprintf(fp_out, ",\r\n");
      else
        fprintf(fp_out, ";\r\n");
    }

    // Write out # of faces and write out face data
    fprintf(fp_out, "  %lu;\r\n", NumFaces);
    for(j=0;j<NumFaces;j++) {
      fprintf(fp_out, "  3;%lu,%lu,%lu;", Indices[j*3], Indices[j*3+1], Indices[j*3+2]);
      if(j < (NumFaces-1))
        fprintf(fp_out, ",\r\n");
      else
        fprintf(fp_out, ";\r\n\r");
    }

    // Write normal data
    fprintf(fp_out, "  MeshNormals {\r\n");
    fprintf(fp_out, "    %lu;\r\n", NumVertices);
    for(j=0;j<NumVertices;j++) {
      fprintf(fp_out, "    %06lf;%06lf;%06lf;", Vertices[j].nx, Vertices[j].ny, Vertices[j].nz);
      if(j < (NumVertices-1))
        fprintf(fp_out, ",\r\n");
      else
        fprintf(fp_out, ";\r\n");
    }
    fprintf(fp_out, "    %lu;\r\n", NumFaces);
    for(j=0;j<NumFaces;j++) {
      fprintf(fp_out, "    3;%lu,%lu,%lu;", Indices[j*3], Indices[j*3+1], Indices[j*3+2]);
      if(j < (NumFaces-1))
        fprintf(fp_out, ",\r\n");
      else
        fprintf(fp_out, ";\r\n");
    }
    fprintf(fp_out, "  }\r\n");

    // Write texture coordinates
    fprintf(fp_out, "  MeshTextureCoords {\r\n");
    fprintf(fp_out, "    %lu;\r\n", NumVertices);

⌨️ 快捷键说明

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