반응형

down link :  NormalMapGenerator






http://goo.gl/bdQfP




올리기올려짐: 2004-09-16 06:33    주제: 높이맵이 문제네요....

lachesis님의 조언대로 NormalMapGenerator라는 노말맵 생성 프로그램의 소스를 분석해 노말맵 생성프로그램을 구현 해보았습니다.(코드량 정말 쪼끔) 
그런데 문제는 그 소벨필터링은 일반적인 칼라이미지가 아닌 높이맵을 읽어서 노말맵을 생성한다는 것입니다. 일단은 GPG2의 부록 CD에 있는 높이맵을 가지고 테스트 해봤습니다. 물론 제대로 노말맵이 생성됩니다. 
그런데 이 높이맵을 어떻게 칼라맵에서 뽑아 낼지가 관건입니다. 

일단은 높이맵이 그레이스케일 이미지라고 해서 픽셀의 RGB값을 더해서(R+G+B) 3으로 나누어 다시 RGB에 똑같은 값으로 저장해 보았습니다. 

RED = (R+G+B)/3; 
GREEN = (R+G+B)/3; 
BLUE = (R+G+B)/3; 

하지만 부록 CD에 있는 높이맵 처럼 나오지가 않습니다. ㅡㅡ 

이 높이맵을 생성할 수 있는 방법을 알고싶네요......................... 


그전에 GPG2 CD의 RadeonDot3Bump3DLight폴더에 있는 FieldstoneBump파일이 높이맵이 맡는지 물어보고 싶네요... 높이맵 같은데 파일 이름끝에 Bump라고 붙어 있어서... ㅡㅡ






voidpeople님께서 지금 하고있으신 작업은 대부분 ATI개발자에 자료가 꽤 있습니다. 

노말맵생성에 대해서도 역시 NormalMapGenerator라는 툴을 제공하고있는데 
소스도 같이 배포하고 있구요, 소스파일은 고작 하나뿐인데 300줄 밖에 되지않습니다. 

TGA형태의 height map을 읽어서 normal map으로 바꿔주는데, 
질문하신 sobel filter를 적용하는 부분도 나와있구요. 

그리고 또 찾아보시면 NormalMapper라는 툴도 소스와 함께 제공하는데, 
보통 Doom 3나 FarCry 등에서 쓰는 하이폴리곤에서 노말맵을 
추출하는 polybump 형태의 툴도 있습니다.


반응형
반응형

DXViewer.exe



예전버전인듯..

반응형
반응형

http://www.nvidia.co.kr/geforce-experience/



드라이버를 최신 상태로 유지하고 게임을 최적화할 수 있는 가장 쉬운 방법

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

NormalMapGenerator  (0) 2013.02.23
x파일 뷰어  (0) 2013.02.17
더미(dummy)  (0) 2013.02.13
스크린 스페이스 데칼  (0) 2013.02.13
기하정보 저장 버퍼  (0) 2013.02.10
반응형

3d max 폴더중 plugins 폴더에 .dle 파일을 복사해 넣으면 된다



PandaDirectXMaxExporter_x64_6.2011.72.0.zip

PandaDirectXMaxExporter_x86_5.2010.67.0.zip






http://www.andytather.co.uk/Panda/directxmax_downloads.aspx




Click below to download the zipped plug-in for 3ds Max 2012.  Note: 3ds Max 2012 already contains all the dependencies, so no further downloads required.

Unzip and extract the .dle file, place in the 'Plugins' sub-directory under the main 3dsmax folder. Backup and remove any previous versions.


Click below to download the zipped plug-in for 3ds Max 2011.  Note: 3ds Max 2011 already contains all the dependencies, so no further downloads required.

Unzip and extract the .dle file, place in the 'Plugins' sub-directory under the main 3dsmax folder. Backup and remove any previous versions.


Click below to download the zipped plug-in for 3ds Max 2010.  Note: 3ds Max 2010 already contains all the dependencies, so no further downloads required.

Unzip and extract the .dle file, place in the 'Plugins' sub-directory under the main 3dsmax folder. Backup and remove any previous versions.

반응형

'그래픽스(Graphics) > 모델' 카테고리의 다른 글

와우 모델 추출하기 (m2->x파일)  (0) 2013.02.13
반응형

1. 와우 모델 추출하기 (m2->x파일)  WOW  / 3D Model Export 

2010/11/17 05:02

복사http://blog.naver.com/anno414/140118276084


첨부파일 (1)

안녕하세요^ㅇ^

 

포폴을 작업하면서 골아픈 작업중 하나가 리소스 확보죠;; 추출도 그렇고요..^^

 

제가 선택한것은 WOW의 모델들이였는데요. Export하는 방법을 구글링해보니 거진 다 옛날에 올라온 글이더군요 'ㅅ';;

 

다들 쉽다고 하시는데.. 전 왤케 삽질을 했을까요;; ㅎㅎㅎ;

 

삽질을 할만큼 하고 , 정리를 해서 올립니다~ 포폴 만드시는분들 저처럼 고생안하셨으면 좋겠네요~ +ㅁ+)

조금이라도 도움이 되기를..

 

 

# 어디까지나 제 경험을 적는거라서 ,

좀더 쉽고 간편하고 ,깔끔하게 뽑는 방법이 분명히 있을겁니다.

제 글을 보고 하시기 이전에 어느정도 검색을  하셔서 정보를 수집한후에 하시는걸 추천드려요..^^

 

 

 

 

 

 

 

# 준비물 : 3D MAX 2010Panda XFile ExportMyWarCraftStudio불타는 성전 클라이언트

(Panda XFile Export와 MyWarCraftStudio는 첨부파일에 넣어놨습니다. 참고하세요) 불성과 맥스는 자급자족 냠냠 -ㅅ-;

 

 

// 익스포트 하기전에 셋팅을 합니다.

1. 맥스2010가 설치된 폴더로 가신후 , plugins에 PandaDirectXMaxExporter_x64.dle을 넣어주시면 X파일 익스포트가 가능해집니다.

2. WOW를 설치합니다. 이때 리치왕의 분노가 아닌 불타는 성전으로 깔아주셔야 합니다.

    여담이지만 확장팩이 출시할때마다 자료구조가 바뀐다네요.ㅋㅋ

// 셋팅 끝~

 

 

// 이제 모델을 뽑아내겠습니다.

1. MyWarCraftStudio 10.6337 버전을 사용합니다. 프로그램을 실행한후 툴바에 Open을 눌러주세요.

    와우/Data/common.MPQ을 불러옵니다.


 

2. 파일이 정상적으로 불러져 왔다면, 아래와같이 폴더들이 보일겁니다.

CHARACTER에는 말그대로 와우의 플레이어블 캐릭터들이 들어가 있습니다. ( 기본적으로 복장과 장비를 갖추지 않습니다 )

CREATURE에는 NPC같은 들어있습니다. ( 복장이 갖추어져있습니다 ) <- 이게 좀 쓸만하겠죠?^^

중요한 폴더는 다음과 같고요.

나머지는 천천히들 찍어보세요^^ 텍스쳐나 파티클들이 즐비합니다.

 

 

3. 저는 이미 저 세상에 가버린 캘타스를 선택했습니다.

아.! 그리고 위에  와우/Data/common.MPQ을 불러온다고 했지만 , 와우/Data/expansion.MPQ파일에도 캐릭터가 들어 있으니 둘러보세요^^

캘타스는 후자에 있어요~


모델을 선택하면 저렇게 나온답니다 켈타스.m2파일을 우클릭 하시면 Extract File To... 라고 메뉴가 보입니다. 클릭해주세요.

m2파일로 익스포트 됩니다. 그리고 텍스쳐들은 .blp라는 파일이 텍스쳐예요^^

MyWarCraftStudio로는 텍스쳐 뽑는게 약간은 불편합니다. 없는게 좀 있더라구요. 켈타스도 텍스쳐가 다 뽑히지 않아요.

저기 하나밖에 보이지 않죠? 부족합니다.. ; ㅅ;

전 개인적으로 텍스쳐 뽑을떄는 wow model viewer를사용했습니다~

(wow model viewer로는 애니메이션이 뽑히지 않더군요; 왜그런지 제보받습니다...ㄷㄷㄷㄷ;)

 

 

자 이걸로 m2파일 export는 끝입니다.

맥스를 켜주세요^^

1. 맥스 스크립트를 켜주세요. WoWM2Import.ms를 사용합니다.

   조금만 기다려 주시면 알아서 Import다이얼로그가 조그맣게 뜹니다..^^


아까 뽑아둔 m2파일을 불러옵니다. Open을 누르셔서 부르세요.

나머지 옵션들은 입맛에 맞게 선택해주시고요...;; ㅋ Import버튼을 눌러줍니다.

이게 모델 용량에 따라 시간이 좀 걸리기도 합니다.. 조금만 기다리세요~

로딩이 끝나면 단축키 'Z' 키를 눌러주세요~ 모델을 화면에 맞춰줍니다.

 



여기까지 되셨으면 어느정도 성공입니다..^^;

문제점이 좀 많아보이기는 하지만. 다 수정하면 되거든요 ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ

 

이제 애니메이션 바를 움직이며, 자기가 원하는 애니메이션이 있는 프레임을 기억해둡니다. (이게 은근히 노가다입니다..^^;;)

다 기억 하셨으면 FIle-> Export를 하시고 , 파일 형식을 Panda DirectX(*.X)로 정하고 저장을 합니다.

그러면 Export Option이 나오는데요.

설정은 스샷으로 대체하겠습니다-_-; 넘 졸려요





아까 기억해둔(혹은 적어둔) 애니메이션 프레임값을 적는곳이죠.

전 3개만 넣었습니다. 물론 프레임은 제 맘대로 넣은거예요. =ㅅ= 비몽사몽..





 

네 다 하셨으면 확인을 눌러주시면 프로그레시브바가 후다닥 지나가고... 정상적으로 .x파일로 나올껍니다..(/^ 0^)a

엑스파일로 불러오시면 잘~ 되고요. 문제 없습니다. 프레임만 잘 설정 해주셨으면 동작도 잘 나올껍니다~



 

아! 현재 텍스쳐를 입히지 않고 그냥 Export시켰죠.

맥스상에서 텍스쳐를 입혀야하는데 이건 제가 내일 다시 포스팅을 하겠습니다. 시간이 너무 늦었네요..;;;;;;;5시입니다 ㅜㅜ

 

혹시 퍼가시거나~ 도움이 되셨다면 격려의 댓글좀 굽신굽신

쓰기 힘들었어요 ^ㅠ^;;

다들 멋진 포폴 만들어서 멋지게 취직해요~ 화이탱~


반응형

'그래픽스(Graphics) > 모델' 카테고리의 다른 글

3dmax x파일 익스포터  (0) 2013.02.13
반응형

http://goo.gl/9yU00




반응형
반응형

http://kblog.popekim.com/2012/10/kgc-2012_12.html

2012년 10월 12일 금요일

스크린 스페이스 데칼 (KGC 2012 발표자료)

KGC 2012에서 발표했던 "스크린 스페이스 데칼에 대해 자세히 알아보자"의 슬라이드 자료 공개합니다.

뒤에 서서 보시는 분들도 여럿 계실정도로 강의실이 꽉 찼던데.... 모두들 찾아와주셔서 감사합니다.


 
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린) from 포프 김 


제 시그래프 자료는 이보단 약간 부실한데.. 굳이 궁금하신 분들은 영문 블로그를 참고해주시기 바랍니다.

반응형
반응형
http://memset.tistory.com/129

기하정보 저장 버퍼

 

버퍼사용 이유

배열이 아닌 버퍼에 저장하는 이유는 버퍼를 비디오 메모리에 저장할 수 있기 때문으로, 시스템 메모리의 데이터를 렌더링하는 것보다는 비디오 메모리의 데이터를 렌더링하는 것이 훨씬 빠르기 때문이다.

버텍스 버퍼 

버텍스 데이터를 보관하는 연속적인 메모리 덩어리
HRESULT IDirect3DDevice9::CreateVertexBuffer(
UNIT Length,                   //버퍼에 할당할 바이트 수
DWORD Usage,              //버퍼가 이용되는 몇 가지 부가적인 특성
DWORD FVF,                 //버텍스 보관될 버텍스 포멧
D3DPOOL Pool,             //버퍼가 위치할 메모리 풀
IDirect3DVertexBuffer9** ppVerTexBuffer, 
                                   //만들어질 버텍스 버퍼를 받을 포인터 
HANDLE* pShareHandle    //이용하지 않는다.0으로 지정
);

ex) 8개 버텍스 정보를 가질수 있는 버퍼 생성
IDirect3DDeviceVertexBuffer9* vb;
Device->CreateVertexBuffer( 8*sizeof(Vertex), 0, 
D3DFVF_XYZ, D3DPOOL_MANAGED, 
&vb,0 );

인덱스 버퍼

인덱스 데이터를 보관하는 연속적인 메모리 덩어리
HRESULt IDirect3DDevice9::CreateIndexBuffer(
   UNIT Length,
   DWORD Usage,
   D3DFORMAT Format,         //만들어질 인덱스 버퍼를 받을 포인터
   D3DPOOL Pool,
   IDirect3DIndexBuffer9** ppIndexBuffer,
   HANDEL* pShareHandle
};

ex) 8개 버텍스 정보를 가질수 있는 버퍼 생성
IDirect3DDeviceIndexBuffer9* ib;
Device->CreateIndexBuffer( 36*sizeof(WORD),D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 
D3DFMT_INDEX16, D3DPOOL_MANAGED, 
&ib,0 );
Usage에서 사용되는 플래그
D3DUSAGE_DYNAMIC – 버퍼를 동적으로 만든다.
D3DUSAGE_POINTS – 버퍼가 포인트 기본형을 보관할 것임을 지정
D3DUSAGE_SOFTWAREPROCESSING – 버텍스 프로세싱을 소프트웨어로 처리
D3DUSAGE_WRITEONLY – 애플리케이션이 버퍼에 쓰기만을 수행할 것임을 지정.만약 버퍼를 읽으려고 하면 오류 발생

정적버퍼

비디오 메모리상 효율적인 메모리 처리, 접근속도 제약이 있음 주로 정적 데이터 처리, D3DUSAGE_DYNAMIC 플래그 지정하지 않은 버퍼 해당
ex) 
데이터 처리빈도가 적은 지형, 건물 기하정보(애플리케이션 초기화 때 정적버퍼에 기하정보 저장)

동적버퍼

D3DUSAGE_DYNAMIC 플래그 지정, AGP메모리 저장, 메모리 처리속도는 비디오 메모리 전송과정이 필요하므로 정적보다 느림, 그러나 갱신속다가 빠름(고속 CPU쓰기 처리)
ex) 파티클 시스템, 프레임별 기하정보 변환이 필요하므로 동적 필요

Tip

비디오 메모리나 AGP메모리에서의 읽기 작업은 상당히 느리므로 런타임시에 기하정보를 자주 읽어 들여야 한다면 지역 시스템 메모리에 복사본을 남겨두고 이를 읽어들이는 것이 바람직하다.

버퍼 메모리에 접근하기

HRESULT IDirect3DVerTexBuffer9::Lock(
   UNIT OffsetLock,   //잠금을 시작할 버퍼 위치의 오프셋
   UNIT SizeLock,     //잠글 바이트의 수(offsetlock + sizelock)
   BYTE** ppbData,   //잠근 메모리의 시작을 가리키는 포인터 수
   DWORD Flags );    //잠근을 이루어지는 방법 지정. 0을 지정하거나 플래그를 지정

HRESULT IDirect3DIndexBuffer9::Lock(
   UNIT OffsetLock,
   UNIT SizeLock,
   BYTE** ppbData,
   DWORD Flags );

ex)
Vertex* vetice;
Vb->Lock( 0, 0, (void**)&vertice, 0 );
Vertice[0] = Vertex( -1.0f, 0.0f , 2.0f );
Vertice[1] = Vertex( 0.0f, 1.0f, 2.0f );
Vertice[2] = Vertex( 1.0f, 0.0f, 2.0f );
Vb -> Unlock();
DWORD Flag 인자
D3DLOCK_DISCARD – 동적 버퍼에만 이용. 하드웨어에게 버퍼를 버리도록 지시하고 새로 할당된 버퍼의 포인터를 리턴
D3DLOCK_NOOVERWRITE – 이 플래그는 동적 버퍼에만 이용. 버퍼에 데이터를 추가하는 작업만 가능하도록 하는 것
D3DLOCK_READONLY – 읽기 전용으로 버퍼를 잠글 것임을 지정

※D3DLOCK_DISCARD와 D3DLOCK_NOOVERWRITE  이 두 플래그를 이용할 수 있는 상황이라면 버퍼를 잠글 때도 렌더링이 정지되는 것을 막을 수 있다.

버텍스/인덱스 버퍼에 대한 정보

상황에 따라 버텍스/인덱스에 대한 정보를 얻는데 이용되는 메서드 이용의 예이다.

D3DVERTEXBUFFER_DESC vbDescription;
vertexBuffer->GetDesc(&vbDescription);   //버텍스 버퍼 정보를 얻는다.

D3DINDEXBUFFER_DESC ibDescription;
indexBuffer->GetDesc(&ibDescription);   //인덱스 버퍼 정보를 얻는다.

렌더 상태

Direct3D는 기하정보가 렌더링되는 방식을 결정하는 다양한 렌더링 상태를 캡슐화하고 있다. 렌더 상태는 모두 디폴트 값을 가지고 있으므로 여러분의 애플리케이션에서 디폴트가 아닌 다른 동작을 필요로 하는 경우에만 이를 변경하면 된다. 
렌더 상태를 알고 싶다면 SDK문서의 D3DRENDERSTATETYPE항목에서 찾을 수 있다
HRESULT IDirect3DDevice9::SetRenderState(
   D3DRENDERSTATETYPE State,         //변경 할 상태
   DWORD Value );                            //새로운 상태 값

ex) 와이어프레임으로 렌더링
device->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );

드로잉

스트림 소스 지정

스트림 소스를 버텍스 버퍼와 연결하여 버퍼의 기하정보를 렌더링파이프라인 보낼 수 있도록 한다.
 HRESULT IDirect3DDevice9::SetStreamSource(
   UNIT StreamNumber,      //버텍스 버퍼를 연결할 스트림 
                                    //소스를 지정.
   IDirect3DVertexBuffer9* pStreamData,  
                                    //스트림과 연결하고자 하는 버텍스 버퍼
                                    //로의 포인토
   UNIT offsetInBytes,
                                    //렌더링 파이프라인으로 공급될 버텍스 
                                    //데이터의 시작을 지정 스트림의 오프셋
   UNIT Stride
                                   //스트림에 연결하고자 하는 버텍스 버퍼 
                                   //내 각 요소의 바이트 수
);
ex)
device->SetStreamSource( 0, vb, 0, sizeof( Vertex ) );

버텍스 포맷을 지정

이후의 드로잉 호출에서 이용될 버텍스포맷을 지정하는 단계
device->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEXT);

인덱스 버퍼를 지정

인덱스 버퍼는 한 번에 하나의 인덱스 버퍼만 이용할 수 있다. 따라서 인덱스 버퍼를 가진 물체를 그려야한다면 인덱스 버퍼를 전환하는 과정이 필요하다.
device->SetIndices( ib ); //인덱스 버퍼 포인터의 복사본을 전달한다.

버텍스/인덱스 버퍼를 이용한 드로잉

DrawPrimitive나 DrawIndexPrimitive 메서드를 이용해 기하정보를 렌더링 파이프라인으로 보내는 실질적인 드로잉을 수행할 수 있다.
버텍스 정보 이용 그리기
HRESULT IDirect3DDevice9::DrawPrimitive( 
   D3DPRIMITIVETYPE PrimitiveType,    //그리고자 하는 기본형 타입
   UNIT StartVertex,                           //버텍스읽기를 시작할 버텍스 
                                                    //요소로의 인덱스.
   UNIT PrimitiveCount                       //그리고자 하는 기본형의 수
 );

ex)
device->DrawPrimitive( D3DPT_TRIANGLELIST, 0 , 4 );

인덱스 정보 이용 그리기
HRESULT IDirect3DDevice9::DrawIndexPrimitive(
D3DPRIMITIVETYPE Type,   //그리고자 하는 기본형 타입
INT BaseVetexIndex,          //이번 호출에 이용될 인덱스에 더해질 기
                                     //반 번호를 지정
UNIT MinIndex,                 //참조할 최소 인덱스 값
UNIT NumVertice,              //이번 호출에 참조될 버텍스의 수
UNIT StartIndex                //인덱스 버퍼내에서 읽기를 시작할 요소로
                                    //의 인덱스
UNIT PrimitiveCount          //그리고자 하는 기본형의 수
);

ex)
device->DrawIndexPrimitive( D3DPT_TRIANGLELIST, 0 ,0 ,8 ,0 , 12 );

장면의 시작과 끝

마지막으로 기억해두어야 할 사항으로는 모든 드로앙 메서드가 BeginScene와 EndScene 호출 내부에 포함되어야 한다.
device->BeginScene();
device->DrawPrimitive();
device->EndScene();

D3DX 기하 물체

코드 내에서 각각의 삼각형을 연결하여 3D물체를 구성하는 작업은 상당히 지루할 것이다.
그래서 우리는 편하게 D3DX에서 제공하는 라이브러리는 몇 가지의 간단한 3D 물체 메쉬 데이터를 생성하는 메서드를 제공한다.

D3DXCreateBox, D3DXCreateSphere, D3DXCreateCylinder, D3DXCreateTeapot, D3DXCreatePolygon,  D3DXCreateTours
생성된 기하 물체를 그리려면 다음 함수를 이용한다.

ID3DXMesh::DrawSubset(DWORD AttribId);
// 드로잉(Drawing) 하는 메쉬의 서브 세트를 지정하는 DWORD. 이 값은, 메쉬내의 면을, 1 개 또는 복수의 속성 그룹에 속하고 있다고 하여 구별하기 위해서 사용된다. 
ex) 티포트 생성
HRESULT D3DXCreateTeapot(
LPDIRECT3DDEVICE9  pDevice,   //메쉬와 연계된 장치
LPD3DMESH* ppMesh,            //메쉬를 받을 포인터
LPD3DXBUFFER* ppAdjacency    //현재는 0으로 지정
);         
ID3DXMESH* mesh = 0;
D3DXCreateTeapot( device, &mesh, 0 );

device->BeginScene();
device->DrawSubset(0);
device->EndScene;

//after using
mesh->Release();
mesh = 0;

[출처] Direct3D 그리기 |작성자 아이엠쏭


반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

더미(dummy)  (0) 2013.02.13
스크린 스페이스 데칼  (0) 2013.02.13
버텍스버퍼 활용  (0) 2013.02.10
Primitive 종류 설명  (0) 2013.02.09
TGA파일에서 알파채널 만들기  (1) 2013.01.31
반응형

http://www.gpgstudy.com/forum/viewtopic.php?topic=8829





엔진 속도를 올려볼려고, 파티클의 빌보드 한개당 DrawPrimitive하던것을 
긴 버텍스 버퍼에 월드 좌표로 때려밖은후에 렌더링 하려고 고치는 중입니다. 

DrawPrimitive횟수도 많이 줄이고요, SetRenderState, SetTexture횟수도 줄이도록 정렬하고있습니다. 

그런데.. 버텍스 버퍼가 크다보니 락/언락만 해도 프레임이 10%로 내려가더군요.. 
엄청난 속도 저하이죠..^^ 정확히 이야기하면 락/언락 하고 그버퍼의 폴리곤 1개만 찍어도 그러더군요.. 
안찍으면 락/언락해도 전혀 안내려가고요... 

