DX에선 삼각형을 폴리곤 명칭이 있다.
삼각형을 그릴려면 우선 3개의 정점와 첫번째 정점의 기준으로 시계방향으로 되게 그려야 한다.
1. Scene.cpp 수정
InitScene() 함수 수정
※ 정점의 갯수를 3개로 봐꿈
void InitScene()
{
Vertex vertices[3];
vertices[0].Position = Vector3(0.0f, 0.0f, 0.0f);
vertices[1].Position = Vector3(-0.5f, 0.5f, 0.0f);
vertices[2].Position = Vector3(0.5f, 0.5f, 0.0f);
vertices[0].Color = D3DXCOLOR(1, 0, 0, 1);
vertices[1].Color = D3DXCOLOR(0, 1, 0, 1);
vertices[2].Color = D3DXCOLOR(0, 0, 1, 1);
//Create VertexBuffer (desc -> SUBRESOURCE -> create buffer)
{
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_DEFAULT; // CPU는 쓸수 없지만 GPU는 쓸수 있음
desc.ByteWidth = sizeof(Vertex) * 3; // 버퍼의 크기를 잡아줌
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; // 사용 용도
//버퍼에 값을 넣고 넘겨줄 정의
D3D11_SUBRESOURCE_DATA data;
ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
data.pSysMem = vertices; // 처음 시작 주소
HRESULT hr = Device->CreateBuffer(&desc, &data, &vertexBuffer);
assert(SUCCEEDED(hr));
}
/*생략*/
}
Render()함수
※ 정점의 갯수 만큼 수정
void Render()
{
D3DXCOLOR bgcolor = D3DXCOLOR(0.22f, 0.27f, 0.44f, 1.0f); // 배경색
DeviceContext->ClearRenderTargetView(RTV, (float*)bgcolor); //앞
{
//..그려주는 코드
UINT stride = sizeof(Vertex); //간격(보폭, 인덱스 나눠줄 크기)
UINT offset = 0; //시작점
DeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
DeviceContext->IASetInputLayout(inputLatout);
//정점 그려주는 방식
//DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); //2개씩 끊어서 그려줌
//DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); //쭉 이어서 그려줌
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//최종적으로 그려주는 코드 (파이프 라인을 호출)
DeviceContext->Draw(3, 0);
}
SwapChain->Present(0, 0); //백퍼에 위에 내용 보냄
}
실행 화면
3개의 정점을 이은 삼각형이 그려지게 되며 내부에도 선형보간 통해서 채워진다.
해당 삼각형을 180도로 돌린 형태로 추가
https://github.com/ascher8159/DX2D
DX2D_01
2. Buffer 활용
1번에서 삼각형을 2개 그려보기 됫으나 문제가 있는데 하나의 Buffer를 통해서 삼각형 객체를 2개를 그리기 때문에 추후 키보드로 이동하거나 조작을 할때 동시에 조작이 되버린다.
왼쪽이 현재 만들고 싶은 상태지만 현재 상태는 우측의 이미지 처럼 동시에 같이 움직인다.
해결 방법은 Buffer 1개를 추가로 만들어서 앞에서 작성한 삼각형 만든 코드 복사해서 넣어 주기만 하면된다.
※ 실행 결과는 동일 하기 때문에 이미지 x
#include "Device.h"
ID3D11Buffer* vertexBuffer = NULL;
ID3D11Buffer* vertexBuffer2 = NULL; //생성
ID3D11InputLayout* inputLatout = NULL;
struct Vertex
{
Vector3 Position;
Color Color;
};
D3D11_INPUT_ELEMENT_DESC layoutDesc[] = {...};
void InitScene()
{
Vertex vertices[3];
vertices[0].Position = Vector3(0.0f, 0.0f, 0.0f);
vertices[1].Position = Vector3(-0.5f, 0.5f, 0.0f);
vertices[2].Position = Vector3(0.5f, 0.5f, 0.0f);
vertices[0].Color = D3DXCOLOR(1, 0, 0, 1);
vertices[1].Color = D3DXCOLOR(0, 1, 0, 1);
vertices[2].Color = D3DXCOLOR(0, 0, 1, 1);
Vertex vertices2[3]; //생성
vertices2[0].Position = Vector3(0.0f, 0.0f, 0.0f);
vertices2[1].Position = Vector3(0.5f, -0.5f, 0.0f);
vertices2[2].Position = Vector3(-0.5f, -0.5f, 0.0f);
vertices2[0].Color = D3DXCOLOR(1, 0, 0, 1);
vertices2[1].Color = D3DXCOLOR(0, 1, 0, 1);
vertices2[2].Color = D3DXCOLOR(0, 0, 1, 1);
//Create VertexBuffer 1
{
. . .
}
//Create VertexBuffer 2 생성
{
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_DEFAULT;
desc.ByteWidth = sizeof(Vertex) * 3;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA data;
ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
data.pSysMem = vertices2;
HRESULT hr = Device->CreateBuffer(&desc, &data, &vertexBuffer2);
assert(SUCCEEDED(hr));
}
//Create InputLayout
{
...
}
}
void DestroyScene()
{
inputLatout->Release();
vertexBuffer->Release();
vertexBuffer2->Release(); //추가
}
void Update() {}
void Render()
{
D3DXCOLOR bgcolor = D3DXCOLOR(0.22f, 0.27f, 0.44f, 1.0f); // 배경색
DeviceContext->ClearRenderTargetView(RTV, (float*)bgcolor); //앞
{
//..그려주는 코드
UINT stride = sizeof(Vertex); //간격(보폭, 인덱스 나눠줄 크기)
UINT offset = 0; //시작점
DeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
DeviceContext->IASetInputLayout(inputLatout);
//정점 그려주는 방식
//DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); //2개씩 끊어서 그려줌
//DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); //쭉 이어서 그려줌
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//최종적으로 그려주는 코드 (파이프 라인을 호출)
DeviceContext->Draw(3, 0);
/*-----2번째 Buffer 추가-----*/
DeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer2, &stride, &offset);
DeviceContext->Draw(3, 0);
}
SwapChain->Present(0, 0); //백퍼에 위에 내용 보냄
}
https://github.com/ascher8159/DX2D
DX2D_02
3. RS C++ 코드 사용
3D에서 2D로 변환 하면서 각종 여러 옵션이 있는데 대표적으론 깊이(Depth), 그리는 방식 (FillMode), 짜르기(CullMode) 이외 여러가지 옵션이 있는데 c++ 코드 에서 작성해서 쉐이더에 넘겨 주는 방식 으로도 사용이 가능 하다.
Scene.cpp (수정)
※ Cull, Fill 모드 사용 하는데 Cull Mode 경우는 아직 의미가 없지만 D3D11_CULL_FRONT 변경하면 그려지지 않는다.
#include "Device.h"
ID3D11Buffer* vertexBuffer = NULL;
ID3D11InputLayout* inputLatout = NULL;
ID3D11RasterizerState* rs_FrameMode = NULL; //추가
struct Vertex{...};
D3D11_INPUT_ELEMENT_DESC layoutDesc[] = {...};
void InitScene()
{
Vertex vertices[6];
vertices[0].Position = Vector3(-0.5f, -0.5f, 0.0f);
vertices[1].Position = Vector3(-0.5f, +0.5f, 0.0f);
vertices[2].Position = Vector3(+0.5f, -0.5f, 0.0f);
vertices[3].Position = Vector3(+0.5f, -0.5f, 0.0f);
vertices[4].Position = Vector3(-0.5f, +0.5f, 0.0f);
vertices[5].Position = Vector3(+0.5f, +0.5f, 0.0f);
vertices[0].Color = D3DXCOLOR(1, 0, 0, 1);
vertices[1].Color = D3DXCOLOR(0, 1, 0, 1);
vertices[2].Color = D3DXCOLOR(0, 0, 1, 1);
vertices[3].Color = D3DXCOLOR(0, 0, 1, 1);
vertices[4].Color = D3DXCOLOR(0, 1, 0, 1);
vertices[5].Color = D3DXCOLOR(1, 0, 0, 1);
//Create VertexBuffer 1
{...}
//Create InputLayout
{...}
//RasterizerState
{
D3D11_RASTERIZER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_RASTERIZER_DESC));
desc.FillMode = D3D11_FILL_WIREFRAME; // 그려주는 방식 (선, 채우기)
desc.CullMode = D3D11_CULL_BACK; // 그림을 자르는 방식 (앞, 뒤)
HRESULT hr = Device->CreateRasterizerState(&desc, &rs_FrameMode);
assert(SUCCEEDED(hr));
}
}
void DestroyScene()
{
inputLatout->Release();
vertexBuffer->Release();
rs_FrameMode->Release();
}
// 키이벤트 관련 추가
bool Wirte = false;
void Update()
{
if (GetAsyncKeyState('1') & 0x8001)
Wirte = !Wirte;
}
void Render()
{
D3DXCOLOR bgcolor = D3DXCOLOR(0.22f, 0.27f, 0.44f, 1.0f); // 배경색
DeviceContext->ClearRenderTargetView(RTV, (float*)bgcolor); //앞
{
UINT stride = sizeof(Vertex); //간격(보폭, 인덱스 나눠줄 크기)
UINT offset = 0; //시작점
DeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
DeviceContext->IASetInputLayout(inputLatout);
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
DeviceContext->RSSetState(Wirte ? rs_FrameMode : NULL); //추가
DeviceContext->Draw(6, 0);
}
SwapChain->Present(0, 0); //백퍼에 위에 내용 보냄
}
실행
https://github.com/ascher8159/DX2D
DX2D_03
위에 옵션 말고 RS 에서 많은 작업을 진행을 하는데 BackspaceCulling 옵션이 있는데 RS -> PS에 값을 넣기전에 그려줄 필요가 없는 정점을 잘라서 PS에서 좀더 빠르게 계산 하기위한 계산 동작 등 여러가지를 한다.
'DirectX > DirectX 2D' 카테고리의 다른 글
DX2D_06 IndexBuffer (2) | 2022.11.22 |
---|---|
DX2D_05 정점 Update (0) | 2022.11.19 |
DX_1 배경 화면 & Line (0) | 2022.11.06 |
DX 렌더링 파이프라인 구조 (0) | 2022.11.06 |
DX 셋팅 (0) | 2022.11.05 |