Zバッファについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kado

Zバッファについて

#1

投稿記事 by kado » 11年前

はじめまして
現在DirectXで3Dを勉強しているのですがちょっと親子関係のZバッファのところでつまずいております。
 [1.1] 自分が今行いたい事は何か
具体的には親自身の回転をもとに子も周りを回転させようとしているのですが本来なら親が手前に来ないといけないところで子の方が手前にきてしまいます。
これを親が手前に来るように修正したいです
 [1.2] どのように取り組んだか
コードはこちらです。

コード:

#define     NAME        "DirectX9 Graphics"
#define     TITLE       "ポリゴン表示"
#include    <Windows.h>
#include    <d3d9.h>
#include    <d3dx9.h>
#include    <mmsystem.h>

// ライブラリのリンク
#pragma     once
#pragma     comment(lib,"d3d9.lib")
#pragma     comment(lib,"d3dx9.lib")
#pragma     comment(lib,"dxguid.lib")
#pragma     comment(lib,"winmm.lib")

#define     SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
#define EMSG(x)     MessageBox(NULL,x,"DirectX D3D",MB_OK);


// 構造体定義
//頂点フォーマット
 #define D3DFVF_VERTEX  (D3DFVF_XYZ | D3DFVF_DIFFUSE)
typedef struct _D3DLVERTEX_
{   float   x,y,z;
    DWORD   color;
}   D3DVERTEX;

//四面体の定義
//親
D3DVERTEX vtx[6]=
{ { -5,    0,      5,      0xff0000ff  },   //青の頂点
    {  5,    0,      5,      0xffff0000  },   //赤の頂点
    {  0,    8.16f,  2.11f,  0xffffffff  },   //白の頂点
    {  0,    0,     -3.66f,  0xff00ff00  },   //緑の頂点
    { -5,    0,      5,      0xff0000ff  },   //青の頂点
    {  5,    0,      5,      0xffff0000  }    //赤の頂点
};

//子
D3DVERTEX vtx2[6]=
{ { -5,    0,      5,      0xffADFF2F  },   
    {  5,    0,      5,      0xffB8860B  },   
    {  0,    8.16f,  2.11f,  0xff9400D3  },   
	{  0,    0,     -3.66f,  0xffFFC0CB  },   
    { -5,    0,      5,      0xffADFF2F  },   
    {  5,    0,      5,      0xffB8860B  }    
};


// グローバル変数:
LPDIRECT3D9             g_pD3D= NULL;
LPDIRECT3DDEVICE9       g_pDEV= NULL;
bool                    g_bActive = false;
D3DXVECTOR3             ViewForm(0.0f,0.0f,50.0f);//カメラの位置

// プロトタイプ宣言
HRESULT Init3DDev(HWND hWnd);
void    Cleanup(void);
void  SetupMatrices(void);
void    Draw(void);
LRESULT CALLBACK MsgProc(HWND hWnd,UINT msg,UINT wParam,LONG lParam);
INT WINAPI  WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT);

//メイン
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{   MSG     msg;

    WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,MsgProc,0L,0L,hInst,
                      NULL,NULL,NULL,NULL,NAME,NULL };
    if (RegisterClassEx(&wc)==0)    return FALSE;
    HWND hWnd = CreateWindowEx(0,NAME,TITLE,WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
                        NULL,NULL,hInst,NULL);
    
    if (FAILED(Init3DDev(hWnd)))    return FALSE;

    ShowWindow(hWnd,SW_SHOWDEFAULT);
    UpdateWindow(hWnd);
    ZeroMemory(&msg,sizeof(msg));
    while(msg.message!=WM_QUIT)
    {   if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {   TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else    Draw();
    }
    Cleanup();
    UnregisterClass(NAME,wc.hInstance);
    return TRUE;
}

