Created
October 25, 2013 12:31
-
-
Save PirosB3/7153953 to your computer and use it in GitHub Desktop.
Rendering code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//**************************************************************************// | |
// This is a modified version of the Microsoft sample code and loads a mesh.// | |
// it uses the helper class CDXUTSDKMesh, as there is no longer any built in// | |
// support for meshes in DirectX 11. // | |
// // | |
// The CDXUTSDKMesh is NOT DorectX, not is the file format it uses, the // | |
// .sdkmesh, a standard file format. You will hnot find the .sdkmesh format // | |
// outside the MS sample code. Both these things are provided as an entry // | |
// point only. // | |
// // | |
// Look for the Nigel style comments, like these, for the bits you need to // | |
// look at. // | |
// // | |
// You may notice that this sample tries to create a DirectX11 rendering // | |
// device, and if it can't do that creates a DirectX 9 device. I'm not // | |
// using DirectX9. // | |
//**************************************************************************// | |
//**************************************************************************// | |
// Modifications to the MS sample code is copyright of Dr Nigel Barlow, // | |
// lecturer in computing, University of Plymouth, UK. // | |
// email: [email protected]. // | |
// // | |
// Sdkmesh added to MS sample Tutorial05. // | |
// // | |
// You may use, modify and distribute this (rather cack-handed in places) // | |
// code subject to the following conditions: // | |
// // | |
// 1: You may not use it, or sell it, or use it in any adapted form for // | |
// financial gain, without my written premission. // | |
// // | |
// 2: You must not remove the copyright messages. // | |
// // | |
// 3: You should correct at least 10% of the typig abd spekking errirs. // | |
//**************************************************************************// | |
//-------------------------------------------------------------------------------------- | |
// File: Tutorial 09 - Meshes Using DXUT Helper Classes.cpp | |
// | |
// This sample shows a simple example of the Microsoft Direct3D's High-Level | |
// Shader Language (HLSL) using the Effect interface. | |
// | |
// Copyright (c) Microsoft Corporation. All rights reserved. | |
//-------------------------------------------------------------------------------------- | |
#include "DXUT.h" | |
#include "DXUTcamera.h" | |
#include "DXUTgui.h" | |
#include "DXUTsettingsDlg.h" | |
#include "SDKmisc.h" | |
#include "SDKMesh.h" | |
#include <xnamath.h> | |
#include "resource.h" | |
//**************************************************************************// | |
// Global Variables. There are many global variables here (we aren't OO // | |
// yet. I doubt Roy Tucker (Comp Sci students will know him) will // | |
// approve pf this either. Sorry, Roy. // | |
//**************************************************************************// | |
CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs | |
CD3DSettingsDlg g_D3DSettingsDlg; // Device settings dialog | |
CDXUTDialog g_HUD; // manages the 3D | |
CDXUTDialog g_SampleUI; // dialog for sample specific controls | |
CModelViewerCamera g_Camera; // Not used by Nigel. | |
CDXUTDirectionWidget g_LightControl; // Not used by Nigel. | |
float g_fLightScale; | |
int g_nNumActiveLights; | |
int g_nActiveLight; | |
bool g_bShowHelp = false; // If true, it renders the UI control text | |
int g_width = 800; | |
int g_height = 600;; | |
CDXUTSDKMesh g_MeshTiger; // Wot, not a pointer type? | |
XMMATRIX g_MatProjection; | |
ID3D11InputLayout *g_pVertexLayout11 = NULL; | |
ID3D11Buffer *g_pVertexBuffer = NULL; | |
ID3D11Buffer *g_pIndexBuffer = NULL; | |
ID3D11VertexShader *g_pVertexShader = NULL; | |
ID3D11PixelShader *g_pPixelShader = NULL; | |
ID3D11SamplerState *g_pSamLinear = NULL; | |
//**********************************************************************// | |
// Variables to control the movement of the tiger. // | |
// The only one I have coded is rotate about Y, we need an x, y, z // | |
// position and maybe rotates about other axes. // | |
//**********************************************************************// | |
float g_f_TigerRY = XMConvertToRadians(45); //45º default | |
float tigerXValue = 0; | |
float tigerYValue = 0; | |
float tigerZValue = 0; | |
float tigerSpeed = 1; | |
XMVECTOR tigerInitialDirection = XMVectorSet(1,0,-1,0); | |
bool g_b_LeftArrowDown = false; //Status of keyboard. Thess are set | |
bool g_b_RightArrowDown = false; //in the callback KeyboardProc(), and | |
bool g_b_UpArrowDown = false; //are used in onFrameMove(). | |
bool g_b_DownArrowDown = false; | |
//**************************************************************************// | |
// This is M$ code, but is usuig old D3DX from DirectX9. I'm glad to see // | |
// that M$ are having issues updating their sample code, same as me - Nigel.// | |
//**************************************************************************// | |
CDXUTTextHelper* g_pTxtHelper = NULL; | |
//**************************************************************************// | |
// This is a structure we pass to the vertex shader. // | |
// Note we do it properly here and pass the WVP matrix, rather than world, // | |
// view and projection matrices separately. // | |
//**************************************************************************// | |
struct CB_VS_PER_OBJECT | |
{ | |
XMMATRIX matWorldViewProj; | |
XMMATRIX matWorld; // needed to transform the normals. | |
}; | |
UINT g_iCBVSPerObjectBind = 0; | |
//**************************************************************************// | |
// These are structures we pass to the pixel shader. // | |
// Note we do it properly here and pass the WVP matrix, rather than world, // | |
// view and projection matrices separately. // | |
// // | |
// These structures must be identical to those defined in the shader that // | |
// you use. So much for encapsulation; Roy Tucker (Comp Sci students will // | |
// know him) will not approve. // | |
//**************************************************************************// | |
struct CB_PS_PER_OBJECT | |
{ | |
XMFLOAT4 m_vObjectColor; | |
}; | |
UINT g_iCBPSPerObjectBind = 0; | |
struct CB_PS_PER_FRAME | |
{ | |
XMFLOAT4 m_vLightDirAmbient; | |
}; | |
struct MexhVertexStructure | |
{ | |
XMFLOAT4 pos; | |
XMFLOAT3 normal; | |
XMFLOAT2 TextureUV; | |
}; | |
UINT g_iCBPSPerFrameBind = 1; | |
//**************************************************************************// | |
// Now a global instance of each constant buffer. // | |
//**************************************************************************// | |
ID3D11Buffer *g_pcbVSPerObject = NULL; | |
ID3D11Buffer *g_pcbPSPerObject = NULL; | |
ID3D11Buffer *g_pcbPSPerFrame = NULL; | |
//-------------------------------------------------------------------------------------- | |
// UI control IDs | |
//-------------------------------------------------------------------------------------- | |
#define IDC_TOGGLEFULLSCREEN 1 | |
#define IDC_TOGGLEREF 3 | |
#define IDC_CHANGEDEVICE 4 | |
//**************************************************************************// | |
// If you are not used to "C" you will find that functions (or methods in // | |
// "C++" must have templates defined in advance. It is usual to define the // | |
// prototypes in a header file, but we'll put them here for now to keep // | |
// things simple. // | |
//**************************************************************************// | |
//-------------------------------------------------------------------------------------- | |
// Forward declarations | |
//-------------------------------------------------------------------------------------- | |
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ); | |
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ); | |
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, | |
void* pUserContext ); | |
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ); | |
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext ); | |
extern bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, | |
bool bWindowed, void* pUserContext ); | |
extern HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, | |
const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); | |
extern HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, | |
void* pUserContext ); | |
extern void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, | |
void* pUserContext ); | |
extern void CALLBACK OnD3D9LostDevice( void* pUserContext ); | |
extern void CALLBACK OnD3D9DestroyDevice( void* pUserContext ); | |
bool CALLBACK IsD3D11DeviceAcceptable(const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, | |
DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext ); | |
HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, | |
void* pUserContext ); | |
HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, | |
const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); | |
void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext ); | |
void CALLBACK OnD3D11DestroyDevice( void* pUserContext ); | |
void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, | |
float fElapsedTime, void* pUserContext ); | |
void InitApp(); | |
void RenderText(); | |
void charStrToWideChar(WCHAR *dest, char *source); | |
void RenderMesh (ID3D11DeviceContext* pd3dImmediateContext, CDXUTSDKMesh *toRender); | |
//**************************************************************************// | |
// A Windows program always kicks off in WinMain. // | |
// Initializes everything and goes into a message processing // | |
// loop. // | |
// // | |
// This version uses DXUT, and is much more complicated than previous // | |
// versions you have seen. This allows you to sync the frame rate to your // | |
// monitor's vertical sync event. // | |
//**************************************************************************// | |
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ) | |
{ | |
// Enable run-time memory check for debug builds. | |
#if defined(DEBUG) | defined(_DEBUG) | |
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); | |
#endif | |
// DXUT will create and use the best device (either D3D9 or D3D11) | |
// that is available on the system depending on which D3D callbacks are set below | |
//**************************************************************************// | |
// Set DXUT callbacks. // | |
//**************************************************************************// | |
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings ); | |
DXUTSetCallbackMsgProc( MsgProc ); | |
DXUTSetCallbackKeyboard( OnKeyboard ); | |
DXUTSetCallbackFrameMove( OnFrameMove ); | |
DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable ); | |
DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice ); | |
DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice ); | |
DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender ); | |
DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice ); | |
DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice ); | |
DXUTSetCallbackD3D11DeviceAcceptable( IsD3D11DeviceAcceptable ); | |
DXUTSetCallbackD3D11DeviceCreated( OnD3D11CreateDevice ); | |
DXUTSetCallbackD3D11SwapChainResized( OnD3D11ResizedSwapChain ); | |
DXUTSetCallbackD3D11FrameRender( OnD3D11FrameRender ); | |
DXUTSetCallbackD3D11SwapChainReleasing( OnD3D11ReleasingSwapChain ); | |
DXUTSetCallbackD3D11DeviceDestroyed( OnD3D11DestroyDevice ); | |
InitApp(); | |
DXUTInit( true, true, NULL ); // Parse the command line, show msgboxes on error, no extra command line params | |
DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen | |
DXUTCreateWindow( L"Tutorial 09 - Meshes Using DXUT Helper Classes" ); | |
DXUTCreateDevice (D3D_FEATURE_LEVEL_9_2, true, 800, 600 ); | |
//DXUTCreateDevice(true, 640, 480); | |
DXUTMainLoop(); // Enter into the DXUT render loop | |
return DXUTGetExitCode(); | |
} | |
//-------------------------------------------------------------------------------------- | |
// Initialize the app | |
//-------------------------------------------------------------------------------------- | |
void InitApp() | |
{ | |
// Initialize dialogs | |
g_D3DSettingsDlg.Init( &g_DialogResourceManager ); | |
g_HUD.Init( &g_DialogResourceManager ); | |
g_SampleUI.Init( &g_DialogResourceManager ); | |
g_HUD.SetCallback( OnGUIEvent ); int iY = 10; | |
g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 0, iY, 170, 23 ); | |
g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 0, iY += 26, 170, 23, VK_F3 ); | |
g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 0, iY += 26, 170, 23, VK_F2 ); | |
g_SampleUI.SetCallback( OnGUIEvent ); iY = 10; | |
} | |
//-------------------------------------------------------------------------------------- | |
// Called right before creating a D3D9 or D3D11 device, allowing the app to modify the device settings as needed | |
//-------------------------------------------------------------------------------------- | |
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ) | |
{ | |
// Uncomment this to get debug information from D3D11 | |
//pDeviceSettings->d3d11.CreateFlags |= D3D11_CREATE_DEVICE_DEBUG; | |
// For the first device created if its a REF device, optionally display a warning dialog box | |
static bool s_bFirstTime = true; | |
if( s_bFirstTime ) | |
{ | |
s_bFirstTime = false; | |
if( ( DXUT_D3D11_DEVICE == pDeviceSettings->ver && | |
pDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE ) ) | |
{ | |
DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver ); | |
} | |
} | |
return true; | |
} | |
//**************************************************************************// | |
// Handle updates to the scene. This is called regardless of which D3D // | |
// API is used (we are only using Dx11). // | |
//**************************************************************************// | |
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ) | |
{ | |
if (g_b_LeftArrowDown) g_f_TigerRY -= fElapsedTime*3; // Frame rate | |
if (g_b_RightArrowDown) g_f_TigerRY += fElapsedTime*3; // independent. | |
if (g_b_UpArrowDown) tigerXValue -= fElapsedTime * 3; | |
if (g_b_DownArrowDown) tigerXValue += fElapsedTime * 3; | |
} | |
//-------------------------------------------------------------------------------------- | |
// Render the help and statistics text | |
//-------------------------------------------------------------------------------------- | |
void RenderText() | |
{ | |
UINT nBackBufferHeight = ( DXUTIsAppRenderingWithD3D9() ) ? DXUTGetD3D9BackBufferSurfaceDesc()->Height : | |
DXUTGetDXGIBackBufferSurfaceDesc()->Height; | |
g_pTxtHelper->Begin(); | |
g_pTxtHelper->SetInsertionPos( 2, 0 ); | |
g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) ); | |
g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) ); | |
g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() ); | |
// Draw help | |
if( g_bShowHelp ) | |
{ | |
g_pTxtHelper->SetInsertionPos( 2, nBackBufferHeight - 20 * 6 ); | |
g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) ); | |
g_pTxtHelper->DrawTextLine( L"Controls:" ); | |
g_pTxtHelper->SetInsertionPos( 20, nBackBufferHeight - 20 * 5 ); | |
g_pTxtHelper->DrawTextLine( L"Rotate model: Left /right arrows\n" | |
L"And extend this yourself\n" ); | |
g_pTxtHelper->SetInsertionPos( 550, nBackBufferHeight - 20 * 5 ); | |
g_pTxtHelper->DrawTextLine( L"Hide help: F1\n" | |
L"Quit: ESC\n" ); | |
} | |
else | |
{ | |
g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) ); | |
g_pTxtHelper->DrawTextLine( L"Press F1 for help" ); | |
} | |
g_pTxtHelper->End(); | |
} | |
//-------------------------------------------------------------------------------------- | |
// Handle messages to the application | |
//-------------------------------------------------------------------------------------- | |
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, | |
void* pUserContext ) | |
{ | |
// Pass messages to dialog resource manager calls so GUI state is updated correctly | |
*pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam ); | |
if( *pbNoFurtherProcessing ) | |
return 0; | |
// Pass messages to settings dialog if its active | |
if( g_D3DSettingsDlg.IsActive() ) | |
{ | |
g_D3DSettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam ); | |
return 0; | |
} | |
// Give the dialogs a chance to handle the message first | |
*pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam ); | |
if( *pbNoFurtherProcessing ) | |
return 0; | |
*pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam ); | |
if( *pbNoFurtherProcessing ) | |
return 0; | |
return 0; | |
} | |
//**************************************************************************// | |
// Handle key presses. // | |
//**************************************************************************// | |
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ) | |
{ | |
if( bKeyDown ) | |
{ | |
switch( nChar ) | |
{ | |
case VK_F1: | |
g_bShowHelp = !g_bShowHelp; break; | |
} | |
} | |
//**************************************************************// | |
// Nigel code to rotate the tiger. // | |
//**************************************************************// | |
switch( nChar ) | |
{ | |
case VK_LEFT: | |
g_b_LeftArrowDown = bKeyDown; | |
break; | |
case VK_RIGHT: g_b_RightArrowDown = bKeyDown; break; | |
case VK_UP: g_b_UpArrowDown = bKeyDown; break; | |
case VK_DOWN: g_b_DownArrowDown = bKeyDown; break; | |
} | |
} | |
//-------------------------------------------------------------------------------------- | |
// Handles the GUI events | |
//-------------------------------------------------------------------------------------- | |
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext ) | |
{ | |
switch( nControlID ) | |
{ | |
case IDC_TOGGLEFULLSCREEN: | |
DXUTToggleFullScreen(); break; | |
case IDC_TOGGLEREF: | |
DXUTToggleREF(); break; | |
case IDC_CHANGEDEVICE: | |
g_D3DSettingsDlg.SetActive( !g_D3DSettingsDlg.IsActive() ); break; | |
} | |
} | |
//-------------------------------------------------------------------------------------- | |
// Reject any D3D11 devices that aren't acceptable by returning false | |
//-------------------------------------------------------------------------------------- | |
bool CALLBACK IsD3D11DeviceAcceptable( const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, | |
DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext ) | |
{ | |
return true; | |
} | |
//**************************************************************************// | |
// Compile the shader file. These files aren't pre-compiled (well, not // | |
// here, and are compiled on he fly). // | |
//**************************************************************************// | |
HRESULT CompileShaderFromFile( WCHAR* szFileName, // File Name | |
LPCSTR szEntryPoint, // Namee of shader | |
LPCSTR szShaderModel, // Shader model | |
ID3DBlob** ppBlobOut ) // Blob returned | |
{ | |
HRESULT hr = S_OK; | |
// find the file | |
WCHAR str[MAX_PATH]; | |
V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, szFileName ) ); | |
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; | |
#if defined( DEBUG ) || defined( _DEBUG ) | |
// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders. | |
// Setting this flag improves the shader debugging experience, but still allows | |
// the shaders to be optimized and to run exactly the way they will run in | |
// the release configuration of this program. | |
dwShaderFlags |= D3DCOMPILE_DEBUG; | |
#endif | |
ID3DBlob* pErrorBlob; | |
hr = D3DX11CompileFromFile( str, NULL, NULL, szEntryPoint, szShaderModel, | |
dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL ); | |
if( FAILED(hr) ) | |
{ | |
WCHAR errorCharsW[200]; | |
if( pErrorBlob != NULL ) | |
{ | |
charStrToWideChar(errorCharsW, (char *)pErrorBlob->GetBufferPointer()); | |
MessageBox( 0, errorCharsW, L"Error", 0 ); | |
} | |
if( pErrorBlob ) pErrorBlob->Release(); | |
return hr; | |
} | |
SAFE_RELEASE( pErrorBlob ); | |
return S_OK; | |
} | |
//-------------------------------------------------------------------------------------- | |
// Create any D3D11 resources that aren't dependant on the back buffer | |
//-------------------------------------------------------------------------------------- | |
HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, | |
void* pUserContext ) | |
{ | |
HRESULT hr; | |
ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); | |
V_RETURN( g_DialogResourceManager.OnD3D11CreateDevice( pd3dDevice, pd3dImmediateContext ) ); | |
V_RETURN( g_D3DSettingsDlg.OnD3D11CreateDevice( pd3dDevice ) ); | |
g_pTxtHelper = new CDXUTTextHelper( pd3dDevice, pd3dImmediateContext, &g_DialogResourceManager, 15 ); | |
//**********************************************************************// | |
// Compile the pixel and vertex shaders. If your computer doesn't // | |
// support shader model 5, try shader model 4. There is nothing we are // | |
// using here that needs shader model 5. // | |
//**********************************************************************.. | |
ID3DBlob* pVertexShaderBuffer = NULL; | |
V_RETURN( CompileShaderFromFile( L"Tutorial 09 - Meshes Using DXUT Helper Classes_VS.hlsl", "VS_DXUTSDKMesh", "vs_5_0", &pVertexShaderBuffer ) ); | |
ID3DBlob* pPixelShaderBuffer = NULL; | |
V_RETURN( CompileShaderFromFile( L"Tutorial 09 - Meshes Using DXUT Helper Classes_PS.hlsl", "PS_DXUTSDKMesh", "ps_5_0", &pPixelShaderBuffer ) ); | |
//**********************************************************************// | |
// Create the pixel and vertex shaders. // | |
//**********************************************************************// | |
V_RETURN( pd3dDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(), | |
pVertexShaderBuffer->GetBufferSize(), NULL, &g_pVertexShader ) ); | |
DXUT_SetDebugName( g_pVertexShader, "VS_DXUTSDKMesh" ); | |
V_RETURN( pd3dDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(), | |
pPixelShaderBuffer->GetBufferSize(), NULL, &g_pPixelShader ) ); | |
DXUT_SetDebugName( g_pPixelShader, "PS_DXUTSDKMesh" ); | |
//**********************************************************************// | |
// Define the input layout. I won't go too much into this except that // | |
// the vertex defined here MUST be consistent with the vertex shader // | |
// input you use in your shader file and the constand buffer structure // | |
// at the top of this module. // | |
// // | |
// Normal vectirs are used by lighting. // | |
//**********************************************************************// | |
const D3D11_INPUT_ELEMENT_DESC layout[] = | |
{ | |
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, | |
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, | |
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, | |
}; | |
V_RETURN( pd3dDevice->CreateInputLayout( layout, ARRAYSIZE( layout ), pVertexShaderBuffer->GetBufferPointer(), | |
pVertexShaderBuffer->GetBufferSize(), &g_pVertexLayout11 ) ); | |
DXUT_SetDebugName( g_pVertexLayout11, "Primary" ); | |
SAFE_RELEASE( pVertexShaderBuffer ); | |
SAFE_RELEASE( pPixelShaderBuffer ); | |
//**************************************************************************// | |
// Initialize the projection matrix. Generally you will only want to create// | |
// this matrix once and then forget it. // | |
//**************************************************************************// | |
g_MatProjection = XMMatrixPerspectiveFovLH( XM_PIDIV2, // Field of view (pi / 2 radians, or 90 degrees | |
g_width / (FLOAT) g_height, // Aspect ratio. | |
0.01f, // Near clipping plane. | |
100.0f ); // Far clipping plane. | |
//**************************************************************************// | |
// Load the mesh. // | |
//**************************************************************************// | |
V_RETURN( g_MeshTiger.Create( pd3dDevice, L"tiger\\tiger.sdkmesh", true ) ); | |
// Create a sampler state | |
D3D11_SAMPLER_DESC SamDesc; | |
SamDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; | |
SamDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; | |
SamDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; | |
SamDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; | |
SamDesc.MipLODBias = 0.0f; | |
SamDesc.MaxAnisotropy = 1; | |
SamDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; | |
SamDesc.BorderColor[0] = SamDesc.BorderColor[1] = SamDesc.BorderColor[2] = SamDesc.BorderColor[3] = 0; | |
SamDesc.MinLOD = 0; | |
SamDesc.MaxLOD = D3D11_FLOAT32_MAX; | |
V_RETURN( pd3dDevice->CreateSamplerState( &SamDesc, &g_pSamLinear ) ); | |
DXUT_SetDebugName( g_pSamLinear, "Primary" ); | |
//**************************************************************************// | |
// Create the 3 constant bufers, using the same buffer descriptor to create // | |
// all three. // | |
//**************************************************************************// | |
D3D11_BUFFER_DESC Desc; | |
ZeroMemory( &Desc, sizeof(Desc) ); | |
Desc.Usage = D3D11_USAGE_DEFAULT; | |
Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; | |
Desc.CPUAccessFlags = 0; | |
Desc.MiscFlags = 0; | |
Desc.ByteWidth = sizeof( CB_VS_PER_OBJECT ); | |
V_RETURN( pd3dDevice->CreateBuffer( &Desc, NULL, &g_pcbVSPerObject ) ); | |
DXUT_SetDebugName( g_pcbVSPerObject, "CB_VS_PER_OBJECT" ); | |
Desc.ByteWidth = sizeof( CB_PS_PER_OBJECT ); | |
V_RETURN( pd3dDevice->CreateBuffer( &Desc, NULL, &g_pcbPSPerObject ) ); | |
DXUT_SetDebugName( g_pcbPSPerObject, "CB_PS_PER_OBJECT" ); | |
Desc.ByteWidth = sizeof( CB_PS_PER_FRAME ); | |
V_RETURN( pd3dDevice->CreateBuffer( &Desc, NULL, &g_pcbPSPerFrame ) ); | |
DXUT_SetDebugName( g_pcbPSPerFrame, "CB_PS_PER_FRAME" ); | |
return S_OK; | |
} | |
//-------------------------------------------------------------------------------------- | |
// Create any D3D11 resources that depend on the back buffer | |
//-------------------------------------------------------------------------------------- | |
HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, | |
const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) | |
{ | |
HRESULT hr; | |
V_RETURN( g_DialogResourceManager.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) ); | |
V_RETURN( g_D3DSettingsDlg.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) ); | |
g_width = pBackBufferSurfaceDesc->Width; | |
g_height = pBackBufferSurfaceDesc->Height; | |
g_HUD.SetLocation( g_width - 170, 0 ); | |
g_HUD.SetSize( 170, 170 ); | |
g_SampleUI.SetLocation( g_width - 170, g_height - 300 ); | |
g_SampleUI.SetSize( 170, 300 ); | |
return S_OK; | |
} | |
//-------------------------------------------------------------------------------------- | |
// Render the scene using the D3D11 device | |
//-------------------------------------------------------------------------------------- | |
void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, | |
float fElapsedTime, void* pUserContext ) | |
{ | |
HRESULT hr; | |
// If the settings dialog is being shown, then render it instead of rendering the app's scene | |
if( g_D3DSettingsDlg.IsActive() ) | |
{ | |
g_D3DSettingsDlg.OnRender( fElapsedTime ); | |
return; | |
} | |
// Clear the render target and depth stencil | |
float ClearColor[4] = { 0.0f, 0.25f, 0.25f, 0.55f }; | |
ID3D11RenderTargetView* pRTV = DXUTGetD3D11RenderTargetView(); | |
pd3dImmediateContext->ClearRenderTargetView( pRTV, ClearColor ); | |
ID3D11DepthStencilView* pDSV = DXUTGetD3D11DepthStencilView(); | |
pd3dImmediateContext->ClearDepthStencilView( pDSV, D3D11_CLEAR_DEPTH, 1.0, 0 ); | |
//**************************************************************************// | |
// Initialize the view matrix. What you do to the viewer matrix moves the // | |
// viewer, or course. // | |
// // | |
// The viewer matrix is created every frame here, which looks silly as the // | |
// viewer never moves. However in general your viewer does move. // | |
//**************************************************************************// | |
XMVECTOR Eye = XMVectorSet( 0.0f, 1.0f, -10.0f, 0.0f ); | |
XMVECTOR At = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f ); | |
XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); | |
XMMATRIX matView; | |
matView = XMMatrixLookAtLH( Eye, // The eye, or viewer's position. | |
At, // The look at point. | |
Up ); // Which way is up. | |
//******************************************************************// | |
// Create the world matrix for the tiger: just a rotate around // | |
// the Y axis of 45 degrees. DirectX does all angles in radians, // | |
// hence the conversion. And a translate. // | |
//******************************************************************// | |
// Calculate rotated position based on initial direction | |
XMMATRIX matTigerRotate = XMMatrixRotationY(g_f_TigerRY); | |
XMVECTOR rotatedPosition = XMVector3Normalize(XMVector3TransformCoord(tigerInitialDirection, matTigerRotate)); | |
// Multiply by speed | |
// MULTIPLY DIRECTION BY ROTATION MATRIX TO GET ROTATED VECTOR (from [0,0,0,0] to [1.2, 0.002, 0, -0.03]) | |
rotatedPosition *= 1 * fElapsedTime; | |
tigerXValue += XMVectorGetX(rotatedPosition); | |
tigerYValue += XMVectorGetY(rotatedPosition); | |
tigerZValue += XMVectorGetZ(rotatedPosition); | |
XMMATRIX matTigerTranslate = XMMatrixTranslation(tigerXValue, tigerYValue, tigerZValue); | |
XMMATRIX matTigerScale = XMMatrixScaling(10, 10, 10); | |
XMMATRIX matTigerWorld = matTigerRotate * matTigerTranslate * matTigerScale; | |
XMMATRIX matWorldViewProjection; | |
matWorldViewProjection = matTigerWorld * matView * g_MatProjection; | |
//******************************************************************// | |
// Update shader variables. We must update these for every mesh // | |
// that we draw (well, actually we need only update the position // | |
// for each mesh, think hard about this - Nigel // | |
// // | |
// We pass the parameters to it in a constant buffer. The buffer // | |
// we define in this module MUST match the constant buffer in the // | |
// shader. // | |
// // | |
// It would seem that the constant buffer we pass to the shader must// | |
// be global, well defined on the heap anyway. Not a local variable// | |
// it would seem. // | |
//******************************************************************// | |
CB_VS_PER_OBJECT CBMatrices; | |
CBMatrices.matWorld = XMMatrixTranspose(matTigerWorld); | |
CBMatrices.matWorldViewProj = XMMatrixTranspose(matWorldViewProjection); | |
pd3dImmediateContext->UpdateSubresource( g_pcbVSPerObject, 0, NULL, &CBMatrices, 0, 0 ); | |
pd3dImmediateContext->VSSetConstantBuffers( 0, 1, &g_pcbVSPerObject ); | |
//******************************************************************// | |
// Lighting. Ambient light and a light direction, above, to the // | |
// left and two paces back, I think. Then normalise the light // | |
// vector. It is kind-a-silly doing this every frame unless the // | |
// light moves. // | |
//******************************************************************// | |
float fAmbient = 0.1f; | |
XMFLOAT3 vectorLightDirection = XMFLOAT3(-1, 1, -2); | |
float vectorLightDirectionMag = sqrt( | |
vectorLightDirection.x*vectorLightDirection.x | |
+ vectorLightDirection.y*vectorLightDirection.y | |
+ vectorLightDirection.z*vectorLightDirection.z); | |
vectorLightDirection.x /= vectorLightDirectionMag; | |
vectorLightDirection.y /= vectorLightDirectionMag; | |
vectorLightDirection.z /= vectorLightDirectionMag; | |
CB_PS_PER_FRAME CBPerFrame; | |
CBPerFrame.m_vLightDirAmbient = XMFLOAT4(vectorLightDirection.x, | |
vectorLightDirection.y, | |
vectorLightDirection.z, fAmbient); | |
pd3dImmediateContext->UpdateSubresource( g_pcbPSPerFrame, 0, NULL, &CBPerFrame, 0, 0 ); | |
pd3dImmediateContext->PSSetConstantBuffers( 0, 2, &g_pcbPSPerFrame ); | |
CB_PS_PER_OBJECT CBPerObject; | |
CBPerObject.m_vObjectColor = XMFLOAT4(1, 1, 1, 1); | |
pd3dImmediateContext->UpdateSubresource( g_pcbPSPerObject, 0, NULL, &CBPerObject, 0, 0 ); | |
pd3dImmediateContext->PSSetConstantBuffers( 0, 3, &g_pcbPSPerObject ); | |
pd3dImmediateContext->PSSetSamplers( 0, 1, &g_pSamLinear ); | |
//**************************************************************************// | |
// Render the mesh. // | |
//**************************************************************************// | |
RenderMesh (pd3dImmediateContext, &g_MeshTiger); | |
//**************************************************************************// | |
// Render what is rather grandly called the head up display. // | |
//**************************************************************************// | |
DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); | |
g_HUD.OnRender( fElapsedTime ); | |
g_SampleUI.OnRender( fElapsedTime ); | |
RenderText(); | |
DXUT_EndPerfEvent(); | |
} | |
//**************************************************************************// | |
// Render a CDXUTSDKMesh, using the Device Context specified. // | |
//**************************************************************************// | |
void RenderMesh (ID3D11DeviceContext *pContext, | |
CDXUTSDKMesh *toRender) | |
{ | |
//Get the mesh | |
//IA setup | |
pContext->IASetInputLayout( g_pVertexLayout11 ); | |
UINT Strides[1]; | |
UINT Offsets[1]; | |
ID3D11Buffer* pVB[1]; | |
pVB[0] = toRender->GetVB11( 0, 0 ); | |
Strides[0] = ( UINT )toRender->GetVertexStride( 0, 0 ); | |
Offsets[0] = 0; | |
pContext->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets ); | |
pContext->IASetIndexBuffer( toRender->GetIB11( 0 ), toRender->GetIBFormat11( 0 ), 0 ); | |
// Set the shaders | |
pContext->VSSetShader( g_pVertexShader, NULL, 0 ); | |
pContext->PSSetShader( g_pPixelShader, NULL, 0 ); | |
for( UINT subset = 0; subset < toRender->GetNumSubsets( 0 ); ++subset ) | |
{ | |
//Render | |
SDKMESH_SUBSET* pSubset = NULL; | |
D3D11_PRIMITIVE_TOPOLOGY PrimType; | |
// Get the subset | |
pSubset = toRender->GetSubset( 0, subset ); | |
PrimType = CDXUTSDKMesh::GetPrimitiveType11( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType ); | |
pContext->IASetPrimitiveTopology( PrimType ); | |
//**************************************************************************// | |
// At the moment we load a texture into video memory every frame, which is // | |
// HORRIBLE, we need to create more Texture2D variables. // | |
//**************************************************************************// | |
ID3D11ShaderResourceView* pDiffuseRV = toRender->GetMaterial( pSubset->MaterialID )->pDiffuseRV11; | |
pContext->PSSetShaderResources( 0, 1, &pDiffuseRV ); | |
pContext->DrawIndexed( ( UINT )pSubset->IndexCount, 0, ( UINT )pSubset->VertexStart ); | |
} | |
} | |
//-------------------------------------------------------------------------------------- | |
// Release D3D11 resources created in OnD3D11ResizedSwapChain | |
//-------------------------------------------------------------------------------------- | |
void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext ) | |
{ | |
g_DialogResourceManager.OnD3D11ReleasingSwapChain(); | |
} | |
//-------------------------------------------------------------------------------------- | |
// Release D3D11 resources created in OnD3D11CreateDevice | |
//-------------------------------------------------------------------------------------- | |
void CALLBACK OnD3D11DestroyDevice( void* pUserContext ) | |
{ | |
g_DialogResourceManager.OnD3D11DestroyDevice(); | |
g_D3DSettingsDlg.OnD3D11DestroyDevice(); | |
DXUTGetGlobalResourceCache().OnDestroyDevice(); | |
SAFE_DELETE( g_pTxtHelper ); | |
g_MeshTiger.Destroy(); | |
SAFE_RELEASE( g_pVertexLayout11 ); | |
SAFE_RELEASE( g_pVertexBuffer ); | |
SAFE_RELEASE( g_pIndexBuffer ); | |
SAFE_RELEASE( g_pVertexShader ); | |
SAFE_RELEASE( g_pPixelShader ); | |
SAFE_RELEASE( g_pSamLinear ); | |
SAFE_RELEASE( g_pcbVSPerObject ); | |
SAFE_RELEASE( g_pcbPSPerObject ); | |
SAFE_RELEASE( g_pcbPSPerFrame ); | |
} | |
//**************************************************************************// | |
// Convert an old chracter (char *) string to a WCHAR * string. There must // | |
// be something built into Visual Studio to do this for me, but I can't // | |
// find it - Nigel. // | |
//**************************************************************************// | |
void charStrToWideChar(WCHAR *dest, char *source) | |
{ | |
int length = strlen(source); | |
for (int i = 0; i <= length; i++) | |
dest[i] = (WCHAR) source[i]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment