검색결과 리스트
DirectX11에 해당되는 글 6건
- 2016.07.03 Device , DeviceContext 생성
- 2016.07.03 텍스처 관련
- 2016.07.02 화면 출력
- 2016.07.02 Direct3D 기본
- 2016.07.02 XNA Math 라이브러리 (행렬)
- 2016.07.02 XNA Math 라이브러리(벡터)
글
Device, DeviceContext 는 물리적인 그래픽 장치 하드웨어에 대한 소프트웨어 제어기라고 생각하면 된다.
ID3D11Device 인터페이스는 기능 지원 점검과 자원 할당에 쓰인다.
ID3D11DeviceContext 인터페이스는 렌더 대상을 설정하고, 자원을 그래픽 파이프 라인에 묶고, GPU가 렌더링 명령들을 지시하는 데 쓰인다.
Device와 DeviceContext를 생성하는 함수
HRESULT D3D11CreateDevice {
IDXGIAdapter *pAdapter,
D3D_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
CONST D3D_FEATURE_LEVEL *pFeatureLevels,
UINT FeatureLevels,
UINT SDKVersion,
ID3D11Device **ppDevice,
D3D__FEATURE_LEVEL *pFeatureLevel,
ID3D11DeviceContext **ppImmediateContext
};
1. pAdapter : 이 함수로 생성할 Device를 나타내는 디스플레이 어댑터를 지정한다.
이 메개 변수에 널 값을 지정하면 기본 디스플레이 어댑터가 사용된다.
2. DriverType : 일반적으로 렌더링에 3차원 그래픽 가속이 적용되게 하기 위해선 이 매개변수에 D3D_DRIVER_TYPE_HARDWARE를 지정한다.
다른 매개 변수로는
ⓐ D3D_DRIVER_TYPE_REFERENCE
- 표준 장치를 생성한다. 즉, 하드웨어가 지원하지 않는 기능을 시험할때, 구동기의 버그를 시험할때 사용한다.
ⓑ D3D_DRIVER_TYPE_SOFTWARE
- 3차원 하드웨어를 흉내내는 소프트웨어 구동기를 생성한다.
ⓒ D3D_DRIVER_TYPE_WARP
- Direct3D 10.1 소프트웨어 구동기를 생성한다. (D3D11버전을 지원하지 않는다.)
3. Software: 소프트웨어 구동기를 지정한다.
4. Flags: 추가적인 장치 플래그들을 지정한다.
(흔히 쓰이는 2개)
ⓐ D3D_CREATE_DEVICE_DEBUG : 디버그 모드 빌드에서 디버그 계층을 활성화 하려면 이 플래그를 설정 해야한다.
( 이 플래그를 지정하면 VC++출력창에 디버그 메세지를 보낸다. )
ⓑ D3D_CREATE_DEVICE_SINGLETHREADED : Direct3D가 여러 개의 스레드에서 호출되지 않는다는 보장이 있을 때, 이 플래그를 지정하면 성능이 향상된다.
( 이 플래그가 활성화 되면 ID3D11Device::CreateDeferredContext의 호출은 실패한다.)
5. pFeatureLevels : D3D_FEATURE_LEVEL 형식의 배열 (널 값이면 최고수준)
6. FeatureLevels : pFeatureLevels 의 갯수 (위에 값이 널값이면 0으로 지정하면 된다.)
7. SDKVersion : 항상 D3D11_SDK_VERSION을 지정한다.
8. ppDevice : 함수가 생성한 Device
9 pFeatureLevel : 위에서 설정된 FeatureLevel을 반영한다.
10. ppImmediateContext : 생성된 DeviceContext를 돌려준다.
위의 매개변수가 Immediate라는 것은 다른 지연된 DeferredContext도 있다.
주 렌더링 스레드에는 Immediate를 사용하고
워커 스레드 에선 임의의 갯수인 Deferred를 사용한다.
1. 각 워커 스레드는 그리기 명령들을 명령목록(ID3D11CommandList)에 기록한다.
2. 주 렌더링 스레드는 Immediate를 이용해서 워커 스레드 명령목록에 있는 명령들을 기록한다.
명령목록을 생성하는데 시간이 걸린다면 다중 코어 시스템에서 이처럼 명령목록들을 병렬로 생성하여 성능향상을 꾀할 수 있다.
글
자원 뷰 (Resource View)
자원 뷰는 자원을 파이프라인에 묶는데(bind) 사용되는 객체이다.
자원뷰의 종류
렌더 타겟 뷰 ( ID3D11RenderTargetView )
깊이/스텐실 뷰 ( ID3D11DepthStencilView )
셰이더 자원 뷰 ( ID3D11ShaderResourceView )
순서 없는 접근 뷰 ( ID3D11UnordereAccessView )
각각의 자원뷰에 대한 설명은 참고 링크에 있다.
자원 뷰들은 독립적으로 두가지 일을 한다.
1. Direct3D에게 자원의 사용방식(즉, 파이프라인의 어떤 단계에 묶을 것인지)을 알려주는 것
2. 생성 시점에서 무형식을 지정한 자원 형식의 구체적인 형식을 결정하는 것
( 무형식 자원의 경우 텍스처 원소를 한 파이프 라인 단계에서는 부동소수점 값으로서 사용하고 다른 단계에서는 정수로서 사용하는 것이 가능함을 뜻한다.)
D3D11 에선 리소스를 생성하고 자원 뷰를 사용해서 파이프 라인에 묶는다.
묶는 방법은
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE
위 처럼 단계를 지정한 결속 플래그를 사용해서 묶는다.
즉, 텍스처를 사용하기 위해선 그 텍스처에 자원뷰가 필요하고 자원뷰를 파이프라인에 묶어서 사용한다.(텍스처가 파이프라인에 묶이는것이 아니라 자원뷰가 묶이는 것)
텍스처의 플래그가 설정되지 않은 뷰에 대해선 뷰를 생성할 수 없다.
텍스처가 D3D11_BIND_DEOTG_STENCIL 플래스가 설정되지 않았으면 ID3D11DepthStencilView를 생성할 수 없다.
D3D11에서 이렇게 하는 이유는?
실행시점 모듈(런타임)과 구동기(드라이버)가 유효성 점검과 매핑을 뷰 생성 시점에서 수행할 수 있기 때문에 결속 시점에서의 형식 점검이 최소화된다.
따라서 텍스처를 렌더대상과 쉐이더 자원으로 사용할 때는 두 개의 뷰를 생성할 필요가 있다.
* 참고
[리소스 뷰에 대한 대략적인 설명]
http://grandstayner.tistory.com/entry/DirectX11%EC%9D%98-%EC%9E%90%EC%9B%90-%EB%B7%B0
[D3D11 텍스쳐 생성]
http://blog.naver.com/sorkelf/40169749877
[자원의 종류 등등]
http://grandstayner.tistory.com/entry/DirectX-11%EC%9D%98-%EC%9E%90%EC%9B%90%EB%93%A4%EC%9D%98-%EA%B0%9C%EC%9A%94
그 외 : 다중 표본화
이해한 것으로는 다중 표본화란 픽셀 하나만 가지고 하나의 픽셀을 출력하는 것이 아니라 화면을 부드럽게 만들기 위해 픽셀의 인접 픽셀들을 이용해서 화면을 부드럽게 출력하는 것이 아닐까 싶다...
표본화를 많이 할수록 품질은 좋아지겠지만 속도가 느려진다.
#define D3D11_MAXMULTISAMPLE_SAMPLE_COUNT ( 32 )
최대 표본 갯수는 32로 정해져 있지만 표본을 4개에서 8개 추출해서 하는 경우가 많다.
(심오한 내용으로 보이니 조금만 알고가는 정도로 넘어가자)
'DirectX11 > Direct3D 초기화' 카테고리의 다른 글
화면 출력 (0) | 2016.07.02 |
---|---|
Direct3D 기본 (0) | 2016.07.02 |
글
1. 이중버퍼링
애니메이션이 깜빡대는 현상을 방지하기 위해 이중 버퍼를 사용한다.
하나는 화면 밖에서 그리고 바꿔치기 하는 것이다.
전면 버퍼와 후면버퍼를 교환해서 화면에 표시하는 것을 제시(Presenting)이라고 한다.
버퍼들을 바꾸는 것은 내용을 바꾸는 것이 아니라 포인터만 맞바꾸는 것이기 때문에 효율적이다.
* 후면 버퍼는 텍스처이므로 그 원소를 텍셀이라고 불러야 하지만, 여기선 그냥 픽셀이라고 한다.
2. 깊이 버퍼링
깊이 버퍼는 이미지 자료를 담지 않은 텍스처이다.
깊이 버퍼는 후면버퍼의 픽셀들과 일대일로 대응한다. 깊이는 0.0 ~1.0 커질수록 멀다.
한 물체의 픽셀들이 다른 물체보다 앞에 있는지 판정하기 위해, 깊이 버퍼링, z-버퍼링 이라는 기법을 사용한다.
깊이 버퍼링에서 물체를 그리는 순서는 중요하지 않다.
깊이 버퍼링 알고리즘
* 렌더링 되는 각 픽셀의 깊이 값을 계산해서 깊이 판정을 수행하고 깊이 값을 비교했을때 관찰자에 가장 가까운 픽셀이 승리하여 후면 버퍼에 기록된다.
깊이 버퍼도 텍스처이므로 특정한 자료형 형식을 지정해서 생성해야 한다.
ⓐ DXGI_FORMAT_D32_FLOAT_S8X24_UNIT : 각 텍셀은 32비트 부동소수점 깊이 값과 [0, 255] 구간으로 사상되는 8비트 부호 없는 정수 스텐실 값(스텐실 버퍼에 쓰임), 그리고 다른 용도 없이 채움(Padding)용으로만 쓰이는 24비트로 구성된다.
ⓑ DXGI_FORMAT_D32_FLOAT : 각 텍셀은 하나의 32비트 부동소수점 깊이 값이다.
ⓒ DXGI_FORMAT_D24_UNORM_S8_UNIT : 각 텍셀은 [0, 1] 구간으로 사상되는 부호 없는 24비트 깊이 값 하나와 [0, 255] 구간으로 사상되는 8비트 부호 없는 정수 스텐실 값으로 구성된다.
ⓓ DXGI_FORMAT_D16_UNORM : 각 텍셀은 [0, 1] 구간으로 사상되는 부호 없는 16비트 깊이 값이다.
(스텐실 버퍼를 반드시 사용하는 것은 아니지만 만일 사용해야 한다면 스텐실 버퍼를 깊이 버퍼에 부착해야 한다.)
'DirectX11 > Direct3D 초기화' 카테고리의 다른 글
텍스처 관련 (0) | 2016.07.03 |
---|---|
Direct3D 기본 (0) | 2016.07.02 |
글
1. Direct3D 9와 11의 차이점
Direct3D 9 과 Direct3D 11이 다른점 9는 능력 집합의 일부만 지원하고 하드웨어가 지원하지 않는 기능을 사용했을 때 지원하는지를 점검하고 지원하지 않으면 호출이 실패하게 되었지만 11에선 기능을 지원하는지 점검할 필요 없이 11의 대응장치이려면 반드시 능력집합 전체를 지원해야한다.
2. COM ( Component Object Model )
DirectX의 프로그래밍 언어 독립성과 하위 호환성을 가능하게 하는 기술이다.
흔히 인터페이스라고 불린다.
COM의 인터페이스는 C++의 new 키워드로 생성하지 않는다.
인터페이스를 사용하고 난 후에는 delete로 삭제하는 것이 아니라 그 인터페이스의 Release 메소드를 호출해 주어야 한다.
(COM인터페이스는 IUnknown이라는 COM 인터페이스의 기능을 상속받는데, 그 인터페이스가 Release라는 메서드를 제공한다.) - COM객체들이 자신만의 방법으로 메모리를 관리하기 때문이다.
3. 텍스처 및 자료 자원 형식
텍스처는 자료 원소들의 행렬이라고 생각하면된다. 2차원 텍스처엔 한 픽셀의 색상이 들어갈 수 있고 , 법선 맵핑에선 3차원 벡터가 들어갈 수도 있다.
하지만 모든 데이터가 들어갈수 있는것은 아니고 정해진 포멧을 따르는 자료만 담을 수 있다.
구체적인 형식은 DXGI_FORMAT이라는 열거형으로 지정한다.
ⓐ DXGI_FORMAT_R32G32B32_FLOAT : 각 원소는 32비트 부동소수점 성분 세개로 이루어진다.
ⓑ DXGI_FORMAT_R16G16B16A16_UNORM : 각 원소는 [0,1] 구간으로 사상되는 16비트 성분 네개로 이루어진다.
ⓒ DXGI_FORMAT_R32G32_UNIT : 각 원소는 32비트 부호없는 정수 성분 두 개로 이루어 진다.
ⓓ DXGI_FORMAT_R8G8B8A8_UNORM : 각 원소는 [0,1] 구간으로 사상되는 8비트 부호 없는 성분 네개로 이루어진다.
ⓔ DXGI_FORMAT_R8G8B8A8_SNORM : 각 원소는 [-1, 1] 구간으로 사상되는 8비트 부호 있는 성분 네개로 이루어진다.
ⓕ DXGI_FORMAT_R8G8B8A8_SINT : 각 원소는 [-128, 127] 구간으로 사상되는 8비트 부호있는 정수 성분 네 개로 이루어진다.
ⓖ DXGI_FORMAT_R8G8B8A8_UNIT : 각 원소는 [0, 255] 구간으로 사사아되는 8비트 부호 없는 정수 성분 네 개로 이루어진다.
DXGI_FORMAT_R8G8B8A8_TYPELESS 이런 무형식도 가능하고
DXGI_FORMAT_R32G32B32_FLOAT 이 형식을 사용하더라도 색이 아니라 3차원 벡터를 넣는 것도 가능하다.
'DirectX11 > Direct3D 초기화' 카테고리의 다른 글
텍스처 관련 (0) | 2016.07.03 |
---|---|
화면 출력 (0) | 2016.07.02 |
글
행렬을 클래스 자료멤버로 저장할 때엔 XMFLOAT4X4를 사용하는 것을 추천한다.
XMMATRIX의 선언은
union
{
XMVECTOR r[4]; // SIMD를 사용하기위해서 4개의 XMVECTOR을 이용한다.
struct
{
FLOAT _11, _12, _13, _14;
FLOAT _21, _22, _23, _24;
FLOAT _31, _32, _33, _34;
FLOAT _41, _42, _43, _44;
};
FLOAT m[4][4];
};
행렬관련 함수들
XMMATRIX XMMatrixIdentity(); // 단위행렬 I를 돌려준다.
BOOL XMMatrixIsIdentity(CXMMATRIX M); // 단위행렬 여부를 알려준다.
XMMATRIX XMMatrixMultiply(CXMMATRIX A, CXMMATRIX B); // 행렬 곱 AB를 돌려준다.
XMMATRIX XMMatrixTranspose( CMMATRIX M); // M의 전치행렬을 돌려준다.
XMVECTOR XMMatrixDeterminant ( CXMMATRIX M); (det M, det M, det M det M)을 돌려준다.
XMMATRIX XMMatrixInverse ( XMVECTOR* pDeterminant, CXMMATRIX M); M의 역행렬을 돌려준다.
XMMATRIX XMMatrixScaling( FLOAT ScaleX, FLOAT ScaleY, FLOAT ScaleZ)
XMMATRIX MXMatrixScalingFromVector( FXMVECTOR Scale );
XMMATRIX XMMatrixRotationX ( FLOAT Angle );
XMMATRIX XMMatrixRotationY( FLOAT Angle ) ;
XMMATRIX XMMatrixRotationZ( FLOAT Angle ) ;
XMMATRIX XMMatrixRotationAxis ( FXMVECTOR Axis, FLOAT Angle );
XMMATRIX XMMatrixTranslation( FLOAT OffsetX, FLOAT OffsetY, FLOAT OffsetZ)
XMMATRIX XMMatrixTranslationFromVector( FXMVECTOR Offset );
XMVECTOR XMVector3Transfrom( FXMVECTOR V, CXMMATRIXM ) ;
XMVECTOR XMVector3TransfromCoord ( FXMVECTOR V, CXMMATRIX M);
XMVECTOR XMVector3TrasnfromNormal ( FXMVECTOR V, CXMMATRIX M);
* 마지막 두함수에서 벡터의 w성분을 신경쓰지 않아도 된다. XMVector3TransfromCoord의 w 값은 항상 1이고 XMVector3TransformNormal은 항상 0이다.
'DirectX11 > 수학관련' 카테고리의 다른 글
XNA Math 라이브러리(벡터) (0) | 2016.07.02 |
---|
글
* Direct3D 9 과 10에선 그래픽스에 필요한 벡터 및 다른 주요 3차원 수학 형식들을 지원하는 수학 유틸리티 라이브러리가 있지만 Direct11 라이브러리에는 3차원 수학코드가 포함되어 있지 않다.
(물론 d3dx10.h>를 포함시키고 d3dx10.lib를 링크해서 D3DX10 Math함수를 사용하는 것도 가능하다.
* XNA 라이브러리는 Windows와 Xbox360에서 사용가능한 특별한 하드웨어 레지스터들을 활용한다.
SIMD 명령 집합을 사용하기 때문에 float나 int네개를 한번에 처리할 수 있다.
- XNA라이브러리는 모든 코드가 인라인화 되어 있어서 헤더파일만 추가하고 따로 라이브러리를 링크할 필요가 없다.
1. XNA 라이브러리에서 벡터를 사용할 때
typedef __m128 XMVECTOR; XNA 라이브러리에서 벡터는 이렇게 선언되어 있다.
계산을 수행할 때 __m128형식은 SIMD의 장점을 취하게 된다.
하지만 XMVECTOR의 경우 16바이트 경계에 정렬되어야 하는데, 지역변수와 전역변수에서는 정렬이 자동으로 이루어진다. 클래스 자료 멤버의 경우에는 이 대신 XMFLOAT2, XMFLOAT3, XMFLOAT4를 사용하는 것이 바람직 하다.
이 구조체들은 이렇게 정의 된다.
typedef struct_XMFLOAT4{
FLOAT x;
FLOAT y;
FLOAT z;
FLOAT w;
} XMFLOAT4;
하지만 이 형식들은 SIMD의 장점을 취하지 못하므로 XMVECTOR형식으로 변환해서 계산해야 SIMD의 장점을 취할 수 있다.
* 적재 및 저장 함수들
XMFLOAT*를 XMVECTOR로
// XMFLOAT2 를 XMVECTOR2에 적재
XMVECTOR XMLoatFloat2( CONST XMFLOAT2 *pSource);
// XMFLOAT3 를 XMVECTOR3에 적재
XMVECTOR XMLoatFloat3( CONST XMFLOAT3 *pSource);
// XMFLOAT4 를 XMVECTOR4에 적재
XMVECTOR XMLoatFloat4( CONST XMFLOAT4 *pSource);
XMVECTOR를 XMFLOAT*로
VOID XMStoreFloat2(XMFLOAT2 *pDestination, FXMVECTOR V); // 3,4 도 있음
이 외에도 3원소 UINT, XMCOLOR, XMBYTE4 등 XMVECTOR로 변환하고 적재하는 함수들도 있다.
XMVECTOR 인스턴스의 성분 하나만 읽거나 변경하고 싶은 경우도 있다 그런경우에 사용하는 조회 설정 함수들도 있다.
FLOAT XMVectorGetX(FXMVECTOR V);
XMVECTOR XMVectorSetX(FXMVECTOR V, FLOAT x); // y,z,w까지 다 있다.
2. 매개변수 전달
SIMD의 장점을 취하려면 함수에 XMVECTOR 형식의 매개변수를 전달할 때 지켜야 할 규칙이 몇 가지 있다.
32비트 Windows와 64비트 WIndows, XBox 360의 규칙들이 서로 다르다.
플랫폼에 독립적인 코드를 위해 XMVECTOR형식의 매개변수에 대해 CXMVECTOR 형식과 FXMVECTOR 형식을 사용한다.
이 형식들은 다음과 같이 정의 되어 있다.
// 32비트 Windows
typedef const XMVECTOR FXMVECTOR;
typedef const XMVECTOR& CXMVECTOR;
// 64비트 Windows
typedef const XMVECTOR& FXMVECTOR;
typedef const XMVECTOR& CXMVECTOR;
구체적인 규칙으론 처음 3개의 매개변수는 FXMVECTOR 형식이어야하고 그 외의 매개변수는 반드시 CXMVECTOR 형식이어야 한다.
즉, 매개변수에 있는 XMVECTOR변수 처음 3개는 FXMVECTOR을 쓰고 이후엔 CXMVECTOR을 써야한다.
3. 상수 벡터
상수(const) XMVECTOR 인스턴스에는 반드시 XMVECTORF32 형식을 사용해야 한다.
간단히 말하면, 초기화 구문을 사용하고자 할 때에는 항상 XMVECTORF32를 사용해야 한다. (XMVECTORF32는 16바이트 경계로 정렬된 구조체로, XMVECTOR로의 변환 연산자를 지원한다.
4. 설정 함수
XMVECTOR XMVectorZero();
XMVECTOR XMVectorSplatOne(); // 벡터 (1, 1, 1, 1) 을 돌려준다.
XMVECTOR XMVectorSet( FLOAT x, FLOAT y, FLOAT z, FLOAT w) // 벡터(x, y, z, w)를 돌려준다.
XMVECTOR XMVectorReplicate( FLOAT s); // 벡터 (s, s, s, s)를 돌려준다.
XMVECTOR XMVectorSplatX( FXMVECTOR V); // 벡터 (Vx, Vx, Vx, Vx)를 돌려준다.
* 수학적 결과가 스칼라 값이라도 XMVECTOR변수를 반환한다 그 이후는 SIMD벡터 연산의 전환을 최소화 해서 SIMD로 유지하는 것이 효율적이기 때문이다.
5. 부동 소수점 연산
* 부동 소수점 연산을 할때에는 오차가 누적되서 변수가 근사값이 되는데 그때에 Epsilon을 두어서 상등을 판정할 수 있다.
XNA라이브러리에는 두 벡터의 상등을 판정하는 XMVector3NearEqual이라는 함수가 있다. 이 함수는 Epsilon을 매개변수로 허용 오차를 받는다.
'DirectX11 > 수학관련' 카테고리의 다른 글
XNA Math 라이브러리 (행렬) (0) | 2016.07.02 |
---|
RECENT COMMENT