IDirect3DDevice9::CreateVertexBuffer

정점 버퍼를 생성한다.

 

Length - [in] 버퍼에 할당할 바이트 수, 8개의 정점을 보관하고 싶다면 8 * sizeof(struct vertex)로 크기를 조정한다.

정점버퍼의 크기, (ex) 한 정점에 들어가는 바이트 수가 들어 있는 변수 offset에 4를 곱하면 정점 4개에 필요한 메모리 크기가 된다.

 

Usage - [in] 버퍼가 이용되는 방법을 결정하는 특성을 지정

  • D3DUSAGE_DYNAMIC - 동적 버퍼 설정
  • D3DUSAGE_POINTS - 버퍼가 포인트 기본형으로 설정 (용책 14장 파티클 시스템), 정점 버퍼에서만 이용가능
  • D3DUSAGE_SOFTWAREPROCESSING - 정점 프로세싱을 소프트웨어로 처리
  • D3DUSAGE_WRITEONLY - 버퍼에 쓰기만을 수행할 것임을 설정, 드라이버가 쓰기 작업에 최적화된 메모리 위치로 버퍼를 이동, 이 버퍼를 읽으려 하면 오류 발생

FVF - [in] 정점 버퍼에 보관될 FVF

Pool - [in] 정점 버퍼가 저장될 메모리의 위치(그래픽 카드, 시스템 메모리)와 관리방식 지정

  • D3DPOOL_MANAGED : D3D가 알아서 관리해주는 메모리 풀 사용하겠다

ppVertexBuffer - [out, return value] 반환된 정점 버퍼를 받을 포인터

pHandle - [in] 사용 안한다, 항상 NULL로 설정한다

 

생성된 정점 버퍼는 쓰레기 값으로 가득 차있다. 정점 버퍼에 값을 넣어주어야 하는데 정점 버퍼의 주소값이 필요하다.

이 때 Lock() 함수로 해당 메모리의 주소를 얻어야 한다.

 

주의 : 정점 버퍼의 해제는 D3D 디바이스 해제 이전에 이루어져야 한다. 정점 버퍼는 D3D 디바이스를 통해 생성되었기 때문이다


IDirect3DVertexBuffer9::Lock

정점 데이터의 범위를 잠그어, 정점 버퍼 메모리의 포인터를 얻어온다.

잠금 카운트가 남아 있는 경우, DrawPrimitive 호출이 불가능하다!

(쓰레드의 Lock()을 생각하면 된다. 다른 자원에선 접근이 불가능하다)

이후 획득한 메모리 포인터에 선언한 정점을 memcpy()로 복사한다.

다 끝난 이후엔 Unlock()으로 버퍼 잠금을 해제한다

gpgstudy.com/forum/viewtopic.php?t=5173

 

버텍스 버퍼에 lock / unlock 은 왜 매번 거는거죠? - GpgStudy 포럼

2D, 3D, 다각형, 픽셀 등 게임의 그래픽 프로그래밍에 관한 포럼입니다. 운영자: 류광 비회원 전체글 글쓴이: 비회원 » 2005-02-23 03:39 음.... 안녕하세요^_^ (일단 인사부터 ^^ ; ) 예전부터 궁금하던것�

gpgstudy.com


IDirect3DDevice9::CreateVertexBuffer

인덱스 버퍼를 생성한다

 

 

 

sizeof(short) * 6 : 인덱스 버퍼의 크기(바이트 수), 16비트 인덱스를 6개 사용하겠다

0 : 특별한 용도로 사용하는건 아니다

D3DFMT_INDEX16 : 각 색인은 16비트이다

D3DPOOL_MANAGED : D3D가 알아서 관리해주는 메모리 풀을 사용하겠다

gpFullscreenQuadIB : 새로 생성된 인덱스 버퍼를 저장할 포인터

NULL : 반드시 NULL이어야 한다

 

 

 

hanjuho.tistory.com/6

 

버텍스 버퍼 3편[사용]

전편에서 정점 버퍼를 생성했으니 이제 값을 넣어야 한다. 정점 버퍼를 생성하고 정점값을 채워넣는다. 정점 버퍼란 기본적으로 정점 정보를 갖고 있는 메모리 블록이다. 정점 버퍼를 생성한 다

hanjuho.tistory.com

