Direct-X study notes--three-dimensional particle system

Source: Internet
Author: User

Wow, a blink of an eye has come to the legend of the particle system, learned the particle system can make some better play effect! Come on!


I. INTRODUCTION

The particle system, as its name, consists of a variety of small particles. Usually used to simulate a flame, explosion, smoke, water, sparks, leaves, rain, snow, etc. difficult to describe the specific shape of the object. Individual particles are very simple and can be represented by polygons, even in pixels. However, do not underestimate such tiny particles, when the number of particles to reach thousands, tens of thousands, or even 100,000, expressive force is its shock!

The following is attached to two DX-band particle Systems:


Handsome ... But I can't do it ...


The particle system has three properties:

1. Group: Particles so small, in order to become a climate, we must gather together.

2. Uniformity: Each particle is of the same nature.

3. Randomness: Elements in a particle system exhibit different characteristics randomly.

The simple generalization is that the whole has a consistent performance, but the individual particles can behave differently.


The fundamental principle of particle systems is the life cycle of particle systems:

1. Create new particles

2. Update the properties of existing particles

3. Delete the extinct particles

4. Drawing particles


Usually one-time allocation of sufficient space, through the data structure to manage the presence of particles and the extinction of particles, if the particles die, do not display.

Two. Package a class of particle systems according to the way of light ink, a snowflake-falling particle system is written:
. h file

/*! * \file Particle.h * * \author puppet_master * \date August 2015 * * particle SYSTEM implementation */#ifndef __cparticle_h_#define __cparticle_h_#in Clude "stdafx.h" #pragma once//particle fixed-point format struct pointvertex{float x, y, z;float u, v;}; #define D3DFVF_POINTVERTEX (d3dfvf_xyz | D3DFVF_TEX1)//particle structure definition struct particlestruct{float x, y, z;//coordinate float rotationx;//around x axis rotation angle float rotationy;//rotation angle around Y axis float speed;//falling speed float rotationspeed;//rotational speed};const int particle_number = 3000;//particle number const int area_width = 10000;// Particle system Area Width const int area_length = 10000;//particle system Area Length const int area_height = 10000;//Particle system Area Height class Cparticle{private: Lpdirect3ddevice9 m_pdevice;//device pointer particlestruct m_particle[particle_number];//particle structure body array Lpdirect3dvertexbuffer9 m_ pvertexbuffer;//vertex buffer lpdirect3dtexture9 m_ptexture;//particle texture public:cparticle (lpdirect3ddevice9); Virtual ~CParticle ( void);//Initialize particle system bool Initparticle ();//update particle bool updateparticle (float);//Draw particle bool renderparticle ();}; #endif


. cpp Files