//デバイスの取得
HRESULT Init3DDev(HWND hWnd)
{   D3DDISPLAYMODE          d3ddm;
    D3DPRESENT_PARAMETERS   d3dpp;

    if (NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))    return E_FAIL;
    if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm)))   return E_FAIL;
    ZeroMemory(&d3dpp,sizeof(d3dpp));
    d3dpp.Windowed                  = TRUE;                     // ウィンドウモード
    d3dpp.SwapEffect                = D3DSWAPEFFECT_DISCARD;    // 映像信号に同期してフリップする
    d3dpp.EnableAutoDepthStencil    = TRUE;                     // デプスバッファ(Zバッファ)とステンシルバッファを作成
    d3dpp.AutoDepthStencilFormat    = D3DFMT_D16;               // デプスバッファとして16bitを使う
    d3dpp.BackBufferFormat          = d3ddm.Format;             // カラーモードの指定

    if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,
                             D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pDEV)))
        return E_FAIL;

	// レンダリングステートパラメータの設定
    g_pDEV->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);           // カリングを行わない
    g_pDEV->SetRenderState(D3DRS_ZENABLE, TRUE);                    // Zバッファを使用


    return S_OK;
}

void Cleanup(void)
{   SAFE_RELEASE(g_pDEV);
    SAFE_RELEASE(g_pD3D);
}

//描画環境設定
void  SetupMatrices(void)
{   
	D3DXMATRIX      matView;
    D3DXMATRIX      matProj;

	//View 座標の設定
    D3DXMatrixLookAtLH(&matView,&ViewForm,
                       &D3DXVECTOR3(0.0f,0.0f,0.0f),&D3DXVECTOR3(0.0f,1.0f,0.0f));
    g_pDEV->SetTransform(D3DTS_VIEW,&matView);
    //透視変換の設定
    D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,0.0f,100.0f);
    g_pDEV->SetTransform(D3DTS_PROJECTION,&matProj);
    g_pDEV->SetRenderState(D3DRS_AMBIENT,0x00808080);
       
	g_pDEV->SetRenderState(D3DRS_ZENABLE, TRUE);
	g_pDEV->SetRenderState(D3DRS_LIGHTING,FALSE);
}


//描画処理
void Draw(void)
{   //黒で塗りつぶして消去
    g_pDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);


    if (SUCCEEDED(g_pDEV->BeginScene()))
    {   

		 D3DXMATRIX      matWorld,matX,matY;
		SetupMatrices();
		//親の行列
		D3DXMatrixRotationY(&matWorld,timeGetTime()/500.0f);
        g_pDEV->SetTransform(D3DTS_WORLD,&matWorld);
		//デバイスに使用する頂点フォーマットをセットする
        g_pDEV->SetFVF(D3DFVF_VERTEX);
        //頂点データ(v)を渡して描画する
         g_pDEV->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,4,vtx,sizeof(D3DVERTEX));

		 D3DXMATRIX      matLocalWorld;
		 D3DXMatrixIdentity(&matLocalWorld);//単位行列で初期化

		 //子の行列
		 D3DXMatrixRotationY(&matY,0);
         D3DXMatrixTranslation(&matX,7.0f,0.0f,0.0f);
         matLocalWorld = matX*matY;
		 matLocalWorld *=matWorld;
		 g_pDEV->SetTransform(D3DTS_WORLD,&matLocalWorld);
		 //デバイスに使用する頂点フォーマットをセットする
		 g_pDEV->SetFVF(D3DFVF_VERTEX);
        //頂点データ(v)を渡して描画する
         g_pDEV->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,4,vtx2,sizeof(D3DVERTEX));
		 g_pDEV->EndScene();
    }
    g_pDEV->Present(NULL,NULL,NULL,NULL);
}


LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    switch(msg)
    {   case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_KEYDOWN:
            switch(wParam)
            {   case VK_ESCAPE:
                    DestroyWindow(hWnd);
                    break;
            }
            break;
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}
 [1.3] どのようなエラーやトラブルで困っているか
i.1でも書きましたが本来なら親が手前に来ないといけないところで子の方が手前にきてしまいます。
 [1.4] 今何がわからないのか、知りたいのか
どの様に修正すればZバッファが適用され、親が手前に来るところで子が親の後ろに隠れ、見えなくなるのでしょうか?
[2] 環境  
 [2.1] OS : Windows7
 [2.2] コンパイラ名 : VC++ 2010EE
[3] その他
DXライブラリとC++でしたら学校で3Dゲームの勉強の始めにと初音ミクProjectDiva風のリズムゲームを制作しました。
C,C++の基本は理解しています。

 ・ライブラリを使っている場合は何を使っているか
DirectXSDKはJune 2010を使用しております。
シェーダーレベルで3Dを扱えるようになりたいと思い、現在DirectXでもう一度勉強し直しているところです。

“C言語何でも質問掲示板” へ戻る