共用方式為


繪製到螢幕

重要 API

最後,我們將繪製旋轉立方結構的程式碼移植到螢幕上。

在 OpenGL ES 2.0 中,繪圖背景內容定義為 EGLContext 型別,該型別包含視窗和曲面參數以及繪製到渲染目標所需的資源,該渲染目標將用來構成顯示在視窗中的最終影像。 您可以使用此前後關聯來設定圖形資源,以正確顯示著色器流程的結果。 其中一個主要資源是後緩衝器 (或幀緩衝器物件),它包含最終的複合渲染目標,準備呈現給顯示器。

在 Direct3D 中,配置繪圖到顯示器的圖形資源的過程更加說教,並且需要相當多的 API。 (不過,Microsoft Visual Studio Direct3D 範本可大幅簡化此程式!)若要取得內容 (稱為 Direct3D 裝置內容),您必須先取得 ID3D11Device1 物件,然後使用它來建立和設定 ID3D11DeviceContext1 物件。 這兩個物件可搭配使用,以設定繪圖至顯示所需的特定資源。

簡而言之,DXGI API 主要包含用於管理直接與圖形介面卡相關的資源的 API,而 Direct3D 包含允許在 GPU 和在 CPU 上運行的主程式之間進行介面的 API。

為便於在本範例中比較,以下是每個 API 的相關型別:

在範本中,轉譯器物件包含下列欄位:

Direct3D 11:裝置和裝置內容宣告

Platform::Agile<Windows::UI::Core::CoreWindow>       m_window;

Microsoft::WRL::ComPtr<ID3D11Device1>                m_d3dDevice;
Microsoft::WRL::ComPtr<ID3D11DeviceContext1>          m_d3dContext;
Microsoft::WRL::ComPtr<IDXGISwapChain1>                      m_swapChainCoreWindow;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView>          m_d3dRenderTargetViewWin;

下面說明如何將後緩衝器配置為呈現目標並提供給交換鏈。

ComPtr<ID3D11Texture2D> backBuffer;
m_swapChainCoreWindow->GetBuffer(0, IID_PPV_ARGS(backBuffer));
m_d3dDevice->CreateRenderTargetView(
  backBuffer.Get(),
  nullptr,
  &m_d3dRenderTargetViewWin);

Direct3D 執行階段會為 ID3D11Texture2D,隱含建立 IDXGI Surface1,此表示紋理為交換鏈可用於顯示的後緩衝區。

您可以在 Direct3D 範本的自訂 CreateDeviceResources 和 CreateWindowSizeDependentResources 方法中找到 Direct3D 裝置和裝置前後關聯的初始化和設定,以及轉譯目標。

如需有關 Direct3D 裝置前後關聯與 EGL 和 EGLContext 型別的詳細資訊,請閱讀 Port EGL 程式碼至 DXGI 和 Direct3D。

指示

步驟 1:呈現場景並顯示它

更新立方結構資料後 (在此例中,略微繞 y 軸旋轉),Render 方法會將視角設定為工程圖前後關聯 (EGLContext) 的尺寸。 此內容包含使用設定的顯示 (EGLDisplay) 顯示到視窗表面 (EGLSurface) 的色彩緩衝區。 此時,範例會更新頂點資料屬性、重新繫結索引緩衝區、繪製立方結構,以及將著色器流程所繪製的色彩緩衝區交換至顯示曲面。

OpenGL ES 2.0:轉譯顯示畫面

void Render(GraphicsContext *drawContext)
{
  Renderer *renderer = drawContext->renderer;

  int loc;
   
  // Set the viewport
  glViewport ( 0, 0, drawContext->width, drawContext->height );
   
   
  // Clear the color buffer
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glEnable(GL_DEPTH_TEST);


  // Use the program object
  glUseProgram (renderer->programObject);

  // Load the a_position attribute with the vertex position portion of a vertex buffer element
  loc = glGetAttribLocation(renderer->programObject, "a_position");
  glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 
      sizeof(Vertex), 0);
  glEnableVertexAttribArray(loc);

  // Load the a_color attribute with the color position portion of a vertex buffer element
  loc = glGetAttribLocation(renderer->programObject, "a_color");
  glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, 
      sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
  glEnableVertexAttribArray(loc);

  // Bind the index buffer
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderer->indexBuffer);

  // Load the MVP matrix
  glUniformMatrix4fv(renderer->mvpLoc, 1, GL_FALSE, (GLfloat*) &renderer->mvpMatrix.m[0][0]);

  // Draw the cube
  glDrawElements(GL_TRIANGLES, renderer->numIndices, GL_UNSIGNED_INT, 0);

  eglSwapBuffers(drawContext->eglDisplay, drawContext->eglSurface);
}

在 Direct3D 11 中,過程非常相似。 (我們假設您使用視角並從 Direct3D 範本轉譯目標組態。

Direct3D 11:呈現用於顯示的框架

void RenderObject::Render()
{
  // ...

  // Only update shader resources that have changed since the last frame.
  m_d3dContext->UpdateSubresource(
    m_constantBuffer.Get(),
    0,
    NULL,
    &m_constantBufferData,
    0,
    0);

  // Set up the IA stage corresponding to the current draw operation.
  UINT stride = sizeof(VertexPositionColor);
  UINT offset = 0;
  m_d3dContext->IASetVertexBuffers(
    0,
    1,
    m_vertexBuffer.GetAddressOf(),
    &stride,
    &offset);

  m_d3dContext->IASetIndexBuffer(
    m_indexBuffer.Get(),
    DXGI_FORMAT_R16_UINT,
    0);

  m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  m_d3dContext->IASetInputLayout(m_inputLayout.Get());

  // Set up the vertex shader corresponding to the current draw operation.
  m_d3dContext->VSSetShader(
    m_vertexShader.Get(),
    nullptr,
    0);

  m_d3dContext->VSSetConstantBuffers(
    0,
    1,
    m_constantBuffer.GetAddressOf());

  // Set up the pixel shader corresponding to the current draw operation.
  m_d3dContext->PSSetShader(
    m_pixelShader.Get(),
    nullptr,
    0);

  m_d3dContext->DrawIndexed(
    m_indexCount,
    0,
    0);

    // ...

  m_swapChainCoreWindow->Present1(1, 0, &parameters);
}

呼叫 IDXGI SwapChain1::Present1 後,您的畫面會輸出到設定的顯示器。

上一步

移植 GLSL

備註

這個範例掩蓋配置裝置資源所花費的複雜程度,特別是針對 Universal Windows Platform (UWP) DirectX 應用程式。 我們建議您檢閱完整的範本程式碼,尤其是執行視窗與裝置資源設定與管理的零件。 UWP 應用程式必須支援旋轉事件以及暫停/恢復事件,範本示範處理介面遺失或顯示參數變更的最佳作法。