Direct3Dでライトがうまくいかない?

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

Direct3Dでライトがうまくいかない?

#1

投稿記事 by あうあう » 12年前

今Direct3Dで3Dゲーム製作を学んでいるのですが、3Dモデルを表示してライトをおいても
3Dモデルが黒く明暗のないのっぺりした感じになってしまいます。どうすればよいでしょうか?
DirectX部分のコードです

コード:

//DirectX.h
#ifndef DEF_DIRECTX_H
#define DEF_DIRECTX_H

HRESULT DxInit(HWND hWnd);
int DxMainloop(void);
int DxEnd(void);
int Draw2Drect(float left,float top,float right,float bottom,DWORD color);
#endif

コード:

//DirectX.cpp
#include <d3d9.h>
#include <d3dx9.h>
#include <tchar.h>
#include <stdio.h>
#include "DirectX.h"

#define SCREEN_WIDTH GetSystemMetrics(SM_CXSCREEN)
#define SCREEN_HEIGHT GetSystemMetrics(SM_CYSCREEN)
#define FVF_CUSTOM ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 )
#define WINDOW_WIDTH (500.0f)
#define WINDOW_HEIGHT  (450.0f)

static LPDIRECT3D9 g_pD3D=NULL;
static LPDIRECT3DDEVICE9 g_pd3dDevice=NULL;
static IDirect3DVertexBuffer9 *pVertex;
static ID3DXBuffer *obj_pMat;
static ID3DXMesh *obj_pMesh;
static D3DLIGHT9 light;
DWORD obj_NumMat;

typedef struct CUSTOMVERTEX{
	float x,y,z;
	float rhw;
	DWORD dwcolor;
	float u,v;
}CUSTOMVERTEX;

HRESULT DxInit(HWND hWnd)
{
    char               msgbuff[2048];
    BOOL			   WINDED = TRUE;

     // DirectXの初期化
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
    {
		g_pD3D->Release();
        MessageBox(hWnd,"Startup Failed.","DirectX9",MB_OK);
        return E_FAIL;
    }

    // 画面などの設定
    D3DDISPLAYMODE d3ddm;
	D3DFORMAT fmt_mode;

    if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
		{
			g_pD3D->Release();
			return E_FAIL;
		}
    D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed                    = WINDED;	// WINDEDには、true か false を入れておく
    
	if(WINDED)
    {
		fmt_mode = d3ddm.Format;
    } else {
         d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;    //D3DPRESENT_RATE_UNLIMITED D3DPRESENT_RATE_DEFAULT
    }

    d3dpp.BackBufferFormat           = fmt_mode;
    d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;  //D3DSWAPEFFECT_FLIP D3DSWAPEFFECT_DISCARD D3DSWAPEFFECT_COPY;//描画フラグ
    d3dpp.EnableAutoDepthStencil     = TRUE;                    // Zバッファを使用する
    d3dpp.AutoDepthStencilFormat     = D3DFMT_D16;
    d3dpp.BackBufferCount            = 1;
    d3dpp.hDeviceWindow              = hWnd;
    d3dpp.BackBufferWidth            = SCREEN_WIDTH;
    d3dpp.BackBufferHeight           = SCREEN_HEIGHT;


    // 設定した画面情報をDirectXに登録する。
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,  &d3dpp, &g_pd3dDevice ) ) )
    {
        if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,  &d3dpp, &g_pd3dDevice ) ) )
        {
            if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,  &d3dpp, &g_pd3dDevice ) ) )
            {
                sprintf_s(msgbuff,"CreateDevice Error. \nBackBufferFormat=0x%04X\n",d3dpp.BackBufferFormat);
                MessageBox(hWnd,msgbuff,"Error!",MB_OK);
                g_pD3D->Release();
				return E_FAIL;
            }
        }
    }

    //-----------------------------------------------
    //  画像以外のDirectXの初期化は、ここで行う
    //-----------------------------------------------
	if(FAILED(D3DXLoadMeshFromX(_T("object.x"),
								D3DXMESH_MANAGED,
								g_pd3dDevice,
								NULL,
								&obj_pMat,
								NULL,
								&obj_NumMat,
								&obj_pMesh)))
											{
											g_pd3dDevice->Release();
											g_pD3D->Release();
											return E_FAIL;
											}
	
	
	ZeroMemory(&light,sizeof(D3DLIGHT9));
	light.Type = D3DLIGHT_DIRECTIONAL;

	light.Diffuse.r= light.Diffuse.g= light.Diffuse.b=0.4f;
	light.Specular.r= light.Specular.g= light.Specular.b=0.1f;
	light.Ambient.r= light.Ambient.g= light.Ambient.b=0.2f;
	
	light.Direction = D3DXVECTOR3(1,-5,1);	// 平行光源なので向きが必要
	g_pd3dDevice->SetLight(0,&light);
	g_pd3dDevice->LightEnable(0,TRUE);
	   g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
	   g_pd3dDevice->SetRenderState( D3DRS_AMBIENT,0x00808080);




	return S_OK;
}

int DxMainloop(void)
{
	D3DXMATRIX World;
	D3DXMATRIX Rot_X,Rot_Y;
	D3DXMATRIX Offset;
	D3DXMATRIX View;
	D3DXMATRIX Persp;
	D3DCOLORVALUE MAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
			

	g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB(40,40,80), 1.0f, 0 );
		g_pd3dDevice->BeginScene();

	//ワールド変換
		D3DXMatrixRotationX(&Rot_X,D3DXToRadian(-3.5f));
		D3DXMatrixRotationY(&Rot_Y,D3DXToRadian(0.55f));
		D3DXMatrixTranslation(&Offset,10,10,10);
		
		D3DXMatrixIdentity(&World);
		D3DXMatrixMultiply(&World,&World,&Offset);
		D3DXMatrixMultiply(&World,&World,&Rot_X);
		D3DXMatrixMultiply(&World,&World,&Rot_Y);
	//ビュー変換
		D3DXMatrixLookAtLH(
                  &View,
                  &D3DXVECTOR3(17.0f, 20.0f, 19.0f),
                  &D3DXVECTOR3(0.0f, 0.0f, 0.0f),
                  &D3DXVECTOR3(0.0f, 1.0f, 0.0f)
                  );
	//射影変換
		D3DXMatrixPerspectiveFovLH(
			&Persp,
			D3DXToRadian(70),
			WINDOW_HEIGHT/WINDOW_WIDTH,
			1.0f,
			10000.0f);
		
		// 行列登録
			g_pd3dDevice->SetTransform(D3DTS_WORLD, &World);
			g_pd3dDevice->SetTransform(D3DTS_VIEW, &View);
			g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &Persp);
			
			for(UINT i=0; i<obj_NumMat; i++){      // 描画
						    D3DXMATERIAL *mtrl = ( (D3DXMATERIAL*)(obj_pMat->GetBufferPointer()) + i);
							mtrl->MatD3D.Ambient = MAmbient;
							g_pd3dDevice->SetMaterial( &mtrl->MatD3D );
							obj_pMesh->DrawSubset(i); 
			};
			

		Draw2Drect(0.0f,0.0f,0.0f,0.0f,RGB(0,0,0));//エラー回避
		g_pd3dDevice->EndScene();
	g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
	return 0;
}

int DxEnd(void)
{
	g_pd3dDevice->Release();
	g_pD3D->Release();
	pVertex->Release();
	obj_pMesh->Release();
	return 0;
}

int Draw2Drect(float left,float top,float right,float bottom,COLORREF color)
{
	CUSTOMVERTEX v[4]=
	{
		{ right , top , 0.0f , 1.0f , color , left , top },
		{ right , bottom , 0.0f , 1.0f , color , left , bottom },
		{ left , top , 0.0f , 1.0f , color , right , top },
		{ left , bottom , 0.0f , 1.0f , color , right , bottom }
	};
	void *pData;

	if(g_pd3dDevice->CreateVertexBuffer(sizeof(CUSTOMVERTEX)*4,
										D3DUSAGE_WRITEONLY,
										FVF_CUSTOM,D3DPOOL_MANAGED,
										&pVertex,NULL)
										!=D3D_OK)
	{
		MessageBox(NULL,_T("内部エラー\n描画に失敗しました"),_T("Error!"),MB_OK);
		g_pd3dDevice->Release();
		g_pD3D->Release();
		return -1;
	}

	if(pVertex->Lock(0,sizeof(CUSTOMVERTEX)*4,(void**)&pData,0)==D3D_OK)
	{
		memcpy(pData,v,sizeof(CUSTOMVERTEX)*4);
		pVertex->Unlock();

	}else{
		MessageBox(NULL,_T("描画失敗"),_T(""),MB_OK);
		g_pd3dDevice->Release();
		g_pD3D->Release();
		return -1;
	}

	g_pd3dDevice->SetStreamSource(0,pVertex,0,sizeof(CUSTOMVERTEX));
	g_pd3dDevice->SetFVF(FVF_CUSTOM);
	g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
	return 0;
}

