Поделиться через


Рисование на экране

Важные API

Наконец, мы переносим код, который рисует куб спиннинга на экран.

В OpenGL ES 2.0 контекст рисования определяется как тип EGLContext, содержащий параметры окна и поверхности, а также ресурсы, необходимые для рисования целевых объектов отрисовки, которые будут использоваться для создания окончательного изображения, отображаемого в окне. Этот контекст используется для настройки графических ресурсов для правильного отображения результатов конвейера шейдера на экране. Одним из основных ресурсов является "обратный буфер" (или "объект буфера кадра"), который содержит окончательные, составные целевые объекты отрисовки, готовые к презентации на экране.

При использовании Direct3D процесс настройки графических ресурсов для рисования на дисплее является более дидактичным и требует довольно нескольких API. (Шаблон Microsoft Visual Studio Direct3D может значительно упростить этот процесс, хотя!) Чтобы получить контекст (называемый контекстом устройства Direct3D), необходимо сначала получить объект ID3D11Device1 и использовать его для создания и настройки объекта ID3D11DeviceContext1. Эти два объекта используются совместно для настройки определенных ресурсов, необходимых для рисования на экране.

Короче говоря, API DXGI содержат в основном API-интерфейсы для управления ресурсами, которые непосредственно относятся к графическому адаптеру, а Direct3D содержит ИНТЕРФЕЙСы API, которые позволяют интерфейсировать между GPU и основной программой, работающей на ЦП.

Для сравнения в этом примере приведены соответствующие типы из каждого API:

  • ID3D11Device1: предоставляет виртуальное представление графического устройства и его ресурсов.
  • ID3D11DeviceContext1: предоставляет интерфейс для настройки буферов и команд отрисовки проблем.
  • IDXGISwapChain1: цепочка буферов аналогична обратному буферу в OpenGL ES 2.0. Это область памяти на графическом адаптере, который содержит окончательные отрисованные изображения для отображения. Он называется "цепочкой буферов", так как он имеет несколько буферов, которые можно записать в и "переключить", чтобы представить последнюю отрисовку на экране.
  • ID3D11RenderTargetView: он содержит буфер 2D-растрового изображения, в который вставляется контекст устройства Direct3D, и который представлен цепочкой буферов. Как и в Случае с OpenGL ES 2.0, вы можете иметь несколько целевых объектов отрисовки, некоторые из которых не привязаны к цепочке буферов, но используются для многопроходных методов заливки.

В шаблоне объект отрисовщика содержит следующие поля:

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 неявно создает идентификатор IDXGISurface1 для ID3D11Texture2D, который представляет текстуру в виде "обратного буфера", который цепочка буферов может использовать для отображения.

Инициализация и настройка контекста устройства Direct3D, а также целевых объектов отрисовки можно найти в пользовательских методах CreateDeviceResources и CreateWindowSizeDependentResources в шаблоне Direct3D.

Дополнительные сведения о контексте устройства Direct3D, связанном с EGL и типом EGLContext, см . код порта EGL в DXGI и Direct3D.

Instructions

Шаг 1. Отрисовка сцены и его отображение

После обновления данных куба (в данном случае, вращая его немного вокруг оси y), метод Render задает окно просмотра измерениям контекста рисования (EGLContext). Этот контекст содержит буфер цвета, который будет отображаться на поверхности окна (EGLSurface), с помощью настроенного дисплея (EGLDisplay). В настоящее время пример обновляет атрибуты данных вершин, повторно привязывает буфер индекса, рисует куб и переключает цветовый буфер, нарисованный конвейером заливки на поверхность отображения.

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

После вызова IDXGISwapChain1::P resent1 кадр выводится в настроенное отображение.

Предыдущий шаг

Перенос GLSL

Замечания

В этом примере рассматривается большая сложность настройки ресурсов устройств, особенно для приложений DirectX универсальная платформа Windows (UWP). Мы рекомендуем просмотреть полный код шаблона, особенно части, которые выполняют настройку и управление ресурсами устройства. Приложения UWP должны поддерживать события поворота, а также события приостановки и возобновления работы, а шаблон демонстрирует рекомендации по обработке потери интерфейса или изменения параметров отображения.