DX中材质不能正确显示的问题(要么黑色,要么白色)

昨天在写shadowMap的时候,渲染其中一辆绿色的轿车的时候,总是渲染不对,要么全白,要么全黑,白思不得其解,原来材质颜色需要搭配光照来能显现出来,如果关闭了光照渲染功能将成白色,如果打开光照渲染功能却没有灯光将成黑色.当然贴图就没这个问题,没开灯光渲染功能的话会以贴图原来的样子显示

为了今出类似的情况,写篇博文,以防今后遇到类似问题.


/*------------------------------------------------------------
ShadowMap.cpp -- achieve shadow map
(c) Seamanj.2014/4/22
------------------------------------------------------------*/

//phase1 : add scene(floor and pillars bonded together: .x file)
//phase2 : add camera
//phase3 : add car

#include "DXUT.h"
#include "resource.h"

#define phase1 1
#define phase2 1
#define phase3 1


#if phase1
#include "SDKmesh.h" // CDXUTXFileMesh要用
CDXUTXFileMesh                  g_Scene; 
D3DVERTEXELEMENT9 g_aVertDecl[] =
{
	{ 0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
	{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },
	{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
	D3DDECL_END()
};

#endif

#if phase2
#include "DXUTcamera.h"
//CModelViewerCamera g_Camera;
CFirstPersonCamera g_Camera;
#endif

#if phase3 
CDXUTXFileMesh                  g_Car; 
D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)
{
	D3DMATERIAL9 mtrl;
	mtrl.Ambient  = a;
	mtrl.Diffuse  = d;
	mtrl.Specular = s;
	mtrl.Emissive = e;
	mtrl.Power    = p;
	return mtrl;
}
const D3DXCOLOR      GREEN( D3DCOLOR_XRGB(  0, 255,   0) );
const D3DXCOLOR      BLACK( D3DCOLOR_XRGB(  0,   0,   0) );
const D3DMATERIAL9 GREEN_MTRL  = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);

#endif

#if phase1
//--------------------------------------------------------------------------------------
// Load mesh from file and convert vertices to our format
//--------------------------------------------------------------------------------------
HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, LPCWSTR wszName, CDXUTXFileMesh& Mesh )
{
	HRESULT hr;

	if( FAILED( hr = Mesh.Create( pd3dDevice, wszName ) ) )
		return hr;
	hr = Mesh.SetVertexDecl( pd3dDevice, g_aVertDecl );

	return hr;
}
#endif

//--------------------------------------------------------------------------------------
// Rejects any D3D9 devices that aren't acceptable to the app by returning false
//--------------------------------------------------------------------------------------
bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
									 bool bWindowed, void* pUserContext )
{
	// Typically want to skip back buffer formats that don't support alpha blending
	IDirect3D9* pD3D = DXUTGetD3D9Object();
	if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
		AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
		D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
		return false;

	return true;
}


//--------------------------------------------------------------------------------------
// Before a device is created, modify the device settings as needed
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )
{
#if phase2
	pDeviceSettings->d3d9.pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
#endif
	return true;
}


//--------------------------------------------------------------------------------------
// Create any D3D9 resources that will live through a device reset (D3DPOOL_MANAGED)
// and aren't tied to the back buffer size
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
									void* pUserContext )
{
#if phase1
	// Load the scene object
	if( FAILED( LoadMesh( pd3dDevice, L"BasicColumnScene.x", g_Scene ) ) )
		return DXUTERR_MEDIANOTFOUND;
#endif

#if phase2
	// Setup the camera's view parameters    
	D3DXVECTOR3 vecEye( 0.0f, 0.0f, -5.0f );  
	D3DXVECTOR3 vecAt ( 0.0f, 0.0f, 0.0f );  
	g_Camera.SetViewParams( &vecEye, &vecAt );  
	//FLOAT fObjectRadius=1;  
	//摄像机缩放的3个参数
	//g_Camera.SetRadius( fObjectRadius * 3.0f, fObjectRadius * 0.5f, fObjectRadius * 10.0f );
	g_Camera.SetEnablePositionMovement( true );
#endif

#if phase3
	// Load the car
	if( FAILED( LoadMesh( pd3dDevice, L"car.x", g_Car ) ) )
		return DXUTERR_MEDIANOTFOUND;
#endif
	return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3D9 resources that won't live through a device reset (D3DPOOL_DEFAULT) 
// or that are tied to the back buffer size 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
								   void* pUserContext )
{
#if phase2
	pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );  
	//关闭光照处理, 默认情况下启用光照处理   
	pd3dDevice->SetRenderState( D3DRS_LIGHTING, true );
	//注意处理材质的时候把灯光计算开启,不然全白色,哎,又浪费我2个小时!!!
	//当然只开灯光计算不行,还得有灯光,不然全黑色  
	D3DLIGHT9 light;
	::ZeroMemory(&light, sizeof(light));

	light.Type      = D3DLIGHT_DIRECTIONAL;
	light.Ambient   = (const D3DXCOLOR)D3DCOLOR_XRGB(255, 255, 255) * 0.6f;
	light.Diffuse   =(const D3DXCOLOR) D3DCOLOR_XRGB(255, 255, 255);
	light.Specular  = (const D3DXCOLOR)D3DCOLOR_XRGB(255, 255, 255) * 0.6f;
	light.Direction = D3DXVECTOR3(1.0f, -0.0f, 0.25f);

	pd3dDevice->SetLight(0, &light);
	pd3dDevice->LightEnable(0, true);
	

	//Setup the camera's projection parameters   
	float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height;  

	g_Camera.SetProjParams( D3DX_PI / 2, fAspectRatio, 0.1f, 5000.0f );  
	//g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );  
	//g_Camera.SetButtonMasks( MOUSE_LEFT_BUTTON, MOUSE_WHEEL, MOUSE_RIGHT_BUTTON ); 
	g_Camera.SetScalers(0.01f, 5.0f);