#include "stdafx.h" #include "Particle.h" #include <time.h>cparticle::cparticle (Lpdirect3ddevice9 pdevice) {m_ pdevice = Pdevice;m_pvertexbuffer = Null;m_ptexture = NULL;} Cparticle::~cparticle (void) {safe_release (m_pvertexbuffer); Safe_release (m_ptexture);} BOOL Cparticle::initparticle () {Srand ((unsigned int) time (0));//Initialize snowflake particle array for (int i = 0; i < Particle_number; i++) {m_ particle[i].x = rand ()% AREA_LENGTH-AREA_LENGTH/2;M_PARTICLE[I].Y = rand ()% AREA_HEIGHT;M_PARTICLE[I].Z = rand ()% A Rea_width-area_width/2;m_particle[i].speed = + rand ()% 500;m_particle[i].rotationspeed = 5.0f + rand ()% 10/10. 0f;} Create snowflake particle vertex Cache m_pdevice->createvertexbuffer (4 * sizeof (POINTVERTEX), 0, D3dfvf_pointvertex, d3dpool_managed, &m _pvertexbuffer, NULL);//fill vertex cache Pointvertex vertices[] = { -10.0f, 0.0f, 0.0f, 0.0f, 1.0f},{-10.0f, 20.0f, 0.0f, 0.0f, 0.0f} , {10.0f, 0.0f, 0.0f, 1.0f, 1.0f},{10.0f, 20.0f, 0.0f, 1.0f, 0.0f}};//locking void* pvertices;m_pvertexbuffer->lock (0, Sizeo f (vertices), (void* *) &pvertices, 0),//copy vertex data memcpy (pvertices, vertices, sizeof (vertices));//unlock M_pvertexbuffer->unlock ();// Load Texture D3DXCreateTextureFromFile (m_pdevice, "snow.jpg", &m_ptexture); return true;} BOOL Cparticle::updateparticle (float felapsedtime) {for (int i = 0; i < Particle_number; i++) {m_particle[i].y-= M_parti Cle[i].speed * FELAPSEDTIME;IF (m_particle[i].y < 0) M_particle[i].y = Area_height;m_particle[i].rotationx + = m_ Particle[i].rotationspeed * Felapsedtime;m_particle[i].rotationy + = M_particle[i].rotationspeed * fElapsedTime;} return true;} BOOL Cparticle::renderparticle () {//disable illumination M_pdevice->setrenderstate (d3drs_lighting, false);//Set Texture m_pdevice-> SetTextureStageState (0, D3dtss_colorop, d3dtop_selectarg1); m_pdevice->settexturestagestate (0, D3DTSS_COLORARG1 , d3dta_texture); m_pdevice->setsamplerstate (0, D3dsamp_minfilter, d3dtexf_linear);m_pdevice-> Setsamplerstate (0, D3dsamp_magfilter, d3dtexf_linear);//Set Alpha Blend factor m_pdevice->setrenderstate (D3drs_ Alphablendenable, True);//Open Alpha blend m_pdevice->setrenderstate (d3drs_srcblend, d3dblend_one);//source mixing factor is 1m_pdevice->setrenderstate ( D3drs_destblend, D3dblend_one);//The Target mixing factor is 1//set without rejecting the back m_pdevice->setrenderstate (D3drs_cullmode, d3dcull_none);// Render for (int i = 0; i < Particle_number; i++) {//Set the world matrix (this is set to a local static variable, similar to a global variable, but is easier to maintain than a global variable, scoped only for that function) static D3dxmatrix Mattrans, Matyaw, Matpitch, Matworld;d3dxmatrixrotationx (&matpitch, M_particle[i].rotationx);D 3DXMatrixRotationY (&matyaw, M_particle[i].rotationy);D 3DXMatrixTranslation (&mattrans, m_particle[i].x, m_ PARTICLE[I].Y, m_particle[i].z); matworld = Matpitch * Matyaw * Mattrans;m_pdevice->settransform (D3DTS_WORLD, & Matworld);//Set texture m_pdevice->settexture (0, m_ptexture);//Draw related M_pdevice->setstreamsource (0, M_pvertexbuffer, 0 , sizeof (Pointvertex)); M_PDEVICE-&GT;SETFVF (D3dfvf_pointvertex); M_pdevice->drawprimitive (D3DPT_TRIANGLESTRIP , 0, 2);} Restore the original state after drawing is complete: alpha blending, back culling, illumination, preventing rendering state leaks, affecting other object drawing m_pdevice->setrenderstate (D3drs_alphablendenable, FAlse); M_pdevice->setrenderstate (D3drs_cullmode, D3DCULL_CCW); M_pdevice->setrenderstate (D3DRS_LIGHTING, true); return true;}



Three. Using the particle system

Run a bit:


A different angle:


Increase the amount of particles:


Enclose the main function code:

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 "#include" SkyBox.h "#include" Particle.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//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 cskybox* G_pskybox = null;//Sky Box class pointer cparticle* g_pparticle = null;//Particle system pointer cmesh* g_pmesh1 = null;//Mesh object pointer 1cmesh* g_pmesh2 = null;//Mesh object pointer 2cmesh* g_ PMESH3 = null;//Mesh object pointer 3d3dxmatrix g_matworld;//World matrix VoiD Oncreatd3d () {g_pd3d = Direct3dcreate9 (d3d_sdk_version), if (!G_PD3D) return;//method for detecting hardware device capability/*D3DCAPS9 caps; ZeroMemory (&caps, sizeof (caps)); G_pd3d->getdevicecaps (D3dadapter_default, D3ddevtype_hal, &caps); */// Get relevant information, screen size, pixel attributes D3ddisplaymode D3DDM; ZeroMemory (&AMP;D3DDM, sizeof (D3DDM)); G_pd3d->getadapterdisplaymode (D3dadapter_default, &AMP;D3DDM);// Set full-screen mode d3dpresent_parameters D3DPP; ZeroMemory (&AMP;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 template buffering d3dpp is turned on. 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, &AMP;D3DPP, &g_pdevice); if (!g_pDevice) return;// Set the render state, set the Enable depth value G_pdevice->setrenderState (d3drs_zenable, true);//Set render status, 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 ("demon.x"); g_pmesh2 = new Cmesh (g_pDevice); G_pmesh2->createmesh ("Dragon. X "); g_pmesh3 = new Cmesh (g_pdevice); G_pmesh3->createmesh (" Miki. X ");} void Createcamera () {G_pcamera = new Ccamera (g_pdevice); G_pcamera->setcameraposition (&d3dxvector3 (0.0f, 800.0f, -500.0f)) g_pcamera->settargetposition (&d3dxvector3 (0.0f, 800.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 (100.0f, 5.0f);} void Createskybox () {g_pskybox = new Cskybox (g_pdevice); G_pskybox->initskybox (20000.0f); g_pskybox->initskyboxtexture ("Skyfront.png", "Skyback.png", "Skyleft.png", "Skyright.png", "skytop.png"); void Createparticle () {g_pparticle = new cparticle (g_pdevice); G_pparticle->initparticle ();}  void SetLight () {D3dlight9 light;  :: ZeroMemory (&light, sizeof (light)); Light.  Type = d3dlight_directional; Light.  Ambient = D3dxcolor (0.7f, 0.7f, 0.7f, 1.0f); Light.  Diffuse = D3dxcolor (1.0f, 1.0f, 1.0f, 1.0f); Light.  Specular = D3dxcolor (0.9f, 0.9f, 0.9f, 1.0f); Light.  Direction = D3dxvector3 (1.0f, 1.0f, 1.0f);  G_pdevice->setlight (0, &light);  G_pdevice->lightenable (0, true);  G_pdevice->setrenderstate (D3drs_normalizenormals, true); G_pdevice->setrenderstate (d3drs_specularenable, True);} void OnInit () {//Initialize D3DONCREATD3D ();//Create Mesh model Createmesh ();//Create Camera Createcamera ();//Create Terrain createterrain ();// Create a Sky Box Createskybox ();//Create Particle system createparticle ();//Set Illumination SetLight ();} void OnDestroy () {safe_delete (g_pdirectinput); Safe_delete (G_pcamera); Safe_delete (G_pterrIan); Safe_delete (G_pskybox); Safe_release (g_pdevice); Safe_delete (G_PMESH1); Safe_delete (G_PMESH2); Safe_delete (G_PMESH3);} 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);// Update particle system g_pparticle->updateparticle (felapsedtime);} 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, Matworldterrain, Matworldsky;  D3DXMatrixTranslation (&matworld1, 0.0f, 800.0f, 0.0f); D3DXMatrixTranslation (&matworld2, 0.0f, 1300.0f, 0.0f);D 3DXMatrixTranslation (&matworld3, -30.0f, 900.0f,- 50.0f);D 3DXMatrixTranslation (&matworldterrain, 0.0f, 0.0f, 0.0f);D 3DXMatrixTranslation (&matworldsky, 0.0f, -2000.0f, 0.0f); G_pmesh1->drawmesh (matWorld1); G_pmesh2->drawmesh (matWorld2); G_pmesh3->drawmesh ( MATWORLD3); G_pskybox->renderskybox (&matworldsky); G_pterrian->renderterrain (&matworldterrain, FALSE); g_pparticle->renderparticle (); 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;//Initialize 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;}



Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Direct-X study notes--three-dimensional particle system

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.