Gambar ke layar

API penting

Akhirnya, kita port kode yang menggambar 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 pada tampilan. Salah satu sumber daya utama adalah "buffer belakang" (atau "objek buffer bingkai") yang berisi target render akhir yang dikomposisikan, siap untuk presentasi ke tampilan.

Dengan Direct3D, proses mengonfigurasi sumber daya grafis untuk menggambar ke layar lebih didactic, dan membutuhkan beberapa API lagi. (Templat Microsoft Visual Studio Direct3D dapat secara signifikan menyederhanakan proses ini!) 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 bersamaan untuk mengonfigurasi sumber daya tertentu 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 di CPU.

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

  • ID3D11Device1: menyediakan representasi virtual perangkat grafis dan sumber dayanya.
  • ID3D11DeviceContext1: menyediakan antarmuka untuk mengonfigurasi buffer dan perintah penyajian masalah.
  • IDXGISwapChain1: rantai pertukaran dianalogikan dengan buffer belakang di OpenGL ES 2.0. Ini adalah wilayah memori pada adaptor grafis yang berisi gambar akhir yang dirender untuk ditampilkan. Ini disebut "rantai pertukaran" karena memiliki beberapa buffer yang dapat ditulis dan "ditukar" untuk menyajikan render terbaru ke layar.
  • ID3D11RenderTargetView: ini berisi buffer bitmap 2D yang ditarik konteks perangkat Direct3D, dan yang disajikan oleh rantai pertukaran. Seperti halnya OpenGL ES 2.0, Anda dapat memiliki beberapa target render, beberapa di antaranya tidak terikat dengan rantai pertukaran tetapi digunakan untuk teknik bayangan 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 pertukaran.

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 pertukaran untuk tampilan.

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

Untuk informasi selengkapnya tentang konteks perangkat Direct3D karena berkaitan dengan EGL dan jenis EGLContext, baca Kode Port EGL ke DXGI dan Direct3D.

Petunjuk

Langkah 1: Merender adegan dan menampilkannya

Setelah memperbarui data kubus (dalam hal ini, dengan memutarnya sedikit di sekitar sumbu y), metode Render mengatur viewport ke dimensi konteks gambarnya (EGLContext). Konteks ini berisi buffer warna yang akan ditampilkan ke permukaan jendela (EGLSurface), menggunakan tampilan yang dikonfigurasi (EGLDisplay). Saat ini, contoh memperbarui atribut data vertex, mengikat kembali buffer indeks, menggambar kubus, dan menukar dalam buffer warna yang digambar oleh alur 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 tampilan

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 adalah output ke tampilan yang dikonfigurasi.

Langkah sebelumnya

Port the GLSL

Keterangan

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