Compartir a través de


Dibujar en la pantalla

Las APIs importantes

Por último, portamos el código que dibuja el cubo giratorio a la pantalla.

En OpenGL ES 2.0, el contexto de dibujo se define como un tipo EGLContext, que contiene los parámetros de ventana y superficie, así como los recursos necesarios para dibujar en los destinos de representación que se usarán para componer la imagen final mostrada en la ventana. Utilizas este contexto para configurar los recursos gráficos y mostrar correctamente los resultados de la canalización de sombreado en la pantalla. Uno de los recursos principales es el "buffer de fondo" (o "frame buffer object") que contiene los objetivos finales de renderizado compuestos, preparados para presentarse en la pantalla.

Con Direct3D, el proceso de configurar los recursos gráficos para dibujar en la pantalla es más didáctico y requiere bastantes más APIs. (Sin embargo, una plantilla de Microsoft Visual Studio Direct3D puede simplificar significativamente este proceso). Para obtener un contexto (denominado contexto de dispositivo Direct3D), primero debe obtener un objeto ID3D11Device1 y usarlo para crear y configurar un objeto ID3D11DeviceContext1. Estos dos objetos se usan junto con para configurar los recursos específicos que necesita para dibujar en la pantalla.

En resumen, las API DXGI contienen principalmente API para administrar recursos que pertenecen directamente al adaptador de gráficos y Direct3D contiene las API que permiten interactuar entre la GPU y el programa principal que se ejecuta en la CPU.

Para los fines de la comparación en este ejemplo, estos son los tipos pertinentes de cada API:

  • id3D11Device1: proporciona una representación virtual del dispositivo gráfico y sus recursos.
  • id3D11DeviceContext1: proporciona la interfaz para configurar búferes y emitir comandos de representación.
  • IDXGISwapChain1: la cadena de intercambio es análoga al búfer de reserva en OpenGL ES 2.0. Es la región de memoria del adaptador de gráficos que contiene las imágenes representadas finales para mostrar. Se denomina "cadena de intercambio" porque tiene varios búferes en los que se puede escribir y "cambiar" para presentar el renderizado más reciente en la pantalla.
  • ID3D11RenderTargetView: contiene el búfer de mapa de bits 2D en el que se dibuja el contexto del dispositivo Direct3D y que presenta la cadena de intercambio. Al igual que con OpenGL ES 2.0, puede tener varios objetivos de renderizado, algunos de los cuales no están vinculados a la cadena de intercambio, pero se utilizan para técnicas de sombreado de varios pasos.

En la plantilla, el objeto de representador contiene los siguientes campos:

Direct3D 11: declaraciones de dispositivo y contexto de dispositivo

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;

Aquí se configura el búfer de reserva como un objetivo de renderizado y se integra en la cadena de intercambio.

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

El tiempo de ejecución de Direct3D crea implícitamente un IDXGISurface1 para el ID3D11Texture2D, que representa la textura como un "búfer de respaldo" que la cadena de intercambio de imágenes puede usar para mostrar.

La inicialización y configuración del dispositivo Direct3D y su contexto de dispositivo, así como los destinos de representación, se pueden encontrar en los métodos personalizados CreateDeviceResources y CreateWindowSizeDependentResources en la plantilla Direct3D.

Para obtener más información sobre el contexto del dispositivo Direct3D en relación con EGL y el tipo EGLContext, consulte la sección sobre cómo portar código EGL a DXGI y Direct3D.

Instrucciones

Paso 1: Representar la escena y mostrarla

Después de actualizar los datos del cubo (en este caso, girando ligeramente alrededor del eje Y), el método Render establece la ventanilla en las dimensiones del contexto de dibujo (un EGLContext). Este contexto contiene el búfer de colores que se mostrará en la superficie de la ventana (un EGLSurface), mediante la pantalla configurada (EGLDisplay). Actualmente, el ejemplo actualiza los atributos de datos de vértices, vuelve a enlazar el búfer de índices, dibuja el cubo e intercambia el búfer de color generado por la canalización de sombreado para la superficie de visualización.

OpenGL ES 2.0: Representación de un marco para mostrar

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

En Direct3D 11, el proceso es muy similar. (Suponiendo que estás utilizando la configuración de vista y de destino de renderizado de la plantilla de Direct3D.

Direct3D 11: Representación de un marco para mostrar

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

Una vez se llama a IDXGISwapChain1::P resent1, el marco se genera en la pantalla configurada.

Paso anterior

Portar el GLSL

Observaciones

En este ejemplo se pasa por alto gran parte de la complejidad que entra en la configuración de los recursos del dispositivo, especialmente para aplicaciones DirectX de la Plataforma Universal de Windows (UWP). Se recomienda revisar el código de plantilla completo, especialmente las partes que realizan la configuración y administración de recursos de dispositivo y ventana. Las aplicaciones para UWP tienen que admitir eventos de rotación, así como eventos de suspensión y reanudación, y la plantilla muestra los procedimientos recomendados para controlar la pérdida de una interfaz o un cambio en los parámetros de visualización.