好了,这是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(); } }