버텍스 버퍼를 D3DPOOL_MANAGED로 만들어서 DrawPrimitive하는순간 시스템메모리에있는 복사본을 
VGA로 넘기나 봅니다. 
그래서 D3DPOOL_DEFAULT로 생성했더니 속도저하가 없더군요..다만 디바이스 리셋시 삭제/복구만 잘해주면 
될듯 싶습니다.. 그게 귀찮아서 이제껏 D3DPOOL_MANAGED만 사용했었거든요.. 

지오메트리랑, 스킨모두 D3DPOOL_MANAGED로 사용하고있거든요.. 
지오메트리야 정점 버퍼 자체는 변하지 않아서 첨 생성해서 만든다음 그냥 사용하고 
스킨은 Tick()마다 락/언락을 하거든요.. 

궁금한점 
1. 락/언락을 하지 않는 버퍼는 D3DPOOL_MANAGED와 D3DPOOL_DEFAULT가 성능이 같나요? 
2. 락/언락을 하는 D3DPOOL_MANAGED버퍼는 DrawPrimitiveUP하고 성능이 같나요? 
3. 모두 D3DPOOL_DEFAULT로 바꾼다면 비디오메모리가 모자랄경우 D3DPOOL_MANAGED에 비해 단점이 있나요? 혹은 디바이스 리셋시 삭제/복구말고, 락할때 옵션이라던지 다른 관리들이 필요한지 궁금하네요..








SDK 도움말에 설명이 나와있하지만.. 그래도 꽤 많은 분들이 헷갈려하시는거 같습니다. 

D3DPOOL_MANAGED 는 풀이 시스템메모리에 백업되고 필요시에 비디오메모리로 로드됩니다. 한번 로드된 풀은 해제되거나 아니면 메모리의 부족으로 강제로 내려갈때까진 메모리상에서 유효합니다. 
시스템메모리에 백업되어있기때문에 디바이스 리셋시에도 별다른 조치를 할 필요가 없습니다. 

D3DPOOL_DEFAULT 는 풀이 비디오메모리에 바로 생성되고 메모리가 부족하면 풀을 만들때 오류를 뱉어냅니다. 따로 백업되어있지않기때문에 디바이스 리셋시에 더이상 유효하지 않게 됩니다. 

D3DPOOL_MANAGED 는 시스템메모리에 백업되어있기때문에 'Read' 하는것에는 별다른 문제가 없습니다. 다만 'Write' 는 하게될때마다 메모리에서 내렸다가 다시 로드되어야되기때문에 무리가 따릅니다. (레퍼런스상에서도 D3DPOOL_MANAGED 로 생성된 버텍스버퍼나 인덱스버퍼는 런타임상에서 업데이트하는걸 성능상에 문제로 추천하고 있지 않습니다. 같은 이유로 렌더타겟같은것들은 D3DPOOL_MANAGED 로 만들수가 없습니다.) 

D3DPOOL_DEFAULT 는 따로 시스템메모리에 백업이 없기때문에 'Read' 에 무리가 있습니다. 다만 'Write' 하는것에는 D3DPOOL_MANAGED 로 만들어진것보단 적합해서 각종 다이나믹 버텍스버퍼/인덱스버퍼 등에 쓰이게 됩니다. 

다이나믹 버텍스버퍼나 인덱스버퍼를 쓸때 자주 쓰이는 옵션인 D3DLOCK_DISCARD 와D3DLOCK_NOOVERWRITE 는 CPU 와 GPU 의 병목현상을 막기위한 플래그들입니다. 
D3DLOCK_DISCARD 는 현재 드라이버가 잡고있는 풀은 그대로 내버려두고 같은 크기의 새로운 풀을 잡아서 거기에 업데이트를 할수 있게합니다. 그리고 잡고있던 풀이 다 쓰여지고 나면 그 풀을 해제되고 새롭게 만들어졌던 풀이 쓰이게 되는거죠. 드라이버가 다 그릴때까지 멈춰있을수없으니 이런식으로 쓰게 됩니다. 
D3DLOCK_NOOVERWRITE 는 현재드라이버가 잡고있는 풀을 업데이트하지 않겠다고 명시적으로 말하는거가 되겠네요. 렌퍼런스에서는 저 두개의 옵션중에 한가지는 꼭 Lock 할때 써주는것을 추천하고 있습니다. (두개같이 쓰는건 비추하고 있습니다.) 

이런저런 이유로 보통 다이나믹 버텍스버퍼나 인덱스버퍼를 쓸때는 조금 큰 하나의 풀을 잡아놓고 거기에 조금씩 알맞는 플래그로 업데이트해가며 렌더링하는게 여러가지면에서 좋은거 같습니다. 

unsigned int uOffset = 0; 
Loop { 
unsigned int uVertexSize = ...; 
if(uOffset+uVertexSize > uVertexBufferSize) { 
uOffset = 0; 

unsigned long dwLockFlag = D3DLOCK_DISCARD; 
if(uOffset > 0) dwLockFlag = D3DLOCK_NOOVERWRITE; 
pVertexBuffer->Lock(uOffset, uVertexSize, ..., dwLockFlag); 
... 
pVertexBuffer->Unlock(); 
DrawPrimitive(...); 
uOffset += uVertexSize; 


1. 
D3DPOOL_MANAGED 나 D3DPOOL_DEFAULT 나 업데이트를 하지 않는다는 조건에서는 성능은 같습니다. (다만 D3DPOOL_MANAGED 로 생성된 많은양의 풀들이 한꺼번에 비디오메모리로 로드되는 순간에는 버벅임같은것을 느낄수는 있습니다.) 
2. 
D3DPOOL_MANAGED 로 생성된 풀을 런타임상에서 계속 Lock/Unlock 하는건 DrawPrimitiveUP 보다 더 느릴수도 있습니다. 
3. 
모두 D3DPOOL_DEFAULT 로 바꾼다면 비디오메모리가 부족하면 아예 풀생성 자체가 안됩니다. 용도에 따라 꼭 D3DPOOL_MANAGED 가 되어야되는경우도 있습니다. (텍스쳐같은걸 Lock/Unlock 등을 통해서 읽어야되는경우) 레퍼런스상에서는 특별한 경우를 제외하곤 D3DPOOL_MANAGED 를 쓰라고 하고 있습니다.

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

스크린 스페이스 데칼  (0) 2013.02.13
기하정보 저장 버퍼  (0) 2013.02.10
Primitive 종류 설명  (0) 2013.02.09
TGA파일에서 알파채널 만들기  (1) 2013.01.31
포샵에서 DDS파일 만들기(2)  (0) 2013.01.31
반응형

http://tadis.tistory.com/category/Direct%20X:



이렉트3D는 정해진 기본형(primitive)을 이용해서 그리는 함수를 4가지를 제공한다.

 

1. 인덱스 버퍼(vertex buffer)를 이용하지 않고 기본형을 그리는 함수

  1) DrawPrimitive(): Drawprimitive 함수는 데이터 입력스트림의 현재 집합으로부터 지정된 형식의 '인덱스 되지 않은 기본형들을 렌더링' 한다. 이 경우 유일한 '데이터 스트림은 SetStreamSource함수에 의해 선언'된 것이다. (버텍스 버퍼를 이용한다.)

 

  - Syntax-

    HRESULT DrawPrimitive(
   D3DPRIMITIVETYPE primitiveType,

   UINT StartVertex, 
   UINT PrimitiveCount

   );

 

  - Parameter-

   ○ primitiveType(Type: D3DPRIMITIVETYPE)

   : 열거된 D3DPRIMITIVETYPE의 맴버로 '랜더링될 기본형의 종류'

   ○ StartVertex(Type: UINT)

   : '첫번째로 로드될 버텍스의 번호'. 첫번째 번호가 설정되면 버텍스 버퍼의 끝까지 읽어들인다.

   ○ PrimitiveCount(Type: UINT): '렌더링할 기본형의 개수'. 출력가능한 최대 개수는 D3DCAPS9 구조체에 있는 MaxPrimitiveCount에서 정보를 얻을 수 있다.

 

   - Return value-

   HRESULT

   : 성공하면 D3D_OK를 리턴한다. 실패하면 D3DERR_INVALIDCALL을 리턴한다.

 

 2) DrawPrimitiveUp(): DrawprimitiveUp 함수는 사용자 메모리 포인터에 의해 지정된 타입의 기본형정보를 렌더링 한다. (버텍스 버퍼를 이용하지 않는다.)

  - Syntax-

  HRESULT DrawPrimitiveUP(
   D3DPRIMITIVETYPE PrimitiveType,
  UINT PrimitiveCount,
  const void *pVertexStreamZeroData,
  UINT VertexStreamZeroStride

  );

 

   - Parameter-

  ○ primitiveType(TYPE: D3DPRIMITIVETYPE)

  : 열거된 D3DPRIMITIVETYPE의 맴버로 '랜더링될 기본형의 종류'

  ○ primitiveCount(Type: UINT): '렌더링할 기본형의 개수'. 출력가능한 최대 개수는 D3DCAPS9 구조체에 있는 MaxPrimitiveCount에서 정보를 얻을 수 있다.

  ○ pVertexStreamZeroData(Type: const void*): 버텍스 데이터의 유저 메모리 포인터 

  ○ pVertexStreamZeroStride(Type: UINT): 각 각의 버텍스데이터의 크기 

 

  - Return value-

   HRESULT

   : 성공하면 D3D_OK를 리턴한다. 실패하면 D3DERR_INVALIDCALL을 리턴한다.

 

3) DrawIndexedPrimitive(): DrawIndexedPrimitive 함수는 인덱스 되어 있는 버텍스를 기본으로 버텍스들의 기본형들을 렌더링 한다. (인덱스 버퍼+버텍스 버퍼를 이용한다.)

 

- Syntax-

   HRESULT DrawIndexedPrimitive(
     D3DPRIMITIVETYPE Type,
     INT BaseVertexIndex,

     UINT MinIndex,

     UINT NumVertices,

     UINT StartIndex,

     UINT PrimitiveCount
  );

 

  - Parameter-

  ○ primitiveType(TYPE: D3DPRIMITIVETYPE)

    : 열거된 D3DPRIMITIVETYPE의 맴버로 '랜더링될 기본형의 종류'

  ○ BaseVertexIndex(TYPE: INT): 버텍스 버퍼의 시작에서 부터 첫번째 버텍스까지의 오프셋

   ○ MinIndex(TYPE: UINT)

    : 호출하는 동안 사용될 최소의 버텍스 인덱스. 0이면 BaseVertexIndex가 기본이 된다.

   ○ NumVertices(TYPE: UINT): 함수 호출하는 동안에 사용될 버텍스들의 숫자. 첫 버택스는 BaseVertexIndex+MinIndex에 위치해 있다.

   ○ StartIndex(TYPE: UINT): 버텍스 버퍼에 접근할때 이용될 첫번째 인덱스의 숫자. 버텍스 버퍼에서 startIndext부터 Index가 시작한다.

   ○ PrimitiveCount(TYPE: UINT): '렌더링할 기본형의 개수'. 출력가능한 최대 개수는 D3DCAPS9 구조체에 있는 MaxPrimitiveCount에서 정보를 얻을 수 있다.

 

  - Return value-

  HRESULT

  : 성공하면 D3D_OK를 리턴한다. 실패하면 D3DERR_INVALIDCALL을 리턴한다.

  

4) DrawIndexedPrimitiveUp(): DrawIndexedPrimitiveUp 함수는 유저에 의해 지정된 메모리 포인터를 이용해여 지정된 기본형들을 렌더링 한다. (인덱스 버퍼+버텍스 버퍼를 이용하지 않는다.)

 

  - Syntax-

  HRESULT DrawIndexedPrimitiveUP(
    D3DPRIMITIVETYPE PrimitiveType,
    UINT MinVertexIndex,
    UINT NumVertices,
    UINT PrimitiveCount,
    const void *pIndexData,
    D3DFORMAT IndexDataFormat,
    const void *pVertexStreamZeroData,
    UINT VertexStreamZeroStride
  );

 

  - Parameter-

  ○ primitiveType(TYPE: D3DPRIMITIVETYPE)

   : 열거된 D3DPRIMITIVETYPE의 맴버로 '랜더링될 기본형의 종류'

  ○ MinVertexIndex(TYPE: UINT): 최소 버텍스 인텍스 (0부터 시작하는 인덱스이다.)

  ○ NumVertices(TYPE: UINT): 함수 호출하는 동안에 사용될 버텍스들의 숫자. 첫번째 버텍스는 MinVertexIndex에서 설정한 인덱스에 있다.

  ○ PrimitiveCount(TYPE: UINT): '렌더링할 기본형의 개수'. 출력가능한 최대 개수는 D3DCAPS9 구조체에 있는 MaxPrimitiveCount에서 정보를 얻을 수 있다.

  ○ pIndexData(TYPE: const void*): 인덱스 데이터의 메모리 포인터.

  ○ IndexDataFormat(TYPE: D3DFORMAT ): D3DFORMAT에서 열거되어 있는 타입. 인덱스 데이터의 형태를 나타만다. 가능한 설정값은 D3DFMT_INDEX16, D3FMT_INDEX32 이다.

  ○ pVertexStreamZeroData(TYPE: const void*): 버텍스 데이터의 메모리 포인터. 이때 버텍스 데이터는 stream0에 위치해야 한다.

  ○ VertexStreamZeroStride(TYPE: UINT): 각각의 버텍스 데이터(자료형의) 크기

 

- Return value-

HRESULT

: 성공하면 D3D_OK를 리턴한다. 실패하면 D3DERR_INVALIDCALL을 리턴한다.

 

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

기하정보 저장 버퍼  (0) 2013.02.10
버텍스버퍼 활용  (0) 2013.02.10
TGA파일에서 알파채널 만들기  (1) 2013.01.31
포샵에서 DDS파일 만들기(2)  (0) 2013.01.31
포샵에서 DDS파일 만들기(1)  (0) 2013.01.31
반응형


BLOG main image




아래 번역한 것은 CEGUI 튜토리얼을 번역한 것입니다

원래 용도는 혼자만 볼것이였습니다, 얼추 번역한다음 소스에 넣었지만 결국엔 유니코드지원이 안되기때문에 빼버리게 된부분입니다만

그냥 지워버리긴 좀 아깝고 혹여나 필요한 분이 있을지도 모른다는 생각에 올려놓습니다

번역은 얼추 번역한것이라 약간 매끄럽진 않을 수도 있습니다

중간 중간 보이는 소스는 개인 프로젝트에 적용하기위해 테스트했던 코드 조각들입니다


번역사이트는 http://www.cegui.org.uk/docs 에서 튜토리얼 부분 입니다






 =================== CEGUI 파일 구성 부분 =================



//@brief CEGUI 를 활용한 GUI 클래스

//@ 아래내용은 http://www.cegui.org.uk/docs 일부 내용을 이해하기 쉽도록 번역한것,  나중에 잊어먹을 경우를 위해서.. [sjh]

//@ 

//CEGUI 는 XML 기반이다

//notice 확장자가 꼭 .xml 이 아니고 의미에 맞는 확장자가 붙는다 ,for example .imageset for an Imageset and .font for a Font 

//또한 이름짖는 규칙은 없다

//1) Imageset : Imageset은 몇몇 소스윤곽에 대해서 지정된 지역들의 모음들이다, 이미지파일 또는 텍스쳐와 같은...

//  imageset 은 scheme의 부분으로서 로드되어지는 한 Imageset을 지정한다

//2) Font : CEGUI 안에서 사용하기위한 폰트를 정의한다, 이것은 두가지 타입이 있다

//  Font는 scheme의 부분으로서 로드되어지는 한 Font를 지정한다

// 1. FreeTypeFont : 표준폰트 .ttf 폰트에 기반되어지는 폰트, 이것은 속성에서 Type="FreeType" 으로 쓰일 수 있고 .font   XML 안에서 사용된다

// 2. PixmapFont : 이 폰트의 타입은  [폰트 glyphs]에대한 이미지들을 정의한 Imageset으로 정의되어진다

// 그리고 비트맵된 폰트로서의 생각되어진 최상이다, .font XML 파일 속성에서  Type="Pixmap" 으로 쓸 수 있다

//3) LookNFeel :  LookNFeel은 CEGUI의 skinning system의 주요한부분으로부터 보관한다

//   WidgetLook과 그 자식에 대한것들을 담고있다

//   LookNFeel은 scheme의 부분으로서 로드되어지는 한 LookNFeel파일을 지정한다

//   

//4) Scheme : Scheme 파일은 다른 데이터 파일들과 리소스들과 함께 그룹화하는 넓은 의미이다 그리고 그것들의

//  상호작용의 몇몇을 정의는 그리고 싱글포인터로부터 CEGUI의 windows와 widgets 를위해서 

//  'skin' 으로 간주되어지는것을 로드하는 의미이다

//  

//5) Layout :  레이아웃파일은 window 레이아웃의 XML표현을 포함한다. 각 집합된 'Window' 속성은 만들어질수있는 

//   window 또는 widget을 정의한다,

//   'Property'요소들은 바랬던 세팅과 각각 정의되어지는 window를 위한 property 값들을 정의한다

//   

//6) Config : CEGUI의 config파일지원은 모든 system default들,  로드되어지는 initial resource들을 지정하는것을 당신에게 허ㅎ ㅓ락한다.

//  뿐만아니라 초기화와 실행하기위한 종료 스크립트파일들(ScriptModule을 사용할때)

// , Renderer와 System오브젝트들을 만들수있는것을 넘어 C++코드의 쓰여지는 라인없이도...

//













 ===================  초기화 부분 ===================



using namespace CEGUI;


//@brief CEGUI 를 활용한 GUI 클래스

//@ 아래내용은 http://www.cegui.org.uk/docs  내용을(전체는 아니지만 중요 부분을 번역한것[SJH], 나중을 위해..



//----------------==========-----------------[ CEGUI의 기본적인 리소스 로딩 sjh]----------------==========-----------------



//CEGUI 의 기본적인 bootstrapSystem() 을 수동으로 만들어주는 구문은 

//http://www.cegui.org.uk/docs/current/rendering_tutorial.html   에서 The Hard Way: Manual object creation. 이하의 구문을

// 따라하면 된다, Call the function to render the GUI 이것 전까지


//리소스 그룹 생성

CEGUI_TRY{

//[ CEGUI 렌더링을 얻기위한 가이드 ] http://www.cegui.org.uk/docs/current/rendering_tutorial.html

//1. 오브젝트로 기반된 CEGUI::Renderer의 인스턴스를 생성한다

//2. CEGUI::System 오브젝트를 생성한다(오브젝트 : 위에서 생성되어진 renderer에서 파싱한것)

//3. 각 프레임,  렌더링을 수행하기위한 CEGUI::System::renderGUI 함수를 호출한다.


// bootstrapSystem 함수는 아래3개를 생성한다, 인자는 CEGUI의 렌더링연산을 위해서 사용되어질 디바이스를 넘긴다

// * 리턴값 : 생성되어졌던  CEGUI::Direct3D9Renderer 오브젝트에 레퍼런스 

//- CEGUI::Direct3D9Renderer

//- CEGUI::DefaultResourceProvider

//- CEGUI::System

//CEGUI 의 기본적인 모든걸 자동적으로 만들어주는 명령문

Direct3D9Renderer& tempRenderer = Direct3D9Renderer::bootstrapSystem( _pD3dDevice );

//initializeManually();





//[ ResourceProviders로 리소스 로딩에 대한 가이드] http://www.cegui.org.uk/docs/current/resprov_tutorial.html

//


// 우리는 당신이 리소스 그룹들과 

// CEGUI와 함께 제공되는 datafiles(C:\sjhPhysics\datafiles\.) 디렉토리안에 data file들을 접근하는 

// 그것들의(리소스 그룹들의) 대상 디렉토리들의 초기화를 수행할 방법, 

// 그리고 우리가 모든 리소스 타입들에 대해 사용되기 위해서 defaultgroups를 할당하는 방법을  보여줄것이다



// 흔히있는 것으로서 핵심 CEGUI::System 오브젝트를 초기화한 후에, 우리는 리소스 그룹들의 한 set과

// 그것들의 타겟 디렉토리들의 한 set을 그때 지정한다.

// ( 타겟 디렉토리들 : 이것은 워킹 디렉토리가 CEGUI 패키지와 함께 'bin' 다렉토리가 될것을  맡는다.)


// DefaultResourceProvider에 대해 필요되는 dirs 를 초기화한다

CEGUI::DefaultResourceProvider* rp = static_cast<CEGUI::DefaultResourceProvider*>

(CEGUI::System::getSingleton().getResourceProvider());

rp->setResourceGroupDirectory("schemes", "../CEGUI/datafiles/schemes/"); //schemes

rp->setResourceGroupDirectory("imagesets", "../CEGUI/datafiles/imagesets/"); //imagesets

rp->setResourceGroupDirectory("fonts", "../CEGUI/datafiles/fonts/"); //font

rp->setResourceGroupDirectory("layouts", "../CEGUI/datafiles/layouts/"); //layouts

rp->setResourceGroupDirectory("looknfeels", "../CEGUI/datafiles/looknfeel/"); //looknfeel

rp->setResourceGroupDirectory("lua_scripts", "../CEGUI/datafiles/lua_scripts/"); //lua_scripts


// 만약 당신이 Xerces를 사용하는 중이고 schemas 위치(locatin)를 지정해야한다면

// 이것은 오직 실제로 필요가 되어진다.

rp->setResourceGroupDirectory("schemas", "../datafiles/xml_schemas/"); //xml_schemas


// 지금 완료되었다, 

// 우리는 그것들(리소스 그룹들)의 대상 디렉토리들 set과 함께 정의되는 리소스 그룹들의 한 멋진 set을 가지고있다.



// 끝으로, 그것들(리소스 그룹들)의 디렉토리들을 사용하는 system을 얻기위해서, 

// 우리는 사용되어지는 default resource groups를 설정한다




//유효성 스키마( validation schemas)를 위한 설치기본그룹 (setup default group)

CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();

if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))

parser->setProperty("SchemaDefaultResourceGroup", "schemas");


// 사용어지는 default resource groups을 설정한다

CEGUI::Scheme::setDefaultResourceGroup("schemes"); //schemes 를 default 그룹으로 설정

CEGUI::Imageset::setDefaultResourceGroup("imagesets"); //imagesets 을 default 그룹으로 설정

CEGUI::Font::setDefaultResourceGroup("fonts"); // fonts 를 default 그룹으로 설정

CEGUI::WindowManager::setDefaultResourceGroup("layouts"); //layouts를 default 그룹으로 설정

CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels"); //looknfeels 를 default 그룹으로 설정

CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts"); //lua_scripts를 default 그룹으로 설정







// 아래 내용을 정리해보면 schema는 어떤 .xsd 파일

// schme는 .xsd 파일안에 있는 내용들의 그룹지어지는 묶음을들을 각각 scheme라고 칭하는 듯



//[ 데이터 파일과 Defaults 초기화에 대한 가이드 ] http://www.cegui.org.uk/docs/current/datafile_tutorial.html

//[소개]

// CEGUI는 다양한 다른 data 파일들을 사용하고

// (적어도 처음에)정확하게 모든 이 파일들이 있는것으로서 몇몇의 혼란과 그것들이 서로 관계되는 방법이 있다.

// 게다가, 당신들이 CEGUI을 사용하는 당신의 다수의 응용프로그램을 위해서 대부분 분명히 

// 설정 할( 설정하기위해서 기술적으로 필요없는 반면에 ) 몇몇의 system 전체 default들이 있다.

// 이 튜토리얼은 당신이 CEGUI와 함께 사용되는 기본 default 옵션들을 설정하는것과 데이터와 함께 더 쉬울 수 있도록

// 명령에 대한 이 주제들에 대한 소개로서 제공될것이다.


//[Font, Imagest, LookNFeel,Scheme, XSD?   그것은 모두 XML 이다]

//

//스크립트 언어 파일들과 로드할수있는 모듈들(.dll/.so files, 등등), 그래픽컬 이미지의 예외와 함께 

// CEGUI를 가지고 사용되어지는 모든 데이터 파일들은 XML기반이다.

// 이것은 당신이 실행 할(.xsd schema 파일들) 첫번째의 가능성있는 방해물로 우리를 실제로 이끈다.

// 

//  스키마 유효성(Schema Validation )

// 비록 Expat 기반 XML 파서 모듈이 XML 데이터 파일들을 파싱하는 것을 위해 지금 default 선택이되었다고 할지라도,

// 이전에 오랬동안 default는 (그리고 여전히 이 저자가 선택을 선호한다) 아파치 소프트웨어 재단(http://xerces.apache.org/xerces-c)

// 으로부터 Xerces-c++ 라이브러리에 대해 기반된 파서이다.

// 이 특별한 파서를 사용하는것의 이점은 그것이 스키마 유효성(schema validation)을 제공하는 것이다.

// 특별한 경험이 없는 사람들을 위해서, 스키마 유효성(schema validation)은 새로온 XML data가 

// 그것이(XML data) 잘 구성되어있고 그것이(XML data) 필요되어지는 정보를 포함한다는것을 보장하기 위해서

// 확인할 수 있는 방법이다.

// 작동하기위한 이 유효성(validation)을 위해서, 몇몇의 추가적인 파일들이 필요되어진다

// 

// ( schema 파일 : schema 파일들로서 알려진 놀랄것도 없이 

//   아래에 설명되어진 CEGUI's 자신의 scheme 파일들에 혼란되지 않기위한 파일들이다 )

//   

// schema 파일들은 XML 입증에 사용된다 왜냐하면 CEGUI는 CEGUI 범위에  datafiles/xml_schema/ 디렉토리안서

// 발견 되어질수 있기때문에, 그리고 .xsd 파일 확장자를 가진다.

//   

// 당신이 현재는 알아야하는 중요한 것은 XML 파서를 기반으로 한 Xerces-C++ 을 사용하는 중일때, 이 .xsd 파일들이

// ResourceProvider system에서 반드시 이용가능하다는 것이다.

// 

// 이것은  schema 파일들을 포함하고있는 디렉토리에서 리소스 그룹들을 세팅하는 것에의해 그리고  

// schema 파일들을 로딩하는 중일때 CEGUI::XercesParser에 의해 사용되는 default 로서 그 그룹을 세팅하는것에

// 대게 가장 잘맞게 달성되어지진다.

// 

// ( schema 파일들 :   The Beginners Guide to resource loading with ResourceProviders

// [http://www.cegui.org.uk/docs/current/resprov_tutorial.html] 이  안에서 

// 이것이(스키마 파일) 다뤄지고있는것을 수행하기위한 세부사항  )



//[데이터 파일]

// 이전에 언급된 것으로서, CEGUI에 대다수의 데이터 파일은 XML기반이다. 

// 일반적 '.xml' 파일 확장자를 사용하는 것 보다, 데이터 파일은 파일들이 실제로 나타내는 것에따라 보통  지정된다

// 예를들어, Imageset을 위한 .imageset과 Font를 위한 .font

// (그렇지만, 이 이름짓는 system의 필요조건은 없다 - 당신은 당신이 좋아하는 어떠한 방법을 이름짓는것은 자유다)

// 목적 각 파일 타입의 매우 간략한 개요를 이제 따른다.

// 

// [Imageset]

// Imageset은 몇몇의 소스외면에 이름지어진 지역들의 모음이다, image파일 또는 texture 와 같은..

// CEGUI 전문용어안에서, 각각의 이 명명된 지역들은 Image 이며 CEGUI에 의해 사용 되어지는 사진의 기본 레벨이다.

// 소스 image파일 또는 텍스쳐 컨텐츠를 수정하는것에 의해서, 또는 Imageset 파일을 가지고 정의되는 지역들의 범위들을

// 수정하는것에 의해서 , 당신은 CEGUI에 의해 그려지는 것의 표현을 쉽게 변화시킨다.

// 

// Imageset 파일들의 완벽한 설명을 위해서, Imageset XML 파일들을 보아라. ( Imageset XML files [http://www.cegui.org.uk/docs/current/xml_imageset.html] )

// 

// [Font]

// 놀랄것도 없이, Font 파일은 CEGUI안에서 사용을위한 폰트를 정의한다.

// 정의되어질 수 있는 폰트는 존재하는 두가지 타입들에 있다  :

// 

// FreeTypeFont) : 이것은 표준 폰트 파일에 기반되어진 폰트이다( true-type '.ttf' font 와 같이 ).

// FreeTypeFont은 .font XML 파일안에서 속성 Type="FreeType"을 통해서 지정된다.

// Imageset 파일들의 완전한 설명을 위해서, Imageset XML files를 보아라

//   (Imageset XML files [http://www.cegui.org.uk/docs/current/xml_imageset.html] )

//

// PixmapFont) : 폰트의 이 타입은 폰트 문자를 위해서 Image들을 정의하는 Imageset에 기반되는 폰트이다,

//  그리고 비트맵된 폰트로서 생각되어지는 최상이다.

//  PixmapFont는 .font XML 파일안에서 속성 Type="Pixamp"을 통해서 지정된다.

// 폰트 파일의 완전한 설명을 위해서, Font XML 파일들을 보아라. 

//   (Font XML files. [http://www.cegui.org.uk/docs/current/xml_font.html] )

// 

// LookNFeel) : LookNFeel은 중요한 대부분의 CEGUI의 skinning system에서 보관한다. 

// 각각은 하나 또는 system 다수 이미지와 자식 widget 구성요소들, 그것들의 위치들, 

// 추가적은 속성 값, 등등에 설명된 더 많은 WidgetLook 정의들을 포함할 것이다.

// 이 WidgetLook 설명은 CEGUI안에 window들과  widget들로서 결국 나타나지는 것으로 system 내부의 요소들을

// 반드시 구체화한다.,


// 폰트 파일들의 완전한 설명을 위해서, Font XML files를 보아라 

// ( Font XML files [http://www.cegui.org.uk/docs/current/xml_font.html] )


// Scheme) :  Scheme 파일은 다른 데이터 파일들과 리소스들과 함께 그룹짓기위한 큰 수단이다.

//         그리고 그것들의 상호작용의 몇몇을 정의하기위해서, 

//         그리고 CEGUI의 window들과 widget들을 위해서 'skin' 으로 간주되어질 것들을 로딩하기위해서 싱글 포인터로부터.

//         Schme는 하나 또는 더 많은 아래것들을 포함할 수 있다.

//         1) Imageset은 scheme의 부분으로서 로드되어지는 Imageset 파일을 지정한다

//         2) Font는 scheme의 부분으로서 로드되어지는 Font 파일을 지정한다

//         3) LookNFeel은 scheme의 부분으로서 로드되어지는 LookNFeel 파일을 지정한다

//         4) WidowSet은 로드할 수있는 모듈의 이름을 지정한다,  widget 이름들의 set은 당신이 system을 등록하려는

//           모듈을(로드할 수있는 모듈의 이름을) 포함한다.

//           ( 비록 어떤 이름들이 열거되지 않더라도, 모듈에서 모든 이용가능한 타입들이 등록되어진다, system 에 )

//           이것은 CEGUI에 추가된 핵심 widget 타입을 더하는것의 편리한 방법이다.

//           ( 특별하게 비록 이 모듈이 타사에의해서 제공되어졌다 할지라도 )

//         5) WindowRendererSet은 로드할 수있는 모듈의 이름을 지정한다, 

//            그리고 window renderer의 set은 당신이 system을 등록하기 바라는 그 모듈(로드할 수있는 모듈의 이름) 내부를 포함한다

//            ( 비록 어떤 이름들이 열거되지 않더라도, 모듈에서 모든 이용가능한 타입들이 등록되어진다, system 에 )

//            'Window Renderer'는 몇몇 기본 window 타입(들)을 위해서 렌더링을 제어할 수있는 오브젝트이다.

//            CEGUI에 의해서 공급되어진 모든 window renderer 오브젝트들은 'Falagard' skinning system의 

//            활용에 의해서 렌더링을 수행한다 (비록 이것이 엄밀한 요구사항이 아닐지라도.. )

//                (Falagard는 웹에서 찾아보니 : CEGUI에서 사용하는 Falagard시스템. 즉 UI커스터마이징을 가능하게 해주는 시스템 

//                          이라 함 , 이 사람이 http://historyis.tistory.com/47 이것에 대한 설명서를 한글화 하여 파일 링크 걸어놓음)

//           6) WindowAlias는 대체 가능한 이름들에 의해서 window/widget 타입에 참조되는 방법을 제공한다.

//               또한 그리고 그것(WindowAlias)은 또 다른 widget 타입을 가지고 이미 등록되어진 Widget 타입을 'hide'  하는데에

//               사용되어질 수있다. ( 그래서 그 다른 widget타입이 대신에 사용되어진다. )

//           7) FalagarMapping은 구체적인 window/widget타입, window renderer타입 그리고 widget look 정의를 링크하는 것에

//               의해서 새로운 사용하기 편리한 window타입을 만든다.

//               

//               scheme파일들의 완벽한 설명을위해서, Scheme XML files를 보아라 [Scheme XML files: http://www.cegui.org.uk/docs/current/xml_scheme.html ]

//

//

// Layout) : layout 파일은 window layout의 XML 설명을 포함한다. 각 끼워넣어진 'Window' 요소는 window 또는 만들어지는 widget을 정의한다,

//               'Property' 요소들은 각 정의되어진 window를 위해서 바랬던 세팅들과 속성 값들을 정의한다.

//     ( layout 파일들의 완벽한 설명을 위해서, Layout XML files을 보아라 [Layout XML files : http://www.cegui.org.uk/docs/current/xml_layout.html ]  )

//  

// Config ) : CEGUI의 config 파일은 모든 system defaults, 로드되어지는 초기 리소스들, 뿐만 아니라 

// Renderer와 System 오브젝트들을 만드는 그것을 넘어 C++코드의 한 줄 쓰는것 없이

// 실행하기( ScriptModule를 사용하는 중일때 ) 위한 초기화와 종료 스크립트 파일들을 지정하는것을 

// 당신에게 ㅎ ㅓ 락한다 

// ( config 파일의 완벽한 설명을 위해서, CEGUI Configuration XML files를 보아라 

//  [CEGUI Configuration XML files : http://www.cegui.org.uk/docs/current/xml_config.html ] )




// [ 기본 파일들을 로딩하는 것 ]

// 

// 것들(일,동작)을 설치하기 위해서 그리고 몇몇 파일들에서 당신이 로드해야만하는 것을 실행하는것.

// 필요되어지는 파일들의 전형적인 set은

// 1) Imageset

// 2) Font

// 3) LookNFeel

// 4) Scheme

// 이다.



//Scheme 파일에 대하여 유용한(당신이 위 설명으로부터 지금까지 쭉 수집되어왔을 것으로 )

// 것은 당신을 위해서 다른 파일들을 자동적으로 로딩할 수 있는것이다.

// 이 튜토리얼의 목적을 위해서, 우리는 scheme 파일들과 font 파일들 로드할 것이다.

// (그것(로드할)은  scheme가 우리를 위해서 Imageset과 LookNFeel을 자동적으로 로드한다는 것을 맡는다 )

// scheme와 font 파일들은 수행되어진다.

// 이와같이 :


// TaharezLook scheme 파일을 생성한다/로드한다

// 이 자동로드 TaharezLook looknfeel와 imageset file들

CEGUI::SchemeManager::getSingleton().create( "TaharezLook.scheme" );

// 폰트를 생성/로드한다

// 로드되어지는 첫번째 폰트는 자동적으로 default 폰트이다, 하지만

// scheme는 이미 로드되어지는 폰트를 가졌을 수있다는것에 주의해야한다,

// 그래서 이미 default set이 존재할것이다,

//  만약 우리가 확실하게 default이기 위해서 "Commonweath-10"폰트를 원한다면, 우리는 명시적으로 나중에

//  default를 설정해야만한다.

//CEGUI::FontManager::getSingleton().create( "DejaVuSans-10.font" );


//위의 코드는(그리고 CEGUI 샘들을안에) 리소스 그릅 위치들과 default 그룹들이 

//[ResourceProviders로 리소스 로딩에 대한 가이드] 에서 설명되어진것으로서 모두 지금까지 쭉

// 설정되어왔다는 것을 가정한다.



//----------------==========-----------------[System defaults 초기화 sjh]----------------==========-----------------

//당신은 System을 위한 몇몇의 default 옵션들을 지정해야한다

//이것은 system은  font와 마우스커서가 이용할수있는 것으로 항상 가지고 있는것을 보증한다

//window 또는widget이 자신의것의 선호가 없음을 지정할때..

//FontManager 는 system default로서  첫번째로 로드되어지는 font 를 자동적으로 세팅한다.

//만약 이것이 당신이 필요로하는 default font가 아니라면, 또는 만약 당신이 이전 font들이 로드되어졌다는것을 보증할수 없다면

// 당신은 명시적으로 default를 지정해야한다, 이 코드로

//System::getSingleton().setDefaultFont( "DejaVuSans-10" );



//또 하나의 당신이 일반적으로 설정 할수있는 오브젝트는 마우스 커서이다

// 이것은 당신이 그것의 커서를 설정하지않은 어떠한 요소의 위로 마우스를 움직일때 마우스커서는 사라지지않는다는것을 보증한다

// 설정하기위한 default 마우스 커서를위한 코드는 아래와 같고

// 이것은 scheme에의해 로드되어지는 TaharezLook imageset을 사용한다

System::getSingleton().setDefaultMouseCursor( "TaharezLook", "MouseArrow" );


//마지막으로, 만약 당신이 툴 팁들을 사용하길 생각한다면

//당신은 당신이 그것의 목적을위해서 사용되는것을 원하는 widget 타입 기반의 ToolTip의 이름을 지정해야한다

// window 단위당 기준에 대해 이것을 설정하는것은 실제로 가능하다

// 비록 이것이 일반적으로 필요되어지지 않고 이 서문의 튜토리얼의 범위를 넘어서는 것일지라도

// default tool tip window 타입을 설정하는 코드는 이것과 같다

System::getSingleton().setDefaultTooltip( "TaharezLook/Tooltip" ); //문서에는 setDefaultToolTip 이라고 되어있지만 T 가 CEGUI::SYSTEM 에서찾아보니 소문자이다

//여기까지가 가장 기본적인 초기화이고 CEGUI 을 초기화하는 최소한의 작업이다








 ===================  =================== ================[ 생성 부분 ]===================  ===================  ===================






using namespace CEGUI;

//CEGUI 창 생성

CEGUI_TRY{


//http://www.cegui.org.uk/docs/current/window_tutorial.html

// The Beginners Guide to Creating a CEGUI Window

//이부분을 더중요한 부분이라 하니 번역해 놓는다.. 역시 나중에 시간이 지나 까먹었을때를 대비해서 [sjh]


// * brief : [모든 widget은 window이다]

// * 이것은 CEGUI로 작동할때 반드시 완전히이해되어져야하는 가장 중심의 개념이다(열라 강조한다...;;)

// * system에있는 모든 widget은 동일한 Window 기반 클래스로부터 상속되어진다.   [ http://www.cegui.org.uk/docs/current/window_tutorial.html 여기의 내용을 중요부분을 번역해놓는다, 다음 문장 번역을 위해 써놓음]

// * 그래서 나는(튜토리얼쓴사람) window를 언급할때는 언제든지, 이 튜토리얼의 목적들을 위해서,

// * 동일한 아이디어들은 push button 또는 스크롤바 widget으로 그냥 쉽게 적용되어질 수있다는 설명을 덧붙인다. (튜토리얼이 비기너 튜토리얼이라 이런 글을 써놓은듯..)

//

// * brief [많은 설정들은 상속되어진다]

// * CEGUI안에서 window들을 위해서 유용한 많은 설정들과 속성들은 window 계층구조아래로 전달되어진다.

// * 예를들어, 그때 default에 의해서, 만약 당신이 0.5로 특정한 window 에 대해 알파 투명도를 설정한다면 모든 window와 widgets은

// * window가 더 높은 값들에서 적용되어진 변화들에의해  또한 영향을받을것으로 붙여진다.

// * 예를들어, 비록 자식 window에대해 실질적으로 설정된것(마지막 값들)을 바뀌지않게 유지하고 그리고/또는 

// * 사용되어진 설정들은 현재 window로 상속된 계층구조안에서 모든 window들로부터 설정되는 값들의 몇몇의 조합들은 

// * 일반적일지라도..

//

//

// * 이것은 window 제거와 같은것들로 또한 적용한다; 예를들어, default에 의해서, window는 붙여진 자식 window들과 widges들을

// * 제거할 것이다 window가 파괴되어질때....

// * 이 방식의 주요 이점은 당신이 알파, visility, enabled/disabled 상태 와같은 것들을 위해서  

// * root window 설정들로 변화들을 만든것에의해 전체 GUI에 쉽게 영향을 줄수있다는 것이다

// *  그리고 root window를 간단하게 파괴하는것에 의해서 전체의 GUI layout을 쉽게 제거할수있다.

// *  

// *  default 상속된 동작들은 제어가 주어진 더 좋은것이 필요로 되어지는 또는

// *  관리 기술들이 향상된 일부가 사용되어지는 window 단위당에 대해 오버라이딩 되어질 수있다.

 


//brief [ window들을 생성한다]

// 동작하게하는 이것(window생성 하는것)의 두가지 방법이 있다, C++ 코드와 XML layout 파일들을 통해서...

// 각 접근은 아래에 논의되어진다

//

// brief [ C++ 코드를 통해 GUI 생성 ]

//  CEGUI에 있는 모든 window들은 WindowManager 싱글톤 오브젝트에 의해 생성되어진다

//  당신은 WindowManager::getSingleton 함수를 통해서 이 오브젝트들로 접근할수 있다.

WindowManager& wmgr = WindowManager::getSingleton();


//대게, 당신은 당신의 GUI 안에 'root' window로서 DefaultWindow(또는 그것의 이전 이름 DefaultGUISheet 을 사용하기위해서 ) 로서 

//알려진 것들을 사용할 것이다

// 이것은 필요하지않다, 하지만 CEGUI를 위해서 사용법의 받아들여지는 패턴이다.

// 그리고 당신이 더 많은 top-level window들을 더하는것을 시작하자마자 그것들(windows)을  배치하는것을 돕는다.

// 

// 본격적으로 시작하기위해서, 

// 그래서 우리는 GUI를 위해서 root 'GUI Sheet'로서 그것(DefaultWindow)을 설정함으로서 DefaultWindow를 생성할 수 있다

Window* myRoot = wmgr.createWindow( "DefaultWindow", "root" );

System::getSingleton().setGUISheet( myRoot ); //setGUISheet 는 Set the active GUI sheet (root) window. 


//WindowManager::createWindow함수는 그것의 파라미터들로서 두개의 스트링들을 취한다

//이 예제안에서 "DefaultWindow" 첫번째 파라미터는 system에게 type 또는당신이 생성하기 바라는

//window의 클래스를 말해준다.

// 일반적으로,  비록 일부일지라 하더라도, 당신이 이용할수있는것을 가지는 window는 

// 당신이 당신의 scheme 파일, DefaultWindow와 같은것을 로드했을때 등록되어지게되는 그것들이(window)

// global 타입들이고 항상 이용가능하다

// 

// 이 예제에서 "root" 두번째 파라미터는 window로 할당되어질 유일한 이름이다

// 이 이름은 나중에 WindowManager로부터 window에대한 포인터를 검색하는 것으로 사용되어질수있다

// 명칭된 당신의 root window "root" 는 필요하지 않지만 일반적인 문법인것을 주의해야한다

// 

// System::setGUISheet함수는 GUI의 root로서 주어진 window를 지정하는 것으로 사용되어진다.

// 이것은 어떤 현재 sheet/root window를 대체할 것이다

// 비록 이전 window계층구조가 실질적으로 소멸되어지지 않는다는것을 주의한다 할지라도(그것은

// 디스플레이로부터 단지 분리되는 것이다  ) 

// 당신은 System::setGUISheet 함수를 하용하는 그것들(window들) 사이에서 간단하게 flipping 에 의해서

// GUI 'pages' 사이에 쉽게 전환할 수있다

// 

// 지금 당신은 당신의 첫번째 윈도우를 지금까지 쭉 만들어왔고 그것을 GUI system으로 붙였다.

// 그리고 system은 그것이 GUI를 그릴때 GUI의 root 로서 이 window를 사용할것이다.

// 하지만 만약 당신이 이 코드를 사용하는 간단한 프로그램을 컴파일을 했다면, 당신은 어떤것도 아직 볼수없다 ;뭣때문이지? <- 내가쓴말 아님 

// 당신의 응용프로그램에 어떤문제는 없다,

// 위에 만들었던 DefaultWindow는 단지 전적으로 눈에 보이지않는다!

// 이것은 root window로서 완벽하게 적합작 DefaultWindow를 만드는 것이다; 그것은 다른 window와 widges들이 붙여질 수 있는

// 빈 도화지로서 제공한다

// 지금 그것들을 해보자...

// 

//여기에 frame window를 만들것이다;

// 이것은 당신의 테스트탑위의 window들에 유사한 방법으로 작동하는 window이다, 이 것은 title bar를 가지며 이동되어질 수있고, 사이즈가조절될 수있다.

FrameWindow* fWnd = static_cast<FrameWindow*>( wmgr.createWindow( "TaharezLook/FrameWindow", "testWindow" ));

//여기서 우리가 "TaharezLook/FramwWindow"  window를 만드는 중이다. 이것의 이름은 system도처에 보여지는 또다른 규칙을 사용한다

// window 타입은 widget set의 이름에 의해서 앞에 붙여진다

// (만약 당신이 WindowsLook scheme를 로드할경우, 당신은 대신에 "WidndowsLook/FramwWindow" 를 생성할수있다 )

// 우리는 우리의 새로운 window에게 "testWindow"의 간단한 테스트 이름을 부여했다

// 기억해야하는 한가지 마지막인것은 캐스트의 사용이다, 이것(캐스트)은 WindowManage::createWindow 함수가 Window 타입을 항상 리턴하기 때문에

// 필요되어진다

// 

// 많은 다른 이 경우에서 기본 window 포인터는 충분할것이다, 

// 하지만 당신이 하위클래스들에 도입된 함수를 접근 하기를 원할 때가있다

// 그래서 보여지게되는것으로서의 캐스트 사용은 CEGUI를 사용하는 중일때 공통이다.

// 우리의 새로운 window로 유용한 어떤것을 할수있는 system을 위해서, 우리는 몇가지 추가적인 단계들을 수행해야한다

// 

// 1) 첫번째,  우리는 위에 설정한 root window로 window를 붙여야한다

myRoot->addChildWindow( fWnd );


//지금 우리는 초기 위치를 설정할수있고 우리의 window를 위한 사이즈를 설정할WindowManager

//CEGUI는 동일한 시간에서 상대적(scale)과 절대적(offset) 구성요소들의 사용을 활성화하는 '통합된' 좌표system을 사용한다

//이것은 당신이 볼것인 각 좌표들이 두 부분을 가지고있는 이유이다.

// 이 개념의 약간 확장되어진 소개를 위해서Falagard skinning system for CEGUI [http://www.cegui.org.uk/docs/current/fal_man.html] 의 부분인

// The Unified Co-ordinate System[http://www.cegui.org.uk/docs/current/fal_intro.html#fal_unifiedsystem]

// 을 보세요. (음......;; 귀차니즘이... )

// 

// 예제로 돌아가서

// 부모의 top-left로부터 거리의 1/4의 위치

fWnd->setPosition( UVector2( UDim( 0.25f, 0 ), UDim( 0.25f, 0 ) ) );


//부모의 절반 사이즈인 크기를 설정한다

fWnd->setSize( UVector2( UDim( 0.5f, 0 ), UDim( 0.5f, 0 ) ) ); //(그럼 1 이 부모의 full 사이즈라는 거네(0.~1.) )


//끝으로, 우리는 framw window의 타이틀바의 설명을 설정한다.

fWnd->setText( "Hello World!" );


//그리고 그것이 전부다!  (ㅋㅋㅋ)

//응용프로그램안에서 컴파일되어질때, 당신이 디스플레이의 중간에 간단한 frame window를 지금 볼것이다.


//[XML layouts]

// 위의 모든것은 아주 훌룡하다, 하지만 하나의 주요한 결점이있다;

// 당신이 GUI layout을 조정하는것을 바라는 어떤 시간에, 당신은 당신의 코드를 수정해야하고 

// 재컴파일을 해야한다. (This will get  old pretty quick), 그래서 당신이 정말로 원하는 것은

// 외부적으로 당신의 GUI layout을 지정할수있는것이다, 그리고 당신의 코드는 파일을 

// 통해 layout을 로드한다.    이것은 CEGUI layout XML 파일들의 목적이다.

// 

// system은 XML layout파일들을 지원한다, 그것은 WindowManager::loadWindowLayout 함수를 통해서 로드되어질수있다.

// 이 함수는 당신을 위한 모든 window들을 만든다 그리고 로드되는 계층구조의 root window에 포인터를 리턴한다

// 그것은 GUI의 root 로서 할당된것으로서 이상적이다!

// 

// 그래서, 모든것의 첫번째로 우리는 layout 파일을 필요로한다, 다음의 XML은 text 파일로서 저장되었다,

// 우리가 위에서 논의했던 코드에  layout 파일에 대응하는 것이다.

// <?xml version="1.0" ?>

// <GUILayout>

// <Window Type="DefaultWindow" Name="root">

// <Window Type="TaharezLook/FrameWindow" Name="testWindow">

// <Property Name="UnifiedPosition" Value="{ {0.25, 0}, {0.25, 0} }" />

// <Property Name="UnifiedSize" Value="{ {0.5, 0}, {0.5, 0} }" />

// <Property Name="Text" Value="Hello World!" />

// </Window>

// </Window>

// </GUILayout>


// Window 요소들은 WindowManager::createWindow 함수들에 확실한 매핑을 보여준다

// -그것들은 이전에 논의되었던 파라미터들에 정확하게 일치하는 타입과 이름을 가진다.

// Window 구성요소들의 내포된것은 다른것으로 어떤 window들을 붙이기위해서 사용되어진다

// 당신이 layout 파일안에서 하나의 'root' level window를 단지 가질것이라는 것에 주의해야한다

// 그것은 당신이 그 밖의 window들과 widget들이 위치되는 캔버스(도화지같은 공간)로서 사용되어지는 

// DefaultWindow를 대게 볼수있는것이 또 하나의 이유이다.


//속성 요소들은 정의되어지는중인 Window에 대한 속성들을 설정하기 위해서 사용되어진다.

// 각 window/widget 클래스를 위해서 이용할수있는 많은 속성들이 있다, 그리고 각 클래스는 

// 그것의(window)의 부모 클래스로부터 모든 속성들이 또한 상속된다.

// 이용가능한 하드코딩된 속성들과 그것들의 value string formats에대한 문서에 대해서 API reference안에

// Properties namespace들을 보시오. 

// 'Falagard' skin들은 그것들 자신의 속성들을 만들 수 있는 때문에, 당신이 사용하는 중인 window들은

// 이전 링크(이 'soft' 속성들에 대한)에서 열거되는 것보다 더 많은 속성들을 포함할 가능성이 있다.

// 당신은 기록문서가 당신이 사용중인 skin과 함게 제공되어지는 어느것이든지 참고해야한다

// 예를들어, CEGUI Wiki를 보시오 : 

// TaharezLook Properties http://www.cegui.org.uk/wiki/index.php/SetProperty

// WindowsLook Properties http://www.cegui.org.uk/wiki/index.php/SetProperty_(WindowsLook)

// 

// 만약 "test.layout" 로 불리는 파일로서 저장했다면, 당신은 이  layout을 로드할 수 있고 다음과 같이 

// GUI root 로서 그것을 설정할 수 있다.

// 


// Window* myRoot = WindowManager::getSingleton().loadWindowLayout( "test.layout" );

// System::getSingleton().setGUISheet( myRoot );


//최종결과는 예상보다 일찍 C++ 코드에서 수행되었던 것으로서 정확하게 동일하다.

// 지금 우리는 수정할 수 있는것을 기대하고 상수편집과 application 코드의 재컴파일에 대해 필요없이

// GUI layout을 향상시킨다.


//[결론]

//여기서 우리는 기본 window 생성을 수행하는 방법, 간단한 window 계층구조를 만드는 방법,

//, 그리고 몇몇의 window 세팅들을 수정하는 방법을 지금까지 쭉 보아왔다

// 당신은 이것이 C++코드와 외부의 XML layout 파일 둘다 사용해서 얻게되어질수있는 방법을 지금까지 쭉 보아왔다

// 양쪽의 방법들을 사용해서 이용가능한 많이 향상된 기능성들이 있다.

// 비록 그런 기능성들은 이 소개의 튜토리얼의 범위를 넘어서 있을지라도



}CEGUI_CATCH(Exception e){


std::cout<<"CEGUI:생성 : "<<e.what()<<std::endl<<std::endl;

return false;

}

return true;

}






 ===================  종료  ===================


종료하면서 해제하는 부분은 따로 번역할 것은 없으며



최근엔


CEGUI::Direct3D9Renderer::destroySystem();

CEGUI::System::destroy(); //모든 실글톤의 객체들을 제거됨



을 하거나 CEGUI 버전에 따라 싱글톤 포인터를 얻어와 해당 포인터를 직접 해제해주거나 해야 하는 방식 입니다







p.s CEGUI나 기타 게임에 관한 공유하실 분 있으면 언제든 환영합니다~






반응형

'그래픽스(Graphics) > GUI Library' 카테고리의 다른 글

CEGUI 설치  (0) 2012.11.02
GUI 제공하는 사이트들  (0) 2012.11.02
반응형


[포토샵] TGA파일에서 알파채널 만들기  Producer 

2010/11/09 19:16

복사http://blog.naver.com/kamikaze329/140117866938



TGA파일에서 알파채널을 만들어 보자. TGA파일은 에프터이팩트에서 여러장의 사진을 불러와 애니메이션 효과를 낼 수 있다. (다른 파일도 가능)

TGA파일을 불러온 후 채널란에 알패채널이 없다. 이제 추가 해보자.



레이어 창을 누른 뒤 background를 더블 클릭 후에 엔터를 쳐 새로운 레이어를 만들자.




새로운 레이어가 만들어 졌으면  왼쪽에 있는 툴을 선택해 알파채널을 만들 부분을 선택한다.



선택한후 Delete키를 누르면 체크 무늬의 배경이 생긴다.


 

여기서 ctrl + Shift + I 를 누르고 오른쪽 아래 채널에서 표시된 아이콘을 누르면 알파 채널이 생성이 된다.

 

ctrl + d 를 누르면 선택을 취소 한다.

ctrl  + s를 눌러 저장을 한다. 저장시 본래의 TGA파일로 선택 후 저장한다.



끝.~


반응형
반응형

DDS파일로 변환하기 두번째  PHOTOSHOP강좌 

2006/09/13 05:21

복사http://blog.naver.com/enuom/30008693994


그림파일 만드시는게 힘드신듯 한데, 예제 소스를 이용하시는 것을 보니 소스 설명은 접어
 
두고 어떻게 알파채널이 적용된 그림파일을 만드는지만 설명하겠습니다.
 
일단, 전 DDS파일 포멧으로 작업을 할것인데, 알파채널을 지원한다면 어떠한 파일 포멧
 
이어도 상관 없어요, 예로써 tga도 상관 없다는 거죠
 
필요한 준비물은 포토샾하고, dds를 다루기 위한 플러그인이 필요한데,
 
NVIDIA홈페이지 가면 있어요
 
http://developer.nvidia.com/object/photoshop_dds_plugins.html
 
다운 받으셨으면, 포토샾 플러그인에 넣어주면 다른이름 저장할때 dds포멧으로
 
저장 가능해질 겁니다.
 
준비 됐으니 만들어 보죠
 
(출처 : '빌보드의 텍스쳐 투명화 하는 법좀 자세힝 알려주세요' - 네이버 지식iN)

 

위와같은 그림으로 이미지를 만들었다고 하고

하얀부분은 투명해야 한다고 한다면

 

선택툴로 하얀 부분만 선택해줍니다.

마술봉(Magic Wand)으로 선택해주면 됩니다.

그런다음

 

채널에 보시면 알파채널이 없을 겁니다.

RGB채널만 있고 알파채널이 없으면 만들어 줍니다.

새로 만들면 선택 영역이 그대로 남아 있는데, 투명하게 되어야 할 곳을 검은색으로

색을 채워줍니다.

이제 dds파일로 저장만 해 주면 되는데 주의 사항이 있습니다.

 

레이어가 여러개일시 Merge시켜서 배경레이어로 합쳐주셔야 합니다.


원문:http://kin.naver.com/db/detail.php?d1id=1&dir_id=10103&eid=E68Wb2DBCvfjTZwNY9sUcsJGOQc8bv2n&qb=RERTxsTAz8DMtvU/

출처 : 지식인에서 crusader2k(출처 : '빌보드의 텍스쳐 투명화 하는 법좀 자세힝 알려주세요' - 네이버 지식iN)

 

DDS파일로 변환하기 두번째/영화광 강일웅(enuom)


반응형
반응형


포샵에서 DDS파일 만들기  PHOTOSHOP강좌 

2006/09/11 03:31

복사http://blog.naver.com/enuom/30008624015

DDS 포맷으로 저장할 일이 생겨서 하루종일 뒤적이고 물어가면서 얻은 팁인데 3D MMORPG의 경우 대다수의 개발사에서 이미지포맷으로 DDS를 사용하고 있으니 알아두면 좋을것 같아 정리해서 올립니다.

 

DDS는 DirectX(이하 DX)의 Texture 포맷과 일대일로 대응하는 파일 포맷으로 손실압축방식이라 다른 포맷에 비해서 상대적으로 비디오메모리를 아낄 수 있고, 많은 갯수의 텍스쳐, 큰 크기의 텍스쳐를 적은 용량으로 해결할 수 있는데다 DDS포맷 용량 그대로 비디오메모리에 올릴 수 있어 높은 퀄리티의 화면을 높은 프레임으로 구현하기가 용이합니다. 현재는 DDS가 거의 모든 그래픽카드에서 가속을 지원한다고 합니다.

 

DDS의 태생에 대해 잠깐 알아두자면, 처음에 S3TC포맷을 Savage사에서 개발하자, 3DFX에서 FXT1라는 포맷을 만들었다고 합니다. 그러자 S3사가 이 포맷을 NVIDIA, ATI에게 라이센스 해줌과 동시에 DX에서 공식적으로 지원하게 되었답니다.

아래 Nvidia 사이트에 가면 포토샵에서 DDS를 컨트롤할 수 있는 플러그인을 다운받을 수 있습니다.

 

http://developer.nvidia.com/object/photoshop_dds_plugins.html 

 

굳이 이 프로그램을 설치하지 않더라도 이 글에 첨부한 파일(dds.8bi)을 포토샵이 설치된 폴더 아래에 있는 Plug-Ins/Import-Export 폴더에 넣어주시면 됩니다.

 

자, 준비가 됐으면 시작해 보겠습니다.

예제 이미지로 얼룩말 무늬 이미지를 갖고 설명을 드리겠습니다.

1.우선 포토샵에서 얼룩말 이미지를 dds로 저장해 보겠습니다.

Save as 에서 파일포맷 dds(*.dds)를 선택하시면 아래와 같은 창이 나타납니다.


2. 창의 각 항목중 중요한 두가지 항목을 설명드리겠습니다.

 

Save Format DDS의 픽셀포맷을 정하는 것입니다.

DXT1, DXT2, DXT3, DXT5, 4:4:4:4 ARGB, 1:5:5:5 ARGB 등등 여러가지 포맷중 하나를 선택해야 합니다.

3. 각각의 선택기준은 상황에 따라 다릅니다만 DXTn 포맷만이 손실압축이고 그 외의 포맷은 비손실  압축이라 DXTn 포맷 외에는 쓸 일이 거의 없어 설명은 하지 않겠습니다.

 

1. DXT1 RGB(No Alpha) : 알파채널이 없는 이미지일 경우 (칼라는 4단계로 보간) 
2. DXT1 ARGB(1bit alpha) : 알파채널이 있지만 alpha test의 용도로만 쓰는 경우(칼라가 3단계로 보간되므로 DXT1 RGB보다 약간 퀄리티가 떨어짐) 
3. DXT3 ARGB(Explicit Alpha) : 알파채널이 있는 이미지 (칼라는 4단계로 보간되고 알파는 4비트로 표현) 
4. DXT5 ARGB(Interpolated) : 알파채널이 그라데이션 스타일인 경우 DXT5를 쓴다. (칼라는 4단계로 보간되고 알파는 8단계로 보간되므로 품질이 가장 좋음) 

 

그외의 포맷은 모르셔도 무방할것 같습니다. 어떤것이냐고 간단히 말씀드리면 4:4:4:4 ARGB는 ARGB(Alpha, Red, Green, Blue)의 심도가 각각 4bit란 얘기입니다. 1:5:5:5 는 Alpha=1bit(알파채널이 있다,없다만 표시), Red=5bit, Green=5bit, Blue=5bit 란 얘기지요.

 

한가지 주의할 점은 DXTn 포맷으로 저장하려는 이미지의 사이즈는 2의 승수가 되어야 합니다(2, 4, 8, 16, 32, 64, 128, 256, 512, 1024...)

2의 승수가 아니면 'DXT is supported for power 2 only' 란 멧세지가 나오면서 Save 버튼이 비활성화됩니다.

 

UI 이미지 같은 경우는 DDS 포맷으로 쓰는것은 심각하게 고려해야 합니다. 앞서 설명드렸듯이 손실압축이라 이미지가 상당히 깨질 수 있기 때문입니다. (슈마에서 렌즈온라인 만들때 UI 이미지를 DDS로 변환했더니 이미지가 아주 작살이 나더군요;;)

알파채널이 있는 UI 이미지는 PNG나 TGA를 쓰는것이 현명하다고 판단됩니다.

 

픽셀포맷 지정옵션 밑에 있는것이 렌더링 방식을 지정하는 옵션인데요. 2D texture, Cube Map, Volume Texture 가 있습니다.


 

4. 각각의 특성을 폴리곤에 맵핑하는 방법을 예로 들어 설명을 드리자면

 

1. 2D Texture : 각 폴리곤들의 texture coordinate(UV)값을 이용해서 입히는 방식(현재 게임 모델링 데이터에 맵핑하는 방식)

2. Cube Map : UV없이 폴리곤의 면적에 따라 맵핑하는 방식

3. Volume Texture : 좀 더 복잡한 굴곡이 있는 폴리곤에 UV없이 면적에 맵핑하는 방식

 

현재 게임개발에선 2D Texture 외엔 쓰지 않는다고 하니 나머지는 중요치 않습니다.

 

MIPMap Generation MIPMap의 생성갯수를 정합니다.(0~13)

MIPMap 은 같은 그림인데 다른 사이즈를 같이 지닌 형태를 말합니다. 한 이미지 파일에 여러 사이즈를 만들어 놓고 맵핑하고자 하는 폴리곤에 가장 근사한 크기를 갖는 밉맵을 이용하여 텍스쳐맵핑을 수행하는 것을 MIP Mapping이라고 하는거죠.

예를 들면 LOD 같은 것인데요, 게임배경으로 쓰인 돌이 멀리 있을때는 작은 사이즈의 이미지를 맵핑하고 가까이 왔을 때는 큰 이미지를 골라 맵핑하는 방법을 쓰는겁니다. 그렇게 되면 퀄리티의 큰 저하없이 좋은 퍼포먼스를 낼 수 있겠지요.

MIPMap의 갯수를 6으로 하여 미리보기를 해 보겠습니다.



5. 원래 사이즈에  1/4 씩 작아진 사이즈 5개가 생성된 것을 보실 수 있습니다.

이 중 제일 작은 사이즈는 굉장히 멀리 있는 오브젝트에 적용되고 그 오브젝트가 가까이 다가올수록 그 거리에 따라 자동으로 적절한 사이즈의 이미지를 골라 맵핑시키는 방식을 쓰는 겁니다. MIPMap의 갯수가 적으면 멀리 있던 이미지가 가까이 올때 흐리던 이미지가 갑자기 팍 선명해져서 어색할 수 있으니 MIPMap의 갯수는 보통은 5~8개 정도로 합니다만 상황에 따라 적절히 선택하시면 되겠습니다.

 

이정도에서 저장해 주시면 되겠습니다. 저장뿐 아니라 dds로 저장된 파일도 포토샵에서 불러와 편집이 됩니다.

 

나름대로 자세히 정리했는데 더 궁금하신 점은 댓글을 달아 주시면 성심껏 답변드리겠습니다.

 

원본위치 : http://cafe.naver.com/ui.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=613

에 dx에서 많이 쓰는 dds포맷에 관한 자료가 있어서 퍼왔습니다.쓰신분은 세거이(seguy)님..

 

 

DDS에 대한 좋은 설명 요약 



chaen님의 DDS에 대한 의견. 



파일포맷과 픽셀포맷에 대한 구분이 좀 있었으면 합니다. TGA, JPG, DDS는 파일 포맷이고, A8R8G8B8, DXT1 같은 것은 픽셀 포맷입니다. 따라서 DDS == DXTn 은 아닙니다. 

DDS는 DirectX의 Texture 포맷과 일대일로 대응하는 '파일 포맷'일 뿐입니다. 
DDS에서도 A8R8G8B8 로 저장할 수 있습니다. 그 내용은 TGA 32bpp와 거의 똑같다고합니다. 
파일 사이즈 역시 거의 비슷하다고 합니다. R8G8B8, A8R8G8B, X1R5G5B5 같은 포맷은 TGA에서 지원하고, R8G8B8 같은 포맷은 JPG(어떻게 보면 압축된 R8G8B8), BMP같은 대부분의 일반적인 이미지 파일포맷들이 지원합니다. 다만, DXTn(DTXc,S3TC)을 저장할 마땅한 포맷이 없어서 DDS를 쓰다보니 DDS == DXTn 이라고 이야기들을 하시는 것같습니다. 

DDS는 밉맵의 각 레벨의 서피스를 묶어서 하나의 파일로 저장할 수도 있고, 심지어 Cube 텍스쳐나 Volume 텍스쳐로도 저장이 가능합니다. 이런 면들을 볼 때 DDS 포맷의 진짜 목적은 DirectX에서 쓰는 텍스쳐와 같은 포맷을 사용함으로써, 텍스쳐 생성 후 파일에서 로딩한 데이터를 텍스쳐의 서피스로 복사해서 넣을 때, 압축해제나 픽셀포맷 변환없이 바로 사용할 수 있다는 게 아닐까 생각됩니다. 예를 들어, TGA 24bpp 이미지는 R8G8B8( B8G8R8 ) 이지만 오늘날 대부분의 그래픽 카드에서는 DirectX에서 이에 해당하는 D3DFMT_R8G8B8 포맷을 잘 지원하지 않습니다. 
대신 대부분 D3DFMT_X8R8G8B8 포맷을 지원하죠. 따라서, 알파 없는 TGA 파일을 사용한다면 항상 모든 픽셀에 대해서 포맷 변환 작업이 필요하게 됩니다. 이때 DDS로 X8R8G8B8 포맷을 만들어서 사용한다면 그런 변환 작업이 필요 없어집니다. 

그럼에도 불구하고 대부분의 개발자들이 JPG나 TGA 파일을 여전히 선호하는 결정적인 이유는 Preview(미리보기)가 가능하기 때문인 거 같습니다. ACDSee나 알씨 같은 이미지 뷰어에서 이미지를 미리 볼 수 없다는 것은 상당히 답답한 일이죠. ( Deep Exploration 같은 좋은 툴이 DDS 포맷을 지원하기는 합니다만.) 또, 포토샵 같은 그래픽툴에서 바로 쓸 수 없어 번거롭죠. (물론, 플러그인 등을 깔면 가능합니다.) 

PC 같이 다양한 하드웨어가 상존하는 플랫폼에서는 어쩌면 픽셀 포맷 변환이라는 것이 필수 불가결한 일 일지도 모릅니다. 적당한 픽셀 포맷을 미리 지정해서 DDS 포맷으로 저장했다고 하더라도, 이를 지원하지 않는 하드웨어를 가진 일부 사용자들은 결국 픽셀변환이 필요하기 때문이죠. 때로는 더 나은 성능을 위해서 32bpp나 24bpp 포맷을 16bpp 포맷으로 변환하는 작업이 필요할 때도 있습니다. 

DXT 포맷을 제외한 나머지 포맷들은 전혀 압축이 되지 않아서 전체 게임데이터 양을 크게 만든다는 단점도 있습니다. 이는 파일서버 여유공간이 부족한 개발사에겐 게임 개발 과정 중 데이터 유지관리에 부담이 될 수도 있으며, 게임 설치후 HDD를 차지하는 공간이 커져서 소비자에게 부담스러울 수도 있습니다. 물론, 퀘이크 시리즈처럼 게임 데이터들을 ZIP 파일로 한번 더 묶어 줌으로서 해결할 수 있는 문제이기도 합니다. 

간단히 추론하자면 적당한 환경이 갖춰진다면 모든 텍스쳐 포맷을 DDS로 쓰는 게 게임의 성능을 위해서 좋지만 현실적으로는 일반적인 이미지 포맷과 DDS를 섞어 쓰는 것도 나쁘지 않다고 생각합니다. 혹은 개발중에는 섞어 쓰다가 릴리즈용 리소스들을 묶어 주면서, 모든 텍스쳐를 DDS 포맷으로 자동으로 변환해 주는 배치 파일이나 툴을 만드는 것도 괜찮을 거 같습니다. 플랫폼과 일대일로 대응하는 포맷을 미리 리소스로 만드는 작업은 콘솔 플랫폼에서는 거의 필수적인 일입니다. 



etds님의 DDS사용에 대한 제안. 


- DXTn을 썼을 때의 장점 
1. 메모리를 꽤 적게 쓴다. (또 메모리 대역폭도 아낄 수 있다.) 
2. 대부분의 비디오카드가 하드웨어 가속을 지원하므로 성능 저하가 없다. 
3. 메모리를 적게 쓰는데 비해 퀄리티가 나쁘지 않다. 특히, 노이즈 같은 주파수가 높은 텍스쳐들에 효율적이다. 
(반대로 그라데이션같은 느낌의 텍스쳐에서는 계단이 눈에 띄게 보인다. 그래서 편법을 쓰지 않으면 노말맵에 쓰기에도 별로 좋지 않다.) 

