렌더링 프레임워크 I: 렌더링 소개Rendering framework I: Intro to rendering

지금까지 UWP(유니버설 Windows 플랫폼) 게임을 구조화하는 방법과 게임의 흐름을 처리하도록 상태 시스템을 정의하는 방법에 대해 살펴보았습니다.We've covered how to structure a Universal Windows Platform (UWP) game and how to define a state machine to handle the flow of the game in the earlier topics. 이제, 렌더링 프레임워크를 어셈블하는 방법에 대해 알아볼 차례입니다.Now, it's time to learn how to assemble the rendering framework. 샘플 게임에서 Direct3D 11 (일반적으로 DirectX 11 이라고 함)을 사용 하 여 게임 장면을 렌더링 하는 방법을 살펴보겠습니다.Let's look at how the sample game renders the game scene using Direct3D 11 (commonly known as DirectX 11).

참고

이 샘플의 최신 게임 코드를 다운로드하지 않은 경우 Direct3D 게임 샘플로 이동합니다.If you haven't downloaded the latest game code for this sample, go to Direct3D game sample. 이 샘플은 UWP 기능 샘플의 큰 컬렉션의 일부입니다.This sample is part of a large collection of UWP feature samples. 샘플을 다운로드하는 방법에 대한 지침은 GitHub에서 UWP 샘플 가져오기를 참조하세요.For instructions on how to download the sample, see Get the UWP samples from GitHub.

Direct3D 11에는 게임과 같이 그래픽 집약적인 응용 프로그램을 위한 3D 그래픽을 생성하는 데 사용할 수 있는 고성능 그래픽 하드웨어의 고급 기능에 액세스할 수 있도록 해주는 API 집합이 포함되어 있습니다.Direct3D 11 contains a set of APIs that provide access to the advanced features of high-performance graphic hardware that can be used to create 3D graphics for graphic intensive applications such as games.

화면상에서 게임 그래픽을 렌더링하는 것은 기본적으로 화면 상에서 프레임 시퀀스를 렌더링하는 것입니다.Rendering game graphics on-screen is basically rendering a sequence of frames on-screen. 각 프레임에서 보기를 기반으로 장면에 표시되는 개체를 렌더링해야 합니다.In each frame, you have to render objects that are visible in the scene, based on the view.

프레임을 렌더링하려면 화면에 표시될 수 있도록 하드웨어에 필요한 장면 정보를 전달해야 합니다.In order to render a frame, you have to pass the required scene information to the hardware so that it can be displayed on the screen. 화면에 뭔가를 표시하고 싶다면 게임 실행이 시작되는 즉시 렌더링을 시작해야 합니다.If you want to have anything displayed on screen, you need to start rendering as soon as the game starts running.

목표Objective

UWP DirectX 게임에 그래픽 출력을 표시하도록 기본 렌더링 프레임워크를 설정하기 위해 이들을 크게 세 가지 단계로 묶을 수 있습니다.To set up a basic rendering framework to display the graphics output for a UWP DirectX game, you can loosely group them into these three steps.

  1. 그래픽 인터페이스에 대한 연결 설정Establish a connection to the graphics interface
  2. 그래픽을 그리기 위해 필요한 리소스 생성Create the resources needed to draw the graphics
  3. 프레임을 렌더링하여 그래픽 표시Display the graphics by rendering the frame

이 문서에서는 그래픽 렌더링 과정을 1 ~ 3단계로 설명합니다.This article explains how graphics are rendered, covering steps 1 and 3.

렌더링 프레임 워크 II: 게임 렌더링은 2단계에 해당하며, 렌더링 프레임워크를 설정하는 방법과 렌더링에 앞서 데이터를 준비하는 방법을 보여줍니다.Rendering framework II: Game rendering covers step 2; how to set up the rendering framework and how data is prepared before rendering can happen.

시작하기Get started

시작에 앞서 기본적인 그래픽 및 렌더링 개념을 숙지해야 합니다.Before you begin, you should familiarize yourself with the basic graphics and rendering concepts. Direct3D 및 렌더링 개념을 처음 접하셨다면 용어 및 개념을 참조하여 이 문서에서 사용되는 그래픽 및 렌더링 용어에 대해 간략히 숙지하세요.If you're new to Direct3D and rendering, see Terms and concepts for a brief description of the graphics and rendering terms used in this article.

이 게임에서는 GameRenderer 클래스 개체가 이 샘플 게임에 대한 렌더러를 나타냅니다.For this game, the GameRenderer class object represents the renderer for this sample game. 렌더러는 게임 시각 효과를 생성하는 데 사용되는 모든 Direct3D 11 및 Direct2D 개체를 만들고 유지 관리합니다.It's responsible for creating and maintaining all the Direct3D 11 and Direct2D objects used to generate the game visuals. 또한 렌더링할 개체 목록을 검색하는 데 사용되는 Simple3DGame 개체를 비롯해 헤드업 디스플레이(HUD)에서의 게임 상태에 대한 참조를 유지합니다.It also maintains a reference to the Simple3DGame object used to retrieve the list of objects to render as well as status of the game for the Heads Up Display (HUD).

자습서의 이 부분에서는 게임에서의 3D 개체 렌더링에 초점을 맞추겠습니다.In this part of the tutorial, we'll focus on rendering 3D objects in the game.

그래픽 인터페이스에 대한 연결 설정Establish a connection to the graphics interface

렌더링을 위해 하드웨어에 액세스하는 방법은 App::Initialize 아래의 UWP 프레임워크 문서를 참조하세요.To access to the hardware for rendering, see the UWP framework article under App::Initialize.

아래와 같이 ___공유 함수__를 사용 하 여 DX::D eviceresources에 대 한 공유_ptr 을 만듭니다 .이를 통해 장치에 대 한 액세스도 제공 합니다.The make_shared function, as shown below, is used to create a shared_ptr to DX::DeviceResources, which also provides access to the device.

Direct3D 11에서는 디바이스가 개체의 할당 및 삭제, 원형 렌더링, 그래픽 드라이버를 통한 그래픽 카드와의 통신에 사용됩니다.In Direct3D 11, a device is used to allocate and destroy objects, render primitives, and communicate with the graphics card through the graphics driver.

App::Initialize 메서드App::Initialize method

void App::Initialize(
    CoreApplicationView^ applicationView
    )
{
    //...

    // At this point we have access to the device. 
    // We can create the device-dependent resources.
    m_deviceResources = std::make_shared<DX::DeviceResources>();
}

프레임을 렌더링하여 그래픽 표시Display the graphics by rendering the frame

게임이 시작되면 게임 장면이 렌더링되어야 합니다.The game scene needs to render when the game is launched. 아래와 같이 렌더링을 위한 지침은 GameMain::Run 메서드에서 시작됩니다.The instructions for rendering start in the GameMain::Run method, as shown below.

간단한 흐름은 다음과 같습니다.The simple flow is:

  1. 업데이트Update
  2. 렌더링Render
  3. 있음Present

GameMain::Run 메서드GameMain::Run method

// Comparing this to App::Run() in the DirectX 11 App template
void GameMain::Run()
{
    while (!m_windowClosed)
    {
        if (m_visible) // if the window is visible
        {
            // Added: Switching different game states since this game sample is more complex
            switch (m_updateState) 
            {

                // ...
                CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
                // 1. Update
                // Also exist in DirectX 11 App template: Update loop to get the latest game changes
                Update();
                
                // 2. Render
                // Present also in DirectX 11 App template: Prepare to render
                m_renderer->Render();
                
                // 3. Present
                // Present also in DirectX 11 App template: Present the 
                // contents of the swap chain to the screen.
                m_deviceResources->Present(); 
                
                // Added: resetting a variable we've added to indicate that 
                // render has been done and no longer needed to render
                m_renderNeeded = false; 
            }
        }
        else
        {   
            // Present also in DirectX 11 App template
            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); 
        }
    }
    m_game->OnSuspending();  // exiting due to window close. Make sure to save state.
}

탭을Update

App::Update and GameMain::Update 메서드에서 게임 상태를 업데이트하는 방법에 대한 자세한 내용은 게임 흐름 관리 문서를 참조하세요.See the Game flow management article for more information about how game states are updated in the App::Update and GameMain::Update method.

렌더링Render

__GameMain::Run__에서 GameRenderer::Render 메서드를 호출하면 렌더링이 실행됩니다.Rendering is implemented by calling the GameRenderer::Render method in GameMain::Run.

스테레오 렌더링이 활성화되어 있으면 두 가지 렌더링 패스가 존재하는데, 하나는 오른쪽 눈을 위한 것이고 다른 하나는 왼쪽 눈을 위한 것입니다.If stereo rendering is enabled, there are two rendering passes: one for the right eye and one for the left eye. 각 렌더링 패스에서 렌더링 대상과 깊이 스텐실 뷰를 장치에 바인딩합니다.In each rendering pass, we bind the render target and the depth-stencil view to the device. 깊이 - 스텐실 보기는 이후에 삭제가 됩니다.We also clear the depth-stencil view afterward.

참고