#endif
	return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene.  This is called regardless of which D3D API is used
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{
#if phase2
	g_Camera.FrameMove( fElapsedTime );
#endif
}


//--------------------------------------------------------------------------------------
// Render the scene using the D3D9 device
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	HRESULT hr;

	// Clear the render target and the zbuffer 
	V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 45, 50, 170 ), 1.0f, 0 ) );

	// Render the scene
	if( SUCCEEDED( pd3dDevice->BeginScene() ) )
	{
#if phase2
		// Set world matrix  
		D3DXMATRIX M;
		D3DXMatrixIdentity( &M ); // M = identity matrix
		pd3dDevice->SetTransform(D3DTS_WORLD, &M) ;  
		// Set view matrix   
		D3DXMATRIX view  = *g_Camera.GetViewMatrix() ;  
		pd3dDevice->SetTransform(D3DTS_VIEW, &view) ;  
		// Set projection matrix   
		D3DXMATRIX proj  = *g_Camera.GetProjMatrix() ;  
		pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj) ; 
#endif 
#if phase1
		pd3dDevice->SetRenderState( D3DRS_LIGHTING, false );
 		LPD3DXMESH pMeshObj;
		pMeshObj = g_Scene.GetMesh();
		// Iterate through each subset and render with its texture
		for( DWORD m = 0; m < g_Scene.m_dwNumMaterials; ++m )
		{
			V( pd3dDevice->SetTexture(0, g_Scene.m_pTextures[m]));
			V( pMeshObj->DrawSubset( m ) );
		}
#endif
#if phase3
		
		D3DXMatrixIdentity( &M ); // M = identity matrix
		D3DXMatrixTranslation(&M, 0, 2.35f, 0);
		pd3dDevice->SetTransform(D3DTS_WORLD, &M) ;  
		pd3dDevice->SetRenderState( D3DRS_LIGHTING, true );
		pMeshObj = g_Car.GetMesh();	
		for( DWORD m = 0; m < g_Car.m_dwNumMaterials; ++m )
		{

			pd3dDevice->SetMaterial(&g_Car.m_pMaterials[m]);
			if( g_Car.m_pTextures[m] )
				V( pd3dDevice->SetTexture(0, g_Car.m_pTextures[m]));

			V( pMeshObj->DrawSubset( m ) );
		}
#endif

		V( pd3dDevice->EndScene() );
	}
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
						 bool* pbNoFurtherProcessing, void* pUserContext )
{
#if phase2
	g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
#endif	
	return 0;
}


//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9ResetDevice callback 
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9LostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9CreateDevice callback 
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
{
#if phase1
	g_Scene.Destroy();
#endif
#if phase3
	g_Car.Destroy();
#endif
}


//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int )
{
	// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

	// Set the callback functions
	DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
	DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );
	DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );
	DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );
	DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );
	DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );
	DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
	DXUTSetCallbackMsgProc( MsgProc );
	DXUTSetCallbackFrameMove( OnFrameMove );

	// TODO: Perform any application-level initialization here

	// Initialize DXUT and create the desired Win32 window and Direct3D device for the application
	DXUTInit( true, true ); // Parse the command line and show msgboxes
	DXUTSetHotkeyHandling( true, true, true );  // handle the default hotkeys
	DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
	DXUTCreateWindow( L"3D_Shader_ShadowMap" );
	DXUTCreateDevice( true, 1024, 768 );

	// Start the render loop
	DXUTMainLoop();

	// TODO: Perform any application-level cleanup here

	return DXUTGetExitCode();
}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值