überspringe Navigation

Tag Archives: OpenGL

Vor langer Zeit habe ich mal damit beschäftigt, wie es möglicht ist mit OpenGL in mehrere Bildschirmelemente (PictureBox z.B.) zu zeichnen. Bei dem Thema bekommt man sofort die Abkürzungen  „hdc“ und „hrc“ um die Ohren geschmissen. Was es damit auf sich hat, erfährt der interessierte Leser hier …

Um OpenGL zu nutzen, benötigt man einen sogenannten Renderkontext (Handle of Rendering Context = HRC), der beim Start des Programms erzeugt werden muss. Dieser Kontext repräsentiert den Zustand von OpenGL, außerdem gehören dem Kontext auch alle Texturen und anderen Materialien an. Alles was man also mittels der API ändert oder in die Grafikkarte lädt, ist dem HRC zugeordnet.

Dieser Renderkontext ist nun verbunden mit einem Gerät (Handle of Device Context = HDC), wobei Gerät symbolisch gemeint ist. Ein HDC repräsentiert keine echten physikalischen Geräte, sondern Elemente, die auf dem Bildschirm angezeigt werden; z.B. Buttons, Zeichenbereiche oder auch Menüs. Ist OpenGL mit dem Rendering fertig, so wird das entstandene Bild auf das Gerät kopiert.

Dabei ist noch zu beachten, dass OpenGL nur auf ein HDC zeichnen kann, wenn dieses ein gültiges Pixelformat besitzt. Normalerweise wird für Grafikelemente auf der Windows-Oberfläche nie ein Pixelformat festleget. Daher müssen wir das selber tun! Und zwar mit der Funktion SetPixelFormat() … jetzt weiß OpenGL wie Farben, Transparenzwerte und andere Dinge auf dem Gerät dargestellt werden sollen.

Zurück zum Thema … ein Renderkontext ist zu jeder Zeit mit genau einem Gerät verbunden. Möchte man nun also auf ein anderes Gerät zeichnen, muss man das Gerät wechseln mit der Funktion wglMakeCurrent. Somit könnten wir nacheinander auf zwei verschiedene Geräte zeichnen und könnten sogar jeweils alle Texturen gemeinsam verwenden, da es sich stets um den gleichen Renderkontext handelt.

Ist das nicht erwünscht, muss man einen zweiten Renderkontext erzeugen, der dann eine andere unabhängige Szene darstellen kann. Dieser zweite Kontext muss jedoch in einem zweiten Thread genutzt werden, denn OpenGL legt fest: Es kann immer nur ein HRC pro Thread aktiv sein.

Vor einiger Zeit bin ich auf das Open Toolkit gestoßen, einen sehr coolen OpenGL/OpenAL .NET-Wrapper. Anders als z.B. Tao funktioniert das Toolkit bei mir auch problemlos unter Linux/Ubuntu. Außerdem bietet OpenTK zusätzlich zur normalen C-API von OpenGL/OpenAL viele High-Level-Klassen. Besonders interessant ist für mich das einfache Zeichnen von Text, der dann auch noch gut aussieht.

Ein weiterer Pluspunkt: Es gibt ein Winforms-Control, was mit Mono und .NET gleichermaßen funktioniert und so erstmals die Entwicklung von CrossPlattform-OpenGL-Programmen mit .NET möglich macht.

Da es bisher kein Stable-Release gibt, sind jedoch Veränderungen der Schnittstelle an der Tagesordnung. Dafür kann man aber auch noch selber Patches einsenden, um diese zu verändern. So habe ich nun beispielsweise Unterstützung für Bezier-Kurven nachgereicht, sowie die Anbindung von Mathe-Klassen an die OpenGL-API ermöglicht.

Bekanntermaßen muss man bei vielen Matrix-Funktionen in OpenGL einen Zeiger übergeben, der auf das float[]-Array zeigt. OpenTK bringt eine Reihe von nützlichen Strukturen wie Vector3 oder Matrix4 mit, mit denen der sichere Umgang mit OpenGL problemlos möglich ist. Auch in Sprachen, die ohne Zeiger auskommen müssen – wie Visual Basic. Beispiel:

Vector3 start = new Vector3(1.0f, 0.0f, 5.0f);
Vector3 end = new Vector3(5.0f, 3.0f, -6.0f);
Matrix4 projection = Matrix4.LookAt( .);

GL.LoadMatrix(ref projection);
GL.Color4(Color.Green);

GL.Begin(BeginMode.Lines);
GL.Vertex3(start);
GL.Vertex3(end);
GL.End();

So einfach war OpenGL-Programmierung noch nie 🙂