18 Graphics

gksrudtlr
|2025. 1. 12. 18:28
#include "pch.h"
#include "Graphics.h"

Graphics::Graphics(HWND hWnd)
{
    hwnd = hWnd;

    CreateDeviceAndSpwaChain();
    CreateRenderTargetView();
    SetViewport();
}

Graphics::~Graphics()
{
}

void Graphics::RenderBegin()
{
    //GPU가 그림을 그리는 것까지 성공하며 렌더링파이프라인에 OM에 후면버퍼나 전면버퍼에 그려달라고 전해주는 함수
    deviceContext->OMSetRenderTargets(1, renderTargetView.GetAddressOf(), nullptr);

    deviceContext->ClearRenderTargetView(renderTargetView.Get(), clearColor);
    deviceContext->RSSetViewports(1, &viewport);
}

void Graphics::RenderEnd()

{
    //후면 버퍼에서 전면 버퍼로 복사해서 출력해주는 함수로 중요하다
    HRESULT hr = swapChain->Present(1, 0);
    CHECK(hr);
}

void Graphics::CreateDeviceAndSpwaChain()
{
    DXGI_SWAP_CHAIN_DESC desc;
    ZeroMemory(&desc, sizeof(desc));//== memset과 같다
    {
        //버퍼의 해상도를 지정
        desc.BufferDesc.Width = GWinSizeX;
        desc.BufferDesc.Height = GWinSizeY;

        //분자/분모를 통해 해상도를 만듦
        desc.BufferDesc.RefreshRate.Numerator = 60;
        desc.BufferDesc.RefreshRate.Denominator = 1;

        desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
        desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

        //멀티샘플링시 보간을 위해 사용
        desc.SampleDesc.Count = 1;

        desc.SampleDesc.Quality = 0;

        //GPU가 연산이 끝났을 때 최종 결과물을 그려주는 역할로 사용하겠다 라는 옵션
        desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

        //후면버퍼 갯수
        desc.BufferCount = 1;
        //윈도우 헨들
        desc.OutputWindow = hwnd;

        desc.Windowed = true;
        desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    }

    ////스마트 포인터를 사용하기 때문에 함수를 통해 꺼내야함, D3D11Device* a;
    //device.Get();//현재 D3D11Device의 값을 꺼내줌, a
    //device.GetAddressOf();//현재 D3D11Device의 값의 주소값을 꺼내줌, &a

    HRESULT hr = ::D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &desc, swapChain.GetAddressOf(), device.GetAddressOf(), nullptr, deviceContext.GetAddressOf());
    //D3D_DRIVER_TYPE_ 내가가진 그래픽을 그릴 수 있는 놈을 선택

    CHECK(hr);
}

void Graphics::CreateRenderTargetView()
{
    HRESULT hr;

    ComPtr<ID3D11Texture2D> backBuffer{};
    //swapChain에 만들어 놓은 백버퍼에서 texture 리소스를  ID3D11Texture2D로 넘겨줌
    hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuffer.GetAddressOf());
    CHECK(hr);
    device->CreateRenderTargetView(backBuffer.Get(), nullptr, renderTargetView.GetAddressOf());
}

void Graphics::SetViewport()
{
    viewport.TopLeftX = 0.0f;
    viewport.TopLeftY = 0.0f;
    viewport.Width = static_cast<float>(GWinSizeX);
    viewport.Height = static_cast<float>(GWinSizeY);
    viewport.MinDepth = 0.0f;
    viewport.MaxDepth = 1.0f;
}
  • 세분화

    • 강의에서 Engine을 만들 때 Pipeline순으로 만들것이다
    • 처음으로 Graphics담당하는 부분을 따로 클래스로 때서 만든 것이다
    • CreateDeviceAndSpwaChain
      • GPU와 통신할 Device 생성한 뒤 GPU에 명령을 설정/실행할 DeviceContext 생성
      • 렌더링된 결과를 화면에 출력할 Swapchain 생성
    • CreateRenderTargetView
      • GPU가 렌더링 결과를 출력할 수 있는 특정 자원을 가리키는 객체
      • 화면에 그릴 데이터를 저장하는 공간인 벡버퍼와 그 공간을 연결하는 역할
    • SetViewport
      • 렌더링될 공간을 설정
    • 기존에 만들었던 이 함수들을 Graphics클래스로 옮기는 과정이다
  • 연결하기

    • shared_ptr<>스마트 포인터로 만든 Graphics 객체를 만들어 동적으로 객체를 만들어 필요할 때 그림을 그리고 필요없을 땐 메모리를 해제하는 식으로 사용할 수 있게 해준다
    • make_shared<>는 스마트 포인터로 만든 객체를 동적으로 할당하는 방법이다
    • 이 과정을 통해 GPU에 그림을 그릴 준비를 해준다다

'DirectX' 카테고리의 다른 글

20 Geometry  (0) 2025.01.12
19 InputAssembler  (0) 2025.01.12
17 SimpleMath 예제  (0) 2025.01.12
31 Animation  (0) 2025.01.12
15 Projection 변환 행렬  (0) 2025.01.12