あうあう

Re: Direct3Dでライトがうまくいかない?

#2

投稿記事 by あうあう » 12年前

3Dモデルを忘れてました;;
http://kie.nu/vMS

史上最悪のデスペナ
記事: 521
登録日時: 14年前

Re: Direct3Dでライトがうまくいかない?

#3

投稿記事 by 史上最悪のデスペナ » 12年前

DirectXは難しいので使ったことがないので、コードも見てませんが・・・・・・・・(見てもわからない
DxLibで私も同じ現象が起きたとき、私は以下のようにして回避しました。参考になれば

1.モデルの自己発光色(エミッシブカラー)を設定する
2.モデルの反射光(スペキュラカラー)を設定する
3.モデルの拡散光色(ディフューズカラー)を設定する
4.モデルの環境光色(アンビエントカラー)を設定する

これはどれか1個だけでよかったのか、複数個設定したのかは覚えてませんが少なくとも二つは設定すれば大丈夫だった気が。
1と2だったかな。。。。。。。?

conio
記事: 9
登録日時: 13年前
連絡を取る:

Re: Direct3Dでライトがうまくいかない?

#4

投稿記事 by conio » 12年前

Xファイルを見てみたのですが、
どうやら法線情報が入っていないようです。

法線情報がないと、どんなライトを設定しても意味がないので、
xファイルを下記の様に MeshNormalsの部分を追加して確認してみてください。
(もしくは下記の文字列をコピーペーストしてテキストに貼り付け、拡張子を.xに変更)

コード:

xof 0302txt 0064

Header{
1;
0;
1;
}

Mesh {
 8;
 -1.00000;1.00000;-1.00000;,
 1.00000;1.00000;-1.00000;,
 1.00000;-1.00000;-1.00000;,
 -1.00000;-1.00000;-1.00000;,
 1.00000;1.00000;1.00000;,
 1.00000;-1.00000;1.00000;,
 -1.00000;1.00000;1.00000;,
 -1.00000;-1.00000;1.00000;;
 
 6;
 4;0,1,2,3;,
 4;1,4,5,2;,
 4;4,6,7,5;,
 4;6,0,3,7;,
 4;6,4,1,0;,
 4;3,2,5,7;;

MeshNormals {
  6;
  0.000000;0.000000;-1.000000;,
  1.000000;0.000000;0.000000;,
  0.000000;0.000000;1.000000;,
  -1.000000;0.000000;0.000000;,
  0.000000;1.000000;0.000000;,
  0.000000;-1.000000;-0.000000;;
  6;
  4;0,0,0,0;,
  4;1,1,1,1;,
  4;2,2,2,2;,
  4;3,3,3,3;,
  4;4,4,4,4;,
  4;5,5,5,5;;
 }
 MeshMaterialList {
  1;
  6;
  0,
  0,
  0,
  0,
  0,
  0;;
  Material {
   1.000000;1.000000;1.000000;1.000000;;
   0.000000;
   0.000000;0.000000;0.000000;;
   0.000000;0.000000;0.000000;;
  }
 }
}

あうあう

Re: Direct3Dでライトがうまくいかない?

#5

投稿記事 by あうあう » 12年前

解決しました!
xファイルをconioさんのアップロードして下さったものに差し替えたところ、
しっかりとうまくライトが働きました。
xファイルに問題があったのですね・・盲点でした。

閉鎖

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