Dibujar en la pantallaDraw to the screen

API importantesImportant APIs

Por fin hemos portado el código que dibuja un cubo giratorio en la pantalla.Finally, we port the code that draws the spinning cube to the screen.

En OpenGL ES 2.0, el contexto de dibujo se define como un tipo EGLContext que contiene los parámetros de superficie y ventana, así como los recursos necesarios para dibujar los destinos de representación que se usarán para componer la imagen final.In OpenGL ES 2.0, your drawing context is defined as an EGLContext type, which contains the window and surface parameters as well the resources necessary for drawing to the render targets that will be used to compose the final image displayed to the window. Usas este contexto para configurar los recursos gráficos, de modo tal que los resultados de la canalización de sombreador se muestren correctamente en pantalla.You use this context to configure the graphics resources to correctly display the results of your shader pipeline on the display. Uno de los recursos principales es el "búfer de reserva" (u "objeto de búfer de trama") que contiene los destinos de representación compuestos y finales, listos para la presentación en pantalla.One of the primary resources is the "back buffer" (or "frame buffer object") that contains the final, composited render targets, ready for presentation to the display.

Con Direct3D, el proceso de configurar los recursos de gráficos para dibujar en la pantalla es más didáctico y requiere pocas API adicionales.With Direct3D, the process of configuring the graphics resources for drawing to the display is more didactic, and requires quite a few more APIs. (Pero recuerda que una plantilla Direct3D de Microsoft Visual Studio puede simplificar de manera significativa este proceso). Para obtener un contexto (denominado contexto de dispositivo Direct3D), primero debes obtener un objeto ID3D11Device1 y usarlo para crear y configurar un objeto ID3D11DeviceContext1.(A Microsoft Visual Studio Direct3D template can significantly simplify this process, though!) To obtain a context (called a Direct3D device context), you must first obtain an ID3D11Device1 object, and use it to create and configure an ID3D11DeviceContext1 object. Estos dos objetos se usan en conjunto para configurar los recursos específicos que necesitas para dibujar en pantalla.These two objects are used in conjunction to configure the specific resources you need for drawing to the display.

En menos palabras, las API de DXGI contienen sobre todo varias API para administrar recursos que directamente pertenecen al adaptador de gráficos y Direct3D contiene las API para una interfaz entre la GPU y tu programa principal que se ejecuta en la CPU. In short, the DXGI APIs contain primarily APIs for managing resources that directly pertain to the graphics adapter, and Direct3D contains the APIs that allow you to interface between the GPU and your main program running on the CPU.

Para que podamos hacer comparaciones en nuestra muestra, estos son los tipos relevantes de cada API:For the purposes of comparison in this sample, here are the relevant types from each API:

  • ID3D11Device1: proporciona una representación visual del dispositivo de gráficos y sus recursos.ID3D11Device1: provides a virtual representation of the graphics device and its resources.
  • ID3D11DeviceContext1: proporciona la interfaz para configurar búferes y emitir comandos de representación.ID3D11DeviceContext1: provides the interface to configure buffers and issue rendering commands.
  • IDXGISwapChain1: la cadena de intercambio es análoga al búfer de reserva en OpenGL ES 2.0.IDXGISwapChain1: the swap chain is analogous to the back buffer in OpenGL ES 2.0. Es la región de la memoria en el adaptador de gráficos que contiene las imágenes finales de representación para mostrar.It is the region of memory on the graphics adapter that contains the final rendered image(s) for display. Se denomina "cadena de intercambio" porque tiene varios búferes que pueden escribirse e "intercambiarse" para presentar la representación más reciente en pantalla.It is called the "swap chain" because it has several buffers that can be written to and "swapped" to present the latest render to the screen.
  • ID3D11RenderTargetView: contiene el búfer del mapa de bits 2D donde el contexto del dispositivo Direct3D dibuja y, además, presenta la cadena de intercambio.ID3D11RenderTargetView: this contains the 2D bitmap buffer that the Direct3D device context draws into, and which is presented by the swap chain. Al igual que con OpenGL ES 2.0, puedes tener varios destinos de representación. Algunos de ellos no se enlazan a la cadena de intercambio, pero se usan para técnicas de sombreado de varios pases.As with OpenGL ES 2.0, you can have multiple render targets, some of which are not bound to the swap chain but are used for multi-pass shading techniques.