꼭지점 인스턴스화나 기하 도형 셰이더를 사용하는 단일 패스 스테레오 같은 다른 메서드를 사용해 스테레오 렌더링을 수행할 수 있습니다.Stereo rendering can be achieved using other methods such as single pass stereo using vertex instancing or geometry shaders. 두 개의 렌더링 패스 메서드를 사용하면 느리지만 보다 편리하게 스테레오 렌더링을 수행할 수 있습니다.The two rendering pass method is a slower, but more convenient way to achieve stereo rendering.

게임이 존재하고 리소소가 로드되면 렌더링 패스당 한 번씩 프로젝트 매트릭스를 업데이트합니다.Once the game exists and resources are loaded, update the projection matrix, once per rendering pass. 개체는 보기마다 약간씩 다릅니다.Objects are slightly different from each view. 그런 다음, 그래픽 렌더링 파이프라인을 설정합니다.Next, set up the graphics rendering pipeline.

참고

리소스 로드 방법에 대한 자세한 내용은 DirectX 그래픽 리소스 생성 및 로드를 참조하세요.See Create and load DirectX graphic resources for more information on how resources are loaded.

이 게임 샘플에서는 모든 개체에서 표준 꼭지점 레이아웃을 사용하도록 렌더러가 설계되어 있습니다.In this game sample, the renderer is designed to use a standard vertex layout across all objects. 따라서 셰이더 디자인을 간소화하고 개체의 기하 도형에 관계 없이 셰이더 간의 변경을 손쉽게 수행할 수 있습니다.This simplifies the shader design and allows for easy changes between shaders, independent of the objects' geometry.

GameRenderer::Render 메서드GameRenderer::Render method

입력 꼭지점 레이아웃을 사용하여 Direct3D 컨텍스트를 설정합니다.Set the Direct3D context to use an input vertex layout. 입력 - 레이아웃 개체는 꼭지점 버퍼 데이터가 렌더링 파이프라인에 어떻게 스트리밍되는지 설명합니다.Input-layout objects describe how vertex buffer data is streamed into the rendering pipeline.

다음으로, 이전에 정의 된 상수 버퍼를 사용 하도록 Direct3D 컨텍스트를 설정 합니다 .이는 꼭 짓 점 셰이더 파이프라인 단계와 픽셀 셰이더 파이프라인 단계에서 사용 됩니다.Next, we set the Direct3D context to use the constant buffers defined earlier, that are used by the vertex shader pipeline stage and the pixel shader pipeline stage.

참고

상수 버퍼의 정의에 대한 자세한 내용은 렌더링 프레임워크 II: 게임 렌더링을 참조하세요.See Rendering framework II: Game rendering for more information about definition of the constant buffers.

파이프라인에 존재하는 모든 셰이더에서 동일한 입력 레이아웃과 상수 버퍼 집합이 사용되므로 프레임마다 한 번씩 설정됩니다.Because the same input layout and set of constant buffers is used for all shaders that are in the pipeline, it's set up once per frame.

void GameRenderer::Render()
{
    bool stereoEnabled = m_deviceResources->GetStereoState();

    auto d3dContext = m_deviceResources->GetD3DDeviceContext();
    auto d2dContext = m_deviceResources->GetD2DDeviceContext();

    int renderingPasses = 1;
    if (stereoEnabled)
    {
        renderingPasses = 2;
    }

    for (int i = 0; i < renderingPasses; i++)
    {
        // Iterate through the number of rendering passes to be completed.
        // 2 rendering passes if stereo is enabled
        if (i > 0)
        {
            // Doing the Right Eye View.
            ID3D11RenderTargetView *const targets[1] = { m_deviceResources->GetBackBufferRenderTargetViewRight() };

            // Resets render targets to the screen.
            // OMSetRenderTargets binds 2 things to the device.
            // 1. Binds one render target atomically to the device.
            // 2. Binds the depth-stencil view, as returned by the GetDepthStencilView method, to the device.
            // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476464.aspx

            d3dContext->OMSetRenderTargets(1, targets, m_deviceResources->GetDepthStencilView());
            
            // Clears the depth stencil view.
            // A depth stencil view contains the format and buffer to hold depth and stencil info.
            // For more info about depth stencil view, go to: 
            // https://docs.microsoft.com/windows/uwp/graphics-concepts/depth-stencil-view--dsv-
            // A depth buffer is used to store depth information to control which areas of 
            // polygons are rendered rather than hidden from view. To learn more about a depth buffer,
            // go to: https://docs.microsoft.com/windows/uwp/graphics-concepts/depth-buffers
            // A stencil buffer is used to mask pixels in an image, to produce special effects. 
            // The mask determines whether a pixel is drawn or not,
            // by setting the bit to a 1 or 0. To learn more about a stencil buffer,
            // go to: https://docs.microsoft.com/windows/uwp/graphics-concepts/stencil-buffers

            d3dContext->ClearDepthStencilView(m_deviceResources->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0);
            
            // d2d -- Discussed later
            d2dContext->SetTarget(m_deviceResources->GetD2DTargetBitmapRight());
        }
        else
        {
            // Doing the Mono or Left Eye View.
            // As compared to the right eye:
            // m_deviceResources->GetBackBufferRenderTargetView instead of GetBackBufferRenderTargetViewRight
            ID3D11RenderTargetView *const targets[1] = { m_deviceResources->GetBackBufferRenderTargetView() }; 
            
            // Same as the Right Eye View.
            d3dContext->OMSetRenderTargets(1, targets, m_deviceResources->GetDepthStencilView());
            d3dContext->ClearDepthStencilView(m_deviceResources->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0);
            
            // d2d -- Discussed later under Adding UI
            d2dContext->SetTarget(m_deviceResources->GetD2DTargetBitmap()); 
        }

        // Render the scene objects
        if (m_game != nullptr && m_gameResourcesLoaded && m_levelResourcesLoaded)
        {
            // This section is only used after the game state has been initialized and all device
            // resources needed for the game have been created and associated with the game objects.
            if (stereoEnabled)
            {
                // When doing stereo, it is necessary to update the projection matrix once per rendering pass.

                auto orientation = m_deviceResources->GetOrientationTransform3D();

                ConstantBufferChangeOnResize changesOnResize;

                // Apply either a left or right eye projection, which is an offset from the middle
                XMStoreFloat4x4(
                    &changesOnResize.projection,
                    XMMatrixMultiply(
                        XMMatrixTranspose(
                            i == 0 ?
                            m_game->GameCamera()->LeftEyeProjection() :
                            m_game->GameCamera()->RightEyeProjection()
                            ),
                        XMMatrixTranspose(XMLoadFloat4x4(&orientation))
                        )
                    );

                d3dContext->UpdateSubresource(
                    m_constantBufferChangeOnResize.Get(),
                    0,
                    nullptr,
                    &changesOnResize,
                    0,
                    0
                    );
            }

            // Update variables that change once per frame.
            ConstantBufferChangesEveryFrame constantBufferChangesEveryFrame;
            XMStoreFloat4x4(
                &constantBufferChangesEveryFrame.view,
                XMMatrixTranspose(m_game->GameCamera()->View())
                );
            d3dContext->UpdateSubresource(
                m_constantBufferChangesEveryFrame.Get(),
                0,
                nullptr,
                &constantBufferChangesEveryFrame,
                0,
                0
                );

            // Setup the graphics pipeline. This sample uses the same InputLayout and set of
            // constant buffers for all shaders, so they only need to be set once per frame.
            // For more info about the graphics or rendering pipeline, 
            // go to https://msdn.microsoft.com/library/windows/desktop/ff476882.aspx

            // IASetInputLayout binds an input-layout object to the input-assembler (IA) stage. 
            // Input-layout objects describe how vertex buffer data is streamed into the IA pipeline stage.
            // Set up the Direct3D context to use this vertex layout.
            // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476454.aspx
            d3dContext->IASetInputLayout(m_vertexLayout.Get());

            // VSSetConstantBuffers sets the constant buffers used by the vertex shader pipeline stage.
            // Set up the Direct3D context to use these constant buffers.
            // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476491.aspx

            d3dContext->VSSetConstantBuffers(0, 1, m_constantBufferNeverChanges.GetAddressOf());
            d3dContext->VSSetConstantBuffers(1, 1, m_constantBufferChangeOnResize.GetAddressOf());
            d3dContext->VSSetConstantBuffers(2, 1, m_constantBufferChangesEveryFrame.GetAddressOf());
            d3dContext->VSSetConstantBuffers(3, 1, m_constantBufferChangesEveryPrim.GetAddressOf());

            // Sets the constant buffers used by the pixel shader pipeline stage. 
            // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476470.aspx

            d3dContext->PSSetConstantBuffers(2, 1, m_constantBufferChangesEveryFrame.GetAddressOf());
            d3dContext->PSSetConstantBuffers(3, 1, m_constantBufferChangesEveryPrim.GetAddressOf());
            d3dContext->PSSetSamplers(0, 1, m_samplerLinear.GetAddressOf());

            auto objects = m_game->RenderObjects();
            for (auto object = objects.begin(); object != objects.end(); object++)
            {
                // The 3D object render method handles the rendering.
                // For more info, see Primitive rendering below.
                (*object)->Render(d3dContext, m_constantBufferChangesEveryPrim.Get()); /
            }
        }
        else
        {
            const float ClearColor[4] = {0.5f, 0.5f, 0.8f, 1.0f};

            // Only need to clear the background when not rendering the full 3D scene since
            // the 3D world is a fully enclosed box and the dynamics prevents the camera from
            // moving outside this space.
            if (i > 0)
            {
                // Doing the Right Eye View.
                d3dContext->ClearRenderTargetView(m_deviceResources->GetBackBufferRenderTargetViewRight(), ClearColor);
            }
            else
            {
                // Doing the Mono or Left Eye View.
                d3dContext->ClearRenderTargetView(m_deviceResources->GetBackBufferRenderTargetView(), ClearColor);
            }
        }

        // Start of 2D rendering
        d3dContext->BeginEventInt(L"D2D BeginDraw", 1);
        d2dContext->BeginDraw();

        // ...
    }
}

