Zeichnen auf dem Bildschirm
Wichtige APIs
Schließlich portieren wir den Code, der den sich drehenden Würfel auf den Bildschirm zeichnet.
In OpenGL ES 2.0 wird der Zeichnungskontext als EGLContext-Typ definiert, der die Fenster- und Oberflächenparameter sowie die Ressourcen enthält, die zum Zeichnen auf die Renderziele erforderlich sind, die zum Verfassen des endgültigen Bilds verwendet werden, das im Fenster angezeigt wird. Sie verwenden diesen Kontext, um die Grafikressourcen so zu konfigurieren, dass die Ergebnisse der Shaderpipeline auf der Anzeige ordnungsgemäß angezeigt werden. Eine der primären Ressourcen ist der "Hintergrundpuffer" (oder "Framepufferobjekt"), der die endgültigen, zusammengesetzten Renderziele enthält, die für die Präsentation bereit für die Anzeige sind.
Mit Direct3D ist der Prozess der Konfiguration der Grafikressourcen für das Zeichnen auf die Anzeige didaktischer und erfordert einige weitere APIs. (Eine Microsoft Visual Studio Direct3D-Vorlage kann diesen Vorgang jedoch erheblich vereinfachen!) Um einen Kontext (als Direct3D-Gerätekontext bezeichnet) abzurufen, müssen Sie zuerst ein ID3D11Device1-Objekt abrufen und es zum Erstellen und Konfigurieren eines ID3D11DeviceContext1-Objekts verwenden. Diese beiden Objekte werden zusammen verwendet, um die spezifischen Ressourcen zu konfigurieren, die Sie zum Zeichnen auf die Anzeige benötigen.
Kurz gesagt, die DXGI-APIs enthalten in erster Linie APIs zum Verwalten von Ressourcen, die direkt zum Grafikadapter gehören, und Direct3D enthält die APIs, mit denen Sie zwischen der GPU und Dem Hauptprogramm, das auf der CPU ausgeführt wird, schnittstellen können.
Für die Zwecke des Vergleichs in diesem Beispiel sind hier die relevanten Typen aus den einzelnen APIs:
- ID3D11Device1: stellt eine virtuelle Darstellung des Grafikgeräts und seiner Ressourcen bereit.
- ID3D11DeviceContext1: Stellt die Schnittstelle zum Konfigurieren von Puffern und Ausgeben von Renderingbefehlen bereit.
- IDXGISwapChain1: Die Swapchain entspricht dem Hintergrundpuffer in OpenGL ES 2.0. Es handelt sich um den Speicherbereich auf dem Grafikkartenadapter, der die endgültigen gerenderten Bilder für die Anzeige enthält. Sie wird als "Swapchain" bezeichnet, da sie mehrere Puffer enthält, die in den Bildschirm geschrieben und "getauscht" werden können, um das neueste Rendern auf dem Bildschirm darzustellen.
- ID3D11RenderTargetView: Dies enthält den 2D-Bitmappuffer, in den der Direct3D-Gerätekontext zeichnet und in den der Swapchain dargestellt wird. Wie bei OpenGL ES 2.0 können Sie über mehrere Renderziele verfügen, von denen einige nicht an die Swapchain gebunden sind, aber für Multi-Pass-Schattierungstechniken verwendet werden.
In der Vorlage enthält das Rendererobjekt die folgenden Felder:
Direct3D 11: Geräte- und Gerätekontextdeklarationen
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;
Hier erfahren Sie, wie der Hintergrundpuffer als Renderziel konfiguriert und der Swapchain bereitgestellt wird.
ComPtr<ID3D11Texture2D> backBuffer;
m_swapChainCoreWindow->GetBuffer(0, IID_PPV_ARGS(backBuffer));
m_d3dDevice->CreateRenderTargetView(
backBuffer.Get(),
nullptr,
&m_d3dRenderTargetViewWin);
Die Direct3D-Laufzeit erstellt implizit eine IDXGISurface1 für die ID3D11Texture2D, die die Textur als "Hintergrundpuffer" darstellt, den die Swapchain für die Anzeige verwenden kann.
Die Initialisierung und Konfiguration des Direct3D-Geräte- und Gerätekontexts sowie der Renderziele finden Sie in den benutzerdefinierten CreateDeviceResources - und CreateWindowSizeDependentResources-Methoden in der Direct3D-Vorlage.
Weitere Informationen zum Direct3D-Gerätekontext im Zusammenhang mit EGL und dem EGLContext-Typ finden Sie unter Port EGL-Code zu DXGI und Direct3D.
Anweisungen
Schritt 1: Rendern der Szene und Anzeigen der Szene
Nach dem Aktualisieren der Cubedaten (in diesem Fall durch eine geringfügige Drehung um die Y-Achse) legt die Render-Methode den Viewport auf die Dimensionen des Zeichnungskontexts (EGLContext) fest. Dieser Kontext enthält den Farbpuffer, der mithilfe der konfigurierten Anzeige (EGLDisplay) auf der Fensteroberfläche (EGLSurface) angezeigt wird. Zu diesem Zeitpunkt aktualisiert das Beispiel die Vertexdatenattribute, bindet den Indexpuffer erneut, zeichnet den Würfel und wechselt in Farbpuffer, der von der Schattierungspipeline auf die Anzeigeoberfläche gezeichnet wird.
OpenGL ES 2.0: Rendern eines Frames für die Anzeige
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);
}
In Direct3D 11 ist der Prozess sehr ähnlich. (Es wird davon ausgegangen, dass Sie die Viewport- und Renderzielkonfiguration aus der Direct3D-Vorlage verwenden.
- Aktualisieren Sie die Konstantenpuffer (in diesem Fall die Modellansicht-Projektionsmatrix) mit Aufrufen von ID3D11DeviceContext1::UpdateSubresource.
- Legen Sie den Vertexpuffer mit ID3D11DeviceContext1::IASetVertexBuffers fest.
- Legen Sie den Indexpuffer mit ID3D11DeviceContext1::IASetIndexBuffer fest.
- Legen Sie die spezifische Dreiecktopologie (eine Dreiecksliste) mit ID3D11DeviceContext1::IASetPrimitiveTopology fest.
- Legen Sie das Eingabelayout des Vertexpuffers mit ID3D11DeviceContext1::IASetInputLayout fest.
- Binden Sie den Vertex-Shader mit ID3D11DeviceContext1::VSSetShader.
- Binden Sie den Fragment-Shader mit ID3D11DeviceContext1::P SSetShader.
- Senden Sie die indizierten Scheitelpunkte durch die Shader, und geben Sie die Farbergebnisse mit ID3D11DeviceContext1::D rawIndexed an den Renderzielpuffer aus.
- Zeigen Sie den Renderzielpuffer mit IDXGISwapChain1::P resent1 an.
Direct3D 11: Rendern eines Frames für die Anzeige
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, ¶meters);
}
Sobald IDXGISwapChain1::P resent1 aufgerufen wird, wird Ihr Frame an die konfigurierte Anzeige ausgegeben.
Vorheriger Schritt
Hinweise
Dieses Beispiel glänzt über einen Großteil der Komplexität, die in die Konfiguration von Geräteressourcen geht, insbesondere für Universelle Windows-Plattform (UWP)-DirectX-Apps. Es wird empfohlen, den vollständigen Vorlagencode zu überprüfen, insbesondere die Teile, die die Einrichtung und Verwaltung von Fenster- und Geräteressourcen ausführen. UWP-Apps müssen Drehungsereignisse sowie Anhalte-/Fortsetzungsereignisse unterstützen, und die Vorlage veranschaulicht bewährte Methoden zum Behandeln des Verlusts einer Schnittstelle oder einer Änderung der Anzeigeparameter.
Zugehörige Themen
- Gewusst wie: Portieren eines einfachen OpenGL ES 2.0-Renderers zu Direct3D 11
- Porten der Shaderobjekte
- Port the GLSL
- Zeichnen auf dem Bildschirm