제가 사용하는 DXTn 사용시 가이드라인은, 
1. 알파채널이 없는 경우 무조건 Opaque DXT1을 쓴다. (칼라는 4단계로 보간) 
2. 알파채널이 있지만 alpha testing의 용도로 쓰는 경우 1bit alpha DXT1을 쓴다. (이 경우 칼라가 3단계로 보간되므로 Opaque DXT1보다 약간 퀄리티가 떨어져 보일 수 있다.) 
3. 알파채널이 중요한 경우 DXT3을 쓴다. (칼라는 4단계로 보간되고 알파는 4비트로 표현) 
4. 알파채널이 그라데이션 스타일인 경우 DXT5를 쓴다. (칼라는 4단계로 보간되고 알파는 8단계로 보간) 
5. 그래픽 디자이너가 이상하다고 하는 경우나, GUI에 쓰이는 글씨 이미지 같은 경우 jpg 또는 tga를 그냥 쓴다. 

이분의 경우 소속된 회사에서 서비스하고 있는 온라인 게임에서 보통 3번째까지 적용하면 대부분 문제가 없었고, 이펙트 등에 쓰이는 알파가 중요하게 들어간 텍스쳐만 4번째까지 적용하곤 했다합니다. 그래픽 디자이너들과의 의견 조율 및 절충으로 5번까지 가는 경우는 생각보다 드물었다고 합니다. 



그외 DDS에 관한 참고가 될만한 이야기. 



비회원으로 로그인 하신분의 글. 



DDS 포맷의 태생은 S3사의 S3TC인데 당시 이 포맷이 나왔을 때에는 비디오메모리가 많이 부족한 시절(4M, 8M)이었고 S3 Savage에서는 S3TC 하드웨어 가속이 가능했었습니다. 또, 당시 DX에서는 지금처럼 기본 텍스춰 포맷으로 지원하지 않고 있었습니다. 당시 가장 좋은(?) 그래픽카드였던 Voodoo2의 경우에는 S3TC의 위력을 보여주기 위해 만든 데모와 같은 고 퀄리티의 화면을 높은 프레임으로 구현하기가 힘들었죠.. 아마도 현재는 이 기술이 모든 그래픽카드에서 가속을 지원한다고 추론해 보았을 때(실제 DDS포맷 용량 그대로 비디오메모리에 올릴 수 있습니다) 

DDS의 장점은 손실압축이지만, 일반 포맷에 비해 상대적으로 비디오메모리를 아낄 수 있고, 많은 개수의 텍스춰, 큰 크기의 텍스춰를 낮은 코스트로 사용할 수 있을 것..만 같습니다. 정확한건 벤치마킹을 해봐야 겠죠. DDS의 압축 특성상 사용해야 할 곳은 색들이 고르게 분포된 텍스춰일 것이고요.. 가장 좋은 예로는 지형 텍스춰들일 것이고, MMORPG의 경우 캐릭터들은 대부분 3인칭에서 보므로, 줌인시의 퀄리티가 HDTV처럼 땀구멍까지 보이게 할 필요도 없으므로 캐릭터 텍스춰에도 적절히 쓸 수 있을 것 같습니다. myevan님이 지적해 주신 UI같은 경우, 매번 줌인(?)되서 보이는 텍스춰 인데다가, DDS의 특성상 주위 픽셀에 따라 색이 많이 왜곡되고, width, height이 낮은 pixel의 텍스춰도 찍어야 되는 상황이 많으므로 DDS를 사용하지 않는 것이 좋겠네요.. 



자료를 좀 더 찾아보니, 처음에 S3사가 S3TC포맷을 Savage사에서 개발하자, 3DFX에서 FXT1라는 
포맷을 만들었다고 합니다. 그러자 S3사가 이 포맷을 NVIDIA, ATI에게 라이센스 해줌과 동시에 DX에서 공식적으로 지원하게 되었답니다. S3TC와 FXT1에 대한 URL이기는 하지만, 퀄리티가 어떻게 나빠지나에 대해 참고가 될 것 입니다. 

http://www.digit-life.com/articles/reviews3tcfxt1/

반응형
반응형


[2007.12.15] 파티클 (Particle)  Direct3D Study 

2007/12/15 23:12

복사http://blog.naver.com/csm3138/110025403677


파티클(Particle)

- 파티클이란, 아주 작은 입자들로서 게임화면에서 눈, 비, 폭발, 연기등의 특수한 효과를 구현하기

  위하여 사용하는 점단위 입자를 말한다.

- 파티클은 매우 작은 입자이며 하나의 점(point)로 모델링이 이루어진다.

- D3DPRIMITIVETYPE에서 점을 그리는 인자값은 D3DPT_POINTLIST(점단위 렌더링) 이다.

   그러나 파티클을 표현하기 위해서는 D3DPT_POINTSPRITE를 사용한다. D3DPT_POINTSPRITE를

   사용하는 이유는 똑같은 점단위 렌더링을 하지만 POINTSPRITE는 텍스처의 적용이 가능하며,

   크기또한 변경이 가능하기 때문이다.

 

파티클 점(point)를 구성하는 구조체

 strucr   Particle

{

      D3DXVECTOR3   pos;            // 파티클 점의 위치

      D3DCOLOR        color;          // 파티클의 컬러값

      static  const  DWORD  FVF;   // 플래그 값

};

const DWORD Particle::FVF = D3DFVF_XYZ|D3DFVF_DIFFUSE;

-> 이 구조체는 파티클의 한점의 정보를 저장하는 구조체이다. 기본적으로 점의 3차원 위치와

     컬러값, 플래그값을 가지고 있다.

     여기에 부동소수점 변수(float형)를 추가하면 파티클의 크기를 지정할수 있다. 파티클의 크기의

     변경은 직접하기보다는 렌더 상태에서 파티클의 크기를 제어해 주어야 한다. 이유는 직접

     파티클 크기를 변경을 지원하지 않는 그래픽 카드도 있기 때문이다.

 

파티클의 크기지정 변수를 추가한 구조체

struct Particle

{

      D3DXVECTOR3   pos;

      D3DCOLOR        color;

      float                  size;        // 파티클의 크기

      static  const  DWORD  FVF;

};

const  DWORD  Particle::FVF = D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_PSIZE;

-> 플래그값도 하나 더 추가하여 준다. D3DFVF_PSIZE

 

포인트 스프라이트 렌더 상태

- 포인트 스프라이트의 동작들은 거의 대부분 렌더 상태에 의하여 제어된다.

  -> SetRenderState()

 

D3DRS_POINTSPRITEENABLE

- 텍스처 매핑에 이용할 텍스처의 형태를 지정하여준다.

- 값은 bool값으로 true, false 값이다.

true : 현재 지정된 전체 텍스처를 포인트 스프라이트 텍스처 매핑에 사용한다.

false : 스프라이트 텍스처 좌표로 지정한(스프라이트 이미지 좌표값에서) 텍셀을 이용하여 포인트

          스프라이트의 텍스처를 입힌다.

(ex) m_pDevice->SetRenterState(D3DRS_POINTSPRITEENABLE, true);

 

D3DRS_POINTSCALEENABLE

- 포인트의 크기를 뷰 또는 스크린 스페이스 단위로 해석지정을 한다.

true : 포인트의 크기를 뷰스페이스 단위로 해석 지정

false : 포인트 크기를 스크린 스페이스 단위로 해석 지정

(ex) m_pDevice->SetRenderState(D3DRS_POINTSCALEENABLE, true);

 

D3DRS_POINTSIZE

- 포인트 스프라이트의 크기를 지정하여준다.

(ex) m_pDevice->SetRender(D3DRS_POINTSIZE, (크기 DWORD));

 

D3DRS_POINTSIZE_MIN

D3DRS_POINTSIZE_MAX

- 포인트 스프라이트의 최대 크기와 최소 크기를 지정하여 준다.

(ex) m_pDevice->SetRenderState(D3DPT_POINTSIZE_MIN, (크기 DWORD));

       m_pDevice->SetRenderState(D3DPT_POINTSIZE_MAX, (크기 DWORD));

 

D3DRS_POINTSCALE_A

D3DRS_POINTSCALE_B

D3DRS_POINTSCALE_C

- 거리에 따른 포인트 스프라이트의 크기를 제어 한다.

- 최종적인 포인트 스프라이트의 크기는

 이다.

   - ViewportHeight : 뷰포트의 높이

   - A, B, C : SCALE의 값

   - D : 뷰 스페이스(카메라 좌표)내의 포인트 스프라이트와 카메라 위치와의 거리

 

파티클과 파티클의 속성들

- 파티클은 위치와 컬러 이외에도 많은 속성들로 이루어져 있다.

- 파티클을 렌더링할때 필요한 데이터와 속성들은 Particle 구조체가 아닌 Attribute 구조체에 따로

  보관하며, 렌더링할 준비가 완료되면 Particle 구조체로 위치와 속성을 복사하여 사용한다.

- 파티클의 속성은 모델링하려는 파티클 시스템의 종류에 따라 달라진다.

- 다음의 구조체는 몇 가지의 공통적인 파티클 속성을 포함하고 있다.

 struct Attribute

{

        D3DXVECTOR3  pos;                  // 월드 스페이스 내의 파티클의 위치

        D3DXVECTOR3  velocity;             // 파티클의 이동속도, 초당 이동단위

        D3DXVECTOR3  acceleration;      // 파티클의 가속도, 초당 이동단위

        D3DXVECTOR3  lifetime;              // 파티클의 생존시간

        D3DXVECTOR3  age;                  // 파티클의 나이(???)

        D3DXVECTOR3  color;                // 파티클의 컬러

        D3DXVECTOR3  colorfade;          // 파티클의 컬러가 시간의 흐름에 따라 변하는 방법

        D3DXVECTOR3  isalive;              // 파티클 생존유무!! 생존 true, 소멸 false

};

 

 

 

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

포샵에서 DDS파일 만들기(2)  (0) 2013.01.31
포샵에서 DDS파일 만들기(1)  (0) 2013.01.31
용책, 해골책  (0) 2013.01.31
간략한 파티클 시스템  (0) 2013.01.31
파티클 간단한 렌더링  (0) 2013.01.31
반응형

http://www.cyworld.com/romejune/


이 블로그에서 용책과 해골책의 소스를 거진 올려놓음 음;;;; 그래도 되나? ㅋ

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

포샵에서 DDS파일 만들기(1)  (0) 2013.01.31
Direct 에서 파티클 SetRenderState 설정 설명  (0) 2013.01.31
간략한 파티클 시스템  (0) 2013.01.31
파티클 간단한 렌더링  (0) 2013.01.31
CommitChanges  (0) 2013.01.27
반응형


http://www.cyworld.com/romejune/5142517


//////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: pSystem.h
//
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Represents a geneal particle system.
//         
//////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __pSystemH__
#define __pSystemH__

#include "d3dUtility.h"
#include "camera.h"
#include <list>


namespace psys
{
 ////파티클의 위치와 컬러를 표현하는 데의 구조체 포맷.
 struct Particle
 {
  D3DXVECTOR3 _position;
  D3DCOLOR    _color;
  static const DWORD FVF;
 };
 
 struct Attribute
 {
  Attribute()
  {
   _lifeTime = 0.0f;
   _age      = 0.0f;
   _isAlive  = true;
  }

  // 파티클과 파티클의 속성들.
  
  // 파티클을 렌더링하는데 필요한 데이터와 파티클 속성을 별도의 구조체 내에 보관하게 되는데,
  // 파티클을 만들고 파괴하고 갱신할 때는 바로 이러한 속성을 이용해 작업하는 것이며,
  // 이를 렌더링할 준비가 완료되면 Particle 구조체로 위치와 속성을 복사해 이용.

  D3DXVECTOR3 _position;     // 월드 스페이스 내의 파티클 위치.
  D3DXVECTOR3 _velocity;     // 파티클의 속도, 보통은 초당 이동 단위로 기록.
  D3DXVECTOR3 _acceleration; // 파티클의 가속. 보통은 초당 이동 단위로 기록.
  float       _lifeTime;     // 파티클이 소멸할 때까지 유지되는 시간.
                                // 예, 레이저 빔 파티클은 특정한 시간동안만 유지.
  
float       _age;          // 파티클의 현재 나이
  D3DXCOLOR   _color;        // 파티클의 컬러
  D3DXCOLOR   _colorFade;    // 파티클의 컬러가 시간의 흐름에 따라 퇴색하는 방법
  bool        _isAlive;    // 파티클이 생존한 경우 true, 소멸한 경우 false
 };

 

 // 파티클 시스템의 요소들.
 
 // 파티클 시스템은 파티클들의 모임이며 파티클을 보여주고 관리하는 역할을 담당한다.
 // 파티클의 크기나 파티클 원천의 위치, 파티클에 적용할 텍스처 등
 // 시스템 내의 모든 파티클에 영향을 주는 전역 특성들을 관리.
 // 기능적 관점에서 보면
 // 파티클 갱신과 디스플레이, 소멸, 생성 등을 관장하는 역할.

 class PSystem
 {
 public:
  // 디폴트 값을 초기화하는 생성자와
  // 장치 인터페이스 (버텍스 버퍼, 텍스처)를 해제하는 디스트럭터
  PSystem();
  virtual ~PSystem();

 

  // init - 포인트 스프라이트를 저장하기 위한 버텍스 버퍼를 만들고
  // 텍스처를 만드는 등의 Direct3D의 장치 의존적인 초기화 작업을 처리.
  
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;

 

 // 렌더링에 앞서 지정해야 할 초기 렌더 상태를 지정.
  // 이 메서드는 시스템에 따라 달라질 수 있으므로 가상 함수로 선언.
  virtual void preRender();

 

  // 시스템 내의 모든 파티클들을 렌더링
  virtual void render();

 

  // 특정 파티클 시스템이 지정했을 수 있는 렌더 상태를 복구하는 데 이용.
  // 이 메서드는 시스템에 따라 달라질 수 있으므로 가상 메서드로 선언.
  virtual void postRender();

 

  // 현재 시스템에 파티클이 없는 경우 true 리턴.
  bool isEmpty();

  

// 시스템 내의 파티클이 모두 죽은 경우 true 리턴.
  bool isDead();

 

protected:
  // 속성 리스트 _particle을 검색하여 죽은 파티클을 리스트에서 제거.
  virtual void removeDeadParticles();

 protected:
  IDirect3DDevice9*       _device;
  D3DXVECTOR3             _origin;  // 시스템의 원천, 시스템 내에서 파티클이 시작되는 곳.
  d3d::BoundingBox        _boundingBox;  // 파티클이 이동할 수 있는 부피를 제한하는 데 이용.
  // 예, 산 정상을 둘러싼 지역에만 눈이 오는 시스템.
  // 원하는 영역을 경계상자로 정의하면 이 영역을 벗어난 파티클들을 곧바로 소멸.
  float                   _emitRate;   // 시스템에 새로운 파티클이 추가되는 비율. 보통은 초당 파티클 수로 기록.
  float                   _size;       // 시스템 내 모든 파티클의 크기
  IDirect3DTexture9*      _tex;
  IDirect3DVertexBuffer9* _vb;
  std::list<Attribute>    _particles;  // 시스템 내 파티클 속성의 리스트.

  // 우리는 파티클을 만들고 제거하고 갱신하는 데 이 리스트를 이용.
  // 파티클을 그릴 준비가 완료되면
  // 리스트 노드의 일부를 버텍스 버퍼로 복사하고
  // 파티클 드로잉 과정을 거친다.
  // 이어 다음 단계의 데이터를 복사하고 다시 파티클을 그리며,
  // 모든 파티클을 그릴 때까지 이 과정을 반복.

 

  int                     _maxParticles; // 주어진 시간 동안 시스템이 가질 수 있는 최대 파티클의 수.
  // 예, 파티클이 파괴되는 속도보다 만들어지는 속도가 빠르다면
  // 엄청나게 많은 수의 파티클이 동시에 존재할 수 있다.
  // 이 멤버는 이와 같은 상황을 막는다.

 

  DWORD _vbSize;      // 버텍스 버퍼가 보관할 수 있는 파티클의 수.
  // 이 값은 실제 파티클 시스템 내의 파티클 수와는 독립적.
  DWORD _vbOffset;    // 파티클 시스템의 렌더링에 이용.
  DWORD _vbBatchSize; // 파티클 시스템의 렌더링에 이용.
 };

 

 // 눈
 class Snow : public PSystem
 {
 public:
  // 생성자
  // 경계 상자 구조체를 가리키는 포인터와 시스템 내 파티클의 수
  // 경계 상자는 눈송이가 떨어질 부피를 정의하며,
  // 만약 눈송이가 이 범위 밖으로 벗어 나면 즉시 소멸하고 다시 만들어짐.
  // 항상 같은 수의 파티클을 유지.
  Snow(d3d::BoundingBox* boundingBox, int numParticles);
  void resetParticle(Attribute* attribute);
  void update(float timeDelta);
 };

 // 불꽃놀이
 class Firework : public PSystem
 {
 public:
  Firework(D3DXVECTOR3* origin, int numParticles);
  void resetParticle(Attribute* attribute);
  void update(float timeDelta);
  void preRender();
  void postRender();
 };

 // 입자총
 class ParticleGun : public PSystem
 {
 public:
  ParticleGun(Camera* camera);
  void resetParticle(Attribute* attribute);
  void update(float timeDelta);
 private:
  Camera* _camera;
 };
}

#endif // __pSystemH__

 

//////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: pSystem.cpp
//
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Represents a geneal particle system.
//         
//////////////////////////////////////////////////////////////////////////////////////////////////

#include <cstdlib>
#include "pSystem.h"

using namespace psys;

const DWORD Particle::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

// 초기화하는 생성자
PSystem::PSystem() 
{
 _device = 0;
 _vb     = 0; //버텍스 버퍼
 _tex    = 0; //텍스처
}

 

// 인터페이스 해제하는 디스트럭터
PSystem::~PSystem()
{
 d3d::Release<IDirect3DVertexBuffer9*>(_vb);
 d3d::Release<IDirect3DTexture9*>(_tex);
}

 

// init - 포인트 스프라이트를 저장하기 위한 버텍스 버퍼를 만들고
// 텍스처를 만드는 등의 Direct3D의 장치 의존적인 초기화 작업을 처리.
bool PSystem::init(IDirect3DDevice9* device, char* texFileName)
{
 // 우리는 동적 버텍스 버퍼를 이용할 것임.
 // 매 프레임 마다 파티클을 갱신해야 하며 이는 곧 버텍스 버퍼의 메모리에 접근해야 함을 의미.
 // 정적 버텍스 버퍼로의 접근 속도는 상당히 느리다는 데 주의.
 // 동적 버텍스 버퍼를 이용하는 것은 바로 이 때문.
 _device = device; 

 HRESULT hr = 0;

 hr = device->CreateVertexBuffer(
  // 버텍스 버퍼 크기가 _viSize에 의해 미리 정의되며
  // 시스템 내의 파티클 수와는 관련이 없음을 주의.
  _vbSize * sizeof(Particle),
  // 버텍스 버퍼가 포인트 스프라이트를 보관할 것임을 지정하는 D3DUSAGE_POINTS를 이용.
  D3DUSAGE_DYNAMIC | D3DUSAGE_POINTS | D3DUSAGE_WRITEONLY, 
  Particle::FVF,
  // 동적 버텍스 버퍼는 관리 메모리 풀에 보관할 수 없으므로 디폴트 메모리 풀을 이용.
  D3DPOOL_DEFAULT,
  &_vb,
  0);
 
 if(FAILED(hr))
 {
  ::MessageBox(0, "CreateVertexBuffer() - FAILED", "PSystem", 0);
  return false;
 }

 hr = D3DXCreateTextureFromFile(
  device,
  texFileName,
  &_tex);

 if(FAILED(hr))
 {
  ::MessageBox(0, "D3DXCreateTextureFromFile() - FAILED", "PSystem", 0);
  return false;
 }

 return true;
}

 

// 시스템 내의 모든 파티클 속성을 리셋.
void PSystem::reset()
{
 std::list<Attribute>::iterator i;
 for(i = _particles.begin(); i != _particles.end(); i++)
 {
  // 한 파티클의 속성을 리셋.
  // 파티클의 속성이 리셋되는 방식은 파티클 시스템에 따라 달라짐.
  // 따라서 하위 클래스에서 메서드를 구현하도록 추상 메서드로 선언.
  resetParticle( &(*i) );
 }
}

// 시스템에 파티클을 추가.
// 이 메서드는 리스트에 추가 하기전에 파티클을 초기화 하는데 resetPaticle 메서드를 이용.
void PSystem::addParticle()
{
 Attribute attribute;

 resetParticle(&attribute);

 _particles.push_back(attribute);
}

// 포인트 스프라이트 렌더 상태.
void PSystem::preRender()
{
 _device->SetRenderState(D3DRS_LIGHTING, false);

 // 현재 지정된 전체 텍스처를 포인트 스프라이트의 텍스처 매핑에 이용할것임을 의미.
 _device->SetRenderState(D3DRS_POINTSPRITEENABLE, true);

 // 포인트 크기를 뷰 스페이스 단위로 해석하도록 지정.
 // 뷰 스페이스 단위는 간단히 카메라 공간 내의 3D 포인트를 나타내며,
 // 포인트 스프라이트의 크기는 카메라와의 거리에 따라 적절하게 조정됨.
 // 즉, 카메라와 멀리 떨어진 파티클은 가까운 파티클에 비해작게 나타남.
 _device->SetRenderState(D3DRS_POINTSCALEENABLE, true);

 // 포인트 스프라이트의 크기를 지정.
 // 이 값은 D3DRS_POINTSCALEENABLE 상태 값에 따라서 뷰 스페이스 내의 크기나
 // 스크린 스페이스 내의 크기로 해석.
 // FtoDw 함수는 float을 DWORD로 형 변환한다.
 // 이 함수가 필요한 것은 일반적인 IDirect3DDevice9::SetRenderState 호출이
 // float이 아닌 DWORD를 필요로 하기 때문.
 _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));
  
 // 텍스처의 알파를 이용.
 _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);
}

 

// 특정 파티클 시스템이 지정했을 수 있는 렌더 상태를 복구하는 데 이용.
// 이 메서드는 시스템에 따라 달라질 수 있으므로 가상 메서드로 선언.
void PSystem::postRender()
{
 _device->SetRenderState(D3DRS_LIGHTING,          true);
 _device->SetRenderState(D3DRS_POINTSPRITEENABLE, false);
 _device->SetRenderState(D3DRS_POINTSCALEENABLE,  false);
 _device->SetRenderState(D3DRS_ALPHABLENDENABLE,  false);
}

 