원형 렌더링Primitive rendering

장면을 렌더링할 때 렌더링이 필요한 모든 개체를 반복합니다.When rendering the scene, you loop through all the objects that need to be rendered. 각 개체(원형)에 대해 아래 단계가 반복됩니다.The steps below are repeated for each object (primitive).

  • 모델의 세계 변환 매트릭스 및 재질 정보를 사용 하 여 상수 버퍼 (m_constantBufferChangesEveryPrim)를 업데이트 합니다.Update the constant buffer(m_constantBufferChangesEveryPrim) with the model's world transformation matrix and material information.
  • M_constantBufferChangesEveryPrim 는 각 개체에 대 한 매개 변수를 포함 합니다.The m_constantBufferChangesEveryPrim contains parameters for each object. 여기에는 월드 변환 매트릭스에 대한 개체를 비롯하여 조명 계산을 위한 색과 반사 지수 같은 재질 속성이 포함되어 있습니다.It includes the object to world transformation matrix as well as material properties like color and specular exponent for lighting calculations.
  • 메시 개체 데이터가 렌더링 파이프라인의 입력 어셈블러(IA) 단계에 스트리밍될 수 있도록 입력 꼭지점 레이아웃을 사용하도록 Direct3D 컨텍스트를 설정합니다.Set Direct3D context to use the input vertex layout for the mesh object data to be streamed into the input-assembler (IA) stage of the rendering pipeline
  • IA 단계에서 인덱스 버퍼를 사용하도록 Direct3D 컨텍스트를 설정합니다.Set Direct3D context to use an index buffer in the IA stage. 원형 정보(유형, 데이터 순서 등)를 제공합니다.Provide the primitive info: type, data order.
  • 인덱싱된 비 인스턴스 원형을 그리기 위해 그리기 호출을 제출합니다.Submit a draw call to draw the indexed, non-instanced primitive. GameObject::Render 메서드는 원형의 상수 버퍼를 지정된 원형 고유의 데이터로 업데이트합니다.The GameObject::Render method updates the primitive constant buffer with the data specific to a given primitive. 그러면 각 원형의 기하 도형을 그릴 수 있도록 컨텍스트에서 __DrawIndexed__가 호출됩니다.This results in a DrawIndexed call on the context to draw the geometry of that each primitive. 구체적으로 설명하자면 이러한 그리기 호출은 상수 버퍼 데이터에 의해 매개 변수화되어 그래픽 처리 장치(GPU)의 대기열에 명령 및 데이터를 저장합니다.Specifically, this draw call queues commands and data to the graphics processing unit (GPU), as parameterized by the constant buffer data. 각 그리기 호출에서 꼭 짓 점 마다 한 번씩 꼭 짓 점 셰이더를 실행 한 다음 기본 형식에서 각 삼각형의 픽셀 마다 한 번씩 픽셀 셰이더 를 실행 합니다.Each draw call executes the vertex shader one time per vertex, and then the pixel shader one time for every pixel of each triangle in the primitive. 텍스처는 픽셀 셰이더가 렌더링을 수행하는 데 사용하는 상태의 일부입니다.The textures are part of the state that the pixel shader uses to do the rendering.

상수 버퍼가 여러 개인 이유는 다음과 같습니다.Reasons for multiple constant buffers: * 게임에서는 여러 상수 버퍼를 사용하지만 이러한 버퍼는 원형당 한 번만 업데이트해야 합니다.The game uses multiple constant buffers but only needs to update these buffers one time per primitive. 앞서 설명했듯이 상수 버퍼는 각 원형에서 실행되는 셰이더에 대한 입력과 같습니다.As mentioned earlier, constant buffers are like inputs to the shaders that run for each primitive. 일부 데이터는 정적 (m_constantBufferNeverChanges)입니다. 일부 데이터는 카메라의 위치와 같이 프레임 (m_constantBufferChangesEveryFrame)을 통해 일정 합니다. 일부 데이터는 색 및 질감 (m_constantBufferChangesEveryPrim)과 같은 기본 형식에만 적용 됩니다.Some data is static (m_constantBufferNeverChanges); some data is constant over the frame (m_constantBufferChangesEveryFrame), like the position of the camera; and some data is specific to the primitive, like its color and textures (m_constantBufferChangesEveryPrim) * 게임 렌더러에서는 이러한 입력을 서로 다른 상수 버퍼로 분리하여 CPU 및 GPU에서 사용하는 메모리 대역폭을 최적화합니다.The game renderer separates these inputs into different constant buffers to optimize the memory bandwidth that the CPU and GPU use. 이러한 접근 방식은 GPU에서 추적해야 하는 데이터의 양을 최소화하는 데도 도움이 됩니다.This approach also helps to minimize the amount of data the GPU needs to keep track of. GPU에는 대형 명령 대기열이 있어서 게임에서 __Draw__를 호출할 때마다 해당 명령이 관련 데이터와 함께 대기열에 저장됩니다.The GPU has a big queue of commands, and each time the game calls Draw, that command is queued along with the data associated with it. 게임에서 원형 상수 버퍼를 업데이트하고 다음 Draw 명령을 실행하면 그래픽 드라이버에서 이 다음 명령과 관련 데이터를 대기열에 추가합니다.When the game updates the primitive constant buffer and issues the next Draw command, the graphics driver adds this next command and the associated data to the queue. 게임에서 100개의 원형을 그리면 대기열에 상수 버퍼 데이터 복사본 100개가 생성될 수 있습니다.If the game draws 100 primitives, it could potentially have 100 copies of the constant buffer data in the queue. 게임에서 GPU로 보내는 데이터의 양을 최소화하려고 하므로 게임에서는 각 원형에 대한 업데이트만 포함하는 별도의 원형 상수 버퍼를 사용합니다.To minimize the amount of data the game is sending to the GPU, the game uses a separate primitive constant buffer that only contains the updates for each primitive.

GameObject::Render 메서드GameObject::Render method

void GameObject::Render(
    _In_ ID3D11DeviceContext *context,
    _In_ ID3D11Buffer *primitiveConstantBuffer
    )
{
    if (!m\_active || (m\_mesh == nullptr) || (m_normalMaterial == nullptr))
    {
        return;
    }

    ConstantBufferChangesEveryPrim constantBuffer;

    // Put the model matrix info into a constant buffer, in world matrix.
    XMStoreFloat4x4(
        &constantBuffer.worldMatrix,
        XMMatrixTranspose(ModelMatrix())
        );

    // Check to see which material to use on the object.
    // If a collision (a hit) is detected, GameObject::Render checks the current context, which 
    // indicates whether the target has been hit by an ammo sphere. If the target has been hit, 
    // this method applies a hit material, which reverses the colors of the rings of the target to 
    // indicate a successful hit to the player. Otherwise, it applies the default material 
    // with the same method. In both cases, it sets the material by calling Material::RenderSetup, 
    // which sets the appropriate constants into the constant buffer. Then, it calls 
    // ID3D11DeviceContext::PSSetShaderResources to set the corresponding texture resource for the 
    // pixel shader, and ID3D11DeviceContext::VSSetShader and ID3D11DeviceContext::PSSetShader 
    // to set the vertex shader and pixel shader objects themselves, respectively.

    if (m_hit && m_hitMaterial != nullptr)
    {
        m_hitMaterial->RenderSetup(context, &constantBuffer);
    }
    else
    {
        m_normalMaterial->RenderSetup(context, &constantBuffer);
    }

    // Update the primitive constant buffer with the object model's info.
    context->UpdateSubresource(primitiveConstantBuffer, 0, nullptr, &constantBuffer, 0, 0);

    // Render the mesh.
    // See MeshObject::Render method below.
    m_mesh->Render(context);
}

#### MeshObject::Render method

void MeshObject::Render(\_In\_ ID3D11DeviceContext *context)
{
    // PNTVertex is a struct. stride provides us the size required for all the mesh data
    // struct PNTVertex
    //{
    //  DirectX::XMFLOAT3 position;
    //  DirectX::XMFLOAT3 normal;
    //  DirectX::XMFLOAT2 textureCoordinate;
    //};
    uint32 stride = sizeof(PNTVertex);
    uint32 offset = 0;

    // Similar to the main render loop.
    // Input-layout objects describe how vertex buffer data is streamed into the IA pipeline stage.
    context->IASetVertexBuffers(0, 1, m_vertexBuffer.GetAddressOf(), &stride, &offset);

    // IASetIndexBuffer binds an index buffer to the input-assembler stage.
    // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476453.aspx
    context->IASetIndexBuffer(m_indexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);

    // Binds information about the primitive type, and data order that describes input data for the input assembler stage.
    // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476455.aspx
    context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    // Draw indexed, non-instanced primitives. A draw API submits work to the rendering pipeline.
    // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476409.aspx
    context->DrawIndexed(m_indexCount, 0, 0);
}