openhead.tistory.com/entry/Direct-%EC%9D%B8%EB%8D%B1%EC%8A%A4-%EB%B2%84%ED%8D%BC-%EC%B4%88%EA%B8%B0%ED%99%94-Index-Buffer

 

Direct 인덱스 버퍼 초기화 ( Index Buffer )

인덱스와 버텍스의 기본은 2013/11/12 - [Direct 3D 9/기초 용어] - Direct 기본 용어 정리 Vertex 와 Index | Polygon 정점(Vertex) 초기화는 2013/12/09 - [Direct 3D 9/초기화] - Direct 정점 버퍼 초기화 새로..

openhead.tistory.com

 

'그래픽스 > Dx 9' 카테고리의 다른 글

Direct X - 정점 선언  (0) 2020.09.16
Direct X 9 - 셰이더(Effect)  (0) 2020.09.16
Direct X 9 - 함수  (0) 2020.09.15

구조체

D3DVERTEXELEMENT9

파이프라인의 입력 정점 데이터를 정의한다.

 

Declaration과 관련된 구조체로, D3DVERTEXELEMENT9 구조체는 각 정보들의 타입이나 데이터의 길이 등을 설정한다.

 

Stream - 복수의 스트림을 구별하기 위한 번호

D3D 장치에 정점버퍼들을 동시에 여러 개 집어넣어줄 수 있는데, 이 때 정점버퍼가 들어가는 슬롯의 인덱스 번호이다. 정점버퍼가 하나면 0으로 설정하면 된다.

 

Offset - 스트림으로 사용하는 구조체의 선두 위치로부터 바이트 수

정점정보가 시작하는 메모리 위치에서 현재 요소가 시작하는 곳까지의 오프셋 값. 정점버퍼의 제일 앞에 위치 값을 넣는다면 오프셋은 0이다.

 

Type - D3DDECLTYPE 의 데이터형을 지정

데이터형이다. 사용하는 데이터에 맞는 형을 설정하면 된다

 

Method - 테셀레이터가 어느 데이터를 평면 분할에 사용하는지에 대한 선언, 하지 않는다면 D3DDECLMETHOD_DEFAULT

김포프 책에서 DEFAULT 이외 다른 값 사용하는 경우 아직 못봤다고 한다.

 

Usage - D3DDECLUSAGE 매크로를 사용하여 설정

해당 데이터 요소의 용도를 정의한다. 위치면 위치, 노말이면 노말, 탄젠트면 탄젠트, 텍스처 좌표면 텍스처 좌표 등

UsageIndex - 1개의 셰이더에 복수의 좌표가 있을 때 이를 구별하기 위한 용도로 사용, 셰이더 프로그래밍에서 dcl_positionX 인덱스에 대응

셰이더에서 TEXCOORD 시맨틱을 사용할 때 뒤에 붙던 숫자들(TEXCOORD0, TEXCOORD1, etc)이 UsageIndex이다.

0, 3 * 4, 6 * 4, 8 * 4

float 3개 3개 2개

셰이더를 사용할 때에는 FVF보다 정점선언을 사용하는게 일반적이다. 정점선언은 FVF에서 지원하지 않는 TANGENT나, BINORMAL같은 형도 지원할 뿐 아니라 FVF에서 특정 순서로 정점정보를 넣어줘야만 하는 제약도 없다.

 

김포프 셰이더 책에서는 정점 선언을 이렇게 처리한다

이러한 방식이 아래와 같은 방식보다는 보기에 편해보이나?

FVF가 좀 더 간편하게 버텍스를 정의해주는 거라면, 정점선언은 좀 더 세세하게 직접 만드는 용도라고 볼 수 있다.

 

 

 

 

telnet.or.kr/directx/graphics/programmingguide/gettingstarted/vertexdeclaration/vertexdeclaration.htm#Mapping_FVF_to_DX9_Decl

 

정점 선언

정점 선언 개념상, 정점 선언은, 정점 DMA (Direct Memory Access)나 그래픽스 파이프의 테설레이터 엔진을 프로그래밍 하는 방법의 1 개이다. 정점 선언은, 데이터 레이아웃과 테셀레이트의 처리를 간��

telnet.or.kr


IDirect3DDevice9::CreateVertexDeclaration

장치 및 정점 요소로부터 정점 셰이더 선언을 생성한다

 

 

