// Remove the file of Tutorial 2 in DX9 SDK, making it triangle with Fixed Functional vs / askEMBLE VS / HLSI VS to render a triangle.
-------------------------------------------------- --------------------------- // File: Matrices.cpp //// Desc: Now That We know how to create a device and render some 2D vertices, // this tutorial goes the next step and renders 3D geometry. to deal the use of 4x4 matrices to transform // the geometry with translations, rotations, scaling, and setting up with // 3D geometry we need to introduce Our // Camera./// geometry is defined in model space. We can move it (translation), // rotate it (rotation), or stretch it (scale) Using a world transform.// the geometry is the SAID To be in world space. next, we need to orthol, somewhere to look at the geometry.// ANOTHER TRANSFORM, VIA The View Matrix, IS Used, to position and // rotateur view. WITH, OUR Last // Transform, Which "Projects" The 3D Scene // Into Our 2D ViewPort./// NO te that in this tutorial, we are introducing the use of D3DX, which // is a set of helper utilities for D3D. In this case, we are using some // of D3DX's useful matrix initialization functions. To use D3DX, simply // Include
// Modifier: nigo.zhou
// Objective: The original fixed pipeline program expands to perform vertex processing using // 1 fixed functional pipeline or using // 2 assembly-grade programmable pipeline to perform vertex processing or use // 3 HLSI can be used to perform vertex processing / / -------------------------------------------------------------------------------------------- ----------------------------- # include
#define safe_release (x) {if (x) x-> release ();
/ / -------------------------------------------------------------------------------------------- ----------------------------- // Global Variables // --------------- -------------------------------------------------- ------------ LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDeviceLPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering deviceLPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
// a structure for u v v {float x, y, z; // the unientsformed, 3D position for the vertex dword color; // the Vertex Color};
// I use the Vertex Declartiaon introduced by DX9 instead of fvflpdirect3dvertexdeclaration9 g_pvertexdeclarative;
// urustom fvf, Which Describes outom vertex structure // # define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
// vertex declarationd3dvertexelement9 decl [] = {// for position {0, 0, d3ddecltype_float3, d3ddeclmethod_default, d3ddeclusage_position, 0},
// for color {0, 12, d3ddecltype_d3dcolor, d3ddeclmethod_default, d3ddeclusage_color, 0},
D3DDECL_END ()};
#if vs_type == 1
// Shader DeclarationConst char * strVertexshader =
"vs_3_0 // Version Instruction / N"
// INPUT Register Declaration "DCL_POSITION V0 // Define Position Data in Register V0 / N" "DCL_COLOR V1 // Define Color / N"
// Output Register Declaration "DCL_Position0 O7 // //" DCL_COLOR O3 // Output Color / N "// Alu (Shader Function / Function Declaration)" M4x4 O7, V0, C0 // Transform Vertices by World / View / Projection Matrix / N "" MOV O3, V1 /// n ""; /// n "" "
LPDIRECT3DVERTEXSHADER9 G_PVS = NULL;
#ENDIF
#if vs_type == 2
Const char * strVertexshader = // Vertex Shader Declaration
"float4x4 worldviewproj: worldviewproj; / n" "struct vs_output / n" "{/ n" "float4 pos: position; / n" "float4 diff: color0; / n" "}; / n" "/ n" "vs_output VS_Matrices (Float4 INPOS: Position, Float4 Indiff: Color0) / N "" {/ n "" vs_output out = (vs_output) 0; / n "" / n "" OUT.POS = MUL (INPOS, WorldViewProj); / N "Out.diff = Indiff; / N" "Return Out; / N" "} / n" "
LPDIRECT3DVERTEXSHADER9 G_PVS = NULL;
#ENDIF
/ / -------------------------------------------------------------------------------------------- ----------------------------- // name: initd3d () // desc: initializes Direct3D / / ------ -------------------------------------------------- -------------------- HRESULT INITD3D (HWND HWND) {// Create The D3D Object. If (null == (g_pd3d = Direct3dcreate9 (D3D_SDK_VERSION)) Return E_FAIL;
// Set up the structure used to create the D3DDevice D3DPRESENT_PARAMETERS d3dpp; ZeroMemory (& d3dpp, sizeof (d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
// Create the D3DDevice if (FAILED (g_pD3D-> CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, & d3dpp, & g_pd3dDevice))) {return E_FAIL;} // Turn off culling, so we see the front and back of the triangle g_pd3dDevice -> setrenderstate (D3DRS_CULLMODE, D3DCULL_NONE);
// Turn Off D3D Lighting, Since We are providing Our OWN VERTEX Colors g_pd3ddevice-> setrenderstate (D3DRS_LIGHTING, FALSE);
Return S_OK;
/ / -------------------------------------------------------------------------------------------- ----------------------------- // name: setupmatrices () // desc: sets up the world, view, and process transport transform Matrice.//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------- void setupmatrices () {// for our world matrix, we will just rotate the object about { The y-axis. d3dxmatrixa16 matworld;
// set up the rotation matrix to generate 1 Full Rotation (2 * pi radians) // Every 1000 ms. To avoid the loss of precision inherent NumBers, The system time is moduted by the rotation // Period Before Conversion To a Radian Angle. uint itime = timegettime ()% 1000; Float Fangle = Itime * (2.0F * D3DX_PI) / 1000.0F; D3DXMatrixrotationY (& MatWorld, Fangle);
// set Up Our View Matrix. A View Matrix Can Be Defined Given An Eye Point, // A Point To Lookat, And A Direction For Which Way Is Up. Here, We set the // Eye Five Units Back Along The Z- Axis and Up Three Units, Look at the // Origin, And Define "Up" to be in the y-direction. d3dxvector3 veyept (0.0F, 3.0F, -5.0F); D3DXVector3 VLOOKATPT (0.0F, 0.0F, 0.0 f); D3DXVECTOR3 vUpVec (0.0f, 1.0f, 0.0f); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH (& matView, & vEyePt, & vLookatPt, & vUpVec); // For the projection matrix, we set up a perspective transform (which // transforms geometry from 3D view space to 2D viewport space, with // a perspective divide making objects smaller in the distance). to build // a perpsective transform, we need the field of view (1/4 pi is common), // the aspect ratio And the Near and Far Clipping Planes (Which Define At // What Distances Ge Al Rendered. D3DXMATRIXA16 MATPROJ; D3DXMATRIXPERSPECTIVEFOV LH (& Matproj, D3DX_PI / 4, 1.0F, 1.0F, 100.0F);
#if VS_TYPE == 0 g_pd3dDevice-> SetTransform (D3DTS_WORLD, & matWorld); g_pd3dDevice-> SetTransform (D3DTS_VIEW, & matView); g_pd3dDevice-> SetTransform (D3DTS_PROJECTION, & matProj); # else D3DXMATRIXA16 compMat; D3DXMatrixMultiply (& compMat, & matWorld, & matView); D3DXMATRIXMULTIPLY (& Compmat, & Compmat, & Matproj); D3DXMATRIXTRANSPOSE (& Compmat, & Compmat); g_pd3dde -> setvertexshaderConstantf (0, (Float *) & Compmat, 4); # ENDIF
}
/ / -------------------------------------------------------------------------------------------- ----------------------------- // name: InitGeometry () // desc: creates the scene geometry // ---- -------------------------------------------------- ----------------------- HRESULT INITGEMETRY () {HRESULT HR; // Initialize Three Vertices for Rendering a Triangle CustomvertEX G_Vertices [] = {-1.0F , -1.0F, 0.0F, 0xFFFF0000,}, {1.0F, -1.0F, 0.0F, 0xFF0000FF,}, {0.0F, 1.0F, 0.0F, 0xFffFFFFF,},}
// Create the vertex buffer. // we use vertex declartion // if (FAILED (g_pd3dDevice-> CreateVertexBuffer (3 * sizeof (CUSTOMVERTEX), // 0, D3DFVF_CUSTOMVERTEX, // D3DPOOL_DEFAULT, & g_pVB, NULL))) if (FAILED (g_pd3ddevice-> createvertexbuffer (3 * Sizeof (CustomvertEX), 0, 0, D3DPool_Default, & g_pvb, null)) {Return E_FAIL;}
// Fill the Vertex Buffer. Void * Pvertices; IF (Failed (G_PVB-> Lock (0, SizeOf (g_vertices), (void **) & pvertices, 0)) Return E_FAIL; Memcpy (Pvertices, G_vertices, Sizeof (g_vertices )); G_pvb-> unlock ();
IF (Failed (HR = g_pd3ddevice-> createvertExDeclaration (decl, & g_pvertexDeclaration)))) {safe_release (g_pvertexdeclarative); returnh HR;}
#if vs_type == 1
// Compile and create the vertex shader LPD3DXBUFFER pShader = NULL; hr = D3DXAssembleShader (strVertexShader, (UINT) strlen (strVertexShader), NULL, NULL, D3DXSHADER_DEBUG, & pShader, NULL // error messages); if (FAILED (hr)) { SAFE_RELEASE (PSHADER); Return Hr;}
// Create the vertex shader hr = g_pd3dDevice-> CreateVertexShader ((DWORD *) pShader-> GetBufferPointer (), & g_pVS); if (FAILED (hr)) {SAFE_RELEASE (pShader); SAFE_RELEASE (g_pVS); return hr;} SAFE_RELEASE (pshader); # Endif
#if vs_type == 2
// Compile and create the vertex shader LPD3DXBUFFER pShader = NULL; hr = D3DXCompileShader (strVertexShader, (UINT) strlen (strVertexShader), NULL, NULL, "VS_Matrices", "vs_2_0", D3DXSHADER_DEBUG, & pShader, NULL, // error messages NULL ); If (Failed (HR)) {Safe_Release (PSHADER); Return Hr;}
// Create the vertex shader hr = g_pd3dDevice-> CreateVertexShader ((DWORD *) pShader-> GetBufferPointer (), & g_pVS); if (FAILED (hr)) {SAFE_RELEASE (pShader); SAFE_RELEASE (g_pVS); return hr;} SAFE_RELEASE (pshader);
#ENDIF
Return S_OK;
/ / -------------------------------------------------------------------------------------------- ----------------------------- // name: render () // desc: Draws the scene // ----- -------------------------------------------------- ---------------------- Void render () {// clear the backbuffer to a black color g_pd3ddevice-> clear (0, null, d3dclear_target, d3dcolor_xrgb (0 , 0, 0), 1.0F, 0);
// begin the scene if (succeeded (g_pd3dde -> beginscene ())) {// setup the world, view, and projection matrices setupmatrices ();
// Render the Vertex Buffer Contents g_pd3ddevice-> setStreamSource (0, g_pvb, 0, sizeof (customertex));
// We use Vertex Declaration g_pd3ddevice-> setvertexDeclaration (g_pvertexdeclarative);
#if vs_type! = 0 g_pd3ddevice-> setvertexshader (g_pvs); # ENDIF
// g_pd3ddevice-> setfvf (D3DFVF_CUSTOMVERTEX); g_pd3ddevice-> DrawPrimitive (D3DPT_TRIANGLESTRIP, 0, 1); # if vs_type! = 0 g_pd3ddevice-> setvertexshader (null); # ENDIF
// end the footne g_pd3dde -> endscene ();
// Present the Backbuffer Contents to the Display g_pd3ddevice-> present (null, null, null, null);}
/ / -------------------------------------------------------------------------------------------- ----------------------------- // name: cleanup () // desc: release Objects // --- -------------------------------------------------- ------------------------ void cleanup () {
SAFE_RELEASE (G_PVERTEXDECLATION); SAFE_RELEASE (G_PVS);
IF (g_pvb! = null) g_pvb-> release ();
IF (g_pd3ddevice! = null) g_pd3ddevice-> release ();
IF (g_pd3d! = null) g_pd3d-> release ();
/ / -------------------------------------------------------------------------------------------- ----------------------------- // name: msgproc () // desc: The window's message handler // ---- -------------------------------------------------- ----------------------- Lresult WinApi MsgProc (HWND HWND, UINT MSG, WPARAM WPARAM, LPARAM LPARAM) {Switch (MSG) {CASE WM_DESTROY: CLEANUP ( ); PostquitMessage (0); return 0;}
Return DefWindowProc (HWND, MSG, WPARAM, LPARAM);
/ / -------------------------------------------------------------------------------------------- ----------------------------- // name: Winmain () // desc: the application's entry point // ---- -------------------------------------------------- ----------------------- Int Winapi Winmain (Hinstance Hinst, Hinstance, LPSTR, INT) {// Register The window Class Wndclassex WC = {Sizeof (WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle (NULL), NULL, NULL, NULL, NULL, "D3D Tutorial", NULL}; RegisterClassEx (& wc); // Create the application's window HWND hWnd = CreateWindow ( "D3D Tutorial "," D3D Tutorial 03: Matrices ", WS_OVERLAPPEDWINDOW, 100, 100, 256, 256, GetDesktopWindow (), NULL, WC.HINSTANCE, NULL;
// Initialize Direct3D if (SUCCEEDED (InitD3D (hWnd))) {// Create the scene geometry if (SUCCEEDED (InitGeometry ())) {// Show the window ShowWindow (hWnd, SW_SHOWDEFAULT); UpdateWindow (hWnd);
// enter the message loop msg msg; ZeromeMory (& MSG); while (msg.Message! = WM_QUIT) {IF (PEEKMESSAGE (& MSG, NULL, 0U, 0U, PM_Remove) {TranslateMessage (& MSG); DispatchMessage (& MSG);}}}
UnregisterClass ("D3D Tutorial"; Return 0;}