표시Present

DX::DeviceResources::Present 메서드를 호출하여 배치한 콘텐츠를 버퍼에 저장하고 이를 표시합니다.We call the DX::DeviceResources::Present method to put the contents we've placed in the buffers and display it.

스왑 체인이라는 용어는 사용자에게 프레임을 표시하는 데 사용되는 버퍼의 컬렉션에 사용됩니다.We use the term swap chain for a collection of buffers that are used for displaying frames to the user. 응용 프로그램이 표시할 새 프레임을 제공할 때마다, 스왑 체인의 첫 버퍼가 표시되는 버퍼의 자리를 차지합니다.Each time an application presents a new frame for display, the first buffer in the swap chain takes the place of the displayed buffer. 이 프로세스를 스와핑 또는 플리핑이라고 부릅니다.This process is called swapping or flipping. 자세한 내용은 스왑 체인을 참조하세요.For more information, see Swap chains.

  • IDXGISwapChain1 인터페이스의 Present 메서드는 DXGI에게 세로 동기화(VSync)가 될 때까지 차단하고 다음 VSync 때까지 응용 프로그램을 절전 모드로 전환하라고 명령합니다.IDXGISwapChain1 interface's Present method the instructs DXGI to block until Vertical Synchronization (VSync), putting the application to sleep until the next VSync. 이렇게 하면 화면에 표시되지 않는 모든 주기 렌더링 프레임을 낭비하지 않게 됩니다.This ensures you don't waste any cycles rendering frames that will never be displayed to the screen.
  • ID3D11DeviceContext3 인터페이스의 DiscardView 메서드는 렌더링 대상의 콘텐츠를 삭제합니다.ID3D11DeviceContext3 interface's DiscardView method discards the contents of the render target. 이는 기존 콘텐츠가 완전히 덮어쓰기 될 때만 유효한 작업입니다.This is a valid operation only when the existing contents will be entirely overwritten. 더티 또는 스크롤 rect가 사용되는 경우에는 이 호출을 제거해야 합니다.If dirty or scroll rects are used, this call should be removed.
  • 동일한 DiscardView 메서드를 사용하여 깊이 - 스텐실의 콘텐츠를 삭제합니다.Using the same DiscardView method, discard the contents of the depth-stencil.
  • HandleDeviceLost 메서드는 디바이스가 제거된 경우에 시나리오를 관리하는 데 사용됩니다.HandleDeviceLost method is used to manage the scenario if the device is removed. 연결 해제 또는 드라이버 업그레이드를 통해 디바이스가 제거되면 모든 디바이스 리소를 다시 만들어야 합니다.If the device was removed either by a disconnection or a driver upgrade, you must recreate all device resources. 자세한 내용은 Direct3D 11에서 디바이스가 제거된 시나리오 처리를 참조하세요.For more information, see Handle device removed scenarios in Direct3D 11.

원활한 프레임 속도를 위해서는 프레임 렌더링을 위한 작업의 양이 VSync 간의 시간에 맞는지 확인해야 합니다.To achieve a smooth frame rate, you must ensure that the amount of work to render a frame fits the time between VSyncs.

// Present the contents of the swap chain to the screen.
void DX::DeviceResources::Present()
{
    // The first argument instructs DXGI to block until VSync, putting the application
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
    // frames that will never be displayed to the screen.
    HRESULT hr = m_swapChain->Present(1, 0);

    // Discard the contents of the render target.
    // This is a valid operation only when the existing contents will be entirely
    // overwritten. If dirty or scroll rects are used, this call should be removed.
    m_d3dContext->DiscardView(m_d3dRenderTargetView.Get());

    // Discard the contents of the depth-stencil.
    m_d3dContext->DiscardView(m_d3dDepthStencilView.Get());

    // If the device was removed either by a disconnection or a driver upgrade, we 
    // must recreate all device resources.
    // For more info about how to handle a device lost scenario, go to:
    // https://docs.microsoft.com/windows/uwp/gaming/handling-device-lost-scenarios
    if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
    {
        HandleDeviceLost();
    }
    else
    {
        DX::ThrowIfFailed(hr);
    }
}

다음 단계Next steps

이 문서에는 디스플레이에서 그래픽이 렌더링되는 방법이 설명되어 있고, 사용되고 있는 일부 렌더링 용어를 간략하게 설명되어 있습니다.This article explained how graphics is rendered on the display and provided a short description for some of the rendering terms used. 렌더링 프레임워크 II: 게임 렌더링 문서에서 렌더링에 대한 자세한 내용을 확인하고 렌더링 전에 필요한 데이터를 준비하는 방법을 알아보세요.Learn more about rendering in the Rendering framework II: Game rendering article, and learn how to prepare the data needed before rendering.

용어 및 개념Terms and concepts

간단한 게임 장면Simple game scene

간단한 게임 장면은 광원이 여러 개인 몇 가지 개체로 이루어져 있습니다.A simple game scene is made up of a few objects with several light sources.

개체의 모양은 공간에서 X, Y, Z 좌표 집합으로 정의됩니다.An object's shape is defined by a set of X, Y, Z coordinates in space. 게임 세계에서의 실제 렌더링 위치는 X, Y, Z 위치 좌표에 변환 매트릭스를 적용하여 결정할 수 있습니다.The actual render location in the game world can be determined by applying a transformation matrix to the positional X, Y, Z coordinates. 여기에는 U와 V 같이 개체에 재료가 적용된 방법을 지정하는 텍스처 좌표 집합도 포함될 수 있습니다.It may also have a set of texture coordinates - U and V which specifies how a material is applied to the object. 이는 개체의 표면 속성을 정의하고 개체의 표면이 테니스 볼 같은 거친지, 아니면 볼링 볼 같이 매끄럽고 윤이 나는지 확인할 수 있도록 해줍니다.This defines the surface properties of the object and gives you the ability to see if an object has a rough surface like a tennis ball or a smooth glossy surface like a bowling ball.

장면 및 개체 정보는 디스플레이 모니터에 구현이 되도록 렌더링 프레임워크가 프레임별로 장면을 다시 생성하는 데 사용됩니다.Scene and object info are used by the rendering framework to recreate the scene frame by frame, making it come alive on your display monitor.

렌더링 파이프라인Rendering pipeline

렌더링 파이프라인은 3D 장면 정보가 화면에 표시되는 이미지로 변환되는 프로세스입니다.The rendering pipeline is the process in which 3D scene info is translated to an image displayed on screen. Direct3D 11에서 이 파이프라인은 프로그래밍이 가능합니다.In Direct3D 11, this pipeline is programmable. 렌더링 요구를 지원하도록 단계를 조정할 수 있습니다.You can adapt the stages to support your rendering needs. 공통 셰이더 코어를 사용하는 단계는 HLSL 프로그래밍 언어를 사용하여 프로그래밍할 수 있습니다.Stages that feature common shader cores are programmable by using the HLSL programming language. 이를 그래픽 렌더링 파이프라인 또는 간단하게 파이프라인이라고 합니다.It is also known as the graphics rendering pipeline or simply pipeline.

이러한 파이프라인을 손쉽게 만들기 위해서는 다음을 숙지해야 합니다.To help you create this pipeline, you need to be familiar with:

자세한 내용은 Direct3D 11 렌더링 파이프라인 이해그래픽 파이프라인을 참조하세요.For more information, see Understand the Direct3D 11 rendering pipeline and Graphics pipeline.

HLSLHLSL

HLSL은 DirectX를 위한 상위 수준 셰이딩 언어입니다.HLSL is the High Level Shading Language for DirectX. HLSL를 사용하여 Direct3D 파이프라인을 위해 C 스타일의 프로그래밍 셰이더를 만들 수 있습니다.Using HLSL, you can create C like programmable shaders for the Direct3D pipeline. 자세한 내용은 HLSL를 참조하세요.For more information, see HLSL.

셰이더Shaders

