제 14 장 파티클 시스템.

Slides:



Advertisements
Similar presentations
멘토링 2 주차 장 프로그래밍을 위한 자바의 자료형  값이 변하지 않는 상수  메모리 기억공간인 변수.
Advertisements

/11 CUDA 를 이용한 병렬 프로그래밍 DirectX 3D 를 이용한 3D 프로그래밍
프로젝트 보고서 학과 : 임학과 학번 : 성명 : 조성환 Windows 프로그래밍.
명품 JAVA Programming 제 3 장 반복문, 배열, 예외처리.
제 3 장 변수와 자료형.
명품 C++ 프로그래밍 3장. 클래스와 객체.
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
2장 렌더링 파이프라인 목표 Direct3D에서 3D 물체를 표현하는 방법을 배운다. 가상카메라를 모델링하는 방법을 배운다.
2장 닷넷 프레임워크.
C++ Espresso 제1장 기초 사항.
IntArray[0] int length 5 intArray 객체 제 3 장 반복문, 배열, 예외처리.
Internet Computing KUT Youn-Hee Han
제12장 유연한 카메라 클래스 만들기 학기 컴퓨터게임(DirectX).
제13장 기본적인 지형 렌더링 학기 컴퓨터게임(DirectX).
실전 프로젝트 2 : 숫자야구 숫자 야구를 구현해보자.
시스템 생명 주기(System Life Cycle)(1/2)
알고리즘(Algorithm)  알고리즘 개요 (효율, 분석, 차수) Part 1 강원대학교 컴퓨터과학전공 문양세.
제6장 객체배열과 벡터 객체 배열을 이해한다. 벡터(vector) 클래스를 사용할 수 있다.
5장. 리스트 리스트 학습목표 목록이나 도표처럼 여러 데이터를 관리할 수 있는 자료형을 추상화
Chapter 02 자바 기본구조 자바 프로그래밍의 기초적인 문법을 소개
8. 객체와 클래스 (기본).
Internet Computing KUT Youn-Hee Han
4장: 자료형과 수식.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
시스템 생명 주기(System Life Cycle)(1/2)
명품 C++ 8장 상속.
Choi, Namseok Java 기초 (Java의 제어문과 배열) Choi, Namseok
연산자 대입 연산자 산술 연산자 관계 연산자 논리 연산자 비트 연산자 콤마 연산자 축약 연산자 sizeof 연산자
제 15 장 픽킹.
문 성 원 3D Game Programming QuadTree Culling 문 성 원 KoreaIT 전문학교 게임학과.
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 03. 클래스의 기본.
명품 Java Programming.
7장 클래스.
제6장 텍스처링 학기 컴퓨터게임(DirectX).
제8장 스텐실.
12장 유연한 카메라 클래스 만들기 한성대학교 멀티미디어공학과 게임 프로그래밍-I 강의노트
제 18 장 픽셀 셰이더의 소개.
Chapter 05. 클래스 완성. chapter 05. 클래스 완성 01. 복사 생성자 복사 생성(Copy Construction) 생성될 때 자신과 같은 타입의 객체를 변수로 받아, 이 객체와 같은 값을 갖는 새로운 객체를 생성하는 것 명시적인 생성 과정뿐만.
DataScience Lab. 박사과정 김희찬 (월)
C ++ 프로그래밍 시작.
정적 멤버 변수/정적 멤버 함수 - friend 함수/클래스 template
제4장 컬 러(COLOR) 컬러 표현 Direct3D는 RGB 세 성분을 이용해 컬러 표현
제5장 조명 학기 컴퓨터게임(DIrectX).
주소록 프로그램.
프로그래밍2 및 실습 C언어 기반의 C++ 2.
스택(Stack) 김진수
제 4주 2014년 1학기 강원대학교 컴퓨터학부 담당교수: 정충교
4주차: Data Types and Functions
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
Chapter 3 클래스. 최호성.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
03. 안드로이드를 위한 Java 문법 제목. 03. 안드로이드를 위한 Java 문법 제목.
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
Terrain.
제2장 제어구조와 배열 if-else 문에 대하여 학습한다. 중첩 if-else 문에 대하여 학습한다.
제 2장 어휘구조와 자료형 토 큰 리 터 럴 주 석 자 료 형 배 열 형.
알고리즘(Algorithm)  알고리즘 개요 (효율, 분석, 차수) Part 년 봄학기
[CPA340] Algorithms and Practice Youn-Hee Han
DirectX 9을 이용한 게임 개발 기본 코스 강의 내용 : blending.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
3장. 클래스의 기본.
제8장 포인터와 동적객체 생성 포인터의 개념을 이해한다. 포인터와 관련된 연산을 이해한다.
Java 3장. 자바의 기본 구조 I : 변수, 자료형, 연산자 public class SumTest {
제 11장. 템플릿과 STL 학기 프로그래밍언어및실습 (C++).
자바 5.0 프로그래밍.
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
컴퓨터 프로그래밍 기초 - 11th : 파일 입출력 및 구조체 -
실습과제 1번 /* 1. 멤버 변수로 반경 radius를 갖고, 그 값을 모니터에 출력하는
DirectX 9 Ch1. Direct3D 초기화.
어서와 C언어는 처음이지 제22장.
Presentation transcript:

제 14 장 파티클 시스템

파티클 시스템 목 표 파티클에 부여할 수 있는 속성들에 대해 배우고 Direct3D 에서 파티클을 표현하는 방법을 확인 목 표 파티클에 부여할 수 있는 속성들에 대해 배우고 Direct3D 에서 파티클을 표현하는 방법을 확인 범용적 이용 가능한 속성과 메서드를 포함하는 유연한 파티클 시스템 기반 클래스 디자인 세 가지의 전형적인 파티클 시스템인 눈, 폭발, 입자총 구현 2010-1학기 컴퓨터게임(DirectX)

파티클과 포인트 스프라이트 파티클은 매우 작은 물체이며 일반적으로 하나의 포인트로 모델링됨 포인트 기본형: D3DPRIMITIVETYPE의 D3DPT_POINTLIST 포인트스프라이트: 포인트 기본형과는 달리 텍스처 적용이 가능하고 크기를 변경할 수 있고, 하나의 포인트로 표현할 수 있다. 구조체 포맷 파티클의 위치와 컬러를 표현 struct Particle { D3DXVECTOR3 _position; D3DCOLOR _color; static const DWORD FVF; }; const DWORD Particle::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE; 2010-1학기 컴퓨터게임(DirectX)

파티클 구조체는 간단히 파티클의 위치와 컬러만을 저장하지만, 애플리케이션의 필요에 따라 텍스처 좌표 세트를 저장할 수 있음. Particle 구조체에 하나의 부동 소수점 변수를 추가하면 파티클의 크기를 지정할 수 있다. D3DFVF_PSIZE 플래그를 FVF포맷에 추가해야 함 파티클이 각자의 크기를 관리하도록 하면 각각의 파티클의 크기를 직접 바꿀 수 있다. 대부분의 그래픽 카드에서는 파티클의 크기 제어를 지원하지 않으므로 이용을 피하는 것이 좋음 2010-1학기 컴퓨터게임(DirectX)

크기 멤버를 갖춘 버텍스 구조체 struct Particle { D3DXVECTOR3 _position; D3DCOLOR _color; Float _size; static const DWORD FVF; }; const DWORD Particle::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_PSIZE; D3DFVFCAPS_PSIZE가 지원되지 않더라도 버텍스 셰이더를 이용하면 파티클 단위의 크기 제어가 가능 2010-1학기 컴퓨터게임(DirectX)

포인트 스프라이트 렌더 상태 포인트 스프라이트의 동작들은 거의 대부분 렌더 상태에 의해 제어됨 포인트 스프라이트와 관련된 렌더 상태 D3DRS_POINTSPRITEENABLE - 부울값. 디폴트는 false True값은 현재 지정된 전체 텍스처를 포인트 스프라이트 텍스처 매핑에 사용할 것임을 의미 False 값은 포인트 스프라이트의 텍스처 좌표로 지정한 텍셀을 이용해 포인트 스프라이트의 텍스처를 입혀야 하도록 지정 _device->SetRenderState(D3DRS_POINTSPRITEENABLE, true); 2010-1학기 컴퓨터게임(DirectX)

D3DRS_POINTSCALEENABLE - 부울값 True : 포인트 크기를 뷰 스페이스 단위로 해석 지정 False : 포인트 크기를 스크린 스페이스 단위로 해석 지정 _device->SetRenderState(D3DRS_POINTSCALEENABLE, true); D3DRS_POINTSIZE - 포인트 스프라이트 크기 지정 _device->SetRenderState(D3DRS_POINTSIZE, d3d::FtoDw(2.5f)); 2010-1학기 컴퓨터게임(DirectX)

d3d::FtoDw함수는 d3dUtility.h/cpp에 추가한 것 float 을 DWORD로 형 변환한다. DWORD d3d::FtoDw(float f) { return *((DWORD*)&f); } D3DRS_POINTSIZE_MIN : 포인트 스프라이트의 지정할 수 있는 최소 크기 지정 _device->SetRenderState(D3DRS_POINTSIZE_MIN, d3d::FtoDw(0.2f)); 2010-1학기 컴퓨터게임(DirectX)

D3DRS_POINTSIZE_MAX : 포인트 스프라이트의 지정할 수 있는 최대 크기를 지정 _device->SetRenderState(D3DRS_POINTSIZE_MAX, d3d::FtoDw(5.0f)); D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, D3DRS_POINTSCALE_C 이 세 개의 상수는 거리에 따라 포인트 스프라이트의 크기가 변하는 방법을 제어 거리란 카메라와 포인트 스프라이트 간의 거리이다. 2010-1학기 컴퓨터게임(DirectX)

 FinalSize = ViewportHeight · Size · A, B, C : 순서대로 D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, D3DRS_POINTSCALE_C 렌더 상태에 지정된 값 D : 뷰 스페이스 내의 포인트 스프라이트와 카메라 위치와의 거리 뷰 스페이스 내의 (x, y, z)에 포인트 스프라이트가 위치한다면 D = x2 + y2+z2 1 A+B(D)+C(D ) 2  2010-1학기 컴퓨터게임(DirectX)

다음 코드는 포인트 스프라이트가 작아지도록 포인트 스프라이트 거리 상수 값을 지정 _device->SetRenderState(D3DRS_POINTSCALE_A, d3d::FtoDw(0.0f)); _device->SetRenderState(D3DRS_POINTSCALE_B, d3d::FtoDw(0.0f)); _device->SetRenderState(D3DRS_POINTSCALE_C, d3d::FtoDw(1.0f)); 2010-1학기 컴퓨터게임(DirectX)

파티클과 파티클의 속성들 파티클은 위치와 컬러 이외의 상당히 많은 속성들로 이루어짐 예: 속도 등 파티클을 렌더링 하는데 필요한 데이터와 파티클 속성을 별도의 구조체 내에 보관 렌더링할 준비가 완료되면 Particle 구조체로 위치와 속성을 복사해 이용 파티클의 속성은 모델링하려는 파티클 시스템의 종류에 따라 달라진다. 2010-1학기 컴퓨터게임(DirectX)

다음의 구조체 예제는 몇 가지의 공통적인 파티클 속성을 포함 struct Attribute{ D3DXVECTOR3 _position; D3DXVECTOR3 _velocity; D3DXVECTOR3 _acceleration; D3DXVECTOR3 _lifeTime; D3DXVECTOR3 _age; D3DXVECTOR3 _color; D3DXVECTOR3 _colorFade; D3DXVECTOR3 _isAlive; }; 2010-1학기 컴퓨터게임(DirectX)

_position : 월드 스페이스 내의 파티클 위치 _velocity : 파티클의 속도, 초당 이동단위 _acceleration : 파티클의 가속, 초당 이동단위 _lifeTime : 파티클이 소멸될 때까지 유지되는 시간 _age : 파티클 현재 나이 _color : 파티클의 컬러 _colorFade : 파티클의 컬러가 시간의 흐름에 따라 퇴색하는 방법 _isAlive : 파티클이 생존한 경우 True, 소멸 False 2010-1학기 컴퓨터게임(DirectX)

파티클 시스템의 요소들 파티클 시스템 파티클들의 모임 파티클을 보여주고 관리하는 역할을 담당 파티클의 크기, 원천의 위치, 적용할 텍스처 등 시스템 내의 모든 파티클에 영향을 주는 전역 특성 관리 파티클 갱신, 디스플레이, 소멸, 생성 등을 관장 Psystem 클래스 모든 파티클 시스템이 공유하는 공통 특성을 Psystem기반 클래스로 추상화 다른 모든 전형적인 파티클 시스템의 부모로 이용 2010-1학기 컴퓨터게임(DirectX)

Psystem 클래스 class PSystem { public: PSystem(); virtual ~PSystem(); virtual bool init(IDirect3DDevice9* device, char* texFileName); virtual void reset(); virtual void resetParticle(Attribute* attribute) = 0; virtual void addParticle(); virtual void update(float timeDelta) = 0; 2010-1학기 컴퓨터게임(DirectX)

virtual void preRender(); virtual void render(); virtual void postRender(); bool isEmpty(); bool isDead(); protected: virtual void removeDeadParticles(); IDirect3DDevice9* _device; D3DXVECTOR3 _origin; d3d::BoundingBox _boundingBox; 2010-1학기 컴퓨터게임(DirectX)

IDirect3DTexture9* _tex; IDirect3DVertexBuffer9* _vb; float _emitRate; float _size; IDirect3DTexture9* _tex; IDirect3DVertexBuffer9* _vb; std::list<Attribute> _particles; int _maxParticles; DWORD _vbSize; // size of vb DWORD _vbOffset; // offset in vb to lock DWORD _vbBatchSize; // number of vertices to lock starting at _vbOffset }; 2010-1학기 컴퓨터게임(DirectX)

_origin : 시스템의 원천. 시스템 내에서 파티클이 시작되는 곳 데이터 멤버 _origin : 시스템의 원천. 시스템 내에서 파티클이 시작되는 곳 _boundingBox : 파티클이 이동할 수 있는 부피를 제한하는데 이용 _emitRate : 시스템에 새로운 파티클이 추가되는 비율. 초당 파티클 수 _size : 시스템 내 모든 파티클의 크기 _particles : 시스템 내 파티클 속성의 리스트. 파티클을 만들고 제거하고 갱신하는데 이용. 2010-1학기 컴퓨터게임(DirectX)

_maxParticles : 주어진 시간 동안 시스템이 가질 수 있는 최대 파티클의 수 _vbSize : 버텍스 버퍼가 보관할 수 있는 파티클의 수 _vbOffset, _vbBatchSize: 파티클시스템의 렌더링에 이용 메서드 Psystem / ~PSystem. : 디폴트 값을 초기화하는 생성자와 장치 인터페이스(버텍스버퍼, 텍스처) 해제 소멸자 Init : 이 메서드는 포인트 스프라이트를 저장하기 위한 버텍스를 만들고 텍스처를 만드는 등의 장치 의존적인 초기화 작업 처리 2010-1학기 컴퓨터게임(DirectX)

hr = device->CreateVertexBuffer( _vbSize * sizeof(Particle), D3DUSAGE_DYNAMIC | D3DUSAGE_POINTS | D3DUSAGE_WRITEONLY, Particle::FVF, D3DPOOL_DEFAULT, &_vb, 0); 동적 버텍스 버퍼를 이용. 매 프레임 마다 파티클을 갱신하며 이 때 버텍스 버퍼 메모리에 접근 버텍스 버퍼가 포인트 스프라이트를 보관할 것임을 지정하는 D3DUSAGE_POINTS 이용 2010-1학기 컴퓨터게임(DirectX)

동적 버텍스 버퍼는 관리 메모리 풀에 보관할 수 없으므로 일반적인 관리 메모리 풀 대신에 디폴트 메모리 풀을 이용 버텍스 크기가 _vbSize에 의해 미리 정의되며 시스템 내의 파티클 수와는 관련이 없음을 주의. _vbSize 가 시스템 내 파티클의 수와 같은 경우는 거의 없음. 동적 버텍스 버퍼는 관리 메모리 풀에 보관할 수 없으므로 일반적인 관리 메모리 풀 대신에 디폴트 메모리 풀을 이용 2010-1학기 컴퓨터게임(DirectX)

reset : 이 메서드는 시스템 내의 모든 파티클 속성을 리셋 void PSystem::reset(){ std::list<Attribute>::iterator i; for(i = _particles.begin(); i != _particles.end(); i++) { resetParticle( &(*i) ); } 2010-1학기 컴퓨터게임(DirectX)

resetParticle : 한 파티클의 속성을 리셋 addParticle : 시스템에 파티클을 추가 void PSystem::addParticle(){ Attribute attribute; resetParticle(&attribute); _particles.push_back(attribute); } update : 시스템 내의 모든 파티클들을 갱신 render : 시스템 내의 모든 파티클들을 렌더링 2010-1학기 컴퓨터게임(DirectX)

preRender : 렌더링에 앞서 지정해야 할 초기 렌더 상태를 지정 void PSystem::preRender() { _device->SetRenderState(D3DRS_LIGHTING, false); _device->SetRenderState(D3DRS_POINTSPRITEENABLE, true); _device->SetRenderState(D3DRS_POINTSCALEENABLE, true); _device->SetRenderState(D3DRS_POINTSIZE, d3d::FtoDw(_size)); _device->SetRenderState(D3DRS_POINTSIZE_MIN, d3d::FtoDw(0.0f)); _device->SetRenderState(D3DRS_POINTSCALE_A, d3d::FtoDw(0.0f)); _device->SetRenderState(D3DRS_POINTSCALE_B, d3d::FtoDw(0.0f)); _device->SetRenderState(D3DRS_POINTSCALE_C, d3d::FtoDw(1.0f)); 2010-1학기 컴퓨터게임(DirectX)

_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); _device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); _device->SetRenderState(D3DRS_ALPHABLENDENABLE, true); _device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); _device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); } 2010-1학기 컴퓨터게임(DirectX)

알파 블렌딩을 활성화 하여 텍스처의 알파 채널이 텍스처의 픽셀 투명도를 결정하도록 했음을 확인 눈덩이와 비슷한 둥근 파티클을 얻기 위해서는 흰색의 원형과 검은색의 알파 채널을 갖는 흰색 택스처를 이용하면 된다. 2010-1학기 컴퓨터게임(DirectX)

postRender : 특정 파티클 시스템이 지정했을 수 있는 렌더 상태를 복구하는데 이용 void PSystem::postRender(){ _device->SetRenderState(D3DRS_LIGHTING, true); _device->SetRenderState(D3DRS_POINTSPRITEENABLE, false); _device->SetRenderState(D3DRS_POINTSCALEENABLE, false); _device->SetRenderState(D3DRS_ALPHABLENDENABLE, false); } 2010-1학기 컴퓨터게임(DirectX)

isEmpty : 현재 시스템에 파티클이 없는 경우 True isDead : 시스템 내 파티클이 모두 죽은 경우 True 2010-1학기 컴퓨터게임(DirectX)

removeDeadParticles : _particle검색 후 죽은 파티클을 리스트에서 제거 void PSystem::removeDeadParticles(){ std::list<Attribute>::iterator i; i = _particles.begin(); while( i != _particles.end() ) { if( i->_isAlive == false ){ i = _particles.erase(i); } else { i++; // next in list 2010-1학기 컴퓨터게임(DirectX)

파티클 시스템의 드로잉 파티클 시스템은 동적이기 때문에 매 프레임마다 시스템의 파티클을 갱신해야 함 파티클 시스템의 렌더링 방식 예 (1) 최대 수의 파티클을 보관할 수 있는 버텍스 버퍼 생성 각 프레임에 다음과 같은 작업 수행 1. 모든 파티클을 갱신 2. 모든 살아있는 파티클들을 버텍스 버퍼로 복사 3. 버텍스 버퍼를 그린다. 효율적이지 못하다: 버텍스 버퍼가 시스템 내의 모든 파티클을 포함할 수 있는 크기를 가져야 하고 리스트에서 버텍스버퍼로 모든 파티클을 복사하는 동안 그래픽카드가 아무일로 하지 않음. 2010-1학기 컴퓨터게임(DirectX)

적당한 크기의 버텍스 버퍼를 만들고, 이를 세그먼트로 나눈다.(예 : 세그먼트 500 지정) 파티클 시스템의 렌더링 방식 예 (2) 적당한 크기의 버텍스 버퍼를 만들고, 이를 세그먼트로 나눈다.(예 : 세그먼트 500 지정) 현재 위치의 세그먼트를 표시하기 위한 전역 변수 i = 0 을 만든다. 각 프레임에 다음과 같은 작업을 수행한다. 세그먼트 0:500 파티클 용량 세그먼트 1:500 파티클 용량 세그먼트 2:500 파티클 용량 세그먼트 3:500 파티클 용량 버텍스 버퍼 : 2000 파티클 용량 2010-1학기 컴퓨터게임(DirectX)

D3DLOCK_NOOVER-WRITE 플래그로 세그먼트 i를 잠근다. 세그먼트 i로 500 파티클을 복사한다. 1. 모든 파티클을 갱신 D3DLOCK_NOOVER-WRITE 플래그로 세그먼트 i를 잠근다. 세그먼트 i로 500 파티클을 복사한다. 2. 만약 버텍스 버퍼가 가득 찼다면 버텍스 버퍼의 처음부터 시작한다. i = 0 D3DLOCK_DISCARD 플래그로 세그먼트 i 잠근다. 세그먼트 i 로 500 파티클을 복사. 3. 세그먼트 i를 렌더링 한다. 4. 다음 세그먼트로 : i++ 2010-1학기 컴퓨터게임(DirectX)

버텍스 버퍼의 일부가 렌더링 될 때 렌더링되지 않는 일부 버퍼를 잠글 수 있게하여 렌더링 지연을 막을 수 있다. 이 방식이 높은 효율을 가짐 필요한 버텍스 버퍼의 크기를 줄일 수 있으며 CPU와 그래픽 카드가 함께 작업할 수 있다. 버텍스 버퍼의 일부가 렌더링 될 때 렌더링되지 않는 일부 버퍼를 잠글 수 있게하여 렌더링 지연을 막을 수 있다. CPU와 그래픽카드가 함께 작업할 수 있다. 렌더링 구현을 위해 다음 데이터멤버 사용 _vbSize : 버텍스 버퍼가 한번에 보관할 수 있는 파티클의 수 _vbOffset : 버텍스 버퍼에서 복사를 시작할 파티클 내 다음 단계로의 오프셋. 바이트가 아닌 파티클 단위. _vbBatchSize : 하나의 단계에 정의된 파티클 수 2010-1학기 컴퓨터게임(DirectX)

렌더링 메서드의 코드 void PSystem::render() { if( !_particles.empty() ) { preRender(); _device->SetTexture(0, _tex); _device->SetFVF(Particle::FVF); _device->SetStreamSource(0, _vb, 0, sizeof(Particle)); if(_vbOffset >= _vbSize) _vbOffset = 0; Particle* v = 0; _vb->Lock( _vbOffset * sizeof( Particle ), _vbBatchSize * sizeof( Particle ), (void**)&v,_vbOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD); 2010-1학기 컴퓨터게임(DirectX)

DWORD numParticlesInBatch = 0; std::list<Attribute>::iterator i; for(i = _particles.begin(); i != _particles.end(); i++) { if( i->_isAlive ) { v->_position = i->_position; v->_color = (D3DCOLOR)i->_color; v++; numParticlesInBatch++; //단체 카운터 증가 //현재 단계가 모두 채워졌는가 if(numParticlesInBatch == _vbBatchSize) // 단계가 그려지는 동안 다음 단계를 // 파티클로 채운다. _vb->Unlock(); 2010-1학기 컴퓨터게임(DirectX)

_device->DrawPrimitive( D3DPT_POINTLIST, _vbOffset, _vbBatchSize); if(_vbOffset >= _vbSize) _vbOffset = 0; _vb->Lock( _vbOffset * sizeof( Particle ), _vbBatchSize * sizeof( Particle ), (void**)&v, _vbOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD); numParticlesInBatch = 0; } 2010-1학기 컴퓨터게임(DirectX)

if( numParticlesInBatch ) { _device->DrawPrimitive( _vb->Unlock(); if( numParticlesInBatch ) { _device->DrawPrimitive( D3DPT_POINTLIST, _vbOffset, numParticlesInBatch); } _vbOffset += _vbBatchSize; postRender(); 2010-1학기 컴퓨터게임(DirectX)

무작위성 시스템의 파티클에는 무작위성이 필요하다. 예 : 눈의 크기, 속도 등 무작위성을 지원하기 위해 d3dUtility.h/cpp 파일에 다음과 같은 두 개의 함수 추가. Float d3d::GetRandomFloat(); [lowBound, highBound] 범위의 임의의 float 리턴 GetRandomVector() 최소점 min, 최대점 max로 정의된 상자 내의 임의 벡터 출력 2010-1학기 컴퓨터게임(DirectX)

float d3d::GetRandomFloat(float lowBound, float highBound) { if( lowBound >= highBound ) // 잘못된 입력 return lowBound; // [0,1]범위의 임의의 float을 얻는다. float f = (rand() % 10000) * 0.0001f; // [lowBound, highBound] 범위의 float을 리턴 return (f * (highBound - lowBound)) + lowBound; } 2010-1학기 컴퓨터게임(DirectX)

void d3d::GetRandomVector( D3DXVECTOR3* out, D3DXVECTOR3* min, D3DXVECTOR3* max) { out->x = GetRandomFloat(min->x, max->x); out->y = GetRandomFloat(min->y, max->y); out->z = GetRandomFloat(min->z, max->z); } 2010-1학기 컴퓨터게임(DirectX)

전형적인 파티클 시스템 눈, 불꽃놀이, 입자 총을 구현하는 과정 눈 시스템: 내리는 눈송이를 모델링 불꽃놀이 시스템: 불꽃놀이와 비슷한 폭발 현상 모델링 입자총 시스템: 사용자 키 입력에 따라 카메라가 바라보는 방향으로 발사되는 입자 총탄 모델링 2010-1학기 컴퓨터게임(DirectX)

예제 : 눈 눈의 클래스 class Snow : public PSystem. { public : snow(d3d::boundingBox* boundingBox, int numParticles); void resetParticle(Attribute* attribute); void update(float timeDelta); }; 2010-1학기 컴퓨터게임(DirectX)

생성자는 경계 상자 구조체를 가리키는 포인터와 시스템 내 파티클의 수를 받는다. 경계상자는 눈송이가 떨어질 부피를 정의 Snow::Snow(d3d::BoundingBox* boundingBox, int numParticles){ _boundingBox = *boundingBox; _size = 0.25f; _vbSize = 2048; _vbOffset = 0; _vbBatchSize = 512; for(int i = 0; i < numParticles; i++) addParticle(); } 2010-1학기 컴퓨터게임(DirectX)

resetParticle은 경계 상자 내 임의의 x와 y좌표 위치에서 눈송이를 만들고, 눈송이에 속도를 부여하여 아래방향으로 약간 왼쪽으로 떨어지게 함 void Snow::resetParticle(Attribute* attribute){ attribute->_isAlive = true; // 눈송이 위치 지정을 위해 임의의 x, z 좌표를 얻는다. d3d::GetRandomVector( &attribute->_position, &_boundingBox._min, &_boundingBox._max); 2010-1학기 컴퓨터게임(DirectX)

// 높이(y-좌표)는 항상 경계 상자의 최상단이 된다. attribute->_position.y = _boundingBox._max.y; // 눈송이는 아래쪽으로 떨어지며 약간 왼쪽을 향한다. attribute->_velocity.x = d3d::GetRandomFloat(0.0f, 1.0f) * -3.0f; attribute->_velocity.y = d3d::GetRandomFloat(0.0f, 1.0f) * -10.0f; attribute->_velocity.z = 0.0f; attribute->_color = d3d::WHITE; } 2010-1학기 컴퓨터게임(DirectX)

파티클의 위치를 갱신하며 시스템의 경계 상자를 벗어났는지 확인 경계상자를 벗어나면 파티클을 초기화 update 메서드 파티클의 위치를 갱신하며 시스템의 경계 상자를 벗어났는지 확인 경계상자를 벗어나면 파티클을 초기화 void Snow::update(float timeDelta) { std::list<Attribute>::iterator i; for(i = _particles.begin(); i != _particles.end(); i++) i->_position += i->_velocity * timeDelta; if( _boundingBox.isPointInside( i->_position ) == false ) resetParticle( &(*i) ); } 2010-1학기 컴퓨터게임(DirectX)

파티클 시스템: 눈 2010-1학기 컴퓨터게임(DirectX)

불 꽃 놀 이 Firework 시스템의 클래스 class Firework : public PSystem { public: Firework(D3DXVECTOR3* origin, int numParticles); void resetParticle(Attribute* attribute); void update(float timeDelta); void preRender(); void postRender(); }; 2010-1학기 컴퓨터게임(DirectX)

생성자는 시스템 원천(origin)으로의 포인터와 시스템이 가진 파티클의 수를 받는다. 원천이란 불꽃이 폭발할 장소를 의미 resetParticle 메서드 시스템 원천의 파티클을 초기화 구체 내에서 임의의 속도를 만들고 시스템 내의 파티클들은 임의의 컬러를 부여받음 각 파티클들이 2초 동안 유지되도록 수명 지정 2010-1학기 컴퓨터게임(DirectX)

void Firework::resetParticle(Attribute* attribute){ attribute->_isAlive = true; attribute->_position = _origin; D3DXVECTOR3 min = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); D3DXVECTOR3 max = D3DXVECTOR3( 1.0f, 1.0f, 1.0f); d3d::GetRandomVector( &attribute->_velocity, &min, &max); D3DXVec3Normalize( &attribute->_velocity); 2010-1학기 컴퓨터게임(DirectX)

attribute->_velocity *= 100.0f; attribute->_color = D3DXCOLOR( d3d::GetRandomFloat(0.0f, 1.0f), 1.0f); attribute->_age = 0.0f; attribute->_lifeTime = 2.0f; // lives for 2 seconds } 2010-1학기 컴퓨터게임(DirectX)

void Firework::update(float timeDelta){ 각 파티클의 위치를 갱신 수명을 초과한 파티클의 죽음을 처리. 죽은 파티클을 제거하지 않고 재활용 void Firework::update(float timeDelta){ std::list<Attribute>::iterator i; for(i = _particles.begin(); i != _particles.end(); i++) { // only update living particles if( i->_isAlive ) 2010-1학기 컴퓨터게임(DirectX)

i->_position += i->_velocity * timeDelta; i->_age += timeDelta; if(i->_age > i->_lifeTime) // kill i->_isAlive = false; } 2010-1학기 컴퓨터게임(DirectX)

Firework 렌더링에는 다른 블렌드 인수가 이용되며 깊이 버퍼로의 쓰기도 허용 안됨 블렌드 인수와 쓰기 변경을 위해 PSystem::preRender, Psystem::postRender 메서드 오버라이드 오버라이드 된 예 void Firework::preRender(){ PSystem::preRender(); _device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); _device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); 2010-1학기 컴퓨터게임(DirectX)

// z-버퍼 읽기는 가능하지만 쓰기는 허용하지 않음 _device->SetRenderState(D3DRS_ZWRITEENABLE, false); } void Firework::postRender() { PSystem::postRender(); _device->SetRenderState(D3DRS_ZWRITEENABLE, true); 두 메서드 모두 부모 버전의 메서드를 호출 => 재사용 2010-1학기 컴퓨터게임(DirectX)

파티클 시스템: 불꽃놀이 2010-1학기 컴퓨터게임(DirectX)

입 자 총 Particle Gun 클래스 class ParticleGun : public PSystem { public: ParticleGun(Camera* camera); void resetParticle(Attribute* attribute); void update(float timeDelta); private: Camera* _camera; }; 2010-1학기 컴퓨터게임(DirectX)

새로운 파티클을 만들 때마다 카메라의 위치와 방향에 대한 정보가 필요하기 때문 생성자는 카메라로의 포인터를 받는다. 새로운 파티클을 만들 때마다 카메라의 위치와 방향에 대한 정보가 필요하기 때문 resetParticle 메서드 파티클의 위치를 카메라의 현재 위치로 지정 파티클의 속도를 카메라가 바라보고 있는 방향의 100배로 지정 2010-1학기 컴퓨터게임(DirectX)

void ParticleGun::resetParticle(Attribute* attribute){ attribute->_isAlive = true; D3DXVECTOR3 cameraPos; _camera->getPosition(&cameraPos); D3DXVECTOR3 cameraDir; _camera->getLook(&cameraDir); attribute->_position = cameraPos; attribute->_position.y -= 1.0f; attribute->_velocity = cameraDir * 100.0f; attribute->_color = D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f); attribute->_age = 0.0f; attribute->_lifeTime = 1.0f; // lives for 1 seconds } 2010-1학기 컴퓨터게임(DirectX)

void ParticleGun::update(float timeDelta){ 파티클의 위치를 갱신 수명이 다한 경우 죽은 것으로 처리 파티클 리스트를 검색하여 죽은 파티클 제거 void ParticleGun::update(float timeDelta){ std::list<Attribute>::iterator i; for(i = _particles.begin(); i != _particles.end(); i++) { i->_position += i->_velocity * timeDelta; i->_age += timeDelta; 2010-1학기 컴퓨터게임(DirectX)

if(i->_age > i->_lifeTime) // kill i->_isAlive = false; } removeDeadParticles(); 2010-1학기 컴퓨터게임(DirectX)

파티클 시스템: 입자총 2010-1학기 컴퓨터게임(DirectX)