// 렌더링 메서드
void PSystem::render()
{
 //
 // Remarks:  The render method works by filling a section of the vertex buffer with data,
 //           then we render that section.  While that section is rendering we lock a new
 //           section and begin to fill that section.  Once that sections filled we render it.
 //           This process continues until all the particles have been drawn.  The benifit
 //           of this method is that we keep the video card and the CPU busy. 

 if( !_particles.empty() )
 {
  //렌더 상태를 지정.
  preRender();
  
  _device->SetTexture(0, _tex);
  _device->SetFVF(Particle::FVF);
  _device->SetStreamSource(0, _vb, 0, sizeof(Particle));


  // render batches one by one
  //

  // 버텍스 버퍼를 벗어날 경우 처음부터 시작한다.
  
  // _vbOffset - 버텍스 버퍼에서 복사를 시작할 파티클 내 다음 단계로의 오프셋(바이트가 아닌 파티클 단위)
  // 예, 단계 1이 0부터 499까지 항목이라면 단계 2로의 오프셋은 500이 된다.
  if(_vbOffset >= _vbSize)
   _vbOffset = 0;

  Particle* v = 0;

  // _vbBatchSize - 하나의 단계에 정의된 파티클의 수.
  _vb->Lock(
   _vbOffset    * sizeof( Particle ),
   _vbBatchSize * sizeof( Particle ),
   (void**)&v,
   _vbOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);

  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++; // next element;

    numParticlesInBatch++; //단계 카운터를 증가시킨다.

    // 현재 단계가 모두 채워져 있는가?
    if(numParticlesInBatch == _vbBatchSize)
    {
     //
     // 버텍스 버퍼로 복사된 마지막 단계의 파티클들을 그린다.
     //
     _vb->Unlock();

     _device->DrawPrimitive(
      D3DPT_POINTLIST,
      _vbOffset,
      _vbBatchSize);

     //
     // 단계가 그려지는 동안 다음 단계를 파티클로 채운다.
     //

     // 다음 단계의 처음 오프셋으로 이동한다.
     _vbOffset += _vbBatchSize;

 

     // 버텍스 버퍼의 경계를 넘는메모리로 오프셋을 설정하지 않는다.
     // 경계를 넘을 경우 처음부터 시작.
     if(_vbOffset >= _vbSize)
      _vbOffset = 0;      

     _vb->Lock(
      _vbOffset    * sizeof( Particle ),
      _vbBatchSize * sizeof( Particle ),
      (void**)&v,
      _vbOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);

     numParticlesInBatch = 0; // 다음 단계를 위한 리셋
    } 
   }
  }

  _vb->Unlock();

 

  // (numParticlesInBatch == _vbBatchSize) 조건이
  // 만족되지 못하여 마지막 단계가 렌더링되지 않는 경우가 발생할 수 있다.
  // 일부만 채워진 단계는 바로 이곳에서 렌더링 된다.
  
  if( numParticlesInBatch )
  {
   _device->DrawPrimitive(
    D3DPT_POINTLIST,
    _vbOffset,
    numParticlesInBatch);
  }

  // 다음 블록
  _vbOffset += _vbBatchSize;

  //
  // reset render states
  //

  postRender();
 }
}

// 현재 시스템에 파티클이 없는 경우 true 리턴.
bool PSystem::isEmpty()
{
 return _particles.empty();
}

 

// 시스템 내의 파티클이 모두 죽은 경우 true 리턴.
// 모든 파티클이 죽은 상태와 시스템이 빈 상태를 혼동하지 않도록.
// 빈 상태는 시스템 내에 파티클이 없는 상태를 의미
// 죽은 상태는 파티클이 존재하지만 죽은 것으로 표시된 상태를 의미.
bool PSystem::isDead()
{
 std::list<Attribute>::iterator i;
 for(i = _particles.begin(); i != _particles.end(); i++)
 {
  // is there at least one living particle?  If yes,
  // the system is not dead.
  if( i->_isAlive )
   return false;
 }
 // no living particles found, the system must be dead.
 return true;
}

 

// 속성 리스트 _particle을 검색하여 죽은 파티클을 리스트에서 제거.
void PSystem::removeDeadParticles()
{
 std::list<Attribute>::iterator i;

 i = _particles.begin();

 while( i != _particles.end() )
 {
  if( i->_isAlive == false )
  {
   // erase는 다음 반복자를 리턴하므로
      // 우리가 반복자를 증가시킬 필요가 없다.
   i = _particles.erase(i);
  }
  else
  {
   i++; // next in list
  }
 }
}

//*****************************************************************************
// Snow System
//***************

// 생성자
  // 경계 상자 구조체를 가리키는 포인터와 시스템 내 파티클의 수
  // 경계 상자는 눈송이가 떨어질 부피를 정의하며,
  // 만약 눈송이가 이 범위 밖으로 벗어 나면 즉시 소멸하고 다시 만들어짐.
  // 항상 같은 수의 파티클을 유지.
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();
}

 

// 한 파티클의 속성을 리셋.
// 파티클의 속성이 리셋되는 방식은 파티클 시스템에 따라 달라짐.
// 따라서 하위 클래스에서 메서드를 구현하도록 추상 메서드로 선

// 경계 상자 내 임의의 x와 z좌표 위치에서 눈송이를 만들고
// y좌표를 경계 상자의 최상단과 같도록 지정.
// 이어 눈송이에 속도를 부여하여 아래 방향으로 그리고 약간 왼쪽으로 떨어지도록 한다.
// 눈송이는 흰색으로 표현.
void Snow::resetParticle(Attribute* attribute)
{
 attribute->_isAlive  = true;

 

// GetRandomVector - 최소점 min과 최대점 max로 정의된 상자 내의 임의 벡터를 출력.
 // 눈송이의 위치 지정을 위해 임의의 x, z 좌표를 얻는다.
 d3d::GetRandomVector(
  &attribute->_position,
  &_boundingBox._min,
  &_boundingBox._max);

 

// 높이 (y좌표) 는 항상 경계 상자의 최상단.
 
attribute->_position.y = _boundingBox._max.y;

 

// GetRandowFloat - [ lowBound, highBound ] 범위에 있는 임의의 float을 리턴.
 // 눈송이는 아래쪽으로 떨어지며 약간 왼쪽을 향한다.
 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;
}

 

// 시스템 내의 모든 파티클들을 갱신.
// 메서드의 구현은 특정 파티클 시스템에 따라 달라지므로
// 하위 클래스에서 메서드를 구현하도록 추상 메서드로 선언.

// 파티클의 위치를 갱신하며
// 시스템의 경계 상자를 벗어났는지 확인.
// 만약 경계 상자를 벗어났다면 해당 파티클을 초기화.
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) );
  }
 }
}

//*****************************************************************************
// Explosion System
//********************

// 불꽃놀이 생성자
// 시스템 원천(불꽃이 폭발할 장소) 으로의 포인터, 시스템이 가진 파티클의 수.
Firework::Firework(D3DXVECTOR3* origin, int numParticles)
{
 _origin        = *origin;
 _size          = 0.9f;
 _vbSize        = 2048;
 _vbOffset      = 0;  
 _vbBatchSize   = 512;

 for(int i = 0; i < numParticles; i++)
  addParticle();
}

 

// 시스템 원천의 파티클을 초기화하고 구체 내에서 임의의 속도를 만들며,
// 시스템 내의 파티클들은 임의의 컬러를 부여.
// 각 파티클들이 2초 동안 유지하도록 수명을 지정.
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,
  &attribute->_velocity);

 attribute->_velocity *= 100.0f;

 attribute->_color = D3DXCOLOR(
  d3d::GetRandomFloat(0.0f, 1.0f),
  d3d::GetRandomFloat(0.0f, 1.0f),
  d3d::GetRandomFloat(0.0f, 1.0f),
  1.0f);

 attribute->_age      = 0.0f;
 attribute->_lifeTime = 2.0f; // 2초 동안의 수명을 가진다.
}

 

// 각 파티클의 위치를 갱신하고 수명을 초과한파티클의 죽음을 처리.
// 이 시스템은 죽은 파티클을 제거하지 않는다.
// 이것은 새로운 불꽃을 만들 때 기존의 죽은 Firework 시스템을 재활용할 수 있기 때문.
// 즉, 파티클을 만들고 제거하는 번거로운 과정을 최소화.
void Firework::update(float timeDelta)
{
 std::list<Attribute>::iterator i;

 for(i = _particles.begin(); i != _particles.end(); i++)
 {
  // 생존한 파티클만 갱신.
  if( i->_isAlive )
  {
   i->_position += i->_velocity * timeDelta;

   i->_age += timeDelta;

   if(i->_age > i->_lifeTime) // 죽인다.
    i->_isAlive = false;
  }
 }
}

 

// 렌더링에 앞서 지정해야 할 초기 렌더 상태를 지정.
// 이 메서드는 시스템에 따라 달라질 수 있으므로 가상 함수로 선언.

// 다른 블렌드 인수가 이용.
// 깊이 버퍼로의 쓰기도 허용되지 않음.
// 디폴트 블렌드 인수와 쓰기 여부를 변경하고자 한다면
// pSystem::preRender와 pSystem::postRender 메서드를 오버라이드하면 됨.
void Firework::preRender()
{
 PSystem::preRender(); // 부모 버전의 메서드를 호출.

 _device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
    _device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

 // z 버퍼 읽기는 가능 하지만 쓰기는 허용하지 않는다.
 _device->SetRenderState(D3DRS_ZWRITEENABLE, false);
}

void Firework::postRender()
{
 PSystem::postRender();

 _device->SetRenderState(D3DRS_ZWRITEENABLE, true);
}

//*****************************************************************************
// Laser System
//****************
// 입자총 생성자

// 카메라로의 포인터를 받는다.
// 새로운 파티클을 만들 때마다 카메라의 위치와 방향에 대한 정보가 필요.
ParticleGun::ParticleGun(Camera* camera) 
{   
 _camera          = camera;
 _size            = 0.8f;
 _vbSize          = 2048;
 _vbOffset        = 0; 
 _vbBatchSize     = 512;
}

 

// 파티클의 위치를 카메라의 현재 위치로 지정하고
// 파티클의 속도를 카메라가 보고 있는 방향의 100배로 지정.
// 이 같은 방법으로 현재 바라보고 있는 방향으로 "총알"을 발사할 수 있다.
// 파티클의 컬러는 녹색으로 지정.
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; // 수명은 1초
}

 

// 파티클의 위치를 갱신하고
// 수명이 다한 경우 죽은 것으로 처리한다.
// 파티클 리스트를 검색하여 죽은 파티클을 제거.
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;

  if(i->_age > i->_lifeTime) // kill
   i->_isAlive = false;
 }
 removeDeadParticles();
}

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

Direct 에서 파티클 SetRenderState 설정 설명  (0) 2013.01.31
용책, 해골책  (0) 2013.01.31
파티클 간단한 렌더링  (0) 2013.01.31
CommitChanges  (0) 2013.01.27
Effect::CommitChanges()  (0) 2013.01.25
반응형


http://blog.naver.com/clous02?Redirect=Log&logNo=110023903727



1) 파티클의 버텍스 버퍼이용 방법

* 버텍스 버퍼정의(최대한의 일정한 사이즈로)

* 파티클의 속성을 다룰 구조체를 정의

   * 구조체 리스트에 이벤트나 최대 숫자의 개수를 정하고 소멸시 하나를 생성하는 방법으로 생성

* 속성에 존재하는 베텍스 데이터 자료를 버텍스 버퍼로 동적인 복사

* 파티클에 관련된 RenderState를 설정

* 렌더링한다.


2) 작동방식

* FVF의 지정: D3DFVF_XYZ | D3DFVF_PSIZE

* Particle 속성을 위한 구조체

: 동적인 버텍스 생성과 소멸  List

* 위치 한계의 최대 사이즈 결정

* 버텍스 버퍼 마련

* 파티클을 생성(총알은 속도 일정 위치 변경)

* 버텍스 버퍼에 이동

* 파티클의 생성  변경  소멸  생성의 과정

* 렌더링 : DrawPrimitive(D3DPT_POINTLIST)

 

3) 파티클 구현 방법

* Particle

  - Bilboard이용 파티클 구현(사각형)

  - D3DPT_POINTLIST : 하나의 픽셀로 렌더링된다

  - Point Sprite(점하나로 가능)

 Texture 적용이 가능  Blending으로 알파 연산

• 크기 변경 가능

• 하나의 포인트로 사용가능

• 성능향상과 메모리 이익

 

4) 파티클의 종류

* 일정한 사이즈로 반복 되는 현상

  - 눈 비등

        - 박스속에 거두고 충돌처리로 사망을 시키면서 사망이 하나라도 벌어지면 자동으로 생성

           한다

 - 파티클정보를 담고 있는 리스트에서 erase시키고 push_back한다

* 이벤트가 발생하면 생성되는 스타일

 - 버텍스 버퍼는 가능한 총알의 최대 사이즈를 지정

 - 속성리스트를 만들고 렌더링해야할 만큼  버텍스 버퍼에 지정하고 렌더링한다

 - 이벤트 발생시 생성

 - 카메라의 위치에서 카메라의 방향으로 발사

 - 일정한 위치를 전진하면 소멸

 - 생성  변경  소멸의 단계

* 두가지 방식다

 - 위치의 속성은 계속하여 변화함으로 일정한 사이즈로 만들어 놓은 버텍스 버퍼에

위치값을 계속하여 갱신한다

5) 파티클에서 주의할 점

* 파티클 사이즈 조정시 주의할 점

  - 렌더스테이트의 사이즈 조정은 모두 DWORD

  - 이벤트에 의하여 파티클이 증가할 경우 조정하지 않으면 버텍스 버퍼의 한계를 초가하는 경우가 발생

  - 눈이 한 개만 출력될 때는 인덱스 증가가 벌어지지 않기 때문

 

6) Point Sprite 렌더 상태

 * D3DRS_POINTSPRITEENABE : default  false

  - true : 지정된 전체 텍스트를 포인트 스프라이트에 텍스쳐 매핑

  - false : 포인트 스프라이트의 텍스쳐 좌표를 이용하여 지정

 * D3DRS_POINTSCALEENABLE : default  false

  - true : 포인트 크기를 뷰스페이스 단위로 해석(카메라와의 거리값에 따라 변화)

  - false : 스크린 스페이스 단위로 해석  사이즈를 3으로 주면 3x3 사이즈로 그려진다

 * D3DRS_POINTSIZE

  - 포인트 스프라이트 크기 지정

  - Device->SetRenderState(D3DRS_POINTSIZE, FtoDw(2.5f));

    DWORD FtoDw(float f)

{

  return *((DWORD*)&f);

}

 * D3DRS_POINTSIZE_MIN : 0.2

 * D3DRS_POINTSIZE_MAX : 5.0

 * 거리에 따라 포인트 스프라이드의 크기가 변화하는 방법을 제어

 * D3DRS_POINTSIZE_A

 * D3DRS_POINTSIZE_B

 * D3DRS_POINTSIZE_C

[출처] 파티클|작성자 clous02

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

용책, 해골책  (0) 2013.01.31
간략한 파티클 시스템  (0) 2013.01.31
CommitChanges  (0) 2013.01.27
Effect::CommitChanges()  (0) 2013.01.25
모션 블러(Motion Blur)  (0) 2013.01.25
반응형

CommitChanges 




현재 테크닉에서 ID3DXEffect::BeginPass/ID3DXEffect::EndPass  가 매칭되는 내부에서  ID3DXEffect::Set~ 함수를 쓰지 않았다면


ID3DXEffect::CommitChanges 를 할필요가 없고 BeginPass,  EndPass 내부에서 ID3DXEffect::Set~ 함수가 쓰인다면 



ID3DXEffect::CommitChanges   ID3DXEffect::BeginPass/ID3DXEffect::EndPass 이 매칭되는 사이에 반드시 호출해야하는데

반드시 DrawxPrimitive 호출하기 전에 ID3DXEffect::CommitChanges 를 호출해야 한다


안에 쓰는것과 밖에 쓰는것은 좀 다른데 밖에쓰면 상관없지만 내부에다 쓰면 공유되는 상태가 되어 다음에까지 영향을 미친다



- 아래는 Direct SDK 에서 발췌한 내용이다






Remarks

If the application changes any effect state using any of the ID3DXEffect::Setx methods inside of an ID3DXEffect::BeginPass/ID3DXEffect::EndPass matching pair, the application must call ID3DXEffect::CommitChanges before any DrawxPrimitive call to propagate state changes to the device before rendering. If no state changes occur within a ID3DXEffect::BeginPass and ID3DXEffect::EndPass matching pair, it is not necessary to call ID3DXEffect::CommitChanges.


This is slightly different for any shared parameters in a cloned effect. When a technique is active on a cloned effect (that is, when ID3DXEffect::Begin has been called but and ID3DXEffect::End has not been called), ID3DXEffect::CommitChanges updates parameters that are not shared as expected. To update a shared parameter (only for a cloned effect whose technique is active), call ID3DXEffect::End to deactivate the technique and ID3DXEffect::Begin to reactivate the technique before calling ID3DXEffect::CommitChanges.





    // Using current technique

    // Begin           starts active technique

    // BeginPass       begins a pass

    // CommitChanges   updates changes to any set calls in the pass. This should be called before any DrawPrimitive call to d3d

    // EndPass         ends a pass

    // End             ends active technique


이건  에 대한 d3dx9effect.h 에 있는 설명 에 있다


반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

간략한 파티클 시스템  (0) 2013.01.31
파티클 간단한 렌더링  (0) 2013.01.31
Effect::CommitChanges()  (0) 2013.01.25
모션 블러(Motion Blur)  (0) 2013.01.25
인스턴싱 (Instancing)  (1) 2013.01.25
반응형


Effect::CommitChanges()  

2006/04/24 20:33

복사http://blog.naver.com/medrian5/20023521146


Effect::BeginPass(0);

.....

Effect::SetTexture(ha, paaaa);

Effect::SetTexture(hb, pbbbb);

....

Effect::EndPass();

 

만약, BeginPass(int)와 EndPass() 사이에서

한번의 Effect::SetTexture() 함수가 호출된 뒤, 또다시 Effect::SetTexture가 호출 되면

Effect::CommitChanges();

 

아래처럼  이녀석을 호출해야 제대로 먹힌다.

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

Effect::BeginPass(0);

.....

Effect::SetTexture(ha, paaaa);

Effect::SetTexture(hb, pbbbb);

Effect::CommitChanges();

....

Effect::EndPass();

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

파티클 간단한 렌더링  (0) 2013.01.31
CommitChanges  (0) 2013.01.27
모션 블러(Motion Blur)  (0) 2013.01.25
인스턴싱 (Instancing)  (1) 2013.01.25
D3DXCreateTextureFromFile 함수  (0) 2013.01.22
반응형


모션 블러(Motion Blur)  3D Programming / Programming 

2012/05/14 00:39

복사http://blog.naver.com/sorkelf/40158984437







즉 위 설명은 아래와 같다.

속도벡터 = 현재위치 이전위치

최종 위치 = dot법선,  속도벡터  ) > 0 ? 현재위치 이전위치

이걸 버텍스 셰이더에서 그대로 구현하면..

  //현재의 버텍스 좌표

   float4 NewPos = mul( Pos, m_WVPNew );

   //과거의 버텍스 좌표
   float4 OldPos = mul( Pos, m_WVPOld );

   //버텍스의 속도벡터
   float3 Dir = NewPos.xyz - OldPos.xyz;

   // 버텍스의 이동벡터와 법선을 내적
   float a = dot( normalize( Dir ), normalize( N ) );

   //최종 위치 계산
   if( a < 0.0f )
      Out.Pos = OldPos;
   else
      Out.Pos = NewPos;


이동궤적 볼륨이 반투명으로 렌더링 되므로 깊이 버퍼를 사용하면 볼륨의 다른 부분이 깊이테스트에서 실패하므로 렌더링되지 않는다

그리고 얼마나 이동했는지 계산한다
다음 텍스처 샘플링 위치를 옮기기 위해 투영공간에서의 속도벡터를 구하고 이를 텍스처 좌표계에 맞도록
스케일링 한 것을 출력한다 (투영공간의 범위가 ~1-1 이므로 스케일링에 0.5배가 필요하며 y좌표가 반대이므로 -1을 곱해줌)


현재위치 mul(현재위치,m_WVP);

이전위치 mul(이전위치, m_prevWVP);


속도 = 현재위치 이전위치 / w * 0.5f;

속도.y *= -1.0f


이걸 버텍스 셰이더에서 그대로 구현하면..

  //-1.0f 부터 1.0f 의 범위를 텍스처 좌표계의 0.0f ~ 1.0f의 텍셀 위치를 참조하기 위해 거리를 절반으로 한다

  float2  velocity =  NewPos.xy / NewPos.w - OldPos.xy / OldPos.w;

  Out.Dir.xy =  velocity  * 0.5f;

   //최종적으로 텍셀의 오프셋값이 되기 위해 y방향을 반대방향으로 한다
   Out.Dir.y *= -1.0f;

   //씬의 Z값을 계산하기 위한 파라미터
   Out.Dir.z = Out.Pos.z;
   Out.Dir.w = Out.Pos.w;

 

   return Out;


여기까지가 버텍스 셰이더가 하는 일이다




이동궤적 지오메트리와  깊이 정보

픽셀 셰이더에서는 이동궤적 볼륨에서의 각각 화면좌표위치(In.Tex/In.Tex.w)로부터 속도방향(In.Velocity)로 조금씩 옮기고
오브젝트만을 렌더링한 텍스처를 샘플링한다.
마지막으로 합계한 결과를 샘플 수로 나누어 평균 색을 구한다.

 float4 PS_Final( VS_Final_OUTPUT In ) : COLOR0

{

   //수치를 크게 하면 크게 할수록 부드러움
   int  NumBlurSample = 10;

   //속도 맵으로부터 속도벡터와 Z값을 얻어옴
   float4 Velocity = tex2D( tex1, In.Tex );

   Velocity.xy /= (float)Blur;

   int cnt = 1;
   float4 BColor;

   // 씬의 렌더링 이미지를 얻어옴, a 성분에 Z 값을 저장된다
   float4 Out = tex2D( tex0, In.Tex );

   for( int i=cnt; i NumBlurSample  ; i++ )
   {
      //속도 벡터의 방향 텍셀 위치를 참조하여, 씬의 렌더링 이미지의 색정보를 얻어온다
      BColor = tex2D( tex0, In.Tex + Velocity.xy * (float)i );

      //속도 맵의 Z 값과 속도 벡터 방향에 있는 텍셀 위치를 샘플링 한 씬의 렌더링 이미지의 Z값을 비교한다
      if( Velocity.a < BColor.a + 0.04f )
      {
         cnt++;
         Out += BColor;
      }
   }

   Out /= (float)cnt;

   return Out;
}





샘플 수를 늘리면 좀 더 부드러운 느낌을 낼 수 있지만 렌더링 속도가 느려지므로 샘플 수는 적당히 타협하는 것이 좋다.


이 때

  //속도 맵의 Z 값과 속도 벡터 방향에 있는 텍셀 위치를 샘플링 한 씬의 렌더링 이미지의 Z값을 비교한다
      if( Velocity.a < BColor.a + 0.04f )
      {
         cnt++;
         Out += BColor;
      }

이 부분에서 Z값을 비교해 블러처리를 할 것인가 말것인가를 하는데 
이는 모델 경계상 에서의 생기는 아티팩트를 없애기 위한 것으로

아래 그림 처럼 뒤의 물체가 모션 블러 될때 앞의 물체에 모션블러 결과가 묻어 나는 것을 방지하기 위한 처리로
Z값을 참조하여 앞의 물체인지 뒤의 물체인지 판단후 앞의 물체이면 샘플링 할때 제외 하는 것이다.




일반적인 샘플링 시..

Z값을 고려하여 처리 한 결과

그 외 2.5D 모션 블러의 단점으로 

이동궤적 볼륨이 파괴(같은 버텍스 좌표에서 법선방향이 다른 모델에서 발생)
같은 변을 공유하며 법선방향이 다른 변에 대해서 폴리곤을 미리 생성하여
폴리곤을 늘릴때(이동궤적 볼륨을 만들때) 추가로 렌더링 하는 방식으로 해결 하며




지오메트리 비용 증가(이동궤적볼륨 있음 + 없음 으로 인한 추가모델을 2번 렌더링)
씬은 정적이고 멀리 있는 오브젝트는 크게 영향을 받지 않으며 카메라에 의한 변화만 의존한다고 가정하고
Z버퍼와 스크린 좌표만을 가지고 Velocity를 계산하는 방식으로 해결한다 (알고리즘은 아래와 같음)

  1. 스크린 좌표와 Z버퍼의 값으로부터 픽셀의 월드 좌표를 역산
  2. 월드 좌표를 1 프레임전의 뷰 프로젝션 행렬로 변환하여 1프레임 전의 스크린 좌표를 계산
  3. 현재 스크린 좌표와 1프레임 전의 스크린 좌표 로부터 Velocity를 계산



DX10이상일 경우에는 지오메트리 셰이더에서 Velocity를 참조하여 폴리곤을 잡아 늘리거나 폴리곤을 생성하는 방식을 사용한다
더 자세한건 DX 10 Sample Browser에 있는 Motion Blur 10내용을 참고하길 바란다.


DX10에서의 모션블러시 생성되는 원리



Reference : 

DirectX9 쉐이더 프로그래밍(타카시 이마기레)
CEDEC 2006 차세대기에 대응하는 게임 엔진 설계 CapCom

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

CommitChanges  (0) 2013.01.27
Effect::CommitChanges()  (0) 2013.01.25
인스턴싱 (Instancing)  (1) 2013.01.25
D3DXCreateTextureFromFile 함수  (0) 2013.01.22
다중스트림 셰이더  (0) 2013.01.21
반응형

 

2012/05/30 13:28

복사http://blog.naver.com/sorkelf/40160183951


인스턴싱 (Instancing)

 : 동일한 객체(오브젝트)를 한 화면에 여러개를 렌더링 시킬 경우에 한번의 DP Call로 처리 하는 방식을 말한다.
   (나무, 풀, 스프라이트, 파티클 등등..)








즉 50개 메시 -> Dp Call 50번 이 아닌 
    50개 메시 -> DP Call 1번으로 처리한다는 것이며 이는 DpCall에 따른 오버헤드를 줄여준다



DirectX SDK에서는 4가지 방식의 인스턴싱 방식을 제시하고 있다
(이 외에 XBox에서는 VFetch 인스턴싱을 사용한다 )

1. 하드웨어 인스턴싱
 : VS_3_0이 필요하며 인스턴싱에 필요한 데이터를
세컨드 버텍스 버퍼에 저장하는 형식이다.

2. 셰이더 인스턴싱
 : 하드웨어인스턴싱이 불가능할 경우 사용하는 가장 효율적인 방식이다
인스턴싱 데이터는 시스템 메모리 배열에 저장된 후 렌더링시 버텍스 셰이더의
Constant에 카피 한다. VS_2_0일 경우 최대가 256개 vs_1_1에서는 최대 96개이다
그러므로 많은 수의 인스턴싱 데이터의 배열 전체를 한번에 처리하는것은 불가능하다

3. Contant 인스턴싱
  셰이더인스턴싱처리로 하지 않을 경우(배치사이즈=1)와 유사하다

4. 스트림 인스턴싱
 : 하드웨어 인스턴싱과 마찬가지로 세컨드 버텍스 버퍼를 사용한다
단, 버텍스 셰이더의 Constant를 설정해서 각 박스의 위치와 색을 갱신하는 것이 아닌
인스턴스 스트림 버퍼 내에 오프셋을 갱신해서 박스를 하나씩 렌더링한다



이 중에서 하드웨어 인스턴싱을 다룬다.. 
( 요샌 3.0 지원하는 카드 많으니까...ㅠㅠ 나중에 시간이 또 되면 셰이더 인스턴싱 설명도 넣어야지..-_-)


하드웨어 인스턴싱은 작업은 전적으로 GPU상에서 수행되며 CPU 사용량은 거의 없다

하드웨어 인스턴싱은 현재 데이터 구조를 변경하지 않는 대신
세컨드 버텍스 버퍼라고 불리는 또 다른 버텍스 버퍼를 추가한다



세컨드 버텍스 버퍼에는 변환행렬 정보등이 저장되어 있으며 인스턴스 하나당 하나씩 포함된다
또한 원래의 메인 버텍스 버퍼와는 다른 녀석이므로 버텍스버퍼 사이즈를 둘다 동일하게 유지할 필요도 없으며
한번에 DP Call로 얼마나 많은 인스턴싱을 할 것인가에 따라 최대 사이즈가 커지게 된다



소스 설명 주저리 주저리...

우선 메인 버텍스 버퍼와 세컨드 버텍스 버퍼에 들어갈 버텍스를 선언한다

 //메인 버텍스 버퍼에 들어갈 버텍스 선언

const D3DVERTEXELEMENT9 g_VBDecl_Geometry[] =
{
    {0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
    {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
    {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0},
    {0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
    {0, 48, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
    D3DDECL_END()
};

//세컨드 버텍스 버퍼에 들어갈 버텍스 선언
const D3DVERTEXELEMENT9 g_VBDecl_InstanceData[] =
{
    {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
    {1, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
    {1, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
    {1, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
    {1, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,    0},
    D3DDECL_END()
};

첫번째 선언은 위치 법선, 탄젠트, 종법선, 및 텍스처 좌표 데이터들로 지오메트리 데이터 를 정의하며
2번째 선언은 오브젝트 인스턴스 별 데이터를 정의한다

2번째 선언에서를 보면 여기서는 각 인스턴스가 4개의 float4형 부동소수점 값 및 4성분 컬러에 의해 정의되고 있다.

처음의 4개의 값은 4x4 행렬의 초기화에 사용할 수 있으며 이 데이터는 각 지오메트리의 
인스턴스 사이즈, 위치, 방향등을 한번에 처리한다

렌더링 하기 전에 IDirect3DDevice9::SetStreamSourceFreq 를 호출하여 버텍스 버퍼의 스트림을 디바이스의 바인드해야 한다
바인드 하는 방법은 아래와 같다

//스트림 0으로 세팅 되어있는 메인 버텍스 버퍼 바인드

//g_NumBoxes 는 출력할 인스턴싱 데이터 개수
pd3dDevice->SetStreamSourceFreq( 0, D3DSTREAMSOURCE_INDEXEDDATA | g_NumBoxes );
pd3dDevice->SetStreamSource( 0, g_pVBBox, 0, sizeof( BOX_VERTEX ) );

//스트림 1로 세팅 되어있는 세컨드 버텍스 버퍼 바인드
//버텍스당 하나의 인스턴싱 데이터를 가지므로 1과 바인드한다
pd3dDevice->SetStreamSourceFreq( 1, D3DSTREAMSOURCE_INSTANCEDATA | 1ul );
pd3dDevice->SetStreamSource( 1, g_pVBInstanceData, 0, sizeof( BOX_INSTANCEDATA_POS ) );

여기서 BOX_VERTEX 는 기존의 버텍스 구조이며 는 BOX_INSTANCEDATA_POS 는 인스턴싱데이터를 가진 구조체이다

IDirect3DDevice9::SetStreamSourceFreq 는 D3DSTREAMSOURCE_INDEXEDDATA를 가지고
인덱스에 따른 지오메트리 데이터를 식별한다

우선 첫번째로 스트림0에 설정된 버텍스 버퍼(메인 버텍스 버퍼)를 바인드 하는데
위와 같이 인스턴싱 데이터 개수만큼 D3DSTREAMSOURCE_INDEXEDDATA와 or 연산하여 설정하면 
렌더링하는 지오메트리의 인스턴스값이 논리적으로 결합된다

다음 스트림1에 설정된 버텍스 버퍼(세컨드 버텍스 버퍼)를 바인드 하는데
이번에는 IDirect3DDevice9::SetStreamSourceFreq 가 D3DSTREAMSOURCE_INSTANCEDATA를 가지고 
인스턴싱 데이터를 포함한 스트림을 식별한다.
이때에 각 버텍스는 하나의 인스턴스 데이터를 포함하므로 D3DSTREAMSOURCE_INSTANCEDATA  1과 결합한다

그리고 IDirect3DDevice9::SetStreamSource를 호출하여 버텍스버퍼 포인터를 디바이스에 바인드 후 렌더링한다


렌더링 종료후...

인스턴싱 데이터 렌더링이 종료되면 버텍스 스트림의 Frequency를 원래대로 돌려주어야 한다

pd3dDevice->SetStreamSourceFreq( 0, 1 );

pd3dDevice->SetStreamSourceFreq( 1, 1 );


즉 렌더의 로직은 아래와 같다

 void OnRenderHWInstancing( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )

{
    HRESULT hr;
    UINT iPass, cPasses;

    //버텍스 선언 세팅
    V( pd3dDevice->SetVertexDeclaration( g_pVertexDeclHardware ) );

    //스트림 0으로 세팅 되어있는 메인 버텍스 버퍼 바인드
    //g_NumBoxes 는 출력할 인스턴싱 데이터 개수
    V( pd3dDevice->SetStreamSourceFreq( 0, D3DSTREAMSOURCE_INDEXEDDATA | g_NumBoxes ) );
    V( pd3dDevice->SetStreamSource( 0, g_pVBBox, 0, sizeof( BOX_VERTEX ) ) );

    //스트림 1로 세팅 되어있는 세컨드 버텍스 버퍼 바인드 
    //버텍스당 하나의 인스턴싱 데이터를 가지므로 1과 바인드한다
    V( pd3dDevice->SetStreamSourceFreq( 1, D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) );
    V( pd3dDevice->SetStreamSource( 1, g_pVBInstanceData, 0, sizeof( BOX_INSTANCEDATA_POS ) ) );

    //인덱스 버퍼 설정
    V( pd3dDevice->SetIndices( g_pIBBox ) );

    // 테크닉 설정
    V( g_pEffect->SetTechnique( g_HandleTechnique ) );

    V( g_pEffect->Begin( &cPasses, 0 ) );
    for( iPass = 0; iPass < cPasses; iPass++ )
    {
        V( g_pEffect->BeginPass( iPass ) );

        V( g_pEffect->SetTexture( g_HandleTexture, g_pBoxTexture ) );

        //BeginPass 와 EndPass 사이에서 호출 필요!
        V( g_pEffect->CommitChanges() );

        V( pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 4 * 6, 0, 6 * 2 ) );

        V( g_pEffect->EndPass() );
    }


    V( g_pEffect->End() );

    //스트림 설정 원래대로
    V( pd3dDevice->SetStreamSourceFreq( 0, 1 ) );
    V( pd3dDevice->SetStreamSourceFreq( 1, 1 ) );
}


이 때 BeginPass와 EndPass 사이에 연속적으로 SetTexture를 하거나 할 경우
CommitChanges()를 부르지 않으면 이펙트에 바로 적용되지 않는다

BeginPass 와 EndPass 하수 특성상 EndPass가 실행되기 전 까지
다음 스테이트로 넘어가지 않고 계속 호출하게 되어 
제일 마지막에 설정한 부분에 모두 출력하게 된다.

CommitChanges()는 렌더링함수 (DrawSubSetDrawPrimitive 계열등)을 부르기 전에 호출해야 한다

또한 위에서도 설명했듯이 버텍스버퍼의 사이즈가 커지면 더 느려질 수도 있으니
노가다를 통해 적절한 버텍스버퍼의 크기를 찾는것이 중요하다-..-



반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

Effect::CommitChanges()  (0) 2013.01.25
모션 블러(Motion Blur)  (0) 2013.01.25
D3DXCreateTextureFromFile 함수  (0) 2013.01.22
다중스트림 셰이더  (0) 2013.01.21
D3DVERTEXELEMENT9 사용법  (0) 2013.01.21
반응형

http://www.silverwolf.co.kr/4876




파일을 기본으로 해 텍스처를 생성 한다.

구문

HRESULT D3DXCreateTextureFromFile(      

    LPDIRECT3DDEVICE9 pDevice,    LPCTSTR pSrcFile,    LPDIRECT3DTEXTURE9 *ppTexture );

파라미터

pDevice
[in] IDirect3DDevice9 인터페이스의 포인터. 텍스처에 관련지을 수 있는 장치를 나타낸다.
pSrcFile
[in] 파일명을 지정하는 캐릭터 라인의 포인터. 컴파일러의 설정이 Unicode 를 요구하고 있는 경우, 데이터 타입 LPCTSTR 는 LPCWSTR 가 된다. 그 이외의 경우는, 이 캐릭터 라인의 데이터 타입은 LPCSTR 가 된다. 「주의」를 참조할것.
ppTexture
[out] 생성 된 큐브 텍스처 개체를 나타내는,IDirect3DTexture9 인터페이스의 포인터 주소.

반환값

성공했을 경우는,D3D_OK 를 돌려준다.

실패했을 경우는, 다음의 몇개의 값을 돌려준다.

D3DERR_NOTAVAILABLE이 장치는, 조회된 테크닉을 지원 하고 있지 않다.
D3DERR_OUTOFVIDEOMEMORYMicrosoft? Direct3D? 가 처리를 실시하는데 충분한 디스플레이 메모리가 없다.
D3DERR_INVALIDCALL메서드의 호출이 무효이다. 예를 들어, 메서드의 파라미터에 무효인 값이 설정되어 있는 경우 등이다.
D3DXERR_INVALIDDATA데이터가 무효이다.
E_OUTOFMEMORYDirect3D 가 호출을 완료하기 위한 충분한 메모리를 할당할 수가 없었다.

주의

컴파일러의 설정에 의해 함수의 버전도 정해진다. Unicode 가 정의되고 있는 경우, 이 함수의 호출은 D3DXCreateTextureFromFileW 가 된다. 그 이외의 경우는 ANSI 캐릭터 라인을 사용하므로, 이 함수의 호출은 D3DXCreateTextureFromFileA 가 된다.

이 함수가 지원 하고 있는 파일 포맷은,. bmp,. dds,. dib,. jpg,. png, 및 . tga 이다.

이 함수는 D3DXCreateTextureFromFileExW(pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, ppTexture)와 동일하다.

밉맵 된 텍스처의 각 레벨에는, 로드 된 텍스처가 자동적으로 저장 된다.

밉맵 된 텍스처에 이미지를 로드할 때, 장치에 따라서는, 1x1 의 이미지로 변환하지 못하고, 함수가 실패하는 일이 있다. 이러한 경우는, 이미지를 수동으로 로드할 필요가 있다.

이 함수를 사용해 생성 한 리소스는, D3DPOOL_MANAGED 로 나타나는 메모리 클래스에 배치된다.

D3DXCreateTextureFromFile 를 사용해 최적인 퍼포먼스를 얻으려면 , 다음 일을 실시한다.

  1. 이미지의 스케일링 및 포맷 변환을 로드시에 실시하면, 처리에 시간이 걸리는 경우가 있다. 이미지는, 사용할 때의 포맷 및 해상도로 보존한다. 타겟 하드웨어로 처리할 수 있는 것이 2 의 거듭제곱의 넓이만의 경우는, 2 의 거듭제곱의 넓이를 사용해 이미지를 생성 해 보존한다.
  2. Microsoft DirectDraw? 표면 (DDS) 파일의 사용을 검토한다. Microsoft DirectX? 9.0 텍스트 포맷은 모두 DDS 파일을 사용해 표현할 수 있기 (위해)때문에, DDS 파일은 Direct3D extension (D3DX)에 있어 읽기나 들이마셔. 또, DDS 파일에 밉맵을 보존할 수가 있어 임의의 밉맵 생성 알고리즘을 사용해 이미지를 생성 할 수 있다.
  3. 함수의 정보

    헤더d3dx9tex.h
    임포트 라이브러리
    d3dx9.lib
    최저한의 operating systemWindows 98

    참조

    D3DXCreateTextureFromFileEx ,텍스처의 색변환


반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

모션 블러(Motion Blur)  (0) 2013.01.25
인스턴싱 (Instancing)  (1) 2013.01.25
다중스트림 셰이더  (0) 2013.01.21
D3DVERTEXELEMENT9 사용법  (0) 2013.01.21
Fast Object Picking  (0) 2013.01.19
반응형


http://blog.daum.net/naganolacpp/37


다중스트림셰이더.zip



g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(0.0f,0.0f,1.0f,1.0f), 1.0f, 0 );

g_pd3dDevice->BeginScene();

 

g_pEffect->SetTechnique( "Technique0" );

setTechniqueVariables();

 

UINT uPasses;
g_pEffect->Begin( &uPasses, 0 );
   
for( UINT uPass = 0; uPass < uPasses; ++uPass )
{
       g_pEffect->BeginPass( uPass );

      

       // 단일 스트림 사용

       //g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(Vertex) );
       g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );

     

       // 다중 스트림 사용
       g_pd3dDevice->SetVertexDeclaration( g_vertex_declaration );

      /* SetFVF와 SetvertexDeclaration은 같이 쓸경우 주의해야한다.

          잘못하면 괴물이 출력된다*/
       g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer0, 0, sizeof(Vertex0) );
       g_pd3dDevice->SetStreamSource( 1, g_pVertexBuffer1, 0, sizeof(Vertex1) );

       // 인덱스 버퍼 Set  
       g_ib->SetIndices();

 

       // 출력
       g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, 4, 0, 2 );

       

       g_pEffect->EndPass();

}
 
g_pEffect->End();

 

g_pd3dDevice->EndScene();

g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

 

/*

이건 사용된 버택스  버퍼 데이터

*/

struct Vertex0
{
 float x, y;
 float tu, tv;
};

struct Vertex1
{
 float z; 
};
Vertex0 g_quadVertices0[] =
{
 {-1.0f,-1.0f,  0.0f,1.0f },
 { 1.0f,-1.0f,  1.0f,1.0f },
 {-1.0f, 1.0f,  0.0f,0.0f },
 { 1.0f, 1.0f,  1.0f,0.0f }   
};

Vertex1 g_quadVertices1[] =
{
 { 0.0f },
 { 0.0f },
 { 0.0f },
 { 0.0f }   
};
D3DVERTEXELEMENT9 g_vertex_description[]=

 { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
 { 0, 8, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
 
 { 1, 0, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 },
 D3DDECL_END()
};

*/


반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

인스턴싱 (Instancing)  (1) 2013.01.25
D3DXCreateTextureFromFile 함수  (0) 2013.01.22
D3DVERTEXELEMENT9 사용법  (0) 2013.01.21
Fast Object Picking  (0) 2013.01.19
게임 이펙트에서의 D3DRS_ZWRITEENABLE의 사용  (1) 2013.01.19
반응형

아래 내용에 덧붙이자면


동일한 정점구조를 동시에 멀티로 세팅하고 싶을때 사용하거나


그냥 일반적으로 사용하기도 한다


멀티로 사용할때는 


LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer0 = NULL;

LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer1 = NULL;


처럼 멀티로 돌릴 개수만큼 정점버퍼를 생성해줘야한다






http://blog.naver.com/red_n_hot/60004005539


LPDIRECT3DVERTEXDECLARATION9       m_pVertexDeclaration;

 

//ㄴ  버텍스 정의하는 변수!?  를 만들어 주고

 

D3DVERTEXELEMENT9 dwDecl3[] = 
{
    {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_POSITION, 0},
  D3DDECL_END()
};

 

//ㄴ 정점선언 이랄까나.. 

 

첫번째인자 스트림 몇번째인지 

두번째 옵셋~!? 시작(0)으로부터  @@??  아니아니... 어디서부터 사용할껀지.. ex)12바이트 까지 사용됬삼

세번째 타입  얼마나 사용할껀지 ex) D3DDECLTYPE_FLOAT3

네번째 메써드  디퍼트!? 디포트!?  몰라 이건

다섯번째 어떻게 사용할찌..  ex)  D3DDECLUSAGE_POSITION   포지션에대한

여섯번째 ex)텍스트 인덱스에 사용

 

typedef struct D3DVERTEXELEMENT9 {
    WORD Stream;
    WORD Offset;
    BYTE Type;
    BYTE Method;
    BYTE Usage;
    BYTE UsageIndex;
} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9;

//-----------------------------

//---------------------------------

struct CUSTOMVERTEX
{
 FLOAT x, y, z; // 공간상의 위치값
};

 

//ㄴ 사용하던데로 만들어 놓는다.

 

 pd3dDevice->CreateVertexDeclaration(dwDecl3, &m_pVertexDeclaration);

 pd3dDevice->SetVertexDeclaration(m_pVertexDeclaration);

 

//ㄴ 다이렉트엑스 sdk 레퍼런스에 요롷게 사용하랜다.

 pd3dDevice->CreateVertexBuffer( 
       8*sizeof(CUSTOMVERTEX),  // 버퍼 
       D3DUSAGE_WRITEONLY,   // 만들어진 버퍼의 성격 (읽기전용)   
       NULL,   // 버퍼 포맷(구조)
       D3DPOOL_DEFAULT,   // 메모리를 어느 영역에 할당할 것인가?
       &m_pTriVB, NULL );

 

//ㄴ 여기서 겁나 해멧삼..   기존 FVF 포멧을 요구하는데..  NULL  제로 값을 넣어주면 포멧 무시하겠단다.

 

 

CUSTOMVERTEX v[] =

 {

                { -1,  1,  1 },            /// v0

                {  1,  1,  1 },            /// v1

                {  1,  1, -1 },            /// v2

                { -1,  1, -1 },            /// v3

 


                { -1, -1,  1 },            /// v4

                {  1, -1,  1 },            /// v5

                {  1, -1, -1 },            /// v6

                { -1, -1, -1 },            /// v7

  };

//ㄴ 요래요래 값을 넣어주고

 

VOID* pVertices;

 m_pTriVB->Lock( 0, sizeof(v), (void**)&pVertices, 0 );
 memcpy( pVertices, v, sizeof(v) );

 m_pTriVB->Unlock();

 

//ㄴ 하던데로 하면됨

 

 

 

//-------------------------------그리는곳-----------------------------------

 

  pd3dDevice->SetStreamSource(0, m_pTriVB, 0, sizeof(CUSTOMVERTEX));

 

  pd3dDevice->SetIndices( m_pTriLB );

 

//ㄴ FVF 로 했던데로 하면된다.

//pd3dDevice->SetFVF( CUSTOMVERTEX::FVF ); 이런거 안해줘도됨






위 포스트ㅏ에 덧붙이자만..


_pD3dDevice->SetVertexDeclaration( _pDecl ); 은 써야함

반응형
반응형


http://gamedevforever.tistory.com/261


Posted by 김포프

예제코드 다운받기


  • C#과 XNA를 이용해서 만들었습니다.

  • XNA를 설치하셔야 합니다.


게임보다는 에디터 따위의 툴에서 더 유용한 기법입니다. 예전에 개인 프로젝트에서 장난삼아 만들어 봤던 놈인데 그뒤로도 몇번이나 동일한 기법을 여러 툴에서 구현하다보니 올리면 유용하겠다 싶어서..... 이미 알고계시는 분들도 많겠지만 혹시나 모르시는 분들을 위해 여기 올리면 좋겠다고 생각해서 올립니다.


이 기법이 해결하려고 하는 건 간단합니다. 맵 에디터 같은 프로그램에서 화면에 있는 물체를 마우스로 클릭해서 선택하는걸 졸라~ 빠르게 구현하는 겁니다.


말로는 쉽죠?... 그런데 보통 구현들 어떻게 하셨나요?


흔히 쓰던 광선 vs AABB 충돌검출 방법

제가 흔히 봤던 방법중 하나는 마우스 클릭한 위치부터 화면 안쪽으로 광선(ray)를 쏴주면서 그 광선과 각 물체의 AABB의 충돌검사를 한뒤 가장 가까이에 있는 물체를 선택하는 거였습니다.


예를 들어 아래 이미지에서 오른쪽 가장자리가 화면이라고 가정하면 이런식으로 ray를 쏴서 aabb를 찾는거죠.



그런데 이 방법에 문제들이 좀 있습니다

  • 월드에 물체들이 많으면 충돌검사 시간 꽤 걸립니다

  • AABB와 충돌검사를 하므로 픽셀단위로 정확한 충돌검사가 불가능합니다.