셰이더는 렌더링 시 개체의 표면이 어떻게 나타나는지를 판단하기 위한 지침의 집합으로 생각하면 됩니다.Shaders can be thought of as a set of instructions that determine how the surface of an object appears when rendered. HLSL를 사용하여 프로그래밍되는 개체를 HLSL 셰이더라고 합니다.Those that are programmed using HLSL are known as HLSL shaders. [HLSL])(#hlsl) 셰이더용 소스 코드 파일의 확장명은 .hlsl입니다.Source code files for [HLSL])(#hlsl) shaders have .hlsl file extension. 이러한 셰이더는 작성 시점이나 실행 시에 컴파일이 되고, 실행 시에 해당되는 파이프라인 단계로 들어갑니다. 컴파일된 셰이더 개체의 파일 확장명은 .cso입니다.These shaders can be compiled at author-time or at runtime, and set at runtime into the appropriate pipeline stage; a compiled shader object has a .cso file extension.

Direct3D 9 셰이더는 셰이더 모델 1, 셰이더 모델 2 및 셰이더 모델 3을 사용하여 설계가 가능하지만, Direct3D 10 셰이더는 셰이더 모델 4를 토대로 해서만 설계가 가능합니다.Direct3D 9 shaders can be designed using shader model 1, shader model 2 and shader model 3; Direct3D 10 shaders can only be designed on shader model 4. Direct3D 11 셰이더는 셰이더 모델 5를 토대로 설계할 수 있습니다.Direct3D 11 shaders can be designed on shader model 5. Direct3D 11.3 및 Direct3D 12는 셰이더 모델 5.1을 토대로, Direct3D 12는 셰이더 모델 6를 토대로 설계가 가능합니다.Direct3D 11.3 and Direct3D 12 can be designed on shader model 5.1, and Direct3D 12 can also be designed on shader model 6.

꼭짓점 셰이더 및 픽셀 셰이더Vertex shaders and pixel shaders

데이터는 원형 스트림 형태로 그래픽 파이프라인으로 들어가고 꼭지점 셰이더나 픽셀 셰이더 같이 다양한 셰이더에 의해 처리됩니다.Data enters the graphics pipeline as a stream of primitives and is processed by various shaders such as the vertex shaders and pixel shaders.

꼭지점 셰이더는 보통 변환, 스킨 지정, 조명 등의 작업을 수행하여 꼭지점을 처리합니다.Vertex shaders processes vertices, typically performing operations such as transformations, skinning, and lighting. 픽셀 셰이더는 픽셀별 조명과 후처리 같은 풍부한 음영 기술을 사용할 수 있도록 해줍니다.Pixel shaders enables rich shading techniques such as per-pixel lighting and post-processing. 또한 상수 변수, 텍스처 데이터, 보간된 꼭지점별 값 및 기타 데이터를 조합하여 픽셀별 출력을 산출합니다.It combines constant variables, texture data, interpolated per-vertex values, and other data to produce per-pixel outputs.

셰이더 단계Shader stages

이러한 원형 스트림을 처리하도록 정의된 다양한 셰이더 시퀀스를 렌더링 파이프라인에서는 셰이더 단계라고 부릅니다.A sequence of these various shaders defined to process this stream of primitives is known as shader stages in a rendering pipeline. 실제 단계는 Direct3D의 버전에 따라 다르지만, 일반적으로 꼭지점, 기하 도형 및 픽셀 단계가 포함되어 있습니다.The actual stages depend on the version of Direct3D, but usually include the vertex, geometry, and pixel stages. 공간 분할을 위한 헐(hull) 및 도메인 셰이더나 컴퓨팅 셰이더 등 다른 단계들도 있습니다.There are also other stages, such as the hull and domain shaders for tessellation, and the compute shader. 이러한 모든 단계는 [HLSL])(#hlsl)을 사용해 완전히 프로그래밍이 가능합니다.All these stages are completely programmable using the [HLSL])(#hlsl). 자세한 내용은 그래픽 파이프라인을 참조하세요.For more information, see Graphics pipeline.

다양한 셰이더 파일 형식Various shader file formats

셰이더 코드 파일 확장면은 다음과 같습니다.Shader code file extensions: * 확장명이 .hlsl인 파일은 [HLSL])(#hlsl) 소스 코드를 보유합니다.A file with the .hlsl extension holds [HLSL])(#hlsl) source code. * 확장명이 .cso인 파일은 컴파일된 셰이더 개체를 보유합니다.A file with the .cso extension holds a compiled shader object. * 확장명이 .h인 파일은 헤더 파일이지만, 셰이더 코드 맥락에서 보자면 이 헤더 파일은 셰이더 데이터를 보유하는 바이트 배열을 정의합니다.A file with the .h extension is a header file, but in a shader code context, this header file defines a byte array that holds shader data. * 확장명이 .hlsli인 파일에는 상수 버퍼의 형식이 포함되어 있습니다.A file with the .hlsli extension contains the format of the constant buffers. 게임 샘플에서 파일은 Shaders>__ConstantBuffers.hlsli__입니다.In the game sample, the file is Shaders>ConstantBuffers.hlsli.

참고

실행 시 .cso 파일을 로드하거나 실행 코드에 .h 파일을 추가하는 방법으로 셰이더를 기본 포함시킬 수 있습니다.You would embed the shader either by loading a .cso file at runtime or adding the .h file in your executable code. 하지만 동일한 셰이더에 대해 둘을 모두 사용하지 않습니다.But you would not use both for the same shader.

DirectX에 대한 깊은 이해Deeper understanding of DirectX

Direct3D 11은 게임 같이 그래픽 집약적이어서 집약적 연산을 처리할 수 있는 뛰어난 그래픽 카드가 요구되는 응용 프로그램에서 그래픽을 생성하도록 도와주는 API 집합입니다.Direct3D 11 is a set of APIs that can help us create graphics for graphics intensive applications like games, where we want to have a good graphics card to process intensive computation. 이 섹션에는 리소스, 하위 리소스, 디바이스, 디바이스 컨텍스트와 같은 Direct3D 11 그래픽 프로그램 개념에 대해 간략하게 설명되어 있습니다.This section briefly explains the Direct3D 11 graphics programming concepts: resource, subresource, device, and device context.

리소스Resource

이 개념을 처음 접하는 사람들은 리소스(디바이스 리소스라고도 함)를 텍스처, 위치, 색상 같은 개체를 렌더링하는 방법에 대한 정보로 생각할 수 있습니다.For those who are new, you can think of resources (also known as device resources) as info on how to render an object like texture, position, color. 리소스는 파이프라인에 정보를 제공하고 장면에서 렌더링되는 내용을 정의합니다.Resources provide data to the pipeline and define what is rendered during your scene. 리소스는 게임 미디어에서 로드하거나 런타임에 동적으로 만들 수 있습니다.Resources can be loaded from your game media or created dynamically at run time.

실제로 리소스는 Direct3D 파이프라인에서 액세스할 수 있는 메모리의 영역을 뜻합니다.A resource is, in fact, an area in memory that can be accessed by the Direct3D pipeline. 파이프라인에서 메모리에 효율적으로 액세스하려면 파이프라인에 제공되는 데이터(입력 기하 도형, 셰이더 리소스, 질감 등)를 리소스에 저장해야 합니다.In order for the pipeline to access memory efficiently, data that is provided to the pipeline (such as input geometry, shader resources, and textures) must be stored in a resource. 모든 Direct3D 리소스가 파생되는 두 가지 리소스 종류는 버퍼와 질감입니다.There are two types of resources from which all Direct3D resources derive: a buffer or a texture. 각 파이프라인 단계마다 최대 128개의 리소스를 활성화할 수 있습니다.Up to 128 resources can be active for each pipeline stage. 자세한 내용은 리소스를 참조하세요.For more information, see Resources.

하위 리소스Subresource

하위 리소스란 리소스의 하위 집합을 나타내는 용어입니다.The term subresource refers to a subset of a resource. Direct3D는 전체 리소스를 참조할 수도 있고 리소스의 하위 집합을 참조할 수도 있습니다.Direct3D can reference an entire resource or it can reference subsets of a resource. 자세한 내용은 하위 리소스를 참조하세요.For more information, see Subresource.

깊이 - 스텐실Depth-stencil

깊이 - 스텐실 리소스에는 깊이와 스텐실 정보를 보유하는 형식 및 버퍼가 포함되어 있습니다.A depth-stencil resource contains the format and buffer to hold depth and stencil information. 이 리소스는 텍스터 리소스를 사용해 만들 수 있습니다.It is created using a texture resource. 깊이 - 스텐실 리소를 만드는 방법에 대한 자세한 내용은 깊이 - 스텐실 기능 구성을 참조하세요.For more information on how to create a depth-stencil resource, see Configuring Depth-Stencil Functionality. ID3D11DepthStencilView 인터페이스를 사용해 구현된 깊이 - 스텐실 보기를 통해 깊이 - 스텐실 리소스에 액세스합니다.We access the depth-stencil resource through the depth-stencil view implemented using the ID3D11DepthStencilView interface.

깊이 정보는 다각형의 어떤 영역이 보기에서 숨겨지지 않고 렌더링되는지를 알려줍니다.Depth info tells us which areas of polygons are rendered rather than hidden from view. 스텐실 정보는 어떤 픽셀이 마스킹되는지 알려줍니다.Stencil info tells us which pixels are masked. 이 정보는 픽셀이 그려져 있는지 여부를 판단하여 1 또는 0으로 설정하기 때문에 특수 효과를 내는 데 사용할 수 있습니다.It can be used to produce special effects since it determines whether a pixel is drawn or not; sets the bit to a 1 or 0.

자세한 내용은 깊이 - 스텐실 보기, 깊이 버퍼스텐실 버퍼를 참조하세요.For more information, see: Depth-stencil view, depth buffer, and stencil buffer.

렌더링 대상Render target

렌더링 대상은 렌더링 패스가 끝날 때 기록이 가능한 리소스입니다.A render target is a resource that we can write to at the end of a render pass. 보통은 ID3D11Device::CreateRenderTargetView 메서드에서 스왑 체인 백 버퍼(이 역시 리소스)를 입력 파라미터로 사용하여 생성됩니다.It is commonly created using the ID3D11Device::CreateRenderTargetView method using the swap chain back buffer (which is also a resource) as the input parameter.

각 렌더링 대상은 해당되는 깊이 - 스텐실 보기를 가지고 있어야 합니다. 왜냐하면 사용에 앞서 OMSetRenderTargets를 통해 렌더링 대상을 설정할 때 깊이 - 스텐실 보기가 필요할 수도 있기 때문입니다.Each render target should also have a corresponding depth-stencil view because when we use OMSetRenderTargets to set the render target before using it, it requires also a depth-stencil view. ID3D11RenderTargetView 인터페이스를 사용해 구현되는 렌더링 대상 보기를 통해 렌더링 대상 리소스에 액세스합니다.We access the render target resource through the render target view implemented using the ID3D11RenderTargetView interface.

장치Device

Direct3D 11이 처음인 사용자는 개체를 할당 및 삭제하고 원형을 렌더링하며 그래픽 드라이버를 통해 그래픽 카드와 통신하는 방법으로 디바이스를 생각할 수 있습니다.For those who are new to Direct3D 11, you can imagine a device as a way to allocate and destroy objects, render primitives, and communicate with the graphics card through the graphics driver.

보다 정확하게 설명하자면 Direct3D 디바이스는 Direct3D의 렌더링 구성 요소입니다.For a more precise explanation, a Direct3D device is the rendering component of Direct3D. 디바이스는 렌더링 상태를 캡슐화하여 저장하고, 변환 및 조명 작업을 수행하며, 이미지를 표면에 래스터화합니다.A device encapsulates and stores the rendering state, performs transformations and lighting operations, and rasterizes an image to a surface. 자세한 내용은 디바이스를 참조하세요.For more information, see Devices

디바이스는 ID3D11Device 인터페이스를 통해 표시됩니다.A device is represented by the ID3D11Device interface. 즉, ID3D11Device 인터페이스는 가상 디스플레이 어댑터를 나타내고 디바이스가 소유하는 리소스를 생성하는 데 사용됩니다.In other words, the ID3D11Device interface represents a virtual display adapter and is used to create resources that are owned by a device.

다양한 버전의 ID3D11Device가 있으며, ID3D11Device5는 ID3D11Device4에 새 메서드를 추가한 최신 버전입니다.Note that there are different versions of ID3D11Device, ID3D11Device5 is the latest version and adds new methods to those in ID3D11Device4. Direct3D가 기반 하드웨어와 어떻게 통신하는지에 대한 자세한 내용은 Windows 장치 드라이버 모델(WDDM) 아키텍처를 참조하세요.For more information on how Direct3D communicates with the underlying hardware, see Windows Device Driver Model (WDDM) architecture.

각 응용 프로그램에는 최소 하나의 디바이스가 있어야 하고, 대부분의 응용 프로그램은 오직 하나의 디바이스만 생성합니다.Each application must have at least one device, most applications only create one device. D3D11CreateDevice 또는 D3D11CreateDeviceAndSwapChain 를 호출 하 고 D3D_드라이버_유형 플래그를 사용 하 여 드라이버 유형을 지정 하 여 컴퓨터에 설치 된 하드웨어 드라이버 중 하나에 대 한 장치를 만듭니다.Create a device for one of the hardware drivers installed on your machine by calling D3D11CreateDevice or D3D11CreateDeviceAndSwapChain and specifying the driver type with the D3D_DRIVER_TYPE flag. 각 디바이스는 원하는 기능에 따라 디바이스 컨텍스트를 하나 이상 사용할 수 있습니다.Each device can use one or more device contexts, depending on the functionality desired. 자세한 내용은 D3D11CreateDevice 함수를 참조하세요.For more information, see D3D11CreateDevice function.

디바이스 컨텍스트Device context

디바이스 컨텍스트는 파이프라인 상태를 설정하고 디바이스가 소유하는 리소스를 사용해 렌더링 명령을 생성합니다.A device context is used to set pipeline state and generate rendering commands using the resources owned by a device.

Direct3D 11은 두 가지 유형의 디바이스 컨텍스트를 구현하는데, 하나는 즉각적인 렌더링을 위한 것이고 다른 하나는 지연된 렌더링을 위한 것입니다. 두 컨텍스트 모두 ID3D11DeviceContext 인터페이스를 통해 표시됩니다.Direct3D 11 implements two types of device contexts, one for immediate rendering and the other for deferred rendering; both contexts are represented with an ID3D11DeviceContext interface.

ID3D11DeviceContext 인터페이스는 다양한 버전이 있으며, __ID3D11DeviceContext4__는 __ID3D11DeviceContext3__에 새 메서드를 추가한 버전입니다.The ID3D11DeviceContext interfaces have different versions; ID3D11DeviceContext4 adds new methods to those in ID3D11DeviceContext3.

참고: Windows 10 크리에이터스 업데이트에 도입된 __ID3D11DeviceContext4__는 ID3D11DeviceContext 인터페이스의 최신 버전입니다.Note: ID3D11DeviceContext4 is introduced in the Windows 10 Creators Update and is the latest version of the ID3D11DeviceContext interface. Windows 10 크리에이터스 업데이트를 대상으로 하는 응용 프로그램은 이전 버전이 아니라 이 버전의 인터페이스를 사용해야 합니다.Applications targeting Windows 10 Creators Update should use this interface instead of earlier versions. 자세한 내용은 ID3D11DeviceContext4를 참조하세요.For more information, see ID3D11DeviceContext4.

DX::DeviceResourcesDX::DeviceResources

DX::DeviceResources 클래스는 DeviceResources.cpp/ .h 파일에 존재하며 모든 DirectX 디바이스 리소스를 제어합니다.The DX::DeviceResources class is in the DeviceResources.cpp/.h files and controls all of DirectX device resources. 샘플 게임 프로젝트와 DirectX 11 앱 템플릿 프로젝트에서는 이러한 파일들이 Commons 폴더에 있습니다.In the sample game project and the DirectX 11 App template project, these files are in the Commons folder. Visual Studio 2015 이상에서 DirectX 11 앱 템플릿 프로젝트를 새로 만들 때 이러한 파일의 최신 버전을 얻을 수 있습니다.You can grab the latest version of these files when you create a new DirectX 11 App template project in Visual Studio 2015 or later.

버퍼Buffer

버퍼 리소스는 완벽하게 입력된 데이터를 수집한 것이며 요소로 그룹화됩니다.A buffer resource is a collection of fully typed data grouped into elements. 버퍼를 사용하면 위치 벡터, 법선 벡터, 꼭지점 버퍼의 텍스처 좌표, 인덱스 버퍼의 인덱스, 디바이스 상태 같이 다양한 데이터를 저장할 수 있습니다.You can use buffers to store a wide variety of data, including position vectors, normal vectors, texture coordinates in a vertex buffer, indexes in an index buffer, or device state. 버퍼 요소에는 압축된 데이터 값(R8G8B8A8 표면 값), 8비트 정수 하나 또는 32비트 부동 소수점 값 네 개가 포함될 수 있습니다.Buffer elements can include packed data values (like R8G8B8A8 surface values), single 8-bit integers, or four 32-bit floating point values.

버퍼의 유형은 꼭지점 버퍼, 인덱스 버퍼, 상수 버퍼 등 세 가지입니다.There are three types of buffers available: Vertex buffer, index buffer, and constant buffer.

꼭지점 버퍼Vertex Buffer

기하 도형을 정의하는 데 사용되는 꼭지점 데이터가 포함되어 있습니다.Contains the vertex data used to define your geometry. 꼭지점 데이터에는 위치 좌표, 색상 데이터, 텍스처 좌표 데이터, 법선 데이터 등이 포함되어 있습니다.Vertex data includes position coordinates, color data, texture coordinate data, normal data, and so on.

인덱스 버퍼Index Buffer

꼭지점 버퍼에 대한 정수 오프셋을 포함하며, 원형을 효율적으로 렌더링하는 데 사용됩니다.Contains integer offsets into vertex buffers and are used to render primitives more efficiently. 인덱스 버퍼는 16비트 또는 32비트 인덱스의 순차 집합을 포함하며, 각 인덱스는 꼭짓점 버퍼에서 꼭짓점을 식별하는 데 사용됩니다.An index buffer contains a sequential set of 16-bit or 32-bit indices; each index is used to identify a vertex in a vertex buffer.

상수 버퍼 또는 셰이더 - 상수 버퍼Constant Buffer or shader-constant buffer

파이프라인에 셰이더 데이터를 효율적으로 제공할 수 있도록 해줍니다.Allows you to efficiently supply shader data to the pipeline. 상수 버퍼를 각각의 원형에서 실행되고 렌더링 파이프라인의 스트림 - 출력 단계의 결과를 저장하는 셰이더에 대한 입력으로 사용할 수 있습니다.You can use constant buffers as inputs to the shaders that run for each primitive and store results of the stream-output stage of the rendering pipeline. 개념적으로 상수 버퍼는 단일 요소 꼭지점 버퍼와 상당히 비슷합니다.Conceptually, a constant buffer looks just like a single-element vertex buffer.

버퍼 디자인 및 구현Design and implementation of buffers

데이터 형식에 따라 버퍼를 설계할 수 있습니다. 예를 들면, 게임 샘플에서 정적 데이터를 위한 버퍼와 프레임의 일정한 데이터를 위한 버퍼, 원형과 관련된 데이터를 위한 버퍼를 따로 설계할 수 있습니다.You can design buffers based on the data type, for example, like in our game sample, one buffer is created for static data, another for data that's constant over the frame, and another for data that's specific to a primitive.

ID3D11Buffer 인터페이스에서 모든 버퍼 형식이 캡슐화되므로 __ID3D11Device::CreateBuffer__를 호출하여 버퍼 리소스를 생성할 수 있습니다.All buffer types are encapsulated by the ID3D11Buffer interface and you can create a buffer resource by calling ID3D11Device::CreateBuffer. 하지만 파이프라인에 버퍼를 먼저 바운딩해야 액세스가 가능합니다.But a buffer must be bound to the pipeline before it can be accessed. 읽기를 위해 버퍼를 동시에 여러 개의 파이프라인 단계에 바인딩할 수 있습니다.Buffers can be bound to multiple pipeline stages simultaneously for reading. 쓰기의 경우 단일 파이프라인 단계에 버퍼를 바인딩할 수도 있지만, 동일한 버퍼를 읽기 및 쓰기를 위해 동시에 바인딩할 수 없습니다.A buffer can also be bound to a single pipeline stage for writing; however, the same buffer cannot be bound for reading and writing simultaneously.

버퍼를 다음과 같이 바인딩합니다.Bind buffers to the: * ID3D11DeviceContext::IASetVertexBuffersID3D11DeviceContext::IASetIndexBuffer 같은 ID3D11DeviceContext 메서드를 호출하여 입력 - 어셈블러 단계에 바인딩Input-assembler stage by calling ID3D11DeviceContext methods like ID3D11DeviceContext::IASetVertexBuffers and ID3D11DeviceContext::IASetIndexBuffer * __ID3D11DeviceContext::SOSetTargets__를 호출하여 스트림 - 출력 단계에 바인딩Stream-output stage by calling ID3D11DeviceContext::SOSetTargets * ID3D11DeviceContext::VSSetConstantBuffers 같은 셰이더 메서드를 호출하여 셰이더 단계에 바인딩Shader stage by calling shader methods, like ID3D11DeviceContext::VSSetConstantBuffers

자세한 내용은 Direct3D 11의 버퍼 소개를 참조하세요.For more information, see Introduction to buffers in Direct3D 11.

DXGIDXGI

Microsoft DXGI (DirectX Graphics Infrastructure)는 Direct3D 10, 10.1, 11 및 11.1에 필요한 하위 수준 작업 중 일부를 캡슐화 하는 Windows Vista에 도입 된 새로운 하위 시스템입니다.Microsoft DirectX Graphics Infrastructure (DXGI) is a new subsystem that was introduced with Windows Vista that encapsulates some of the low-level tasks that are needed by Direct3D 10, 10.1, 11, and 11.1. 교착 상태가 발생하지 않도록 하려면 다중 스레딩된 응용 프로그램에서 DXGI를 사용할 때 특히 주의를 기울여야 합니다.Special care must be taken when using DXGI in a multithreaded application to ensure that deadlocks do not occur. 자세한 내용은 DirectX Graphics Infrastructure(DXGI): 모범 사례 - 다중 스레딩을 참조하세요.For more info, see DirectX Graphics Infrastructure (DXGI): Best Practices- Multithreading

기능 수준Feature Level

기능 수준은 도입 신규 및 기존 컴퓨터에서 다양한 비디오 카드를 처리하기 위해 Direct3D 11에 도입된 개념입니다.Feature level is a concept introduced in Direct3D 11 to handle the diversity of video cards in new and existing machines. 기능 수준은 체계적으로 정의된 그래픽 처리 장치(GPU) 기능 집합입니다.A feature level is a well defined set of graphics processing unit (GPU) functionality.

각 비디오 카드는 설치된 GPU에 따라 특정 수준의 DirectX 기능을 구현합니다.Each video card implements a certain level of DirectX functionality depending on the GPUs installed. Microsoft Direct3D의 이전 버전에서는 비디오 카드에 구현된 Direct3D 버전을 찾아서 그에 따라 응용 프로그램을 프로그래밍할 수 있었습니다.In prior versions of Microsoft Direct3D, you could find out the version of Direct3D the video card implemented, and then program your application accordingly.

기능 수준을 사용하면 디바이스를 만들 때 요청하고자 하는 기능 수준에 맞게 디바이스를 생성하려고 시도할 있습니다.With feature level, when you create a device, you can attempt to create a device for the feature level that you want to request. 디바이스 생성이 진행되면 기능 수준이 지원되는 것이고, 그렇지 않으면 하드웨어에서 기능 수준이 지원되지 않는 것입니다.If the device creation works, that feature level exists, if not, the hardware does not support that feature level. 더 낮은 기능 수준에서 디바이스를 다시 생성해 보거나 애플리케이션을 종료하는 방법을 선택할 수 있습니다.You can either try to recreate a device at a lower feature level or you can choose to exit the application. 예를 들어 12_0 기능 수준에는 Direct3D 11.3 또는 Direct3D 12와 셰이더 모델 5.1이 필요 합니다.For instance, the 12_0 feature level requires Direct3D 11.3 or Direct3D 12, and shader model 5.1. 자세한 내용은 Direct3D 기능 수준: 각 기능 수준에 대한 개요를 참조하세요.For more information, see Direct3D feature levels: Overview for each feature level.

기능 수준을 사용 하 여 Direct3D 9, Microsoft Direct3D 10 또는 Direct3D 11 용 응용 프로그램을 개발 하 고 9, 10 또는 11 하드웨어 (몇 가지 예외 포함)에서 실행할 수 있습니다.Using feature levels, you can develop an application for Direct3D 9, Microsoft Direct3D 10, or Direct3D 11, and then run it on 9, 10, or 11 hardware (with some exceptions). 자세한 내용은 Direct3D 기능 수준을 참조하세요.For more information, see Direct3D feature levels.

스테레오 렌더링Stereo rendering

스테레오 렌더링은 깊이 효과를 높이는 데 사용됩니다.Stereo rendering is used to enhance the illusion of depth. 디스플레이 화면에 장면을 표시하기 위해 두 개의 이미지가 사용되는데, 하나는 왼쪽 눈에서 나온 것이고 다른 하나는 오른쪽 눈에서 나온 것입니다.It uses two images, one from the left eye and the other from the right eye to display a scene on the display screen.

수학적으로 보면 깊이 효과를 위해 일반적인 모노 투영 매트릭스에 대해 왼쪽과 오른쪽에 대해 약간의 가로 오프셋이 있는 스테레오 투영 매트릭스를 적용하는 것입니다.Mathematically, we apply a stereo projection matrix, which is a slight horizontal offset to the right and to the left, of the regular mono projection matrix to achieve this.

이 게임 샘플에서는 스테리오 렌더링을 실현하기 위해 두 개의 렌더링 패스를 사용했습니다.We did two rendering passes to achieve stereo rendering in this game sample:

  • 오른쪽 렌더링 대상에 바인딩해서 오른쪽 투영을 적용한 다음, 원형 개체를 그립니다.Bind to right render target, apply right projection, then draw the primitive object.
  • 왼쪽 렌더링 대상에 바인딩해서 왼쪽 투영을 적용한 다음, 원형 개체를 그립니다.Bind to left render target, apply left projection, then draw the primitive object.

카메라 및 좌표 공간Camera and coordinate space

게임에는 고유한 좌표계로 월드(경우에 따라 월드 공간 또는 장면 공간이라고 함)를 업데이트하는 코드가 있습니다.The game has the code in place to update the world in its own coordinate system (sometimes called the world space or scene space). 카메라를 포함한 모든 개체를 이 공간에 배치하고 방향을 지정합니다.All objects, including the camera, are positioned and oriented in this space. 자세한 내용은 좌표계를 참조하세요.For more information, see Coordinate systems.

꼭지점 셰이더는 다음 알고리즘(여기에서 V는 벡터, M은 매트릭스)을 통해 모델 좌표를 디바이스 좌표로 대대적으로 변환합니다.A vertex shader does the heavy lifting of converting from the model coordinates to device coordinates with the following algorithm (where V is a vector and M is a matrix).

V(디바이스) = V(모델) x M(모델 - 월드) x M(월드 - 보기) x M(보기 - 디바이스)V(device) = V(model) x M(model-to-world) x M(world-to-view) x M(view-to-device).

각 항목은 다음을 의미합니다.where:

  • M(모델 - 월드)은 모델 좌표를 월드 좌표로 변환하는 매트릭스로, 월드 변환 매트릭스라고도 합니다.M(model-to-world) is a transformation matrix for model coordinates to world coordinates, also known as the World transform matrix. 이 매트릭스는 원형에서 제공합니다.This is provided by the primitive.
  • M(월드 - 보기)는 월드 좌표를 보기 좌표로 변환하는 매트릭스로, 보기 변환 매트릭스라고도 합니다.M(world-to-view) is a transformation matrix for world coordinates to view coordinates, also known as the View transform matrix.
    • 이 매트릭스는 카메라의 보기 매트릭스에서 제공합니다.This is provided by the view matrix of the camera. 보기 벡터(카메라에서 장면을 직접 가리키는 "정면 보기" 벡터 및 카메라와 수직으로 위쪽을 가리키는 "위 보기" 벡터)와 함께 카메라의 위치에 의해 정의됩니다.It's defined by the camera's position along with the look vectors (the "look at" vector that points directly into the scene from the camera, and the "look up" vector that is upwards perpendicular to it)
    • 샘플 게임에서 m_viewMatrix 는 뷰 변환 매트릭스 이며 Camera:: setviewparams 를 사용 하 여 계산 됩니다.In the sample game, m_viewMatrix is the view transformation matrix and is calculated using Camera::SetViewParams
  • M(보기 - 디바이스)은 보기 좌표를 디바이스 좌표로 변환하는 매트릭스로 투영 변환 매트릭스라고도 합니다.M(view-to-device) is a transformation matrix for view coordinates to device coordinates, also known as the Projection transform matrix
    • 이 매트릭스는 카메라의 투영에서 제공합니다.This is provided by the projection of the camera. 해당 공간에서 어느 정도가 최종 장면에 실제로 표시될 것인지에 대한 정보를 제공합니다.It provides info how much of that space is actually visible in the final scene. 시야각(FoV), 가로 세로 비율 및 클리핑 평면은 투영 변환 매트릭스를 정의합니다.The Field of View (FoV), aspect ratio, and clipping planes define the projection transform matrix.
    • 샘플 게임에서 m_projectionMatrix카메라:: SetProjParams 를 사용 하 여 계산 되는 프로젝션 좌표에 대 한 변환을 정의 합니다. 스테레오 프로젝션의 경우 각 눈동자 보기에 대해 하나씩 두 개의 프로젝션 매트릭스를 사용 합니다.In the sample game, m_projectionMatrix defines transformation to the projection coordinates, calculated using Camera::SetProjParams (For stereo projection, you use two projection matrices: one for each eye's view.)

VertexShader.hlsl의 셰이더 코드는 이러한 벡터 및 매트릭스와 함께 상수 버퍼에서 로드되며, 모든 꼭지점에 대해 이 변환을 수행합니다.The shader code in VertexShader.hlsl is loaded with these vectors and matrices from the constant buffers, and performs this transformation for every vertex.

좌표 변환Coordinate transformation

Direct3D는 3D 모델 좌표를 픽셀 좌표(화면 공간)를 변경하기 위해 세 가지 변환을 사용하고 있습니다.Direct3D uses three transformations to change your 3D model coordinates into pixel coordinates (screen space). 월드 변환, 보기 변환, 투영 변환이 바로 그것입니다.These transformations are world transform, view transform, and projection transform. 자세한 내용은 변환 개요를 참조하세요.For more info, go to Transform overview.

월드 변환 매트릭스World transform matrix

월드 변환은 모델 공간의 좌표(모델의 로컬 원점을 기준으로 꼭지점 정의)를 월드 공간의 좌표(장면의 모든 개체에 공통적인 원점을 기준으로 꼭지점 정의)로 변경합니다.A world transform changes coordinates from model space, where vertices are defined relative to a model's local origin, to world space, where vertices are defined relative to an origin common to all the objects in a scene. 이름에서 알 수 있듯이 기본적으로 월드 변환은 모델을 월드에 배치합니다.In essence, the world transform places a model into the world; hence its name. 자세한 내용은 월드 변환을 참조하세요.For more information, see World transform.

보기 변환 매트릭스View transform matrix

보기 변환은 월드 공간에 뷰어를 배치하여 꼭지점을 카메라 공간으로 변환합니다.The view transform locates the viewer in world space, transforming vertices into camera space. 카메라 공간에서 카메라 또는 뷰어는 원점에 있으며 양의 Z축 방향을 바라봅니다.In camera space, the camera, or viewer, is at the origin, looking in the positive z-direction. 자세한 내용은 보기 변환을 참조하세요.For more info, go to View transform.

투영 변환 매트릭스Projection transform matrix

투영 변환은 절두체 보기를 직육면체 모양으로 변환합니다.The projection transform converts the viewing frustum to a cuboid shape. 절두체 보기는 뷰포트의 카메라를 기준으로 배치되는 장면의 3D 볼륨입니다.A viewing frustum is a 3D volume in a scene positioned relative to the viewport's camera. 뷰포트는 3D 장면이 투영되는 2D 사각형입니다.A viewport is a 2D rectangle into which a 3D scene is projected. 자세한 내용은 뷰포트 및 클리핑을 참조하세요.For more information, see Viewports and clipping

절두체 보기의 가까운 쪽 끝이 먼 쪽 끝보다 작기 때문에 카메라에 가까운 개체를 확대하는 효과가 있습니다. 이것이 장면에 원근이 적용되는 방법입니다.Because the near end of the viewing frustum is smaller than the far end, this has the effect of expanding objects that are near to the camera; this is how perspective is applied to the scene. 따라서 플레이어에 보다 가까운 개체는 더 크게, 먼 개체는 더 작게 표시됩니다.So objects that are closer to the player, appear larger; objects that are further away, appear smaller.

수학적으로 보면 투영 변환은 배율 및 원근감을 모두 투영하는 매트릭스입니다.Mathematically, the projection transform is a matrix that is typically both a scale and perspective projection. 이는 마치 카메라 렌즈처럼 작동합니다.It functions like the lens of a camera. 자세한 내용은 투영 변환을 참조하세요.For more information, see Projection transform.

샘플러 상태Sampler state

샘플러 상태는 텍스처 주소 지정 모드, 필터링 및 상세 수준을 사용하여 텍스처 데이터를 샘플링하는 방법을 결정합니다.Sampler state determines how texture data is sampled using texture addressing modes, filtering, and level of detail. 텍스처에서 텍스처 픽셀(텍셀)을 읽을 때마다 샘플링이 수행됩니다.Sampling is done each time a texture pixel, or texel, is read from a texture.

하나의 텍스처에는 여러 텍셀이 포함되어 있습니다.A texture contains an array of texels, or texture pixels. 각 텍셀의 위치는 (u,v)로 표시되는데, 여기에서 u는 너비를, v는 높이를 나타냅니다. 텍스처 너비 및 높이에 따라 0과 1 사이의 값으로 매핑됩니다.The position of each texel is denoted by (u,v), where u is the width and v is the height, and is mapped between 0 and 1 based on the texture width and height. 그 결과로 나온 텍스처 좌표는 텍스처를 샘플링할 때 텍셀의 주소를 지정하는 데 사용됩니다.The resulting texture coordinates are used to address a texel when sampling a texture.

텍스처 좌표가 0과 1 사이에 있을 때 텍스처 주소 모드는 텍스처 좌표가 텍셀 위치의 주소를 지정하는 방법을 정의합니다.When texture coordinates are below 0 or above 1, the texture address mode defines how the texture coordinate addresses a texel location. 예를 들어 __TextureAddressMode.Clamp__를 사용할 때는 0 ~ 1의 범위를 벗어난 좌표는 샘플링에 앞서 최대 값 1, 최소 값 0으로 고정됩니다.For example, when using TextureAddressMode.Clamp, any coordinate outside the 0-1 range is clamped to a maximum value of 1, and minimum value of 0 before sampling.

텍스처가 다각형에서 너무 크거나 작으면 공간에 맞게 텍스처가 필터링됩니다.If the texture is too large or too small for the polygon, the texture is filtered to fit the space. 확대 필터는 텍스처를 확장하고 축소 필터는 작은 영역에 맞게 텍스처를 축소합니다.A magnification filter enlarges a texture, a minification filter reduces the texture to fit into a smaller area. 텍스처 확대는 하나 이상의 주소에 대해 샘플 텍셀을 반복하기 때문에 이미지가 흐릿해질 수 있습니다.Texture magnification repeats the sample texel for one or more addresses which yields a blurrier image. 텍스처 축소는 하나 이상의 텍셀 값을 단일 값으로 통합해야 한다는 점에서 좀더 복잡합니다.Texture minification is more complicated because it requires combining more than one texel value into a single value. 이로 인해 텍스처 데이터에 따라 가장 자리가 들쭉날쭉 해지는 등 앨리어싱 현상이 발생할 수 있습니다.This can cause aliasing or jagged edges depending on the texture data. 가장 널리 사용되는 축소 접근 방식은 Mipmap을 사용하는 것입니다.The most popular approach for minification is to use a mipmap. Mipmap은 다단계 텍스처입니다.A mipmap is a multi-level texture. 각 단계의 크기는 이전 단계보다 2배 작습니다(최소 1x1 텍스처).The size of each level is a power-of-two smaller than the previous level down to a 1x1 texture. 게임에서 축소 기능이 사용되면 렌더링 시 필요한 크기와 가장 가까운 Mipmap 수준이 선택됩니다.When minification is used, a game chooses the mipmap level closest to the size that is needed at render time.

BasicLoaderBasicLoader

__BasicLoader__는 디스크 상의 파일에서 셰이더, 텍스처 및 메시를 로드할 수 있도록 지원하는 간단한 로더 클래스입니다.BasicLoader is a simple loader class that provides support for loading shaders, textures, and meshes from files on disk. 동기 및 비동기 방법을 모두 제공합니다.It provides both synchronous and asynchronous methods. 이 게임 샘플에서는 BasicLoader.h/.cpp 파일이 Commons 폴더에 있습니다.In this game sample, the BasicLoader.h/.cpp files are found in the Commons folder.

자세한 내용은 기본 로더를 참조하세요.For more information, see Basic Loader.