D3DVERTEXELEMENT로 만들어진 배열을 in 인자에 넣고, out 인자로 얻은 IDirect3DVertexDeclaration9** 정점 선언 포인터는, 나중에 메시를 그릴 때 이 정점버퍼의 포맷은 이러이러하니 알아서 올바른 데이터를 뽑아갈 것 이라는 지시를 D3D에 내리는데 사용한다.

 


IDirect3DDevice9::SetVertexDeclaration

정점 셰이더 선언을 설정한다

SetVertexDeclaration은 vertex의 정보 값을 나타낸다.

Vertex의 속성을 SetVertexDeclaration으로 설정해놓으면, 디바이스는 버텍스 정보를 받아와 정점 입력 레지스터로 받아온다. 

 

'그래픽스 > Dx 9' 카테고리의 다른 글

Direct X - 버텍스, 인덱스 버퍼  (0) 2020.09.16
Direct X 9 - 셰이더(Effect)  (0) 2020.09.16
Direct X 9 - 함수  (0) 2020.09.15

https://www.acmicpc.net/problem/10972

 

10972번: 다음 순열

첫째 줄에 입력으로 주어진 순열의 다음에 오는 순열을 출력한다. 만약, 사전순으로 마지막에 오는 순열인 경우에는 -1을 출력한다.

www.acmicpc.net

 

 

https://www.acmicpc.net/problem/10973

 

10973번: 이전 순열

첫째 줄에 입력으로 주어진 순열의 이전에 오는 순열을 출력한다. 만약, 사전순으로 가장 처음에 오는 순열인 경우에는 -1을 출력한다.

www.acmicpc.net

 

'알고리즘' 카테고리의 다른 글

백준 15666 : N과 M(12)  (0) 2020.10.22
백준 6588 : 골드바흐의 추측  (0) 2020.10.22
백준 9095 : 1, 2, 3 더하기  (0) 2020.09.09
koi : 타일 채우기(DP아님)  (0) 2020.08.19
동적 계획법  (0) 2020.08.19

https://www.acmicpc.net/problem/9095

 

9095번: 1, 2, 3 더하기

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.

www.acmicpc.net

 

 

플랫 셰이딩

면의 법선벡터와 조명벡터로 면의 밝기를 계산한다

 

공간 변환 후 넘겨주기만 하면 된다. 월드공간 좌표는 따로 빼고

ddx / ddy 함수는 변화량을 구하는 함수, hlsl ddx 검색


고로 셰이딩

정점의 법선벡터와 조명벡터로 정점의 밝기를 계산한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
float4x4 matViewProjection;
 
float4 gWorldLightPosition;
float4 gWorldCameraPosition;
 
struct VS_INPUT 
{
   float4 mPosition : POSITION0;  
   float3 mNormal : NORMAL; 
};
 
struct VS_OUTPUT 
{
   float4 mPosition : POSITION0;   
   float3 mColor : COLOR1;
};
 
VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;
 
   Output.mPosition = mul( Input.mPosition, matViewProjection );
   
   float4 projectionLightPosition = mul(gWorldLightPosition, matViewProjection);
   float4 projectionCameraPosition = mul(gWorldCameraPosition, matViewProjection);
   float3 projectionNormal = mul(Input.mNormal, (float3x3)matViewProjection);
   
   float3 lightDir = Output.mPosition.xyz - projectionLightPosition.xyz;
   lightDir = normalize(lightDir);
   
   float3 viewDir = Output.mPosition.xyz - projectionCameraPosition.xyz;
   viewDir = normalize(viewDir);
   
   float3 reflection = reflect(lightDir, projectionNormal);
   reflection = normalize(reflection);
   
   float3 diffuse = dot(-lightDir, projectionNormal);
   diffuse = saturate(diffuse);
   
   float3 specular = 0;
   
   if(diffuse.x > 0)
   {
      specular = saturate(dot(reflection, -viewDir));
      specular = pow(specular, 20.0f);
   }
   
   float3 ambient = float3(0.1f, 0.1f, 0.1f);
   
   Output.mColor = float4(ambient + diffuse + specular, 1);
   
   return( Output );
}
cs

투영 공간에서 연산을 수행했다

1
2
3
4
5
6
7
8
9
10
struct PS_INPUT
   float3 mColor : COLOR1;
};
 
