Direct3Dの解説 1 どういうプロジェクトにするか

Direct3Dの解説を読みつつ実験をする段になって、はたと困りました。
Direct3Dは通常のアプリと違います。アプリが起動している間、ずーっと描画と表示を繰り返しているのですね。したがっていままでのようにMFCを使ったプロジェクトを使うと無限ループで描画、表示を繰り返すのに余計な仕掛けを使わなければなりません。普通のDirect3Dの解説で、ほとんどがMFCを使わないのはそれが原因でしょう。

というわけで、ウィンドウズの解説かたがた、この3Dの解説1回目は何もしない、単純なウィンドウズアプリの制作から入りましょう。そのあとにDirect3Dのコードを入れていけば理解しやすい解説になると思います。

では、早速ですが、新規プロジェクトを作ります。VC++6の場合だと、Win32アプリケーションを作ります。コンソールではありません。「単純なWIN32アプリケーション」を選択します。すると、最低限のコードがかかれたソースを作ってくれます。インクルードされているのは「stdafx.lib]です。これは実行すると何もしないで終わってしまいます。
そこの以下のコードを打ち込んでください。
 

/*----------------------------------------------------------
何もしないウィンドウプログラム
--------------------------------------------------------------*/
#define STRICT
#include <stdafx.h>
#include <string.h>
 
#define RELEASE(x) if(x){x->Release();x=NULL;}
/*-------------------------------------------
外部変数
--------------------------------------------*/
HINSTANCE hInstApp;
HWND hwndApp;
char szAppName[] = "Direct3D IM test";
char szDevice[128], szDDDeviceName[128] = "default";
 
LRESULT CALLBACK MainWndProc(HWND hWnd,UINT msg,UINT wParam,LONG lParam);
/*-------------------------------------------
アプリケーション初期化
--------------------------------------------*/
int InitApp(HINSTANCE hInst,int nCmdShow)
{
 WNDCLASS wndclass;
 hInstApp=hInst;
 /*ウィンドウクラスの登録*/
 wndclass.hCursor =LoadCursor(NULL,IDC_ARROW);
 wndclass.hIcon =NULL;
 wndclass.lpszMenuName =NULL;
 wndclass.lpszClassName ="Main Window";
 wndclass.hbrBackground =(HBRUSH)GetStockObject(BLACK_BRUSH);
 wndclass.hInstance =hInst;
 wndclass.style =CS_BYTEALIGNCLIENT|CS_VREDRAW|CS_HREDRAW;
 wndclass.lpfnWndProc =(WNDPROC)MainWndProc;
 wndclass.cbClsExtra =0;
 wndclass.cbWndExtra =0;
 if(!RegisterClass(&wndclass))
  return FALSE;
  /*メインウィンドウ*/
  hwndApp = CreateWindowEx(0,"Main Window",szAppName,
  WS_POPUP,
  0,0,640,480,
  (HWND)NULL,(HMENU)NULL,
  hInst,(LPSTR)NULL);
  ShowWindow(hwndApp,nCmdShow);
  UpdateWindow(hwndApp);
  return TRUE;
 }
 /*-------------------------------------------
 終了の処理
 --------------------------------------------*/
 int EndApp(void)
 {
  return TRUE;
 }
 /*-------------------------------------------
 ウィンドウ処理
 --------------------------------------------*/
 LRESULT CALLBACK MainWndProc(HWND hWnd,UINT msg,UINT wParam,LONG lParam)
 {
  switch(msg){
  case WM_KEYDOWN:
  switch(wParam){
  case VK_ESCAPE:
  case VK_F12:
   DestroyWindow(hWnd);
   break;
  default:
   break;
 }
  break;
  case WM_DESTROY:
   PostQuitMessage(0);
   break;
  default:
   return DefWindowProc(hWnd,msg,wParam,lParam);
 }
 return 0L;
 }
 
 /*--------------------------------------------
 メイン
 ---------------------------------------------*/
 int APIENTRY WinMain(HINSTANCE hInst,
 HINSTANCE hPrevInst,
 LPSTR lpCmdLine,
 int nCmdShow )

 {
  MSG msg;
  if(!InitApp(hInst,nCmdShow))
   return FALSE;
 
   while(TRUE){
    if(PeekMessage(&msg,0,0,0,PM_REMOVE)){
     if(msg.message == WM_QUIT)
      break;
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
   }
  EndApp();
  return msg.wParam;
}
 

青い部分は、VC++が作ったところで打ち込みは、緑と黒の部分です。
VC5の場合は新規ソースファイルを作成して全部打ち込みます。

ちょと長いですか?

よく見てみると、いかにも最低限の事しかしていませんね。
まずウィンドウを登録してメッセージを見て、メッセージが来たら処理する、というのは見てわかるとおりです。

コンパイルして実行して見てください。黒い四角が出ましたか?これが枠もメニューも無い、何もしないウィンドウプログラムです。必要に応じてフレームやメニューをつけるとおなじみのウインドウプログラムになるのですが、最初はこれだけにします。ウィンドウ内で動く3Dプログラムは、3Dのプログラム解説後に作りましょう。

これにDirec3Dのコードを付け足していきながら説明します。