일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Brute Force
- binary search
- DP
- union find
- 이진탐색
- String
- 그래프
- 다익스트라
- SQL
- Stored Procedure
- two pointer
- Hash
- 스토어드 프로시저
- Trie
- Dijkstra
- Two Points
- MYSQL
- Today
- Total
목록computer graphics/DirectX11 (18)
codingfarm
애니메이션을 정확히 수행하려면 시간을 측정해야한다. 특히, 애니메이션의 프레임들 사이에 흐른 시간과 양을(경과시간; elpased time)을 측정할 수 있어야 한다. 1. 성능 타이머(Performance Timer) 시간 측정을 위해 Windows가 제공하는 성능 타이머(performance timer)를 사용한다. 이를 성능 카운터(poerformance counter)라고도 한다. 성능 타이머를 조회하는 Win32 함수를 사용하려면 windows.h 헤더파일을 추가해야 한다. 성능 타이머는 시간을 개수(count) 단위로 측정한다. 성능 타이머로부터 개수 단위의 현재 시간을 얻을 때에는 다음과 같이 QueryPerformanceCounter 함수를 사용한다. __int64 currTime; Que..
보통은 3차원 장면을 후면 버퍼 전체에 그린다. 그러나 원한다면 후면버퍼의 일부를 차지하는 직사각형 영역에만 그리는것도 가능하다. 장면을 그려 넣고자 하는 후면 버퍼의 부분지가각형 영역을 뷰포트(viewport)라고 부른다. 다음은 이 뷰포트를 서술하는 데 쓰이는 구조체이다. typedef struct D3D11_VIEWPORT { FLOAT TopLeftX; FLOAT TopLeftY; FLOAT Width; FLOAT Height; FLOAT MinDepth; FLOAT MaxDepth; } D3D11_VIEWPORT; 뷰포트를 수정함으로써 3차원 장면을 후면 버퍼의 한 부분직사각형에 그린 모습이다. 그리고 후면 버퍼를 응용 프로그램창의 클라이언트 영역에 제시한다. 처음 4개의 필드는 뷰포트를 표시할..
후면버퍼와 깊이$\cdot$스텐실 버퍼에 대한 뷰들을 생성했으니, 이제 이 뷰들을 파이프라인의 출력 병합기 단계에 묶어 보자. 이 과정을 거쳐야 비로소 자원들이 파이프라인의 렌더 대상과 깊이$\cdot$스텐실 버퍼로 작용하게 된다. 필요한 코드는 아래와 같다. md3dImmediateContext->OMSetRenderTargets( 1, &mRenderTargetView, mDepthStencilView); 함수에 쓰인 각 매개변수의 기능에 대해서 알아본다. 첫번째 매개변수는 묶고자 하는 렌더대상의 갯수로 여기에서는 하나만 정하지만 장면을 여러개의 렌더 대상에 동시에 렌더링 하는 경우(고급기법이다)에는 여러개의 렌더대상 뷰를 지정할 수 있다. 둘째 매개변수는 파이프라인에 묶을 렌더 대상 뷰들을 가리키는..
이제 깊이, 스텐실 버퍼를 생성해야 한다. 이전에 설명했듯이, 깊이 버퍼는 그냥 깊이정보를 담는 (그리고 스텐실을 사용하는 경우 스텐실 정보도 담는) 2차원 텍스처이다. 2차원 텍스처를 생성할 때에는 생성할 텍스처를 서술하는 D3D11_TEXTURE2D_DESC 구조체를 채우고 ID3D11Device::CreateTexture2D 메서드를 호출해야 한다. D3D11_TEXTURE2D_DESC 구조체의 정의는 아래와 같다. typedef struct D3D11_TEXTURE2D_DESC { UINT Width; UINT Height; UINT MipLevels; UINT ArraySize; DXGI_FORMAT Format; DXGI_SAMPLE_DESC SampleDesc; D3D11_USAGE Usag..
어떤 자원을 파이프라인의 단계에 직접 묶는것이 아니다. 대신 자원에 대한 뷰를 생성하고 그 뷰를 파이프라인 단계에 묶어야 한다. 좀더 구체적으로, 후면 버퍼를 파이프라인의 출력 병합기(output merger) 단계에 묶으려면(그래야 Direct3D가 버퍼에 뭔가를 그릴 수 있다) 우선 후면 버퍼에 대한 렌더 대상 뷰를 생성해야 한다. 다음은 렌더대상뷰를 생성하는 코드의 예이다. ID3D11RenderTargetView* mRenderTargetView; ID3D11Texture2D* backBuffer; mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast(&backBuffer)); md3dDevice->CreateRenderTarg..
교환 사슬의 생성 초기화 공정 이후에는 교환 사슬을 생성해야한다. 이를 위해선 우선 DXGI_SWAP_CHAIN_DESC 구조체의 인스턴스를 만들어서 원하는 교화 ㄴ사슬의 특성들을 설정해야 한다. 이 구조체의 정의는 다음과 같다. typedef struct DXGI_SWAP_CHAIN_DESC { DXGI_MODE_DESC BufferDesc; DXGI_SAMPLE_DESC SampleDesc; DXGI_USAGE BufferUsage; UINT BufferCount; HWND OutputWindow; BOOL Windowed; DXGI_SWAP_EFFECT SwapEffect; UINT Flags; } DXGI_SWAP_CHAIN_DESC; DXGI_MODE_DESC 형식은 아래와 같이 정의되는 또 다..
장치 생성 이후에는 하드웨어가 4X MSAA를 위한 품질 수준을 지원하는지 점검할 수 있다. 앞에서 말했듯이 모든 Direct3D 11 대응 장치는 모든 렌더 대상 형식에 대해 4X MSAA를 지원한다.(지원하는 품질 수준은 서로 다를 수 있다.) UINT m4xMsaaQuality; HR(md3dDevice->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, & m4xMsaaQuality)); assert(m4xMsaaQuality > 0); 4X MSAA가 항상 지원되므로, 반환된 품질 수준값은 반드시 0보다 커야하며, 이를 강제하기 위해 assert를 사용했다.
Direct3D 초기화의 시작은 direct3D 11 장치(ID3D11Device)와 그 문맥(ID3D11Device Context)를 생성하는 것이다. 이 두 인터페이스는 Direct3D의 주된 인터페이스로, 물리적인 그래픽 장치 하드웨어에 대한 소프트웨어 제어기라고 생각하면 될 것이다. 즉, 응용 프로그램은 이 인터페이스들을 통해서 하드웨어에게 할 일(GPU 메모리에 자원 할당, 후면 버퍼 지우기, 자원을 여러 파이프 라인 단계에 묶기, 기하구조 그리기 등)을 지시한다. 좀 더 구체적으로 말하면, 1. ID3D11Device 인터페이스는 기능 지원 점검과 자원 할당에 쓰인다. 2. ID3D11DeviceContext 인터페이스는 렌더 대상을 설정하고, 자원을 그래픽 파이프 라인에 묶고, GPU가 수행..
Direct3D를 초기화하는 구체적인 방법을 살펴보자, Direct3D 초기화 과정은 아래와 같은 단계들로 구성된다. 1. D3D11CreateDevice 함수를 이용해서 장치(Device), 즉 ID3D11Device 인터페이스와 장치 문맥(Device Context), 즉 ID3D11DeviceContext 인터페이스를 생성한다. 2. ID3D11Device::CheckMultisampleQualityLevels 메서드를 이용해서 4X MSAA 품질 수준 지원 여부를 점검한다. 3. 생성할 교환 사슬의 특성을 서술하는 DXGI_SWAP_CHAIN_DESC 구조체를 채운다. 4. 장치를 생성하는 데 사용했던 IDXGIFactory 인터페이스를 질의해서 IDXGISwapChain 인스턴스를 생성한다. 5..
Direct3D 11은 기능수준(feature level) 이라는 개념을 도입했다. 코드에서 D3D_FEATURE_LEVEL 이라는 열거형으로 대표되는 이 기능 수준은, 대략적으로 버전 9에서 11까지의 여러 Direct3D 버전들에 대응된다. typedef enum D3D_FEATURE_LEVEL { D3D_FEATURE_LEVEL_1_0_CORE, D3D_FEATURE_LEVEL_9_1, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE..
모니터의 픽셀들이 무한히 작지는 않기 때문에, 모니터 화면에 임의의 선을 완벽하게 나타내는것은 불가능하다. 선을 픽셀들의 배열로 근사할 때 생기는, 계단현상이라고도 하는 앨리어싱(aliasing)의 예가 아래그림에 나타난다. 위와같은 픽셀을 제거하기 위한 앨리어싱 제거(antialiasing) 기법들이 존재하며, 이를 통해 아래와 같은 개선된 효과를 얻을 수 있다. 여기서 소개하는 안티애얼리싱 기법은 총 2가지가 있다. 초과 표본화(supersampling) 후면 버퍼와 깊이 버퍼를 화면 해상도보다 4배(가로, 세로 2배씩) 크게 잡는다. 후면 버퍼에 렌더링하고, 이미지를 화면에 제시할 때 후면 버퍼를 원래 크기의 버퍼로 환원(resolving) 한다. 하향표준화(downsampling) 이라고도 하는 ..
렌더링 파이프라인에는 텍스처를 묶을(bind) 수 있는 단계(stage)들이 여럿 있다. 흔한 용도는 텍스처를 렌더 대상으로 묶는것(Direct3D가 텍스처에 렌더링 하는경우)과 셰이더 자원으로서 묶는 것(셰이더 안에서 텍스처를 추출하는 경우)이다. 이 두 가지 용도의 텍스처를 생성할 때에는 다음과 같이 텍스처를 묶을 두 파이프라인 단계를 지정한 결속 플래그(bind flag)를 사용한다. D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE 그런데 사실 텍스처 자원이 파이프라인의 단계에 직접 묶이는 것은 아니다. 실제로는 텍스처가 연관된 자원 뷰를 파이프라인 단계에 묶는다. 어떤 용도이든 Direct3D에서 텍스처를 사용하려면 텍스처의 초기화 시점에서 그 텍스..
렌더링 과정에서 GPU는 자원들에 자료를 기록하거나(후면 버퍼나 깊이, 스텐실 버퍼 등) 자원들에서 자료를 읽어들인다.(표면의 모습을 서술하는 텍스처나 장면안의 기하구조의 3차원 위치들을 담은 버퍼 등) 그리기 명령을 제출하기 전에, 먼저 해당 그리기 호출이 참조할 자원들을 렌더링 파이프라인에 묶어야(bind)한다. 이를 가리켜 자원을 파이프라인에 "연결(Link)한다" 또는 "바인딩(Binding)한다" 라고 말하기도 한다. 그리기 호출마다 달라지는 자원도 있으며, 필요에 따라 그리기 호출마다 그런 자원들의 바인딩을 갱신해 주어야 한다. 그런데 GPU 자원들이 파이프라인에 직접 묶이는것은 아니다. 실제로 파이프라인에 묶이는것은 해당 자원을 참조하는 서술자(Descriptor) 객체이다. 서술자 객체는 ..
깊이 버퍼(Depth Buffer)는 이미지 자료를 담지 않는 텍스처의 한 예이다. 깊이 버퍼는 각 픽셀의 깊이 정보를 담는다. 픽셀의 깊이는 0.0에서 1.0 까지의 값으로, 0.0은 관찰자와 최대한 가까운 픽셀에 해당하고 1.0은 최대한 먼 픽셀에 해당한다. 깊이 버퍼의 원소들과 후면 버퍼의 픽셀들은 일대일로 대응된다. 즉, 깊이 버퍼와 후면버퍼는 같은 해상도를 지닌다. 아래 그림처럼 몇몇 물체가 다른 물체들을 가리고 있다고 해보자 한 물체의 픽셀들이 다른 물체보다 앞에 있는지 판정 하기 위해 Direct3D는 깊이 버퍼링 또는 z-버퍼링이라는 기법을 사용한다.깊이 버퍼링을 이용하면 물체들을 그리는 순서에 상관없이 물체들이 제대로 가려진다. 깊이 문제를 해결하는 방법은 장면의 물체를 먼것에서 가까운것..
모니터에 하나의 프레임 버퍼를 가지고 게임화면을 표현한다면, 매 프레임마다 버퍼를 지우고 그리거나 이미 그려진 버퍼에 덮어쓸것이다 전자의 경우에는 버퍼가 지워지는 찰나의 순간이 화면에 표시되면 화면 깜빡임(Screen Flickering)현상이 나타나며, 후자의 경우에는 화면이 그려지는 도중에 이전 화면가 현재화면이 겹처지면서 화면 찢어짐(Screen Tearing)현상이 생길것이다. 결국 이는 보는이에게 불편함을 끼치게 된다. 이러한 현상을 피하고자 사용하는 방법이 2개의 프레임 버퍼를 이용하는것이다. 각각의 프레임 버퍼는 각 화면 바깥의 텍스처인 후면 버퍼(Back Buffer)와 전면 버퍼(Front Buffer)을 뜻한다. 전면버퍼를 이용해 현재 화면을 표현하면서, 다음 화면이 될 장면을 후면 버..
2차원 텍스처는 자료 원소들의 행렬(2차원 배열)이다. 2차원 텍스처의 용도 중 하나는 2차원 이미지 자료를 저장하는 것인데, 이때 텍스처의 각 원소는 픽셀 하나의 색상을 담는다. 하지만 텍스처가 꼭 이미지 자료의 저장만을 위해 사용되는 것은 아니며 훨씬 범용적으로 사용된다. 예를 들면 법선 매핑 같은 경우 텍스처에 각 원소의 색상이 아닌 3차원 벡터를 담는다. 텍스처에는 아무 자료나 담을 수 있는 것은 아니다. 텍스처에는 특정 형식(format)의 자료 원소들만 담을 수 있는데, 구체적인 형식은 DXGI_FORMAT이라는 열거형으로 지정한다. 자료 원소 형식들을 나열하면 다음과 같다. docs.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiforma..
COM(Component Object Model)은 어떤 프로그램이나 시스템을 이루는 컴포넌트들이 상호 통신할 수 있도록 하는 메커니즘이라고 할 수 있다. 그렇기 때문에 COM을 이용하면 DirectX의 프로그래밍 언어 독립성과 하위 호환성을 가능하게 할 수 있다. COM 객체는 흔히 인터페이스라 부르지만, C++클래스로 간주해도 무방하므로 흔히 COM 객체라고 부른다. C++로 DirectX 응용프로그램을 프로그래밍 할때 COM의 세부사항 대부분은 프로그래머에게 드러나지 않는다. 프로그래머가 알아야 할 것은 필요한 COM 인터페이스를 가리키는 포인터를 특별한 함수들을 이용해서, 또는 다른 COM 인터페이스의 메서드를 이용해서 얻는 방법 뿐이다. COM 인터페이스를 new나 delete를 이용하여 색성,..
Direct3D는 응용 프로그램이 3차원 그래픽 가속기능을 이용해서 3차원 세계를 렌더링할 수 있게 하는 저수준 API(Application Programing Interface)이다. 그래픽 하드웨어를 제어할 수 있는 소프트웨어 인터페이스를 제공한다. 응용프로그램과 그래픽 하드웨어 사이에 간접층로써 응용프로그램 개발자는 하드웨어의 구체적인 세부사항을 걱정할 필요가 없다. 이를 위해서는 GPU 제조사들이 Direct3D 팀과의 협업으로 Direct3D를 준수하는 드라이버를 제공해야 한다. 과거에는 GPU 장치가 Direct3D 9 능력 집합의 일부만 지원해도 되었다. 그래서 Direct3D 9의 어떤 특정 기능을 사용하고자 하는 응용 프로그램은 반드시 현재 하드웨어가 그 기능을 지원하는지를 먼저 점검해야..