好了,这是DXUT的最后一个实战,接下来我可能会学习下NVDIA FX Composer 2.5以及Shader Debugger,另外准备每周至少一个shader吧,今天任务把<<Pro OGRE 3D Programming>>第4章和第5章搞定,有时间的话再看下FX的帮助文档.
好了上源码:
//--------------------------------------------------------------------------------------
// File: control_color_by_using_HLSLwithEffects_DXUT(june_2010)_D3D9.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "DXUT.h"
#include "DXUTgui.h"
#include "SDKmisc.h"
#include "resource.h"
//--------------------------------------------------------------------------------------
// UI control IDs
//--------------------------------------------------------------------------------------
#define IDC_SLIDER_RED 1
#define IDC_SLIDER_GREEN 2
#define IDC_SLIDER_BLUE 3
#define IDC_STATIC_RED 4
#define IDC_STATIC_GREEN 5
#define IDC_STATIC_BLUE 6
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
CDXUTDialogResourceManager g_dlg_resource_manager;
CDXUTDialog g_control_dlg;
int r,g,b;
D3DXHANDLE g_hR = 0;
D3DXHANDLE g_hG = 0;
D3DXHANDLE g_hB = 0;
D3DXHANDLE g_hTech = 0;
// Scene
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
ID3DXEffect* g_pEffect = NULL; // D3DX effect interface
//--------------------------------------------------------------------------------------
// 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 )
{
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 )
{
HRESULT hr;
V_RETURN(g_dlg_resource_manager.OnD3D9CreateDevice(pd3dDevice));
// Create vertex shader
WCHAR str[MAX_PATH];
// Read the D3DX effect file
V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"myFX.fx" ) );
// Create the effect
V_RETURN( D3DXCreateEffectFromFile(
pd3dDevice, // associated device
str, // effect filename
NULL, // no preprocessor definitions
NULL, // no ID3DXInclude interface
D3DXSHADER_DEBUG, // compile flags
NULL, // don't share parameters
&g_pEffect, // return effect
NULL // return error messages
) );
// Get handle
g_hTech = g_pEffect->GetTechniqueByName("myTechnique");
g_hR = g_pEffect->GetParameterByName(0, "r");
g_hG = g_pEffect->GetParameterByName(0, "g");
g_hB = g_pEffect->GetParameterByName(0, "b");
return S_OK;
}
struct MY_V3F
{
FLOAT x, y, z;
};
static HRESULT initVertexBuffer(IDirect3DDevice9* pd3dDevice)
{
// Create and initialize vertex buffer
static const MY_V3F triangleVertices[] = {
{ -0.8f, 0.8f, 0.0f },
{ 0.0f, 0.8f, 0.0f },
{ -0.4f, 0.0f, 0.0f }
};
if (FAILED(pd3dDevice->CreateVertexBuffer(sizeof(triangleVertices),
0, D3DFVF_XYZ,
D3DPOOL_DEFAULT,
&g_pVB, NULL))) {
return E_FAIL;
}
void* pVertices;
if (FAILED(g_pVB->Lock(0, 0, /* map entire buffer */
&pVertices, 0))) {
return E_FAIL;
}
memcpy(pVertices, triangleVertices, sizeof(triangleVertices));
g_pVB->Unlock();
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 )
{
HRESULT hr;
V_RETURN(g_dlg_resource_manager.OnD3D9ResetDevice());
if( g_pEffect )
V_RETURN( g_pEffect->OnResetDevice() );
pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_control_dlg.SetLocation(pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 350);
g_control_dlg.SetSize(170, 300);
return initVertexBuffer(pd3dDevice);
}
//--------------------------------------------------------------------------------------
// Handle updates to the scene. This is called regardless of which D3D API is used
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{
g_pEffect->SetFloat(g_hR, (float)r/255);
g_pEffect->SetFloat(g_hG, (float)g/255);
g_pEffect->SetFloat(g_hB, (float)b/255);
}
//--------------------------------------------------------------------------------------
// Render the scene using the D3D9 device
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
HRESULT hr;
UINT iPass, cPasses;
// 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() ) )
{
V(g_pEffect->SetTechnique(g_hTech));
V( g_pEffect->Begin( &cPasses, 0 ) );
for( iPass = 0; iPass < cPasses; iPass++ )
{
V( g_pEffect->BeginPass( iPass ) );
pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(MY_V3F));
pd3dDevice->SetFVF(D3DFVF_XYZ);
pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
V( g_pEffect->EndPass() );
}
V( g_pEffect->End() );
V(g_control_dlg.OnRender(fElapsedTime));
V( pd3dDevice->EndScene() );
}
}
//--------------------------------------------------------------------------------------
// Handle messages to the application
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool* pbNoFurtherProcessing, void* pUserContext )
{
*pbNoFurtherProcessing = g_dlg_resource_manager.MsgProc(hWnd, uMsg, wParam, lParam);
if(*pbNoFurtherProcessing)
return 0;
*pbNoFurtherProcessing = g_control_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
if(*pbNoFurtherProcessing)
return 0;
return 0;
}
//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9ResetDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9LostDevice( void* pUserContext )
{
g_dlg_resource_manager.OnD3D9LostDevice();
if( g_pEffect )
g_pEffect->OnLostDevice();
SAFE_RELEASE(g_pVB);
}
//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9CreateDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
{
g_dlg_resource_manager.OnD3D9DestroyDevice();
SAFE_RELEASE(g_pEffect);
}
void CALLBACK OnGUIEvent(UINT event, int control_id, CDXUTControl* control, void* user_context)
{
switch(control_id)
{
case IDC_SLIDER_RED:
{
r = g_control_dlg.GetSlider(IDC_SLIDER_RED)->GetValue();
CDXUTStatic* pStatic = g_control_dlg.GetStatic(IDC_STATIC_RED);
if(pStatic)
{
WCHAR wszText[128];
swprintf_s( wszText, 128, L"R:%3d", r );
pStatic->SetText( wszText );
}
break;
}
case IDC_SLIDER_GREEN:
{
g = g_control_dlg.GetSlider(IDC_SLIDER_GREEN)->GetValue();
CDXUTStatic* pStatic = g_control_dlg.GetStatic(IDC_STATIC_GREEN);
if(pStatic)
{
WCHAR wszText[128];
swprintf_s( wszText, 128, L"G:%3d", g );
pStatic->SetText( wszText );
}
break;
}
case IDC_SLIDER_BLUE:
b = g_control_dlg.GetSlider(IDC_SLIDER_BLUE)->GetValue();
CDXUTStatic* pStatic = g_control_dlg.GetStatic(IDC_STATIC_BLUE);
if(pStatic)
{
WCHAR wszText[128];
swprintf_s( wszText, 128, L"B:%3d", b );
pStatic->SetText( wszText );
}
break;
}
}
void InitDialogs()
{
g_control_dlg.Init(&g_dlg_resource_manager);
int y = 10, height = 22;
g_control_dlg.SetCallback(OnGUIEvent);
g_control_dlg.AddStatic(IDC_STATIC_RED,L"R:100",10, y+24, 30, height);
g_control_dlg.AddSlider(IDC_SLIDER_RED, 50, y += 24, 100, height);
g_control_dlg.GetSlider(IDC_SLIDER_RED)->SetRange(0, 255);
g_control_dlg.GetSlider(IDC_SLIDER_RED)->SetValue(100);
r = 100;
g_control_dlg.AddStatic(IDC_STATIC_GREEN,L"G:100",10, y+24, 30, height);
g_control_dlg.AddSlider(IDC_SLIDER_GREEN, 50, y += 24, 100, height);
g_control_dlg.GetSlider(IDC_SLIDER_GREEN)->SetRange(0, 255);
g_control_dlg.GetSlider(IDC_SLIDER_GREEN)->SetValue(100);
g = 100;
g_control_dlg.AddStatic(IDC_STATIC_BLUE,L"B:100",10, y+24, 30, height);
g_control_dlg.AddSlider(IDC_SLIDER_BLUE, 50, y += 24, 100, height);
g_control_dlg.GetSlider(IDC_SLIDER_BLUE)->SetRange(0, 255);
g_control_dlg.GetSlider(IDC_SLIDER_BLUE)->SetValue(100);
b = 100;
}
//--------------------------------------------------------------------------------------
// 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
InitDialogs();
// 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"control_color_by_using_HLSLwithEffects_DXUT(june_2010)_D3D9" );
DXUTCreateDevice( true, 400, 400 );
// Start the render loop
DXUTMainLoop();
// TODO: Perform any application-level cleanup here
return DXUTGetExitCode();
}
/*--------------------------------------------------------------------------
myFX.fx -- the vertex shader controling the color of the triangle
(c) Seamanj.2013/7/10
--------------------------------------------------------------------------*/
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
float r,g,b;
//--------------------------------------------------------------------------------------
// Vertex shader output structure
//--------------------------------------------------------------------------------------
struct VS_Output {
float4 position : POSITION;
float3 color : COLOR;
};
//--------------------------------------------------------------------------------------
// Vertex shader
//--------------------------------------------------------------------------------------
VS_Output myVertexEntry(float2 position : POSITION)
{
VS_Output OUT;
OUT.position = float4(position,0,1);
OUT.color = float3(r,g,b);
return OUT;
}
//--------------------------------------------------------------------------------------
// Renders scene to render target
//--------------------------------------------------------------------------------------
technique myTechnique
{
pass P0
{
VertexShader = compile vs_2_0 myVertexEntry();
}
}