Renderkontext: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
K (Der Ausdruck ''<pascal>(.*?)</pascal>'' wurde ersetzt mit ''<source lang="pascal">$1</source>''.)
(Siehe auch)
 
Zeile 53: Zeile 53:
  
 
== Siehe auch ==
 
== Siehe auch ==
[[Tutorial_Quickstart]]
+
[[Tutorial_Quickstart]]<br>
 +
[[Tutorial OpenGL3 Zeichenkontext]]

Aktuelle Version vom 19. März 2014, 16:24 Uhr

Hinweis: Dieser Artikel ist noch unvollständig.
(Mehr Informationen/weitere Artikel)

Hier fehlen noch einige Angaben zur Erzeugung (v.A. unter Linux!) und Verwendung. Zudem sollte noch mal jemand drüberschauen, ob die angegebenen Informationen zu den enthaltenen Info's korrekt sind.

Incomplete.jpg

Der Renderkontext enthält alle nötigen Informationen, die eine Zeichenfläche und die zu dieser zugeordneten Ressourcen beschreiben. Diese Informationen enthalten dabei Angaben zum verwendeten Pixelformat, den Abmessungen der Zeichenfläche (Höhe, Breite, Aspekt-Ratio), sowie Angaben zur Lage der Datenpuffer für Farb-, Stencil-, Tiefen- und Transparenz-Informationen. Zudem enthält der Render-Kontext allgemeine Statusinformationen wie die Art und Dicke zu zeichnender Linien, die zum Zeichnen zu verwendenden Texturen sowie andere Angaben, die für das Zeichnen notwendig sind.

Anlegen eines Renderkontext

Info DGL.png Dieser Abschnitt beschreibt das Vorgehen unter Windows. Unter Linux können Details abweichen (Wenn jemand mit Linux mehr Erfahrung hat, wäre eine Teilung und differenziertere Beschreibung erwünscht)

Um überhaupt mit OpenGL arbeiten zu können, muss zuerst einmal ein Renderkontext angelegt werden. Dabei muss man einen vorhandenen Gerätekontext (DC) zugrunde legen. Ein Renderkontext spannt sich dabei immer über den gesamten Gerätekontext und damit über den gesamten Clientbereich des Fensters oder das gesamte Speicher-Bitmap, zu dem der Gerätekontext gehört.

Beim Anlegen werden sowohl auf der Grafikkarte als auch im RAM abhängig von den Einstellungen des Gerätekontextes (Pixelformat, Höhe, Breite...) diverse Speicherbereiche reserviert, in denen später dann Farb- oder Tiefenpuffer, die Informationen der Statemachine, Texturen, Displaylisten oder VBOs abgelegt werden (natürlich werden auch einige Bereiche erst später dynamisch reserviert).

Beispiel

var
  DC, RC:HDC;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
  DC:=GetDC(Handle);
  RC:=CreateRenderingContext(DC,          //Device Contest
                             [opDoubleBuffered], //Optionen
                             32,          //ColorBits
                             24,          //ZBits
                             0,           //StencilBits
                             0,           //AccumBits
                             0,           //AuxBuffers
                             0);          //Layer
  ActivateRenderingContext(DC, RC);
end;
  • DC ist der Gerätekontext an dem der Rendercontext hängt. Zum Beispiel der Kontext eines Formulars oder aber der eines Panels. Je nachdem wo später drauf gezeichnet werden soll.
  • Optionen sind hinweise wie z.B: opDoubleBuffered. Diese Option gibt an, dass Doppelpufferung genutzt werden soll. TODO Bitte weitere Optionen bzw. Link wo man nachlesen kann.
  • ColorBits, hier 32, gibt die Farbtiefe an. 32 bedeutet, dass für die 4 Farbkanäle (Rot, Grün, Blau, Alpha(Transparenz)) jeweils 1Byte=8Bit zur Verfügung stehen. Das bedeutet für jeden Kanal können 256 Abstufungen genutzt werden. Das macht insgesamt 256^4 = ... verdammt viele!
  • ZBits, hier 24, gibt an wie viele Bits für den Tiefenpuffer reserviert werden. 24Bits bedeutet, dass Einträge von 0 bis 2^24=16,7Mio möglich sind. Je höher der Wert, desto feiner/genauer der Tiefentest. (Mehr dazu im Tiefetest-Artikel)
  • StencilBits werden für den Stencil Test benötigt. (Maskieren von Bildschirmteilen)
  • AccumBits geben an, wie viele Bits im Akkumulationspuffer gespeichert werden können.
  • AuxBuffer gibt an, wie viele Bits im Hilfspuffer gespeichert werden können.
  • Layer gibt die Anzahl ebenen an.


Problem mit erweiterungsabhängigen Pixelformaten

Ein bekanntes Problem bei der Tatsache, dass ein Renderkontext an einen Gerätekontext gebunden ist und dass man das Pixelformat eines Gerätekontextes nur ein einziges Mal festlegen kann, ist, dass man für einige Einstellungen im Pixelformat erst wissen muss, ob die passenden Erweiterungen zur Verfügung stehen. Um das zu ermitteln muss man allerdings wiederum einen Renderkontext erstellt haben.

Um dieses Problem zu umgehen, wird häufig ein Testgerätekontext auf einem versteckten Fenster erstellt, auf dem dann ein Testrenderkontext erstellt wird, wo man die Erweiterungen abfragt.

Diese Problematik tritt häufig bei Multisampling (Antialiasing) auf, da dies eine entsprechende Erweiterung beziehungsweise die Fähigkeit der Hardware benötigt und im Pixelformat festgelegt sein muss.

Einflussnahme auf den Renderkontext

Bei jedem Aufruf einer Funktion von OpenGL, die an der Art und Weise, wie etwas gezeichnet werden soll, oder die selbst etwas zeichnet, nimmt OpenGL Veränderungen an den im Renderkontext hinterlegten Angaben vor. Diese Veränderungen spiegeln dabei die auszuführende Operation (z.B. Ändern der Linienstärke beim Zeichnen mit GL_LINES) in Form einer Status-Änderung wieder (Ändern des Wertes, der die zu verwendende Linien-Breite angibt).

Renderkontextübergreifende Daten

OpenGL bietet (zumindest unter Windows) mittels wglShareLists die Möglichkeit, kontextspezifische Objekte wie Texturen oder Displaylisten übergreifend über zwei Renderkontexte zu verwenden. Dies ist zum Beispiel im Falle einer Editoranwendung hilfreich, die mehrere Viewports hat, die aus technischen Gründen nicht in einem Renderkontext liegen können. Für jeden Viewport alle Texturen und VBOs beziehungsweise Displaylisten zu laden, wäre natürlich viel zu großer Aufwand. Statt dessen benutzt man etwas wie wglShareLists, um die Objekte nur einmal laden zu müssen.

Das Thread-Problem

Ein Problem, auf das man im Zusammenhang mit dem Laden von Daten in den Renderkontext später eventuell treffen kann ist, dass man einen Renderkontext nur so lange verändern kann, wie man sich in demjenigen Thread befindet, in dem der Kontext erstellt wurde. Das heißt, dass man Texturen oder andere OpenGL-Objekte nicht aus einem nebenläufigen Lade-Thread heraus erstellen kann. Wohl aber kann man die Daten erstmal in den RAM laden und dann an den Hauptthread weiterreichen, der sie dann an die Grafikkarte schickt.

Siehe auch

Tutorial_Quickstart
Tutorial OpenGL3 Zeichenkontext