您的位置:首页 > 其它

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

2014-04-23 08:24 381 查看
昨天在写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();
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: