OpenGL im RDP

Oft habe ich in der Vergangenheit mit Grafik-Entwicklern über das Thema OpenGL in RDP Sitzungen gestritten.
Die sagen nämlich: “Das geht nicht.”

“Das geht sehr wohl” lautet dann mein Widerspruch.

Nein! Doch! Ohh!


Zwischendurch ein kurzer Ausschnitt zur bekannten “Nein! Doch! Ohh!” Szene von Louis de funess

[ Youtube Video Link ]

Nun, wenn ich von OpenGL spreche, meine ich OpenGL 1.1 und nicht “das inkompatible moderne Zeug”, das heute als OpenGL 2,3,4 oder EmbeddedGL verkauft wird.

Shader liefen unter Windows bis Version 8 nicht in RDP Sitzungen. Wie es heute aussieht, weiß ich nicht, aber es könnte sich vielleicht mal die Gelegenheit für ein paar Tests bieten.

“Reguläre” OpenGL 1.1 Programme laufen jedenfalls üblicherweise auch nicht innerhalb von Remote-Desktopsitzungen, weil ihnen die APIs bei der Initialisierung der Zeichenoberfläche Fehler liefern.

Aber:
Windows unterstützt ja einen OpenGL 1.1 Software-Renderer und dieser könnte in solchen “virtuellen” Sitzungen ja sofort übernehmen, womit auch in RDP Sitzungen OpenGL Code Grafik produzieren kann … nur eben viel langsamer.

Die Initialisierung schlägt aber aus einem recht trivialen Grund meist fehl:
Die Erwartungen an RDP sind zu hoch!

16 bit oder weniger müssen reichen!

Fast jeder OpenGL Code will per PIXELFORMATDESCRIPTOR mindestens 24 bits pro Pixel (also True-Color Qualität) ansteuern.
Aber der klassische virtuelle RDP-Grafik-Treiber ist nicht für mehr als 16 bit ausgelegt. Windows 8 und 10 schaffen hier offenbar mehr, aber ob das immer so ist, lässt sich schwer garantieren.

In meinen Tests konnte ich mit der Änderungen auf pixelformatdescriptor.cColorBits = 16 unmittelbar zum gewünschten Ergebnis gelangen: Man erhält einen OpenGL-Software-Render-Kontext und kann darauf Zeichen … und es wird auch alles davon am Schirm sichtbar.

Es macht also Sinn in der Liste der unterstützten Pixel-Formate die Anforderungen zu senken, und schon bekommt man ein Format zugeordnet, das auch in einer RDP Sitzung sofort lauffähig ist.

glDrawArrays() verbindet die Welten

Ein häufiges Argument gegen OpenGL 1.1 ist, dass sein Code nicht kompatibel mit neueren GL Versionen ist.

glBegin() und glEnd() gibt es nicht mehr!

heißt es dann.

Ja stimmt, es gibt aber noch die Funktion glDrawArrays(), mit der man sehr viel machen kann, was man früher zwischen glBegin() und glEnd() geschrieben hat. Man setzt zuerst mit glVertexPointer() die Punkte, ordnet per glColorXX() die Farben zu und glDrawArrays() zeichnet die Dreiecke, Polygone usw. auf die Oberfläche.

Und schon haben wir eine Codebase, die mit OpenGL 1.1 genau so gut läuft, wie mit OpenGL 2, 3 oder 4.

Auch Texturen funktionieren in GL 1.1 super … sie haben nur die Einschränkung von maximal 1024 Pixel in ihren Dimensionen … aber mal ehrlich, wer so große Bilder braucht, kann sie auch auf ein paar Stücke zerteilen.

Unflexible Implementierungen

Tatsächlich ärgere ich mich oft über Software, die - aus meiner Sicht - grundlos nicht RDP-tauglich ist, oder auf älteren Systemen oder Systemen ohne aktuellen OpenGL Treiber nicht läuft.

Bestes Beispiel ist die Software meines alten 3D-Druckers. Diese ist extrem primitiv und kann nur Modelle auf den Bildschirm zeichnen und die ganze Ansicht drehen.

Das kann man mit der Fixed-Function-Pipeline von OpenGL 1.1 wunderbar abdecken. Leider erwartet die Software aber zwingend OpenGL 2 oder 3 mit Shadern, womit sie gleich unter folgenden Umgebungen nicht läuft:

  • Alte Intel Onboard-Grafikkarten unterstützen nur OpenGL 1.4 per Treiber
  • Systeme ohne speziellen Grafiktreiber, z.B. Server-Boards
  • RDP Sitzungen

Ich kann daher wegen eines OpenGL-Fehlers nicht eines meiner alten Intel-Atom Systeme als 3D-Druck Dienststation einsetzen, die aus der Ferne bedient wird.

Tatsächlich wäre aber nicht viel Programmierarbeit notwendig um die Software hier lauffertig zu bekommen.

Fazit

Eine gute Software passt sich an das System an und stellt nicht Anforderungen, die sie gar nicht braucht. Man kann den 16-bit Farbmodus ja auch nur als Probier-Option vorsehen und bessere Grafikmodi im Nachgang oder Voraus prüfen und nur im RDP-Fall wird dann zum 16-bit Fallback gewechselt.

Niemand kann mir heute glaubhaft erzählen, dass Grafik NUR mit neuen OpenGL Standards funktioniert.
Denn wer sich an vor 2000 erinnert, an die Zeit von Half-Life-1, der weiß, dass man mit OpenGL auch mit Software-Rendering hoch komplexe 3D-Landschaften abbilden konnte.

Und heute erklärt mir eine CAD-Anwendung, dass sie wegen der Pixel-Bits in Software kein 10x10cm Arduino-Case rendern kann?

Nee … das muss nicht sein!
Es geht!
Man muss sich nur Mühe bei der Entwicklung geben!