제가 쓰는 렌더타겟과 물체 ID를 이용한 방법

저는 GPU를 이용해서 위 문제점들을 해결했습니다. 알고리듬은 매우 간단합니다. 자세한 코드는 위에 첨부해 놓은 예제코드를 봐주세요.

  1. 각 물체마다 고유 해쉬 아이디(32비트 정수)를 부여한다.

  2. 화면크기와 동일한 A8R8G8B8 렌더타겟을 하나 만든다. (이후 ID맵이라 부름)

  3. ID Map맵 렌더타겟을 설정한다.

  4. 모든 물체를 그려주면서 물체 해쉬(32비트)값을 8비트씩 짤라 R,G,B,A채널에 써준다

  5. 마우스가 클릭된 위치의 픽셀을 읽어온다

  6. 그 해쉬값과 동일한 물체를 선택한다.

  7. 선택된 물체로 하고 싶은 짓을 한다 -_-

  8. 끝 -_-


해쉬아이디

해쉬 아이디는 아무렇게나 생성이 가능합니다. 각 물체마다 고유하기만 하면 되죠. 제 예제에서는 그냥 물체 이름인 string으로부터 해쉬 아이디를 생성했습니다.


해쉬아이디를 색상으로 바꾸는 법

해쉬 아이디를 RGBA로 바꾸는 코드는 다음과 같습니다.


private static Color HashIDToColour(int hash)

{

    int a = (hash >> 24) & 0xff;

    int b = (hash >> 16) & 0xff;

    int g = (hash >> 8) & 0xff;

    int r = hash & 0xff;


    return new Color(r, g, b, a);

}


이 후 이걸 셰이더 함수로 대입해준 뒤


ColourFX.Parameters["Colour"].SetValue(HashIDToColour(go.Hash).ToVector4());


셰이더 안에서 다음과 같이 그려만 주면 됩니다.

float4 ps(VtxOut In) : COLOR

{

 return Colour;

}


해쉬아이디 읽어오기

매우 간단합니다. 그냥 그 픽셀값을 32비트로 읽어오면 끝입니다. (이미 해쉬 ID에서 색상으로 변환할때 byte순서및 엔디안 문제를 고려했거든요


public int PickObject(int x, int y)

{

    int hash = Hash.INVALID;


    int [] pickedPixel = new int[1];


    IDMap.GetData<int>(0, new Rectangle(x, y, 1, 1), pickedPixel, 0, 1);


    hash = pickedPixel[0];


    return hash;

}


예제 결과

일단 제 샘플 코드를 실행해보면 다음과 같은 그림이 보일겁니다.


메인 화면에 3개의 공이 있고.. 오른쪽 아래는 ID맵입니다.


여기서 파란색 공위에 마우스를 클릭하면 다음과 같이 됩니다.


현재 선택된 물체를 노란색으로 표현했습니다. 그리고 현재 선택된 물체를 ID 맵에 안그려서 다시 한번 더 클릭을 하면 그뒤에 있는 물체가 대신 선택되게 만들었습니다.



이정도면 대충 보여드린듯 하죠? 자세한건 직접 받아서 실행해보세요.. -_-;


기타 응용

최근에 이 기법을 응용해서 물체 ID 대신에 물체의 깊이를 저장도 해봤답니다. 마우스 클릭 위치 근처에 있는 복셀(voxel)들을 전부다 고칠일이 있어서... 그냥 마우스 클릭 깊이만 찾아다 그로부터 월드위치 구한 뒤, octree를 뒤져서 근처에 있는 복셀들을 찾아냈죠.


기타 등등의 응용법이 있을 겁니다.




오랜만에 글써본 포프였습니다.



저작자 표시 비영리 변경 금지
  1. Favicon of http://kindtis.tistory.com 친절한티스 2012/12/03 13:27      

    오왕~ 이렇게 하면 픽셀 단위로 픽킹이 가능하겠네요.

    근데 동일한 화면 크기를 사용하면 고해상도시 메모리 사용량도 높을거 같은데...

    픽킹용 렌더 타겟은 저해상도로 해서 찾아내도 되지 않으까요?

    정확한 픽셀 단위까지 체크할거 아니면 상관 없을거 같은데...

    • 김포프 2012/12/04 12:58    

      적당히 저해상도로 해도 되죠.. 실제로 고해상도로 해도 MSAA쓰면 경계 부분은 아마 정확한 해쉬값이 안나올거에요....

  2. 조금신 2012/12/03 17:37      

    DX9 이하에서는 픽셀값을 읽어올 때, GetRenderTargetData를 사용해야 하는 것으로 알고 있는데, 이 함수 자체가 하드웨어특성을 많이 타는 문제있는 함수라, 경우에 따라서는 picking ray를 이용한 검출 보다 느린 것으로 알고 있습니다. 혹시 다른 방법으로 픽셀을 읽는 방법이 있는지요?

    • 김포프 2012/12/04 12:58    

      어차피 개발자용 컴퓨터에서 사용할 함수니까(맵 에디터를 공개 안한단 조건하에..) 별 상관없지 않나요?

      한마디로 다른 방법은 모릅니다. ^_^ surface를 통채로 systemmem에 있는 렌더타겟에 복사한 뒤 거기서 찾아보면 어떨까요.. -_-;

    • Hybrid 2012/12/11 17:26    

      기억이 확실하지 않은데 제가 기억하는게 맞다면, 아마 이 방법이 고전적인 OpenGL 에서 기본 제공하는 피킹의 내부 메카니즘일겁니다.
      http://content.gpwiki.org/index.php/OpenGL:Tutorials:Picking
      이쪽에서는 자체 API를 이용하는거니 물론 화면 데이터를 다 가져올 필요가 없지요.

      일단 화면 메모리 락걸고 메모리 카피하느라 생기는 성능저하를 생각하면, 아무래도 직접 OpenGL API를 (다룰 수 있다면) 다루는게 훨씬 빠를르겠네요. (OpenGL 코드는 매우 간단하죠.)
      DX 도 비슷한게 있을꺼 같은데..... DX는 잘 모르겠고.... @.@

    • 김포프 2012/12/30 05:34    

      DX자체에서 지원하는 방법은 없는것 같구요... 뭐 전 여러번 써본 방법인데 툴에서 쓰기에 속도저하는 크게 걱정할 부분이 아니었습니다.. 정 속도저하가 되면 그냥 더블 버퍼링 걸면 되겠죠.. -_-; (1프레임 딜레이 쯤이야!....)

  3. 대마왕J 2012/12/11 22:40      

    쉬운데.....? -_-a (오호?) 첨에 공 그림들이 뭔소리인지 이해가 안가서 글만 정독하니까 그때야 그림이 이해가 가네요. 그림에 민감한것도 참 이럴땐 단점 ... 
    저도 나중에 툴 만들고 막 이렇게 되면 써야겠어요. 툴에서야 뭐 퍼포먼스따위... 하드웨어빨로 밀어붙이면 되니까.. 

    • 김포프 2012/12/30 05:34    

      제가 아트에 약합니다.. 흑흑 ..ㅜ_ㅜ

반응형
반응형

http://cafe.naver.com/jzsdn/3286




게임 이펙트를 구현하시려고 하는분을 위해 간략히 써봅니다.

제가 하는 이야기가 무슨말인지 경험자분들은 대개 알고 계실거라 생각됩니다.

 

아시는 분은 아시겠지만... 일반적으로 게임 오브젝트를 렌더링 할경우

비알파 오브젝트를 먼저 렌더링하고 알파적용 오브젝트를 렌더링하게 됩니다.

 

 

그래야 알파적용 오브젝트가 비알파 오브젝트를 뒷배경으로 알파블렌딩 효과를

나타내기 때문이죠...

 

 

대개의 이펙트 효과는 반투명(알파 블렌딩) 의 효과를 가진게 많이 존재합니다.

 

일반적으로 여러개의 알파적용 오브젝트를 렌더링 할 경우에는 카메라와 거리를 재서

먼것부터 그려나가기 시작하죠

 

그래야 블렌딩 효과가 적용되기 때문입니다. 가까운것을 먼저그리게 되면

멀리 있는 오브젝트를 가까이 있는 오브젝트가 블렌딩하지 못하게됩니다.

게다가 뒷쪽에 오브젝트는 Z버퍼에 위해 걸러지게 되어 전체적으로

이상한 형상을 뛰게됩니다. 

 

 

여기까지는 아마 대개 렌더링 정책에 관한 이야기로 이미 알고 계신분들도 많으실겁니다 ^^;

 

 

이펙트를 구현하다보면 현실적으로 수많은 이펙트 메쉬들을 전부다 카메라와 거리를 통해

그려나간다는것은 불가능하다고 봐야겠죠... ^^

 

게다가 원통형의 마법형태를 구현하려고 하면 반정도가 이상한 모습을 뛴 모양이 나오게

될겁니다.

 

이런것들을 한방에 해결하게 해주는 요소가 바로 렌더링설정에서 D3DRS_ZWRITEENABLE

FALSE로 설정하는 것입니다.

 

비알파 오브젝트를 먼저 렌더링하게 되면  Z버퍼에 상에 비알파 오브젝트에 대한 사항이

먼저 적용됩니다. (여기서도 비알파 오브젝트는 먼저 그려져야 합니다. ^^)

여기서는 D3DRS_ZWRITEENABLE가 물론 TRUE겠죠.

 

D3DRS_ZWRITEENABLE을 FASLE로 설정하고 이펙트를 렌더링하게 되면

Z버퍼를 갱신하지않고 렌더링이 적용되게 되죠. 그래서 가까이있는게

먼저 그려진다고 하더라도 이 가까운 메쉬에 위해 Z버퍼가 갱신되지 않게됩니다.

 

 

순차적으로 접근해보면....(다시 수정)

1. 가까운 메쉬가 그려진다. (Z버퍼가 갱신되지 않고 가장 먼상태로 그대로 유지된다.)

2. 먼 메쉬가 그려진다. ( Z버퍼가 갱신되지 않고 먼상태이기에 먼 메쉬도 그려진다.)

 

 

이상황에서 블렌딩을 적용하게 되면 자연스럽게 두색상이 적당히 혼합되 뒤쪽에 있는 메쉬를

가까이 있는 메쉬가 비추는듯한 효과가 생기게 되는거지요.

 

만약 이펙트가 비알파 오브젝트 뒤쪽에 존재한다면.. 이미 비알파오브젝트를 렌더링하고

Z버퍼는 비알파 오브젝트에 위해 갱신된값을 가지기 때문에

그려지지 않게됩니다. (이게 바로 Z버퍼를 끄지않고 D3DRS_ZWRITEENABLE를 사용하는 이유입니다.)

 

해당 아티클을 적용할시에 대개 블렌딩 모드를

 

lDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);   
lDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

 

lDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);   
lDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

 

lDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);   
lDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);

 

lDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);   
lDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);

 

이 넷중에 하나로 설정할때 사용합니다. 

반응형
반응형
http://parkpd.egloos.com/3790654

이번에는 [http]Adding a Skybox to RenderMonkey 블로깅을 간단하게 번역해 봤습니다. 쉐이더 코드에 한글 주석을 넣으면 error X3000 가 생기는 경우가 있군요. 컴파일 에러가 나면 한글 주석을 다 빼고 해 보세요.

RenderMonkey 에 스카이박스 붙이기

전에는 [http]RenderMonkey 에 대한 기본적인 튜토리얼을 블로깅했습니다. 이번에는 어떻게 하면 RenderMonkey 에서 화면에 보여지는 단색 배경 대신 스카이박스(skybox) 를 보여줄 수 있을지를 얘기해 볼까 합니다. 저는 이미 여러분이 [http]이전 튜토리얼을 읽고 따라해 봤고, HLSL 에 대해 익숙하며 RenderMonkey 가 아닌 다른 곳에서 스카이박스를 어떻게 만드는지 알고 있다고 가정하겠습니다. 인터넷 찾아보시면 (이 블로깅처럼) 스카이박스를 어떻게 구현하는지 좋은 자료를 많이 찾아볼 수 있습니다. 그나저나 제가 구현한 방식은 Riemer Grootjans 의 책 [http]XNA 3.0 Game Programming Recipes 에 기초하고 있습니다. 이 책에서는 이 외에도 여러 다양한 주제를 다루고 있는데 도움되는 내용이 많습니다.

소개

RenderMonkey 에서 처음 쉐이더를 짜기 시작하면서 환경매핑(environment mapping) 같은 이펙트를 제대로 테스트하기 위해 씬에 스카이박스를 붙이는 법을 찾아봤습니다. RenderMonkey 의 인터페이스를 뒤져봤지만 스카이박스를 그려주는 기능을 찾을 수가 없더군요. 결국 직접 구현하기로 했습니다. 뭔가 더 쉽고 직관적인 방법이 있을 거 같기도 해서, 사실 제 방식을 공개하는게 큰 의미가 있을까 망설이기도 했습니다. 그러니 더 쉬운 방법이 있다면 제발 저에게 알려주세요.

제가 스카이박스를 그리는 비결은 이펙트에 두 번째 쉐이더 패스를 추가해서, 첫 번째 쉐이더로는 스카이박스를 그리고, 두 번째 쉐이더로 모델을 그리는 것입니다. 여기에서 보여드릴 구현에서는 항상 카메라 중점에 위치하는 (RenderMonkey 에서 생성한) 간단한 텍스처 맵핑 큐브모델을 사용할 겁니다. 이렇게 하면 카메라가 어디 있더라도 스카이박스는 충분한 거리를 항상 유지할 수 있습니다. 그래픽 카드의 렌더 스테이트를 바꾸고 감기 순서(culling order)를 뒤집어서 안이 그려지도록 하고, 스카이박스를 그릴때 Z-버퍼 쓰기를 막아서 두 번째 패스에서 모델을 그리는데 아무 문제가 없게 했습니다. 스카이박스에 텍스처를 입히기 위해서는 기본으로 제공되는 큐브맵과 texCUBE 이라는 HLSL 기본함수만 있으면 됩니다. 이제 시작해 봅시다!

이펙트 시작하기

먼저 워크스페이스에 새로운 DirectX 이펙트를 만들고(Effect Workspace -> Add Default Effect -> DirectX -> DirectX), 이펙트 위에서 우클릭한 뒤 "Add Pass" 를 선택해 두 번째 패스를 추가합시다.

a_pass1.jpg


이후 워크스페이스는 다음과 같을 겁니다.

a_pass2.jpg


지금부터 스카이박스를 설치하는 대부분의 작업은 첫 번째 패스(Pass 0)에서 하게 됩니다. 큐브 모델을 만들고, 몇가지 변수와 쉐이더에서 쓸 큐브맵 텍스처를 준비하고, 쉐이더를 작성하고 그래픽 카드의 렌더 스테이트도 제대로 잡아줘야 합니다. 단계별로 나갈테니 너무 걱정마세요.

큐브 만들기

스카이박스로 쓸 큐브 모델을 만들기 위해서는, 이펙스 위에서 우클릭해서 새로운 모델을 추가해야 합니다. 하지만 목록 중에서 모델을 선택하진 마세요. 대신에 목록 최상단에 있는 기본 모델(Model) 을 선택합니다. myModel1 이라는 객체가 생길텐데 기존 모델과 헷갈리는 게 싫으니 이름을 "Box" 로 바꿔줍시다.

b_model1.jpg


이제 새로 만든 모델 Box 위에서 우클릭한 뒤 "Generator" -> "Geometry Generator" 를 선택합니다. 이러면RenderMonkey 가 우리의 선택에 따라서 적당한 데이터를 모델에 채워줍니다.

b_model2.jpg


팝업창에서 적당한 크기의 상자를 생성합니다. near 평면과 far 평면을 어떻게 설정하느냐에 따라서 박스 크기가 너무 작거나 클 경우에 문제가 생길 수 있습니다. 여기에서는 25x25x25 크기의 박스를 만들겠습니다.

b_model3.jpg


까먹기전에 Pass 0 를 열어서 model 위에서 우클릭한 뒤 새로 생성한 상자를 할당합시다(아마 model 은 처음 추가한 model 을 가리키고 있었을 겁니다). 

b_model4.jpg


변수 생성

아래에서 보여드릴 스카이박스 쉐이더에서는 3 개의 전역 변수를 사용하는데, 각각 카메라의 위치, 뷰-프로젝션 행렬, 하늘(sky)에 사용할 큐브맵 텍스처입니다.
float4 ViewPosition;
float4x4 ViewProjection;
sampler Texture;

이전 튜토리얼에서 봤던 것처럼 이들 변수를 생성합시다. 적당한 데이터타입과 시멘틱을 지정하는 것을 잊지 맙시다. ViewProjection 행렬은 기본적으로 들어있지만(matViewProjection), 기본 이름이 맘에 들지 않기 때문에 이름을 ViewProjection으로 바꿨습니다. Pass 0, Pass 1 의 쉐이더 코드에서 matViewProjection 를 찾아 전부 ViewProjection 로 바꿔줍시다. ViewPosition 같은 경우 Float 의 미리 정의된 (predefined) 변수에서 찾을 수 있습니다. 

c_var1.jpg


텍스처를 로딩하기 위해서 Cubemap 옵션을 사용합니다(Add Texture -> Add Cubemap -> Snow.dds).

c_var2.jpg


방금 생성한 큐브맵(Snow)과 링크되는 Texture Object 를 "Texture" 라는 이름으로 Pass 0 에 추가하는 것도 잊지 맙시다.

c_var4.jpg


원한다면 텍스처 객체가 좀더 나은 필터링 방식을 쓰게 할 수도 있습니다.

c_var5.jpg


코드 추가

이제 정점 쉐이더와 픽셀 쉐이더 코드를 추가해 봅시다. 아래에 이미 코드가 준비되어 있습니다. 각각 Pass 0 의 정점 쉐이더와 픽셀 쉐이더에 복사해 붙여넣습니다. 코드가 어떤 작업을 하는지를 주석으로 설명해 넣었습니다만, 궁금한 점이 있으면 언제든지 물어봐주세요.

정점 쉐이더 :
float4 ViewPosition;
float4x4 ViewProjection;
  
struct VS_INPUT
{
   float4 position : POSITION0;
};
  
struct VS_OUTPUT
{
   float4 position : POSITION0;
   float3 position3D : TEXCOORD0;
};
  
// 이동 행렬을 만든다.
float4x4 translation(float3 position)
{
   return float4x4(
              float4(1,0,0,0),
              float4(0,1,0,0),
              float4(0,0,1,0),
              float4(position.xyz, 1)
          );
}
  
VS_OUTPUT vs_main(VS_INPUT input)
{
   VS_OUTPUT output;
  
   // 스카이박스를 카메라 위치로 옮기는 월드 행렬을 만든다.
   float4x4 world = translation(ViewPosition.xyz);
  
   // 월드행렬을 기존 뷰-프로젝션 행렬과 곱한다.
   float4x4 WorldViewProjection = mul(world, ViewProjection);
  
   // 이렇게 만든 공간으로 정점을 이동시킨다.
   output.position = mul(input.position, WorldViewProjection);
 
   // 모델 공간에서의 원래 정점 위치를 저장한다.
   // 큐브 모델은 중심점이 원점에 있기 때문에
   // 원래 정점 위치값을 큐브맵의 방향값으로 바로 활용할 수 있다.
   output.position3D = input.position;
  
   return output;
}
(한글 주석 때문에 error X3000: syntax error: unexpected end of file 에러가 뜨는 경우가 있네요. 한글 주석을 제거하면 에러가 사라집니다. 한글주석이나 경로에 한글이 들어가면 이런 현상이 있다고 하는데 RenderMonkey 의 버그인지 뭔지 정확한 원인을 모르겠네요.)

픽셀 쉐이더 :
sampler Texture;
  
struct VS_OUTPUT
{
   float4 position : POSITION0;
   float3 position3D : TEXCOORD0;
};
  
float4 ps_main(VS_OUTPUT input) : COLOR0
{
   // 원래 정점 위치를 큐브맵 텍스처를 샘플링하는데 사용한다.
   return texCUBE(Texture, input.position3D);
}

렌더 스테이트 설정

아직 화면에는 아무 것도 안 나오겠지만, 쉐이더는 아무 문제없이 컴파일 될 겁니다. 아무 것도 보이지 않는 이유는 우리가 큐브 모델 내부에서 그려지지 않는 안쪽 평면을 보고 있기 때문입니다. 그래픽 카드의 감기 방식(culling mode)를 바꿔줍시다. 또한 우리는 하늘(sky)가 씬의 마지막까지 남게 하고 싶기 때문에 z-버퍼 쓰기를 금지시켜야 합니다.

이를 위해서 Pass 0 에 우클릭한 뒤 "Add Render State Block" 을 추가, 편집해 줘야 합니다. 이런 변경사항은 모델 그릴 때에는 원래대로 되돌려놔야 하기 때문에 Pass 1 에서 같은 작업을 반복해야 합니다.

Pass 0 의 Render State Options :
D3DRS_CULLMODE 를 D3DCULL_CW 로 변경
D3DRS_ZWRITEENABLE 을 FALSE 로 변경
e_state1.jpg


Pass 1 의 Render State Options:
D3DRS_CULLMODE 를 D3DCULL_CCW 로 변경
D3DRS_ZWRITEENABLE 을 TRUE 로 변경
e_state2.jpg


결론

이제 끝났습니다! 이제 Pass 1 를 바꿔서 원하는 쉐이더를 써 넣어도, 스카이박스는 계속 보일 것이고 카메라에 맞춰서 반응할 것입니다. 결과는 다음과 같습니다 :

g_end.jpg


적당한 스카이박스가 준비되어 있다면 아래와 같은 반사(reflection) 나 굴절(refraction) 등의 여러 이펙트도 시험해 볼 수 있습니다.

example.jpg


마지막 팁 : 기본적으로 Pass 1 은 Pass 0 과 똑같은 Stream Mapping 구조체를 참조하고 있습니다. 각 pass 별로 다른 구조체가 필요하다면, 이펙트별로 새로운 Stream Mapping 객체를 만들어 우클릭한 뒤 Pass 1 의 참조를 새로운 인스턴스로 바꿔주기만 하면 됩니다.

오늘은 여기까지입니다. 도움이 되었으면 좋겠네요.

반응형
반응형

http://stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader




What you generally do when you want a random value in a pixel shader is to pass in a texture containing noise. While it's not actually "random" - it looks random.

For example, here's some code from a pixel shader I have lying around:

float3 random = (tex2D(noiseTexture, texCoord * noiseScale + noiseOffset));

The texture I use is an RGB-noise texture, which can come in handy some times. But the same technique would work for a grayscale one.

By scaling it I ensure that the pixels in the noise texture line up to on-screen pixels (you may also want to set the texture sampler to "point" mode so you don't blur the noise texture).

By using an offset you can scroll the texture - which is kind of like seeding a random number generator. Use a random offset if you want to avoid that "scrolling" look.

반응형
반응형
http://www.gpgstudy.com/m/forum/topic/22596

정점 셰이더 초기화에 대한 궁금증입니다

예를 들어 구조체가 
D3DXVECTOR3 p; 
D3DXVECTOR3 n; 
DWORD Diffuse; 
float u, v; 

라고 했을때 

이런식으로 했는데 잘 안되네요.. 
D3DVERTEXELEMENT9 declaration[] = 

{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, 
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, 
{ 0, 24, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, 
{ 0, 28, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, 
D3DDECL_END() 
}; 

후미 4시간째 해메고 있습니다

color쪽이 틀린것 같네요.

코드:
{ 0, 24, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, 


대신에 

코드:
{ 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, 


쓰셔야 할것 같아요.

Re:

감사합니다 ㅠㅠ

반응형

+ Recent posts