Before learning the mesh model of the import, drawing, understand the X file and other related knowledge, but, it is difficult to draw, and to draw a model requires a lot of code, is a process-oriented thinking, this time, learn how to put the grid model import and mapping functions encapsulated in a class. and deepen your understanding of world transform. Feel your 3D thinking is still not cultivated, want to draw an object, draw out and the position of the imagination is very far away.
I. Review the relevant knowledge of the grid model
Grid model is a kind of resources we make in the art tool, through some API interface we can make the model of art children's shoes easy to import the program. We just need to know how to create a mesh model from a file and how to draw a mesh model.
This time, we were like the last time we had a program that reads the grid file information from a file and then loads the texture of the material based on the information read, but adds a grid optimization and encapsulates the grid loading and drawing in a class.
Two. Optimize the grid we usually use the Optimizeinplace function to optimize the grid content, to remove some useless vertices and other information, so that we can be used in drawing more smoothly. The Optimizeinplace function parameters are as follows, and this function is optimized directly on the original mesh. There is also a optimize function that outputs the optimized mesh to the position pointed to by another mesh pointer.
HRESULT Optimizeinplace ( [in] DWORD flags,//parameter, as written in the example [in] const DWORD *padjacencyin,// The pointer to an array of pre-grid adjacency information is optimized [out] DWORD *padjacencyout,//is optimized after the pointer [out] of the grid adjacency information array [out] DWORD *pfaceremap,<//null can be [out] Lpd3dxbuffer *ppvertexremap//null can be);
Three. Mesh class design for the object Long live! Come on, encapsulate a class! Before we draw a mesh we need two functions, a bunch of global variables, this time, we encapsulate it in a class.
Header file:
/*! * \file Mesh.h * * \author puppet_master * \date July 2015 * Grid Model class: Responsible for importing models and drawing models * */ #ifndef __mesh_h_#define __mesh_h_#p Ragma once#include "stdafx.h" Class Cmesh{public:cmesh (Lpdirect3ddevice9 pdevice), ~cmesh (void);//Create Mesh object void Createmesh (LPSTR filename);//Draw Mesh object void DrawMesh (const d3dxmatrixa16& matworld);p Rivate:lpdirect3ddevice9 m_ pdevice; D3D device pointer lpd3dxmesh m_pmesh;//mesh object lpdirect3dtexture9* m_ptextures;//mesh texture Information d3dmaterial9* m_pmaterials;// Grid material information DWORD m_dwnummtrls;//mesh material number}; #endif//!__mesh_h_
CPP file:
#include "stdafx.h" #include "Mesh.h" Cmesh::cmesh (Lpdirect3ddevice9 pdevice): M_pdevice (pdevice) {}cmesh::~cmesh ( void) {//Releases related resources Safe_delete_array (m_pmaterials); if (m_ptextures) {for (int i = 0; i < M_dwnummtrls; i++) {safe_release (M _ptextures[i]);} Safe_delete_array (m_ptextures);} Safe_release (M_pmesh);} void Cmesh::createmesh (LPSTR filename) {lpd3dxbuffer padjbuffer = NULL; Lpd3dxbuffer pmtrlbuffer = NULL;D3DXLOADMESHFROMX (filename, d3dxmesh_managed, M_pdevice, &padjbuffer, & Pmtrlbuffer, NULL, &m_dwnummtrls, &m_pmesh);//read material and texture data d3dxmaterial *pmtrl = (d3dxmaterial*) pmtrlbuffer-> GetBufferPointer (); m_pmaterials = new d3dmaterial9[m_dwnummtrls];m_ptextures = new Lpdirect3dtexture9[m_dwnummtrls]; for (int i = 0; i < M_dwnummtrls; i++) {m_pmaterials[i] = Pmtrl[i]. Matd3d;m_pmaterials[i]. Ambient = M_pmaterials[i]. Diffuse;m_ptextures[i] = Null;d3dxcreatetexturefromfilea (M_pdevice, Pmtrl[i].ptexturefilename, &m_pTextures[i] );} Optimized mesh model M_pmesh->optimizeinplace (D3dxmeshopt_coMPACT | D3dxmeshopt_attrsort| D3dxmeshopt_stripreorder, (dword*) padjbuffer->getbufferpointer (), NULL, NULL, NULL); Safe_release (Padjbuffer); Safe_release (Pmtrlbuffer);} void Cmesh::D rawmesh (const d3dxmatrixa16& matworld) {m_pdevice->settransform (D3dts_world, &matWorld); m_ Pdevice->setrenderstate (d3drs_lighting, false); for (int i = 0; i < M_dwnummtrls; i++) {m_pdevice->setmaterial (& Amp;m_pmaterials[i]); m_pdevice->settexture (0, m_ptextures[i]); M_pmesh->drawsubset (i);}}
Four. Practical use here only the code for the main function file is posted:
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 3lpdirect3dtexture9 g_pgroundtexture = null;//ground Texture D3dxmatrix g_matworld;//World Matrix//------------drawing drawings Step 1. Define flexible vertex formats # D3dfvf_customvertex (d3dfvf_xyz| D3DFVF_TEX1)//coordinates are transformed screen coordinates, vertex color//------------drawing Graphics Step 2. Based on the vertex format defined above, create a struct of a vertex struct stvertex{float _x, _y, _z;//position coordinate float _u, _v;/ /texture coordinate Stvertex (float x, float y, float z, float u, float v): _x (x), _y (y), _z (z), _u (U), _v (v) {}stvertex () {}};//---------- Drawing a drawing step 3. Declare a vertex buffer pointer & an index buffer pointer lpdirect3dvertexbuffer9 G_PVB = NULL; Lpdirect3dindexbuffer9 G_PIB = null;void oncreatd3d () {g_pd3d = Direct3dcreate9 (d3d_sdk_version); if (!g_pD3D) return;// Method of detecting the capability of hardware equipment/*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;//swap the original buffer data discarded//whether to turn on automatic depth template buffer d3dpp. EnableAutoDepthStencil = true;//The current automatic depth template 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, true);//Set render state, turn off light g_pdevice->setrenderstate (D3drs _lighting, false);//Set render state, cropping mode g_pdevice->setrenderstate (D3drs_cullmode, D3dcull_none);//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 ");} void Createcamera () {G_pcamera = new Ccamera (g_pdevice); G_pcamera->setcameraposition (&d3dxvector3 (0.0f, 0.0f, -500.0f)); G_pcamera->settargetposition (&d3dxvector3 (0.0f, 0.0f, 0.0f)); G_PCAMERA-> Setviewmatrix (); G_pcamera->setprojectionmartix ();} 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 of the right vector and the rotation of the upper vector//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);//Save the correct world transformation matrix to G_ Matworld d3dxmatrixtranslation (&g_matworld, 0.0f, 0.0f, Fposz);} 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 emptying the template 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; D3DXMatrixTranslation (&matworld1, 0.0f, 100.0f, 0.0f); D3DXMatrixTranslation (&matworld2, 300.0f, 0.0f, 0.0f);D 3DXMatrixTranslation (&matworld3, 0.0f, 0.0f, 0.0f); g_ Pmesh1->drawmesh (matWorld1); G_pmesh2->drawmesh (matWorld2); G_pmesh3->drawmesh (matWorld3); 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;//Initialization of 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;}
Well, in fact, this is mainly to consolidate the worldtransform, the feeling of learning D3D a short period of time, or did not form a 3D of thinking.
OK, and from the light ink big there stolen resources ...
Dragon Knight Beauty Maiden:
Devils's Stuff:
Camera observation (0,0,0), position at (0, 0,-500), Dragon in (0, 0, 0), that is, the camera observation point, and the initial model at (0, 100, 0), that is, above the dragon, and the Red Monster at (500, 0, 0), that is, on the right side of the dragon.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Direct-X Learning notes-Encapsulating a grid model class