Partager via


Dessiner sur l’écran

API importantes

Enfin, nous portons le code qui dessine le cube épinglant à l’écran.

Dans OpenGL ES 2.0, votre contexte de dessin est défini comme un type EGLContext, qui contient les paramètres de fenêtre et de surface, ainsi que les ressources nécessaires pour dessiner sur les cibles de rendu qui seront utilisées pour composer l’image finale affichée dans la fenêtre. Vous utilisez ce contexte pour configurer les ressources graphiques pour afficher correctement les résultats de votre pipeline de nuanceur sur l’affichage. L’une des ressources principales est la « mémoire tampon de retour » (ou l’objet de mémoire tampon de trame) qui contient les cibles de rendu finales composites, prêtes pour la présentation à l’affichage.

Avec Direct3D, le processus de configuration des ressources graphiques pour dessiner sur l’affichage est plus didactique et nécessite quelques API supplémentaires. (Un modèle Microsoft Visual Studio Direct3D peut simplifier considérablement ce processus, cependant !) Pour obtenir un contexte (appelé contexte d’appareil Direct3D), vous devez d’abord obtenir un objet ID3D11Device1, puis l’utiliser pour créer et configurer un objet ID3D11DeviceContext1. Ces deux objets sont utilisés conjointement pour configurer les ressources spécifiques dont vous avez besoin pour dessiner sur l’affichage.

En bref, les API DXGI contiennent principalement des API pour la gestion des ressources qui se rapportent directement à la carte graphique, et Direct3D contient les API qui vous permettent d’interagir entre le GPU et votre programme principal s’exécutant sur l’UC.

Pour les besoins de comparaison dans cet exemple, voici les types pertinents de chaque API :

  • ID3D11Device1 : fournit une représentation virtuelle de l’appareil graphique et de ses ressources.
  • ID3D11DeviceContext1 : fournit l’interface pour configurer des mémoires tampons et émettre des commandes de rendu.
  • IDXGISwapChain1 : la chaîne d’échange est analogue à la mémoire tampon arrière dans OpenGL ES 2.0. Il s’agit de la région de mémoire sur l’adaptateur graphique qui contient la ou les images rendues finales pour l’affichage. Il est appelé « chaîne d’échange », car il a plusieurs mémoires tampons qui peuvent être écrites dans et « permutées » pour présenter le rendu le plus récent à l’écran.
  • ID3D11RenderTargetView : contient la mémoire tampon bitmap 2D dans laquelle le contexte d’appareil Direct3D s’inscrit et qui est présenté par la chaîne d’échange. Comme avec OpenGL ES 2.0, vous pouvez avoir plusieurs cibles de rendu, dont certaines ne sont pas liées à la chaîne d’échange, mais sont utilisées pour les techniques d’ombrage multi-passe.

Dans le modèle, l’objet renderer contient les champs suivants :

Direct3D 11 : Déclarations de contexte d’appareil et d’appareil

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;

Voici comment la mémoire tampon de retour est configurée en tant que cible de rendu et fournie à la chaîne d’échange.

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

Le runtime Direct3D crée implicitement un IDXGISurface1 pour l’ID3D11Texture2D, qui représente la texture en tant que « mémoire tampon back » que la chaîne d’échange peut utiliser pour l’affichage.

L’initialisation et la configuration du contexte d’appareil et d’appareil Direct3D, ainsi que les cibles de rendu, sont disponibles dans les méthodes CreateDeviceResources et CreateWindowSizeDependentResources personnalisées dans le modèle Direct3D.

Pour plus d’informations sur le contexte d’appareil Direct3D, car il est lié à EGL et au type EGLContext, lisez le code EGL du port vers DXGI et Direct3D.

Instructions

Étape 1 : Rendu de la scène et affichage de celle-ci

Après avoir mis à jour les données de cube (dans ce cas, en la faisant pivoter légèrement autour de l’axe y), la méthode Render définit la fenêtre d’affichage sur les dimensions du contexte de dessin (un EGLContext). Ce contexte contient la mémoire tampon de couleur qui s’affiche sur l’aire de fenêtre (un EGLSurface), à l’aide de l’affichage configuré (EGLDisplay). À ce stade, l’exemple met à jour les attributs de données de vertex, lie à nouveau la mémoire tampon d’index, dessine le cube et permute la mémoire tampon de couleur dessinée par le pipeline d’ombrage vers l’aire d’affichage.

OpenGL ES 2.0 : rendu d’un cadre pour l’affichage

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

Dans Direct3D 11, le processus est très similaire. (Nous partons du principe que vous utilisez la fenêtre d’affichage et affichez la configuration cible à partir du modèle Direct3D.

Direct3D 11 : Rendu d’un cadre pour l’affichage

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

Une fois que IDXGISwapChain1 ::P resent1 est appelé, votre frame est généré dans l’affichage configuré.

Étape précédente

Porter le langage GLSL

Notes

Cet exemple illustre une grande partie de la complexité de la configuration des ressources d’appareil, en particulier pour les applications DirectX (UWP) plateforme Windows universelle. Nous vous suggérons de passer en revue le code de modèle complet, en particulier les parties qui effectuent la configuration et la gestion des ressources de fenêtre et d’appareil. Les applications UWP doivent prendre en charge les événements de rotation, ainsi que les événements de suspension/reprise, et le modèle illustre les meilleures pratiques de gestion de la perte d’une interface ou d’une modification des paramètres d’affichage.