Write a friend who is written to the CBS C / C
The National Day is finally over, and the desolate life will continue, although this rainy holiday is also very desolate. When I went out this morning, I lifted the eye was the gloomy sky covered this comic city, and I made me a little breathless. Sinking, the busy crowd has a blown from the wind. I think that the days are like this day, I have traveled in the dark clouds in the sky, but I still have confused, squatting, and the soul of the soul, I can't help but tears, exactly When I can find the harbor with that sunny sky?
If you don't say these unhappy, the last article is not ended, which is ready to continue the content of the last article in this article, mainly telling the various effects of OpenGL. But when I got a few of my pen, I found that I can't continue. There are too many content in OpenGL. I only explain a special effect. For example, the fog will account for a lot of space, or even more than the upper article. So now I have to apologize to everyone for my food. Today, we will start our other interesting topics - Direct3D, in the following content I will simultaneously start the method to start from the easiest program, making a small box similar to the last routine. If you don't say more, you will start below.
Have you heard that DirectX9.0 is released? If not, you should also listen to me now, then go http://download.microsoft.com/download/b/6/a/b6ab32f3-39e8-4096-9445-d38e6675de85/dx90bsdk.exe download one latest DirectX9.0's SDK because I will use D3D9 to explain the full text. In fact, there is a very detailed tutorial and reference in DirectX9.0. Most people only need to see these help, I can learn D3D themselves. My article is suitable for those very lazy but I want to get started quickly, I don't understand English or programming knowledge. Lack of people watching. After loading DirectX9.0, open VC.NET, create a new Win32 project, add the following statement in stdafx.h:
#include
// D3D
Standard header file
#include
// D3D
Mathematical library header file
#include
//
Don't you say this?
#pragma comment (LIB, "D3D9") // D3D static library
#pragma comment (lib, "d3dx9") // D3D math library static library
Then make the code in the file in Winmain as follows:
#include "stdafx.h"
#define max_loadstring 100
Hinstance g_hinst;
HWND G_HWND;
IDIRECT3D9 * G_PD3D;
IDirect3ddevice9 * g_pd3ddevice;
IDirect3dvertexbuffer9 * g_pvb;
Tchar Sztitle [MAX_LOADSTRING];
Tchar SzwindowClass [MAX_LOADSTRING];
Atom MyRegisterClass (Hinstance Hinstance);
Bool InitInstance (Hinstance, Int);
Lresult Callback WndProc (HWND, UINT, WPARAM, LPARAM);
LResult Callback About (HWND, UINT, WPARAM, LPARAM);
Void OnIdle (Void);
Void oncreate (hwnd hwnd);
HRESULT INITD3D (VOID); HRESULT CREATEOBJECT (VOID);
Void ReleaseD3D (Void);
HRESULT SETMODALMATRIX (VOID);
HRESULT SETPROJMAMATRIX (Word Word WHEIGHT);
Void Beforepaint (Void);
Int apientry _twinmain (Hinstance Hinstance, Hinstance Hprevinstance, LPTSTR LPCMDLINE, INT NCMDSHOW)
{
MSG msg;
Haccel HaccelTable;
LoadString (Hinstance, IDS_APP_TITLE, SZTITLE, MAX_LOADSTRING);
LoadString (Hinstance, IDC_D3DTEST, SZWINDOWCLASS, MAX_LOADSTRING);
MyRegisterClass (Hinstance);
IF (! initinstance (hinstance, ncmdshow))
{
Return False;
}
Hacceltable = loadingAccelerators (Hinstance, (lpctstr) IDC_D3DTEST;
While (True)
{
IF (PEEKMESSAGE (& MSG, NULL, 0, 0, PM_REMOVE))
{
IF (! TranslateAccelerator (Msg.hwnd, HaccelTable, & MSG))
{
TranslateMessage (& MSG);
DispatchMessage (& MSG);
}
CONTINUE;
}
IF (wm_quit == msg.message)
{
Break;
}
OnIdle ();
}
UnregisterClass (SzWindowClass, g_hinst);
Return (int) msg.wparam;
}
Atom MyRegisterClass (Hinstance Hinstance)
{
WNDCLASSEX WCEX;
Wcex.cbsize = sizeof (wndclassex);
WCEX.Style = CS_HREDRAW | CS_VREDRAW;
WCEX.LPFNWNDPROC = (WndProc) WndProc;
Wcex.cbclsextra = 0;
Wcex.cbWndextra = 0;
WCEX.HINSTANCE = HINSTANCE
WCEX.HICON = Loadicon (Hinstance, (LPCTSTR) IDI_D3DTEST;
Wcex.hcursor = loadingcursor (null, idc_arrow);
Wcex.hbrbackground = (Hbrush) (Color_Window 1);
WCEX.LPSZMENUNAME = (LPCTSTR) IDC_D3DTEST;
WCEX.LPSZCLASSNAME = SzWindowClass;
Wcex.hiconsm = loading (Wcex.hinstance, (LPCTSTR) IDI_SMALL);
Return RegisterClassex (& WCEX);
}
Bool InitInstance (Hinstance Hinstance, Int ncmdshow) {
g_hinst = hinstance;
CreateWindow (SzwindowClass, Sztitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, HINSTANCE, NULL
IF (! g_hwnd)
{
Return False;
}
Showwindow (g_hwnd, ncmdshow);
UpdateWindow (G_HWND);
Return True;
}
Lresult Callback WndProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM)
{
Int Wmid, WMEVENT;
Switch (Message)
{
Case WM_CREATE:
Oncreate (hwnd);
Break;
Case WM_COMMAND:
WMID = loword (wparam);
WMEVENT = HiWord (WPARAM);
Switch (WMID)
{
Case idm_exit:
DestroyWindow (hwnd);
Break;
DEFAULT:
Return DefWindowProc (Hwnd, Message, WPARAM, LPARAM);
}
Break;
Case WM_SIZE:
SetProjmatrix (Loword (LPARAM), HiWord (LPARAM);
Break;
Case WM_DESTROY:
ReleaseD3D ();
PostquitMessage (0);
Break;
DEFAULT:
Return DefWindowProc (Hwnd, Message, WPARAM, LPARAM);
}
Return 0;
}
Void oncreate (HWND HWND)
{
g_hwnd = hwnd;
INITD3D ();
CREATEOBJECT ();
}
Void ReleaseD3D (Void)
{
}
HRESULT INITD3D (VOID)
{
Return S_OK;
}
Void Beforepaint (Void)
{
}
HRESULT CREATEOBJECT (VOID)
{
Return S_OK;
}
Void OnIdle (Void)
{
}
HRESULT SETMODALMATRIX (Void)
{
Return S_OK;
}
HRESULT SETPROJMAMATRIX (Word wwidth, Word WHEIGHT)
{
Return S_OK;
}
The above code is only a framework, and the friends who carefully study the article on the article should be very clear about these codes, but I still need to explain it. In the InitInstance function, the beginning of the initializer instance, we put the handle of the instance to the global variable for future use:
g_hinst = hinstance;
When you create a form, I didn't directly return the return value of CREATEWINDOW to the global variable g_hwnd because the CreateWindow function triggered several messages in the execution, where there is WM_CREATE, the processing of this message In the oncreate in the function, I executed the following statement:
g_hwnd = hwnd;
In this way, we can use G_hWnd earlier. SetProjmatrix is the setting of the projection matrix, the projection rectangle is only affected by the window aspect ratio, so it can be called when the WM_SIZE event is called. SETMODALMATRIX is setting the model matrix, which is the Dongdong and the viewpoints, so it must be in the Rander, accurately saying it before render. INITD3D is called when the form is created, used to initialize the D3D device. CreateObject and initd3d are the initialization function, which is used to create a three-dimensional object. For the mechanism of the message loop, see OpenGL Getting Started. Let's fill in the code, first is initialization, we fill in the following code in the initd3d function: g_pd3d = Direct3dcreate9 (D3D_SDK_Version); if (null == g_pd3d) {Return E_FAIL;}
D3DPresent_Parameters D3DPP; ZeromeMory (& D3DP, SIZEOF (D3DP)); D3DPP.Windowed = true; d3dpp.swapeffect = D3DSWAPEFFECT_DISCARD; D3DPP.BACKBUFFERMAT = D3DFMT_A8R8G8B8;
g_pD3D-> CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, & d3dpp, & g_pd3dDevice); g_pd3dDevice-> SetRenderState (D3DRS_LIGHTING, TRUE); g_pd3dDevice-> SetRenderState (D3DRS_AMBIENT, D3DCOLOR_COLORVALUE (0.3f, 0.3f, 0.3f, 1.0) ); g_pd3ddevice-> lightenable (0, true);
D3DMAMEMORY (& mtrl, sizeof (mtrl)); mtrl.diffuse.r = mtrl.Ambient.r = 140.0F / 255.0F; mtrl.diffuse.g = mtrl.ambient.g = 200.0F / 255.0F; mtrl .Diffuse.b = mtrl.ambient.b = 255.0f / 255.0f; mtrl.diffuse.a = mtrl.ambient.a = 1.0f; g_pd3ddevice-> setMaterial (& mtrl); return s_ok;
The Direct3DCreate9 function creates a D3D interface pointer and returns the interface pointer to the global variable, and the parameters must be D3D_SDK_Version. D3DPresent_Parameters is a structure, which is the same as PixelFormat in OpenGL, which is created to specify some properties of the device.
D3DPP.Windowed = true; // device is a window device instead of full screen D3DPP.swapeffect = D3DSWAPEFFECT_DISCARD; / / When the buffer does not change the back buffer D3DPP.BACKBufferFormat = D3DFMT_A8R8G8B8; // argb color mode
After that, we can call CreateDevice to create a device. The first parameter specifies the use of the main display driver, the second parameter specifies whether the device uses hardware to process the display, and the third parameter is of course your form handle. The fourth parameter If specified D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE efficiency will increase much. g_pd3ddevice-> setrenderstate (d3drs_lighting, true); g_pd3ddevice-> setrenderstate (D3DRS_AMBIENT, D3DCOLOR_COLORVALUE (0.6F, 0.6F, 0.6F, 1.0));
These two sentences are used to turn on the light and set ambient light color. Then I set the material:
mtrl.diffuse.r = mtrl.Ambient.r = 140.0f / 255.0f; mtrl.diffuse.g = mtrl.Ambient.g = 200.0f / 255.0f; mtrl.diffuse.b = mtrl.ambient.b = 255.0f / 255.0f; mtrl.diffuse.a = mtrl.ambient.a = 1.0f;
In order to make a contrast with the previous routine, I used the same material. When CreateDevice is successful, we should create D3D-based three-dimensional objects.
D3DVector SrcBox [] = {{5.0F, 5.0F, 0.0F}, {5.0F, 5.0F, 10.0F}, {5.0F, -5.0F, 10.0F, 10.0F }, {-5.0F, -5.0F, 0.0F}, {-5.0F, -5.0F, 10.0F}, {-5.0F, 5.0F, 0.0F}, {-5.0F, 5.0F, 10.0F },}; Word WINDEX [] = {0, 4, 6, 0, 2, 4, 0, 6, 7, 0, 7, 1, 0, 3, 2, 0, 1, 3, 5, 2, 3, 5, 4, 2, 5, 6, 4, 5, 7, 6, 5, 1, 7, 5, 3, 1,};
Are you familiar with these data? Yes, or the data in the previous one, the D3D is D3D to prepare a very good structure D3DVector, encapsulated 3D seats X, Y, and Z. We also need to define an extra our own structure to store our three-dimensional closing information:
Struct CustomvertEx {D3DVector Pos; D3DVector Normal;
The first member POS is used to store the vertex coordinate data, and the second member Normal is used to store the plane of the plane. - I am talking about this concept. Like OpenGL, we also need to expand the vertex array in order to guide:
CustomvertEx ExpandBox [SizeOf (WINDEX) / SIZEOF (WORD)];
For (int i = 0; i <36; i ) {expandbox [i] .pos = srcbox [windex [I]];
Then use the following code as the vertex calculation method, the source code of the CalcNormal function is in the previous one.
For (i = 0; i <12; i ) {d3dvector tri [3]; tri [0] = expandbox [i * 3 0] .pos; TRI [1] = expandbox [i * 3 1] .pos ; TRI [2] = expandbox [i * 3 2] .pos; expandbox [i * 3 0] .NORMAL.X = 0.0f; Expandbox [i * 3 0] .NORMAL.Y = 0.0F; ExpandBox [i * 3 0] .NORMAL.Z = 1.0f; CalcNormal (TRI, & (Expandbox [i * 3 0] .NORMAL)); ExpandBox [i * 3 1] .NORMAL = ExpAndbox [i * 3 0] .NORMAL; ExpandBox [i * 3 2] .NORMAL = Expandbox [i * 3 0] .NORMAL;} Here I need to spend a convention, a concept FVF exists only in D3D. D3D is not in the way when processing display data, OpenGL is an array of independent arrays, such as VertexBuffer, IndexBuffer, Normalbuffer, etc., and D3D is put together with these data of each vertex, form a unit for processing, also That is to say there is only one array, and all the data of a single vertex is included in each element of the array, so he is called Flexible Vertex Format, and the structural CustomvertEx I just defined is a unit of array. Each unit can contain the information you need. For example, you only need the vertex coordinate data and color, then you only need to be slightly modified to the structure, but how to let D3D know which data in your structure ? Of course, we can specify a parameter at CreatevertExbuffer to tell D3D: D3DFVF_XYZ | D3DFVF_NORMAL, we can use this value in many places, so we define a macro to express it:
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL)
Then you can ask another question, maybe D3D can know which data in our elements contains the vertices, but how D3D knows how these data is in the structure, is the order in memory? Unfortunately, D3D can't know your order, but D3D specifies the order of these data, such as the normal vector is behind the vertices, and the color must be placed behind. About this order list you have to see the details of the MSDN on Vertex Formats. Let's create a vertex array:
IF (Failed (g_pd3ddevice-> createvertexbuffer (sizeof (expandbox), 0, d3dfvf_customvertex, d3dpool_default, & g_pvb, null)) {Return E_FAIL;
These parameters have been mentioned above, I believe you will understand, I will not say much. How to store our square box data into this creation of a good vertex buffer? DirectX has its own memory management method, I mentioned in front of "WinAMP Detailed", which is Lock and Unlock: Void * Pvertices; IF (Failed (g_pvb-> lock) (0, Sizeof (Void), (void **) & pvertices, 0)) RETURN E_FAIL; MoveMemory (Pvertices, ExpandBox, SizeOf (ExpandBox)); g_pvb-> unlock ();
Like OpenGL, after the initialization work, the other thing that must be done is to set the matrix. First, the projection matrix, we add these code to the setProjmatrix function:
D3DXMATRIX matProj; D3DXMatrixPerspectiveFovLH (& matProj, D3DX_PI / 4, (float) wWidth / (float) wHeight, 1.0f, 100.0f); return g_pd3dDevice-> SetTransform (D3DTS_PROJECTION, & matProj);
Then the view matrix, add the following code to SetModalMatrix
static float fRadius = 0.5f; fRadius - = 0.003f; if (fRadius <0) {fRadius = D3DX_PI * 2;} D3DXMATRIX matWorld; D3DXMatrixRotationZ (& matWorld, 0.0f); if (FAILED (g_pd3dDevice-> SetTransform (D3DTS_WORLD, & matWorld ))) {return E_FAIL;} D3DXMATRIX matView; D3DXMatrixLookAtLH (& matView, & D3DXVECTOR3 (cosf (fRadius) * 40.0f, sinf (fRadius) * 40.0f, 30.0), & D3DXVECTOR3 (0.0f, 0.0f, 0.0f), & D3DXVECTOR3 ( 0.0F, 0.0F, 1.0F)); g_pd3ddevice-> setTransform (D3DTS_VIEW, & MATVIEW); RETURN S_OK;
I think I don't say you can understand the meaning of these code, is it very similar to OpenGL? Ok, now all preparations will continue, now we can start to draw a square box. Find the OniDEL handler, then add the following code here:
IF (g_pd3ddevice! = NULL)
{
g_pd3ddevice-> clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB (255, 255, 200), 1.0F, 0);
IF (succeeded (g_pd3ddedevice-> beginscene ())))
{
Beforepaint ();
IF (Failed (SetModalmatrix ())))
{
Return;
}
g_pd3ddevice-> setStreamSource (0, g_pvb, 0, sizeof (customertex));
g_pd3ddevice-> setfvf (D3DFVF_CUSTOMVERTEX); g_pd3ddevice-> DrawPrimitive (D3DPT_TRIANGLIST, 0, 12);
g_pd3ddevice-> endscene ();
g_pd3ddevice-> present (null, null, null, null);
}
}
g_pd3dDevice-> Clear corresponds glClear, g_pd3dDevice-> BeginScene and g_pd3dDevice-> EndScene equivalent glBegin and glEnd, g_pd3dDevice-> SetStreamSource corresponds glSet ** Pointer, g_pd3dDevice-> DrawPrimitive corresponds glDrawArray, g_pd3dDevice-> Present equivalent SwapBuffer, The difference here and OpenGL is that D3D is here to be equipped with FVF, a very simple process:
g_pd3ddevice-> setfvf (D3DFVF_CUSTomVertex);
In addition, the background color of the D3D is specified when Clear. Now you can run your program, but you will find that the box is a black, that is because you didn't open any light. OpenGL is pure white when not open any light source, huh, it has certain confusion ~ Now let's open a light, let it illuminate this object. Just in Beforepaint:
D3DLight9 Light; ZeromeMory (Light); Light.Position = D3DXVector3 (30.0F, 30.0F, 30.0F); Light.attion1 = 0.05F; light.diffuse.r = 1.0f; light.diffuse.g = 1.0f; light.diffuse.b = 1.0f; light.range = 1000.0f; light.type = D3DLight_Point; g_pd3ddevice-> setlight (0, & light); g_pd3ddevice-> lightenable (0, true);
Why do you want to put it in BeForePain? Because we can also realize dynamic light and shadow, it is to move the light source. This is not particularly paying, this top is not a direction source, is a point source, D3DLight_Point, its light is no direction, diverged from any direction from the seat point to any direction, you can set three attenuation components The attenuation formula in D3D is: atten = 1 / (att0 att1 * d att2 * d * d), when your three attenuation is 0, it will be wrong. Here we use ATT1, let it equal 0.05, very small value? The smaller, the smaller the attenuation, the stronger the light.
Now your code should look like this:
#include "stdafx.h" #include "d3dtest.h" #define max_loadstring 100 #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL)
Struct CustomvertEx {D3DVector Pos; D3DVector Normal;}; hinstance g_hinst; hinstance g_hinst; hwnd g_hwnd; idirect3d9 * g_pd3d; idirect3ddevice9 * g_pd3ddevice; idirect3dvertexbuffer9 * g_pvb;
Tchar sztitle [max_loadstring]; tchar szwindowclass [max_loadstring];
ATOM MyRegisterClass (HINSTANCE hInstance); BOOL InitInstance (HINSTANCE, int); LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM); void OnIdle (void); void OnCreate ( HWND hWnd); HRESULT InitD3D (void); HRESULT CreateObject (void); void ReleaseD3D (void); HRESULT SetModalMatrix (void); HRESULT SetProjMatrix (WORD wWidth, WORD wHeight); void BeforePaint (void);
Void CalcNormal (Const D3dVector * Pvertices, D3DVector * PVertices, D3DVector V1, V2; V1.X = Pvertices [0] .x - pvertices [1] .x; v1.y = pvertices [0] .y - pvertices [1 ] .y; v1.z = pvertices [0] .z - pvertices [1] .z; v2.x = pVertices [1] .x - pvertices [2] .x; v2.y = pvertices [1] .y .y - Pvertices [2] .y; v2.z = pvertices [1] .z - pvertices [2] .z; d3dxvector3 temp (v1.y * v2.z - v1.z * v2.y, v1.z * v2 .x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); d3dxvec3normalize ((d3dxvector3 *) pnormal, & temp);
class CTimer {public: CTimer () {QueryPerformanceFrequency (& m_Frequency); Start ();} void Start () {QueryPerformanceCounter (& m_StartCount);} double End () {LARGE_INTEGER CurrentCount; QueryPerformanceCounter (& CurrentCount); return double (CurrentCount.LowPart - m_StartCount.LowPart) / (double) m_Frequency.LowPart;} private: LARGE_INTEGER m_Frequency; LARGE_INTEGER m_StartCount;}; int APIENTRY _tWinMain (hINSTANCE hInstance, hINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {MSG msg; HACCEL hAccelTable;
LoadString (Hinstance, IDs_App_Title, Sztitle, Max_LoadString); LoadString (Hinstance, IDC_D3DTEST, SZWINDOWCLASS, MAX_LOADSTRING); MyRegisterClass (Hinstance);
IF (! initinstance (hinstance, ncmdshow) Return False;
Hacceltable = loadingAccelerators (Hinstance, (lpctstr) IDC_D3DTEST;
(! TranslateAccelerator (msg.hwnd, hAccelTable, & msg)) while (true) {if (PeekMessage (& msg, NULL, 0, 0, PM_REMOVE)) {if {TranslateMessage (& msg); DispatchMessage (& msg);} continue;} IF (wm_quit == msg.Message) Break; onidle ();}
UnregisterClass (SzWindowClass, g_hinst);
Return (int) msg.wparam;}
Atom myregisterclass (hinstance hinstance) {WNDCLASSEX WCEX;
Wcex.cbsize = sizeof (wndclassex);
wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC) WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon (hInstance, (LPCTSTR) IDI_D3DTEST); wcex .hCursor = LoadCursor (NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW 1); wcex.lpszMenuName = (LPCTSTR) IDC_D3DTEST; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon (wcex.hInstance, (LPCTSTR Idi_small; return registerclassex (& wcex);
BOOL InitInstance (HINSTANCE hInstance, int nCmdShow) {g_hInst = hInstance; CreateWindow (szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (! G_hWnd) {return FALSE;} ShowWindow (g_hwnd, ncmdshow); UpdateWindow (g_hwnd); return true;}
Lresult Callback WndProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM) {Int WMID, WMEVENT
switch (message) {case WM_CREATE: OnCreate (hWnd); break; case WM_COMMAND: wmId = LOWORD (wParam); wmEvent = HIWORD (wParam); switch (wmId) {case IDM_EXIT: DestroyWindow (hWnd); break; default: return DefWindowProc (hWnd, message, wParam, lParam);} break; case WM_SIZE: SetProjMatrix (LOWORD (lParam), HIWORD (lParam)); break; case WM_DESTROY: ReleaseD3D (); PostQuitMessage (0); break; default: return DefWindowProc (hwnd, message, wparam, lparam);} return 0;} void oncreate (hwnd hwnd) {g_hwnd = hWnd; initd3d (); createObject ();}
Void released3d (void) {if (g_pvb! = null) {g_pvb-> release ();} if (g_pd3ddevice! = null) {g_pd3ddevice-> release ();} if (g_pd3d! = null) {g_pd3d-> Release ();
HRESULT InitD3D (void) {g_pD3D = Direct3DCreate9 (D3D_SDK_VERSION); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory (& d3dpp, sizeof (d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
g_pD3D-> CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, & d3dpp, & g_pd3dDevice); g_pd3dDevice-> SetRenderState (D3DRS_LIGHTING, TRUE); g_pd3dDevice-> SetRenderState (D3DRS_AMBIENT, D3DCOLOR_COLORVALUE (0.6f, 0.6f, 0.6f, 1.0) ); G_pd3ddevice-> lighttenable (0, true); D3DMaRial9 mtrl; zeromeMory (& mtrl, sizeof (mtrl)); mtrl.diffuse.r = mtrl.Ambient.r = 140.0F / 255.0F; mtrl.diffuse.g = mtrl .Ambient.g = 200.0F / 255.0F; mtrl.diffuse.b = mtrl.ambient.b = 255.0F / 255.0F; mtrl.diffuse.a = mtrl.ambient.a = 1.0f; g_pd3ddevice-> setMaTerial (& mtrl) RETURN S_OK;
Void Beforepaint (Void) {D3DLight 9 Light; ZeromeMory (Light); Light.Position = D3DXVector3 (30.0F, 30.0F, 30.0F); Light.attion1 = 0.05f; light.diffuse.r = 1.0f Light.diffuse.g = 1.0f; light.diffuse.b = 1.0f; light.range = 1000.0f; light.type = D3DLight_Point; g_pd3dde -> setLight (0, & light); g_pd3ddevice-> lightenable (0, true) }
HRESULT CREATEOBJECT (VOID) {D3DVector srcbox [] = {{5.0F, 5.0F, 0.0F}, {5.0F, 5.0F, 10.0F}, {5.0F, -5.0F, 0.0F}, {5.0F, -5.0F, 10.0F}, {-5.0F, -5.0F, 0.0F}, {-5.0F, -5.0F, 10.0F}, {-5.0F, 5.0F, 0.0F}, {-5.0F , 5.0F, 10.0F},}; Word WINDEX [] = {0, 4, 6, 0, 2, 4, 0, 6, 7, 0, 7, 1, 0, 3, 2, 0, 1, 3, 5, 2, 3, 5, 4, 2, 5, 6, 4, 5, 7, 6, 5, 1, 7, 5, 3, 1,}; customvertex expandbox [sizeof (windex) / Sizeof Word)]; for (int i = 0; i <36; i ) expandbox [i] .pos = srcbox [WINDEX [I]];
For (i = 0; i <12; i ) {d3dvector tri [3]; tri [0] = expandbox [i * 3 0] .pos; TRI [1] = expandbox [i * 3 1] .pos ; TRI [2] = expandbox [i * 3 2] .pos; expandbox [i * 3 0] .NORMAL.X = 0.0f; Expandbox [i * 3 0] .NORMAL.Y = 0.0F; ExpandBox [i * 3 0] .NORMAL.Z = 1.0f; CalcNormal (TRI, & (Expandbox [i * 3 0] .NORMAL)); ExpandBox [i * 3 1] .NORMAL = ExpAndbox [i * 3 0] .normal; ExpandBox [i * 3 2] .normal = ExpandBox [i * 3 0] .normal;} g_pd3dDevice-> CreateVertexBuffer (sizeof (ExpandBox), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, & g_pVB, NULL); Void * pvertices; g_pvb-> lock (0, sizeof (void **) & pvertices, 0); MoveMemory (pvertices, expandbox, sizeof (expandbox)); g_pvb-> unlock (); return s_ok;}
Void OnIdle (void) {Static CTimer T; static double dt = t.end (); double temp = t.end (); char szvalue [256]; sprintf (SzValue, "Current Frame:% F", 1 / (Temp - DT)); setWindowText (g_hwnd, szvalue); DT = Temp; if (g_pd3dde! = null) {g_pd3ddevice-> Clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB (255, 200), 1.0F, 0); IF SUCCEEDED (g_pd3dDevice-> BeginScene ())) {BeforePaint (); if (FAILED (SetModalMatrix ())) {return;} g_pd3dDevice-> SetStreamSource (0, g_pVB, 0, sizeof (CUSTOMVERTEX)); g_pd3dDevice-> SetFVF ( D3DFVF_CUSTOMVERTEX); g_pd3ddevice-> DrawPrimitive (D3DPT_TRIANGLIST, 0, 12); g_pd3ddevice-> endscene (); g_pd3ddevice-> present (null, null, null, null); }}}
HRESULT SetModalMatrix (void) {static float fRadius = 0.5f; fRadius - = 0.003f; if (fRadius <0) {fRadius = D3DX_PI * 2;} D3DXMATRIX matWorld; D3DXMatrixRotationZ (& matWorld, 0.0f); if (FAILED (g_pd3dDevice- > SetTransform (D3DTS_WORLD, & matWorld))) {return E_FAIL;} D3DXMATRIX matView; D3DXMatrixLookAtLH (& matView, & D3DXVECTOR3 (cosf (fRadius) * 40.0f, sinf (fRadius) * 40.0f, 30.0), & D3DXVECTOR3 (0.0f, 0.0f, 0.0F), & D3DXVECTOR3 (0.0F, 0.0F, 1.0F)); g_pd3ddevice-> setTransform (D3DTS_VIEW, & MATVIEW); RETURN S_OK;}
HRESULT SetProjMatrix (WORD wWidth, WORD wHeight) {D3DXMATRIX matProj; D3DXMatrixPerspectiveFovLH (& matProj, D3DX_PI / 4, (float) wWidth / (float) wHeight, 1.0f, 100.0f); return g_pd3dDevice-> SetTransform (D3DTS_PROJECTION, & matProj);}
See which effect of OpenGL is better? I would like to use D3D to do these things. This article has been dragged for a long time, and the National Day holiday is a major reason. Of course, there are factors that are very busy in the unit. In all, now I have to say sorry to everyone here. However, I would like to thank our big version of the main Ckacka and Steedhorse, who have been silently reviewing another FAQ, letting me seek to write a little in the east. Also, I would like to thank Li Xuefeng. Our company's OpenGL expert, consultant-level person, is a powerful and powerful technical skills and guarantee for my last article, and thank my puppy Anny, bringing me endless Joy; of course, I will thank you or everyone. It is your spiritual power to support me to continue writing.
Creamdog completed at 21:46 on October 10, 2003