Gambar ke layar

API Penting

Akhirnya, kami port kode yang menarik kubus berputar ke layar.

Di OpenGL ES 2.0, konteks gambar Anda didefinisikan sebagai jenis EGLContext, yang berisi parameter jendela dan permukaan serta sumber daya yang diperlukan untuk menggambar ke target render yang akan digunakan untuk menyusun gambar akhir yang ditampilkan ke jendela. Anda menggunakan konteks ini untuk mengonfigurasi sumber daya grafis untuk menampilkan hasil alur shader Anda dengan benar di layar. Salah satu sumber daya utama adalah "buffer belakang" (atau "objek penyangga bingkai") yang berisi target render komposit akhir, siap untuk presentasi ke layar.

Dengan Direct3D, proses konfigurasi sumber daya grafis untuk menggambar ke layar lebih didaktik, dan membutuhkan beberapa API lagi. (Template Direct3D Microsoft Visual Studio dapat menyederhanakan proses ini secara signifikan!) Untuk mendapatkan konteks (disebut konteks perangkat Direct3D), Anda harus terlebih dahulu mendapatkan objek ID3D11Device1, dan menggunakannya untuk membuat dan mengonfigurasi objek ID3D11DeviceContext1. Kedua objek ini digunakan bersama untuk mengonfigurasi sumber daya spesifik yang Anda butuhkan untuk menggambar ke layar.

Singkatnya, API DXGI terutama berisi API untuk mengelola sumber daya yang secara langsung berkaitan dengan adaptor grafis, dan Direct3D berisi API yang memungkinkan Anda untuk berinteraksi antara GPU dan program utama Anda yang berjalan pada CPU.

Untuk tujuan perbandingan dalam sampel ini, berikut adalah jenis yang relevan dari setiap API:

  • ID3D11Device1: menyediakan representasi virtual dari perangkat grafis dan sumber dayanya.
  • ID3D11DeviceContext1: menyediakan antarmuka untuk mengonfigurasi buffer dan mengeluarkan perintah rendering.
  • IDXGISwapChain1: rantai swap analog dengan buffer belakang di OpenGL ES 2.0. Ini adalah wilayah memori pada adaptor grafis yang berisi gambar yang dirender akhir untuk ditampilkan. Ini disebut "rantai swap" karena memiliki beberapa buffer yang dapat ditulis dan "ditukar" untuk menyajikan render terbaru ke layar.
  • ID3D11RenderTargetView: ini berisi buffer bitmap 2D yang ditarik ke dalam konteks perangkat Direct3D, dan yang disajikan oleh rantai swap. Seperti OpenGL ES 2.0, Anda dapat memiliki beberapa target render, beberapa di antaranya tidak terikat pada rantai swap tetapi digunakan untuk teknik shading multi-pass.

Dalam templat, objek perender berisi bidang berikut:

Direct3D 11: Deklarasi konteks perangkat dan perangkat

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;

Berikut adalah bagaimana buffer belakang dikonfigurasi sebagai target render dan disediakan untuk rantai swap.

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

Runtime Direct3D secara implisit membuat IDXGISurface1 untuk ID3D11Texture2D, yang mewakili tekstur sebagai "buffer belakang" yang dapat digunakan rantai swap untuk ditampilkan.

Inisialisasi dan konfigurasi perangkat Direct3D dan konteks perangkat, serta target render, dapat ditemukan di metode CreateDeviceResources dan CreateWindowSizeDependentResources kustom dalam template Direct3D.

Untuk info lebih lanjut tentang konteks perangkat Direct3D yang berkaitan dengan EGL dan tipe EGLContext, baca kode Port EGL ke DXGI dan Direct3D.

Instruksi

Langkah 1: Merender adegan dan menampilkannya

Setelah memperbarui data kubus (dalam hal ini, dengan memutarnya sedikit di sekitar sumbu y), metode Render menetapkan viewport ke dimensi konteks gambarnya (EGLContext). Konteks ini berisi buffer warna yang akan ditampilkan ke permukaan jendela (EGLSurface), menggunakan tampilan yang dikonfigurasi (EGLDisplay). Pada saat ini, contoh memperbarui atribut data simpul, mengikat kembali buffer indeks, menggambar kubus, dan menukar buffer warna yang digambar oleh pipa bayangan ke permukaan tampilan.

OpenGL ES 2.0: Merender bingkai untuk ditampilkan

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);
}

Dalam Direct3D 11, prosesnya sangat mirip. (Kami berasumsi bahwa Anda menggunakan viewport dan merender konfigurasi target dari templat Direct3D.

Direct3D 11: Merender bingkai untuk ditampilkan

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);
}

Setelah IDXGISwapChain1::P resent1 dipanggil, bingkai Anda akan keluar ke layar yang dikonfigurasi.

Langkah sebelumnya

Pelabuhan GLSL

Keterangan

Contoh ini mengabaikan banyak kompleksitas yang masuk ke dalam konfigurasi sumber daya perangkat, terutama untuk aplikasi DirectX Universal Windows Platform (UWP). Kami sarankan Anda meninjau kode template lengkap, terutama bagian-bagian yang melakukan pengaturan dan manajemen sumber daya jendela dan perangkat. Aplikasi UWP harus mendukung peristiwa rotasi serta menangguhkan / melanjutkan acara, dan template menunjukkan praktik terbaik untuk menangani hilangnya antarmuka atau perubahan parameter tampilan.