En la plantilla, el objeto de representador contiene estos campos:In the template, the renderer object contains the following fields:

Direct3D 11: declaraciones de dispositivo y contexto de dispositivoDirect3D 11: Device and device context declarations

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;

Analiza este ejemplo para saber cómo se configura un búfer de reserva como destino de representación y cómo se proporciona a la cadena de intercambio.Here's how the back buffer is configured as a render target and provided to the swap chain.

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 una interfaz IDXGISurface1 para ID3D11Texture2D; esta representa la textura como un "búfer de reserva", para que así la cadena de intercambio pueda mostrarla.The Direct3D runtime implicitly creates an IDXGISurface1 for the ID3D11Texture2D, which represents the texture as a "back buffer" that the swap chain can use for display.

La inicialización y la configuración del dispositivo Direct3D, el contexto del dispositivo y los destinos de representación, pueden enlazarse en los métodos personalizados CreateDeviceResources y CreateWindowSizeDependentResources de la plantilla Direct3D.The initialization and configuration of the Direct3D device and device context, as well as the render targets, can be found in the custom CreateDeviceResources and CreateWindowSizeDependentResources methods in the Direct3D template.

Para obtener más información sobre el contexto de dispositivo de Direct3D en lo que se refiere a EGL y al tipo EGLContext, lea el código EGL de puerto para DXGI y Direct3D.For more info on Direct3D device context as it relates to EGL and the EGLContext type, read Port EGL code to DXGI and Direct3D.

InstructionsInstructions

Paso 1: representar la escena y mostrarlaStep 1: Rendering the scene and displaying it

Después de actualizar los datos del cubo (en este caso, al girarlo levemente alrededor del eje y), el método Render establece la ventanilla en las dimensiones del contexto de dibujo (un elemento EGLContext).After updating the cube data (in this case, by rotating it slightly around the y axis), the Render method sets the viewport to the dimensions of he drawing context (an EGLContext). Este contexto contiene el búfer de color que se mostrará en la superficie de la ventana (un EGLSurface), usando la pantalla configurada (EGLDisplay).This context contains the color buffer that will be displayed to the window surface (an EGLSurface), using the configured display (EGLDisplay). Esta vez el ejemplo actualiza los atributos de datos de vértice, reenlaza el búfer de índices, dibuja el cubo y realiza el intercambio en el búfer de color dibujado por la canalización de sombreado en la superficie de pantalla.At this time, the example updates the vertex data attributes, re-binds the index buffer, draws the cube, and swaps in color buffer drawn by the shading pipeline to the display surface.

OpenGL ES 2.0: representar un marco para mostrarOpenGL ES 2.0: Rendering a frame for display

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.In Direct3D 11, the process is very similar. (Suponemos que estás usando la ventanilla y la configuración del destino de representación de la plantilla Direct3D).(We're assuming that you're using the viewport and render target configuration from the Direct3D template.

Direct3D 11: representar un marco para mostrarDirect3D 11: Rendering a frame for display

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 realizada la llamada a IDXGISwapChain1::Present1, el marco aparece en la pantalla configurada.Once IDXGISwapChain1::Present1 is called, your frame is output to the configured display.

Paso anteriorPrevious step

Migrar GLSLPort the GLSL

ObservacionesRemarks

Este ejemplo pasa por alto gran parte de la complejidad que implica configurar los recursos del dispositivo, en especial aplicaciones DirectX para la Plataforma universal de Windows (UWP).This example glosses over much of the complexity that goes into configuring device resources, especially for Universal Windows Platform (UWP) DirectX apps. Sugerimos que revises el código completo de la plantilla, sobre todo las partes encargadas de la administración y configuración de recursos de dispositivo y ventana.We suggest you review the full template code, especially the parts that perform the window and device resource setup and management. Las aplicaciones para UWP tienen que admitir tanto eventos de rotación como eventos de suspensión y reanudación. Asimismo, la plantilla muestra los procedimientos recomendados para controlar la pérdida de una interfaz o un cambio en los parámetros de la pantalla.UWP apps have to support rotation events as well as suspend/resume events, and the template demonstrates best practices for handling the loss of an interface or a change in the display parameters.