Today to learn the depth of the test, but this thing seems to be a temporary understanding of the principle, because the DX default is to open the depth test, that is, we do not need to set up to use the depth of the test function, but this is necessary to understand, one is the DX process more understanding, Second, we can manually set the parameters and functions of the depth test to achieve some of the effects you want to achieve.
I. INTRODUCTION
Three-dimensional world, there are all kinds of objects, and these objects will inevitably have occlusion, and the same object will have a different part of the relationship, to show a more realistic effect, it is necessary to use the depth buffer (Z buffer), supporting depth testing technology.
The depth cache is also tasted as a Z-cache, and D3D holds a depth value for each pixel on the screen, and when drawn, D3D compares the depth of the current pixel point of each object to the point in the depth buffer, if the test result is true, draws the current pixel, and updates the depth buffer, otherwise it is not drawn.
Two. Steps for deep testing
There are four steps to using the depth buffer:
1. Create a depth buffer
2. Turn on the depth test
3. Setting the depth test function
4. Update depth Buffers
Let's look at the following separately:
1. Create a depth buffer:
This is what we do when we initialize direct, and we've written it before. Is the two items of the struct when the D3D device is created:
Whether to turn on the auto depth buffer d3dpp. EnableAutoDepthStencil = true;//The current automatic depth buffer format D3DPP. Autodepthstencilformat = d3dfmt_d16;//has 16 bits of storage space per pixel, storing depth information
2. Turn on the depth test:
or the SetRenderState function, the first argument is d3drs_zenable, the second is ture or false to open the depth buffer
Set the render state, set the Enable depth value G_pdevice->setrenderstate (d3drs_zenable, true);
3. Setting the depth test function
The so-called depth test function, is some macro, DX has been written for us, we have to do is to choose these macros can be.
4. Depending on the return value of the depth test function, the update buffer can be set or not updated. DX gives us the right to choose freely, let us make a better effect.
Three. To turn the depth test on or off the following is an example where you can control whether the depth test is turned on by using the SPACEBAR.
Open depth test, "wall" inserted into the Dragon's body, you can see the stereoscopic effect is very lifelike:
Close the depth test, not only the wall has been blocked in front of the dragon, even the mesh model itself is drawing a problem, the characters "in turn."
Here to pay attention to a problem: why the character will reverse, if not applicable to the depth test, DX default will use the painter algorithm, that is, the east of the painting is in the back, after painting the East in front, and not to consider the possible mask relationship, and use the ZBuffer, you can better determine between objects, Or the mask relationship of the object itself.
D3DDemo.cpp: Defines the entry point for the application. #include "stdafx.h" #include "D3DDemo.h" #include "DirectInput.h" #include "Camera.h" #include "Terrain.h" #include " MESH.H "#define MAX_LOADSTRING 100//global variable: hinstance hinst;//current instance Tchar sztitle[max_loadstring];//title bar text Tchar szwindowclass[max_loadstring];//main window class name//The forward declaration of functions contained in this code module: HWND g_hwnd; Atommyregisterclass (hinstance hinstance); Boolinitinstance (HINSTANCE, int.); LRESULT Callbackwndproc (HWND, UINT, WPARAM, LPARAM);//---------The content needed to retrofit 3D windows------------lpdirect3d9 g_pd3d = null;// D3D interface pointer Lpdirect3ddevice9 g_pdevice = NULL;//D3D device pointer cdirectinput* g_pdirectinput = null;//control pointer ccamera* G_pCamera = NULL; Camera pointer cterrain* G_pterrian = null;//Terrain class pointer cmesh* g_pmesh1 = null;//Mesh object pointer 1cmesh* g_pmesh2 = null;//Mesh object pointer 2cmesh* g_pmesh3 = null;//Mesh object pointer 3lpd3dxmesh g_pmeshwall = null;//Wall grid pointer lpdirect3dtexture9 G_pgroundtexture = null;//ground texture d3dxmatrix g_matworld;//World matrix Void Oncreatd3d () {g_pd3d = Direct3dcreate9(d3d_sdk_version); if (!G_PD3D) return;//detects hardware device capabilities/*D3DCAPS9 caps; ZeroMemory (&caps, sizeof (caps)); G_pd3d->getdevicecaps (D3dadapter_default, D3ddevtype_hal, &caps); */// Get relevant information, screen size, pixel attributes D3ddisplaymode D3DDM; ZeroMemory (&D3DDM, sizeof (D3DDM)); G_pd3d->getadapterdisplaymode (D3dadapter_default, &D3DDM);// Set full-screen mode d3dpresent_parameters D3DPP; ZeroMemory (&D3DPP, sizeof (D3DPP));/*d3dpp. windowed = FALSE;D3DPP. Backbufferwidth = D3DDM. WIDTH;D3DPP. Backbufferheight = D3DDM. HEIGHT;*/D3DPP. windowed = TRUE;D3DPP. Backbufferformat = D3DDM. FORMAT;D3DPP. BackBufferCount = 1;D3DPP. SwapEffect = d3dswapeffect_discard;//The original buffer data is discarded//whether automatic depth buffer d3dpp is turned on. EnableAutoDepthStencil = true;//The current automatic depth buffer format D3DPP. Autodepthstencilformat = d3dfmt_d16;//Each pixel has 16 bits of storage space, storage distance from the camera g_pd3d->createdevice (D3dadapter_default, D3ddevtype_hal, G_hwnd, d3dcreate_software_vertexprocessing, &D3DPP, &g_pdevice); if (!g_pDevice) return;// Set render state, set enable depth value G_pdevice->setrenderstate (d3drs_zenable, false);//Set render state, turn off light g_Pdevice->setrenderstate (d3drs_lighting, false);//Set render state, crop mode g_pdevice->setrenderstate (D3drs_cullmode, D3dcull_none);} void Createmesh () {g_pmesh1 = new Cmesh (g_pdevice); G_pmesh1->createmesh ("Miki. X "); g_pmesh2 = new Cmesh (g_pdevice); G_pmesh2->createmesh (" demon.x "); g_pmesh3 = new Cmesh (g_pdevice);g_pmesh3-> Createmesh ("Dragon. X ");D 3DXCreateBox (g_pdevice, 50.0f, 50.0f, 1.0f, &g_pmeshwall, NULL);} void Createcamera () {G_pcamera = new Ccamera (g_pdevice); G_pcamera->setcameraposition (&d3dxvector3 (0.0f, 500.0f, -500.0f)) g_pcamera->settargetposition (&d3dxvector3 (0.0f, 500.0f, 0.0f));g_pcamera-> Setviewmatrix (); G_pcamera->setprojectionmartix ();} void Createterrain () {G_pterrian = new Cterrain (g_pdevice); G_pterrian->loadterrainfromfile (TEXT ("Heighmap.raw"), TEXT ("terraintexture.jpg")); G_pterrian->initterrain (30.0f, 3.0f);} void OnInit () {//Initialize D3DONCREATD3D ();//Initialize vertex buffer initvb ();//Create Mesh model Createmesh ();//Create Camera Createcamera ();// Create terrain Createterrain ();} void onDestroy () {safe_delete (g_pdirectinput); Safe_delete (G_pcamera); Safe_delete (G_pterrian); Safe_release (g_pdevice);} void Onlogic (float felapsedtime) {//Use DirectInput class to read Data G_pdirectinput->getinput ();//move angle of view along camera components if (g_ Pdirectinput->iskeydown (DIK_A)) G_pcamera->movealongrightvec ( -10.0f); if (G_pdirectinput->iskeydown (DIK_ D) G_pcamera->movealongrightvec (10.0f), if (G_pdirectinput->iskeydown (dik_w)) g_pcamera-> Movealonglookvec (10.0f), if (G_pdirectinput->iskeydown (dik_s)) G_pcamera->movealonglookvec ( -10.0f), if (g_ Pdirectinput->iskeydown (dik_i)) G_pcamera->movealongupvec (10.0f); if (G_pdirectinput->iskeydown (DIK_K)) G _pcamera->movealongupvec ( -10.0f);//rotate angle of view if (G_pdirectinput->iskeydown (dik_left)) g_pcamera-> along the camera components Rotationupvec ( -0.003f); if (G_pdirectinput->iskeydown (dik_right)) G_pcamera->rotationupvec (0.003f); if (g_ Pdirectinput->iskeydown (DIK_UP)) G_pcamera->rotationrightvec ( -0.003f); if (G_pdirectinput->iskeydown (DIK _down)) g_pcAmera->rotationrightvec (0.003f), if (G_pdirectinput->iskeydown (Dik_j)) G_pcamera->rotationlookvec (- 0.001F); if (G_pdirectinput->iskeydown (dik_l)) G_pcamera->rotationlookvec (0.001f);//mouse control right vector and upper vector rotation//g_ Pcamera->rotationupvec (G_pdirectinput->mousedx () * 0.001f);//g_pcamera->rotationrightvec (g_ Pdirectinput->mousedy () * 0.001f);//mouse wheel control observation point contraction operation static FLOAT Fposz=0.0f;fposz + = G_pdirectinput->mousedz () * 3.0f;//calculates and sets the framing transformation matrix D3dxmatrix Matview;g_pcamera->calculateviewmatrix (&matview); g_pdevice->settransform (D3dts_view, &matview);//the correct world transformation matrix is stored in the G_matworld d3dxmatrixtranslation (&g_matworld, 0.0f, 0.0f, Fposz); static bool M_biszbufferon;<span style= "White-space:pre" ></span>//set whether to turn on depth test if (g_pdirectinput-> Iskeydown (Dik_space)) {M_biszbufferon =!m_biszbufferon;g_pdevice->setrenderstate (D3DRS_ZENABLE, M_bIsZbufferOn );}} void OnRender (float felasedtime) {/////The first two parameters are 0 and null when the contents of the entire game window are emptied (clear background)//The third object is clear: The front means clear the color buffer, followed by the clear depth buffer, d3dclear_ Stencil Empty MoldPlate buffer g_pdevice->clear (0, NULL, d3dclear_target| D3dclear_zbuffer, D3dcolor_xrgb (0,100,100), 1.0f, 0), G_pdevice->beginscene ();D 3DXMATRIX matWorld1, MatWorld2, MatWorld3, MatWorld4; D3DXMatrixTranslation (&matworld1, 0.0f, 600.0f, 0.0f); D3DXMatrixTranslation (&matworld2, 500.0f, 500.0f, 0.0f);D 3DXMatrixTranslation (&matworld3, 0.0f, 500.0f, 0.0f );D 3DXMatrixTranslation (&matworld4, 0.0f, 0.0f, 0.0f); G_pmesh1->drawmesh (matWorld1); G_pmesh2->drawmesh ( MATWORLD2); G_pmesh3->drawmesh (matWorld3); g_pmeshwall->drawsubset (0);//g_pterrian->renderterrain (& MatWorld4, False); G_pdevice->endscene (); g_pdevice->present (null, NULL, NULL, NULL);} int Apientry _tWinMain (_in_ hinstance hinstance, _in_opt_ hinstance hprevinstance, _in_ LPTSTR lpcmdline, _in_ int ncmdshow) {unreferenced_parameter (hprevinstance); Unreferenced_parameter (lpCmdLine); TODO: Place the code here. MSG msg; Haccel hacceltable;//initializes the global string loadsTring (HInstance, Ids_app_title, SzTitle, max_loadstring); LoadString (HInstance, Idc_d3ddemo, Szwindowclass, max_loadstring); MyRegisterClass (HINSTANCE);//Execution of application initialization: if (! InitInstance (HINSTANCE, nCmdShow)) {return FALSE;} hacceltable = Loadaccelerators (hinstance, Makeintresource (Idc_d3ddemo)); ZeroMemory (&msg, sizeof (msg)), while (msg.message! = wm_quit) {if (PeekMessage (&msg, NULL, 0, 0, pm_remove)) { TranslateMessage (&msg);D ispatchmessage (&msg);} else{static DWORD dwtime = timegettime ();D Word dwcurrenttime = timegettime ();D word dwelapsedtime = dwcurrenttime-dwtime; float felapsedtime = dwelapsedtime * 0.001f;//------------Rendering and Logic part code----------onlogic (felapsedtime); OnRender ( Felapsedtime);//-----------------------------------------if (Dwelapsedtime < 1000/60) {Sleep (1000/60- Dwelapsedtime);} Dwtime = Dwcurrenttime;}} OnDestroy (); return (int) Msg.wparam;} Function: MyRegisterClass ()////Purpose: Registers the window class. ATOM MyRegisterClass (hinstance hinstance) {wndclassex wcex;wcex.cbsize = sizeof (WNdclassex); wcex.style= Cs_hredraw | cs_vredraw;wcex.lpfnwndproc= wndproc;wcex.cbclsextra= 0;wcex.cbwndextra= 0;wcex.hinstance= hInstance;wcex.hIcon= LoadIcon (HInstance, Makeintresource (Idi_d3ddemo)); wcex.hcursor= loadcursor (NULL, Idc_arrow); Wcex.hbrBackground= ( Hbrush) (color_window+1); wcex.lpszmenuname= makeintresource (Idc_d3ddemo); wcex.lpszclassname= SzWindowClass; Wcex.hiconsm= LoadIcon (Wcex.hinstance, Makeintresource (Idi_small)); return RegisterClassEx (&wcex);} Function: InitInstance (hinstance, int)////Purpose: Save the instance handle and create the main window////Note:////in this function, we save the instance handle in the global variable and//create and display the master thread The Sequence window. BOOL InitInstance (hinstance hinstance, int ncmdshow) {hInst = hinstance;//Store instance handle in global variable G_hwnd = CreateWindow (Szwi Ndowclass, SzTitle, Ws_overlappedwindow, Cw_usedefault, 0, cw_usedefault, 0, NULL, NULL, HINSTANCE, NULL); if (!g_hwnd) {return FALSE; }//Initialize DirectInput class g_pdirectinput = new Cdirectinput (); G_pdirectinput->init (G_hwnd, HInst, discl_foreground| Discl_nonexcLusive, discl_foreground| discl_nonexclusive); SetMenu (G_hwnd, NULL); ShowWindow (G_hwnd, ncmdshow); UpdateWindow (G_hwnd); OnInit (); return TRUE;} Functions: WndProc (HWND, UINT, WPARAM, LPARAM)////Purpose: Handles the message of the main window. wm_command-processing Application Menu//wm_paint-Draw main window//wm_destroy-send exit message and return////lresult CALLBACK WndProc (HWND g_hwnd, UINT Messa GE, WPARAM WPARAM, LPARAM LPARAM) {switch (message) {case Wm_keydown:if (WPARAM = vk_escape) postquitmessage (0); break; Case Wm_close:destroywindow (G_hwnd); Break;case wm_destroy:postquitmessage (0); Break;default:return DefWindowProc (g _hwnd, message, WParam, LParam);} return 0;}
Visible, depth buffer in the 3D world is a very important function, if we do not need to do too much operation, DX default depth test can be, if we also want to make some wonderful effect, you can change some depth test settings.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Direct-X study notes--deep cache