float4 ps_main(PS_INPUT Input) : COLOR0
{   
   return float4(Input.mColor, 1);
   
}
cs

ambient가 이렇게 간단하게 계산이 될 것 같지는 않지만,

고로 셰이딩은 간단히 말해 밝기 계산을 정점 셰이더에서 처리하는 것을 의미한다.

보간의 힘을 빌리기 때문에 굳이 어떻게든 퀄리티를 떨어트린다면 이정도로 떨어트릴 수 있다.

 

예전 게임들에서 자주 보인 빛의 형태가 보인다.


퐁 셰이딩

픽셀의 법선벡터와 조명벡터로 픽셀의 밝기를 계산

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
float4x4 matViewProjection;
 
float4 gWorldLightPosition;
float4 gWorldCameraPosition;
 
struct VS_INPUT 
{
   float4 mPosition : POSITION0;  
   float3 mNormal : NORMAL; 
};
 
struct VS_OUTPUT 
{
   float4 mPosition : POSITION0;   
   float3 mLightDir : TEXCOORD0;
   float3 mViewDir : TEXCOORD1;
   float3 mNormal : TEXCOORD2;
};
 
VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;
 
   Output.mPosition = mul( Input.mPosition, matViewProjection );
   
   float4 projectionLightPosition = mul(gWorldLightPosition, matViewProjection);
   float4 projectionCameraPosition = mul(gWorldCameraPosition, matViewProjection);
   
   float3 projectionNormal = mul(Input.mNormal, (float3x3)matViewProjection);
   Output.mNormal = projectionNormal;
   
   float3 lightDir = Output.mPosition.xyz - projectionLightPosition.xyz;
   lightDir = normalize(lightDir);
   Output.mLightDir = lightDir;
   
   float3 viewDir = Output.mPosition.xyz - projectionCameraPosition.xyz;
   viewDir = normalize(viewDir);
   Output.mViewDir = viewDir;
   
   return Output;
}
cs

마찬가지로, 투영 공간에서 광원벡터, 카메라벡터를 계산했다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct PS_INPUT
   float3 mLightDir : TEXCOORD0;
   float3 mViewDir : TEXCOORD1;
   float3 mNormal : TEXCOORD2;
};
 
float4 ps_main(PS_INPUT Input) : COLOR0
{  
   Input.mLightDir = normalize(Input.mLightDir);
   Input.mViewDir = normalize(Input.mViewDir);
   Input.mNormal = normalize(Input.mNormal);
 
   float3 diffuse = dot(-Input.mLightDir, Input.mNormal);
   diffuse = saturate(diffuse);
   
   float3 reflection = reflect(Input.mLightDir, Input.mNormal);
   reflection = normalize(reflection);
   
   float3 specular = 0;
   
   if(diffuse.x > 0)
   {
      specular = saturate(dot(reflection, -Input.mViewDir));
      specular = pow(specular, 20.0f);
   }
   
   float3 ambient = float3(0.1f, 0.1f, 0.1f);
   
   return float4(diffuse + ambient + specular, 1);
   
}
cs

실제 밝기의 계산은 픽셀 셰이더에서 해줘야 한다.

 

아니 근데 이게 맞나...?

 

 

결과물만 보자면 맞긴 한데... 이 방식이 맞나

 

보다시피, 둘이 대놓고 비교하면 큰 차이가 나긴 한다.

 

아무튼, 고로 셰이딩과 퐁 셰이딩은 위와 같다.

 

androgameprgm.tistory.com/entry/RenderMonkey-Tutorial-03?category=217339

 

RenderMonkey Tutorial - 03

간단한 Phong Reflect 를 이용한 Specular 예제입니다. ---- Vertex Shader ---- 퍼 픽셀 셰이더로 구현 ( 픽셀 단위당 라이트 계산을 하므로 위 그림과 같이 매우 견고한 라이트가 나옵니다. ) float4x4 matView..

androgameprgm.tistory.com

 

'그래픽스' 카테고리의 다른 글

유니티 셰이더, 셰이더  (0) 2020.09.08
Volumetric Light  (0) 2020.09.08
상수 버퍼, constant buffer  (0) 2020.09.08
Assimp  (0) 2020.09.08
God Ray  (0) 2020.09.07

+ Recent posts