여태까지 VertexBuffer를 통해서 총 6개의 정점을 통해서 사각형을 그렸는데 사실 정점의 갯수가 많아지면 계산량이 많기 때문에 정점의 갯수를 줄이고선 사용 할려는 방법이다. 똑같은 Buffer를 태우지만 그리는 순서만 넘겨주는 형태로 선언
아래 이미지 처럼 기존엔 6개 통해서 그렸던 거를 4개의 정점으로 사각형을 그리는 형태 Index Buffer 및 코드를 변경
1. Scene.cpp (Vertex관련)
Vertex 구조체 변수 관련 변수들 수정
※ 정점 갯수를 4개로 봐꺼주고 바꾼 갯수 만큼 관련이 되는 값들 변경
Vertex vertices[4];
void InitScene()
{
//VertexBuffer Setting & Create VertexBuffer
{
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[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, 1, 1, 1);
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = sizeof(Vertex) * 4;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
//desc.Usage = D3D11_USAGE_DEFAULT; //GPU 방식 잘 사용 안함
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
D3D11_SUBRESOURCE_DATA data;
ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
data.pSysMem = vertices;
HRESULT hr = Device->CreateBuffer(&desc, &data, &vertexBuffer);
assert(SUCCEEDED(hr));
}
{...}
}
void Update()
※ 키보드 반복문 조건 & Subresouce 크기 수정
void Update()
{
//if (GetAsyncKeyState('1') & 0x8001)
if(Key->Toggle('1')) Wirte = !Wirte;
if (Key->Press('A'))
{
for(int i =0 ; i < ARRAYSIZE(vertices) ; i++)
vertices[i].Position.x -= 1e-4f;
}
else if (Key->Press('D'))
{
for (int i = 0; i < ARRAYSIZE(vertices); i++)
vertices[i].Position.x += 1e-4f;
}
if (Key->Press('W'))
{
for (int i = 0; i < ARRAYSIZE(vertices); i++)
vertices[i].Position.y += 1e-4f;
}
else if (Key->Press('S'))
{
for (int i = 0; i < ARRAYSIZE(vertices); i++)
vertices[i].Position.y -= 1e-4f;
}
// Subresouce (CPU방식)
D3D11_MAPPED_SUBRESOURCE subResouce;
DeviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subResouce);
{
//메모리 카피(저장 받을 Subresource, 복사할 시작위치, 크기)
memcpy(subResouce.pData, vertices, sizeof(Vertex) * 4);
}
DeviceContext->Unmap(vertexBuffer, 0);
}
void Render()
※ 줄어든 배열의 갯수 만큼 수정 Draw 삭제
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);
}
SwapChain->Present(0, 0); //백퍼에 위에 내용 보냄
}
2. Scene.cpp (Index 관련)
Buffer 선언
※ VertexBuffer 선언한 영역에 추가로 IndexBuffer용 한개 선언
ID3D11Buffer* IndexBuffer = NULL;
void InitScene() 수정
※ Vertex Buffer 밑에 Index Buffer 관련으로 셋팅, 배열의 값은 삼각형을 그리는 시계 방향으로 값 셋팅
void InitScene()
{
//Vs 관련
{...}
// Index Buffer & IndexBuffer Setting
{
// - 값을 안넣기위한 unsigned int
UINT indices[6] = { 0, 1 ,2 ,2 ,1 ,3 };
//Create indexBuffer
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_IMMUTABLE; // GPU, CPU 에서 수정 못하게 막기
desc.ByteWidth = sizeof(UINT) * 6;
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
D3D11_SUBRESOURCE_DATA data;
ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
data.pSysMem = indices;
HRESULT hr = Device->CreateBuffer(&desc, &data, &IndexBuffer);
assert(SUCCEEDED(hr));
}
//Rs 관련
{...}
}
void DestroyScene()
※ 메모리 해제
void DestroyScene()
{
inputLatout->Release();
vertexBuffer->Release();
IndexBuffer->Release();
rs_FrameMode->Release();
}
void Render()
※ IndexBuffer도 DeviceContext->IASetIndexBuffer() 함수를 통해서 셋팅, DrawIndexed() 통해서 그리기
※ IASetIndexBuffer(버퍼, 넣어줄려는 형태(바이트), 인덱스 시작 위치);
※ DrawIndexed(인덱스의 크기, 시작 인덱스, 정점 단위);
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->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 3);
DeviceContext->IASetInputLayout(inputLatout);
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
DeviceContext->RSSetState(Wirte ? rs_FrameMode : NULL);
DeviceContext->DrawIndexed(6 , 0 , 0);
}
SwapChain->Present(0, 0); //백퍼에 위에 내용 보냄
}
3. 실행
※ 이제 정점 정보 4개와 인덱스 Buffer를 통해서 좀더 계산 속도 상승 시킴
요약
1. Index Buffer를 사용 하게 되면 정점의 순서와 상관 없이 Index 순서만 맞게 시계 방향으로 셋팅만 되면 그려진다.
2. 정점의 갯수가 줄어든거에 따라서 계산 속도도 빨라져서 프레임 속도 상향
https://github.com/ascher8159/DX2D
DX2D_06
'DirectX > DirectX 2D' 카테고리의 다른 글
정리 & Plug in (0) | 2022.11.26 |
---|---|
DX2D_07 Librarie 및 Utilitie (0) | 2022.11.24 |
DX2D_05 정점 Update (0) | 2022.11.19 |
DX_2 삼각형, DX_3 RS (0) | 2022.11.13 |
DX_1 배경 화면 & Line (0) | 2022.11.06 |