# Include <d3dx9. h>
# Pragma comment (Lib, "d3d9. lib ")
# Pragma comment (Lib, "d3dx9. lib ")
# Pragma comment (Lib, "winmm. lib ")
//-----------------------------------------------------------------------------
// Desc: global variable
//-----------------------------------------------------------------------------
Lpdirect3d9 g_pd3d = NULL; // direct3d object
Lpdirect3ddevice9 g_pd3ddevice = NULL; // direct3d device object
Lpdirect3dvertexbuffer9 g_pvb = NULL; // vertex buffer object
//-----------------------------------------------------------------------------
// Desc: vertex Structure
//-----------------------------------------------------------------------------
Struct customvertex
{
D3dxvector3 position; // vertex position
D3dxvector3 normal; // vertex normal
};
# Define d3dfvf_customvertex (d3dfvf_xyz | d3dfvf_normal)
//-----------------------------------------------------------------------------
// Desc: sets the transformation matrix.
//-----------------------------------------------------------------------------
Void setmatrices ()
{
// Create and set the world Matrix
D3dxmatrix matworld;
D3dxmatrixidentity (& matworld );
G_pd3ddevice-> settransform (d3dts_world, & matworld );
// Create and set the observation matrix
D3dxvector3 veyept (0.0f, 3.0f,-5.0f );
D3dxvector3 vlookatpt (0.0f, 0.0f, 0.0f );
D3dxvector3 vupvec (0.0f, 1.0f, 0.0f );
D3dxmatrix matview;
D3dxmatrixlookatlh (& matview, & veyept, & vlookatpt, & vupvec );
G_pd3ddevice-> settransform (d3dts_view, & matview );
// Create and set the Projection Matrix
D3dxmatrix matproj;
D3dxmatrixperspectivefovlh (& matproj, d3dx_pi/4, 1.0f, 1.0f, 100366f );
G_pd3ddevice-> settransform (d3dts_projection, & matproj );
}
//-----------------------------------------------------------------------------
// Desc: Initialize direct3d
//-----------------------------------------------------------------------------
Hresult initd3d (hwnd)
{
// Create a direct3d object used to create a direct3d device object
If (null = (g_pd3d = direct3dcreate9 (d3d_sdk_version )))
Return e_fail;
// Set the d3dpresent_parameters structure to create a direct3d device object
D3dpresent_parameters d3dpp;
Zeromemory (& d3dpp, sizeof (d3dpp ));
D3dpp. paiwed = true;
D3dpp. swapeffect = d3dswapeffect_discard;
D3dpp. backbufferformat = d3dfmt_unknown;
D3dpp. enableautodepthstencel = true;
D3dpp. autodepthstencilformat = d3dfmt_d16;
// Create a direct3d device object
If (failed (g_pd3d-> createdevice (d3dadapter_default, d3ddevtype_hal, hwnd,
D3dcreate_software_vertexprocessing,
& D3dpp, & g_pd3ddevice )))
{
Return e_fail;
}
// Set the picking mode to not picking out any surface (front and side)
G_pd3ddevice-> setrenderstate (d3drs_cullmode, d3dcull_none );
// Enable deep Test
G_pd3ddevice-> setrenderstate (d3drs_zenable, true );
// Set the transformation matrix
Setmatrices ();
Return s_ OK;
}
//-----------------------------------------------------------------------------
// Desc: Creates a scene image.
//-----------------------------------------------------------------------------
Hresult initgeometry ()
{
// Create a vertex buffer
If (failed (g_pd3ddevice-> createvertexbuffer (50*2 * sizeof (customvertex ),
0, d3dfvf_customvertex,
D3dpool_default, & g_pvb, null )))
{
Return e_fail;
}
// Fill in the vertex buffer
Customvertex * pvertices;
If (failed (g_pvb-> lock (0, 0, (void **) & pvertices, 0 )))
Return e_fail;
For (DWORD I = 0; I <50; I ++)
{
Float Theta = (2 * d3dx_pi * I)/(50-1 );
Pvertices [2 * I + 0]. Position = d3dxvector3 (sinf (theta),-1.0f, cosf (theta ));
Pvertices [2 * I + 0]. Normal = d3dxvector3 (sinf (theta), 0.0f, cosf (theta ));
Pvertices [2 * I + 1]. Position = d3dxvector3 (sinf (theta), 1.0f, cosf (theta ));
Pvertices [2 * I + 1]. Normal = d3dxvector3 (sinf (theta), 0.0f, cosf (theta ));
}
G_pvb-> unlock ();
Return s_ OK;
}
//-----------------------------------------------------------------------------
// Desc: Set materials and lights
//-----------------------------------------------------------------------------
Void setlight ()
{
// Set the material.
D3dmaterial9 mtrl;
Zeromemory (& mtrl, sizeof (d3dmaterial9 ));
Mtrl. Diffuse. r = mtrl. Ambient. r = 1.0f;
Mtrl. Diffuse. G = mtrl. Ambient. G = 1.0f;
Mtrl. Diffuse. B = mtrl. Ambient. B = 1.0f;
Mtrl. Diffuse. A = mtrl. Ambient. A = 1.0f;
G_pd3ddevice-> setmaterial (& mtrl );
// Set the light
D3dxvector3 vecdir;
D3dlight9 light;
Zeromemory (& Light, sizeof (d3dlight9 ));
Light. type = d3dlight_directional;
Light. Diffuse. r = 1.0f;
Light. Diffuse. G = 1.0f;
Light. Diffuse. B = 1.0f;
Vecdir = d3dxvector3 (cosf (timegettime ()/3500000f ),
1.0f,
Sinf (timegettime ()/3500000f ));
// Vecdir = d3dxvector3 (1.0f, 1.0f, 0.0f );
D3dxvec3normalize (d3dxvector3 *) & Light. Direction, & vecdir );
Light. range = 100366f;
G_pd3ddevice-> setlight (0, & Light );
G_pd3ddevice-> lightenable (0, true );
G_pd3ddevice-> setrenderstate (d3drs_lighting, true );
// Set the ambient light
G_pd3ddevice-> setrenderstate (d3drs_ambient, 0xff00ffff );
}
//-----------------------------------------------------------------------------
// Desc: Release the created object
//-----------------------------------------------------------------------------
Void cleanup (hwnd)
{
Killtimer (hwnd, 1 );
// Release the vertex buffer object
If (g_pvb! = NULL)
G_pvb-> release ();
// Release the direct3d device object
If (g_pd3ddevice! = NULL)
G_pd3ddevice-> release ();
// Release the direct3d object
If (g_pd3d! = NULL)
G_pd3d-> release ();
}
//-----------------------------------------------------------------------------
// Desc: rendering the image
//-----------------------------------------------------------------------------
Void render ()
{
// Clear the background Buffer
G_pd3ddevice-> clear (0, null, d3dclear_target | d3dclear_zbuffer,
D3dcolor_xrgb (45, 50,170), 1.0f, 0 );
// Start drawing the image in the background Buffer
If (succeeded (g_pd3ddevice-> beginscene ()))
{
// Set the light and material
Setlight ();
// Draw a graph in the background Buffer
G_pd3ddevice-> setstreamsource (0, g_pvb, 0, sizeof (customvertex ));
G_pd3ddevice-> setfvf (d3dfvf_customvertex );
G_pd3ddevice-> drawprimitive (d3dpt_trianglestrip, 0, 2*50-2 );
// End rendering in the background Buffer
G_pd3ddevice-> endscene ();
}
// Submit the drawing drawn in the background buffer area to the front-end buffer area for display.
G_pd3ddevice-> present (null, null );
}
Void callback timerproc (hwnd, uint umsg, uint idevent, DWORD dwtime)
{
Render ();
}
//-----------------------------------------------------------------------------
// Desc: Message Processing
//-----------------------------------------------------------------------------
Lresult winapi msgproc (hwnd, uint MSG, wparam, lparam)
{
Switch (MSG)
{
Case wm_destroy:
Cleanup (hwnd );
Postquitmessage (0 );
Return 0;
}
Return defwindowproc (hwnd, MSG, wparam, lparam );
}
//-----------------------------------------------------------------------------
// Desc: entry function
//-----------------------------------------------------------------------------
Int winapi winmain (hinstance hinst, hinstance, lpstr, INT)
{
// Register the window class
Wndclassex WC = {sizeof (wndclassex), cs_classdc, msgproc, 0l, 0l,
Getmodulehandle (null), null,
"Classname", null };
Registerclassex (& WC );
// Create a window
Hwnd = createwindow ("classname", "light ",
Ws_overlappedwindow, 200,100,500,500,
Null, null, WC. hinstance, null );
// Initialize direct3d
If (succeeded (initd3d (hwnd )))
{
// Create a scene image
If (succeeded (initgeometry ()))
{
// Display window
Showwindow (hwnd, sw_showdefault );
Updatewindow (hwnd );
Settimer (hwnd, 1, 10, timerproc );
// Enter the message loop
MSG;
Zeromemory (& MSG, sizeof (MSG ));
While (msg. message! = Wm_quit)
{
If (peekmessage (& MSG, null, 0u, 0u, pm_remove ))
{
Translatemessage (& MSG );
Dispatchmessage (& MSG );
}
}
}
}
Unregisterclass ("classname", WC. hinstance );
Return 0;
}
Light. range = 1000000f for direction light; this value is meaningless and can be left unspecified.
Do not place the render in the loop body when rendering the image. This will result in the failure to refresh the image in time due to resolution, computer performance, and drag windows.
The correct method is to use a timer to control
1. settimer (hwnd, 1, 10, timerproc );
2.
Void callback timerproc (hwnd, uint umsg, uint idevent, DWORD dwtime)
{
Render ();
}