OpenGL vs. DirectX - Ich bin [nicht mehr] verwirrt.

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

OpenGL vs. DirectX - Ich bin [nicht mehr] verwirrt.

Beitrag von Schrompf »

Moin!

Wie ihr ja wisst, porte ich gerade Splatter auf Mac/Linux. Der allergrößte Teil der Arbeit daran ist die Übersetzung von Direct3D zu OpenGL. Und da knackt es im Gebälk. Denn eigentlich möchte ich meinen DirectX-Code behalten.

Nur stellt es sich so langsam heraus, dass es anscheinend unmöglich ist, die Differenzen zwischen OGL und D3D zu abstrahieren.

a) Clip Space

DirectX geht von links -1 bis rechts +1, oben -1 bis unten +1 und vorne 0 bis hinten +1. OpenGL geht eigentlich genauso, aber vorne +1 bis hinten -1. Wenn ich da meinen Standard-Matrixcode drauf loslasse, funktioniert der aber stressfrei. Und transponieren muss ich sowohl bei D3D als auch bei OpenGL gleichermaßen, damit meine Matrizen im Shader das Richtige mit einem nachmultiplizierten Vektor tun.

Immerhin habe ich schon begriffen, dass ich damit unter OpenGL ein Bit DepthBuffer-Auflösung verschwende, weil ich weiter nur Tiefenwerte zwischen 0 und 1 ausgebe. Warum die 1 trotzdem hinten und die 0 vorne ist, ist mir unbegreiflich.

b) Bildschirmkoordinaten.

Das ist weniger ein Problem. Direct3D9 betrachtet (0,0) als Zentrum des linken unteren Pixels, OpenGL und Direct3D10+ die linke untere Ecke des linken unteren Pixels. Da ich langfristig eh weg von DX9 will, hab ich damit kein Problem.

c) Texturkoordinaten

Hier wird's wieder richtig wirr. DX hat (0,0) links oben, OpenGL hat (0, 0) links unten. Theoretisch sollte also alles Texturiertes erstmal auf dem Kopf erscheinen. OpenGL erwartet nun aber Grafikdaten mit der untersten Zeile zuerst, während DirectX mit seinem Lock() / Unlock() Grafikdaten von oben nach unten erwartet. Damit kann ich OpenGL also statische Texturen aus 2D-Grafiken erstmal genauso anbieten wie unter D3D, die beiden senkrechten Spiegelungen heben einander auf. Dafür dürfte mein Programm einen Heldentod sterben, sobald ich was mit Rendertargets mache. Dann steckt da eine Invertierung weniger drin und meine Shadow Map steht plötzlich auf dem Kopf.

Und das üble ist, dass ich dazu meinen Shader-Quelltext anpassen muss. Ich dachte, ich kriege das mit einem generierten Header und einer genormten Innen-Funktion alá Valve hin, aber das hier würde bedeuten, die v-Koordinate jedes Texturzugriffs vorher zu invertieren, damit die restliche Logik weiter bleiben kann wie bisher.

Was für ein Mist! Und dafür gibt's nach meiner Suche anscheinend auch keine Extension

d) Sampler

Unten D3D definiert man einen Sampler, bestimmt dessen Eigenschaften (Wrapping/Clamping, Interpolation) und klöppelt ne Textur dran. Unter OpenGL bindet man ne Textur, bestimmt deren Eigenschaften, und kriegt die später alle wiederhergestellt, sobald man die Textur erneut bindet. Tja. Vorbei sind die Zeiten, da ich die selbe Textur an mehrere Sampler geknüpft habe, um die Texturcaches besser ausnutzen zu können. Und richtig lustig wird's ja dann, wenn man unter D3D10+ die Textur und den Sampler getrennt im Shader benennen kann. Und OpenGL winkt fröhlich aus der Ferne?

Dafür gibt's ja anscheinend ne Extension, aber wieder keine Garantie, wie verbreitet oder verlässlich die ist.

e) Shader

OpenGL klöppelt alle Shader in ein gemeinsames Programm. Ok, gute Idee erstmal, erlaubt die frühzeitige Verifikation. Da ich eh in dem Abwasch auch gleich DX11 angehen will, würde ich das Konzept übernehmen und die Vertexeingabe-Zusammenstellung auch gleich noch mit reinschmeißen. Und da wird's schon wieder lustig. Unter DX9 gibt's einen linearen Konstantenspeicher. Unter OpenGL einen irgendwie hinter uints versteckten Speicher, der mit dem Shader bzw. genauer Programm mitgeschleppt wird. Unter DX10+ dann mehrere Speicher, die man separat beladen und einzeln anklemmen kann. Unter OpenGL ist ja allein die Reflection eine opengl-typische Katastrophe mit glGetUniformLocation auf dem aktuell gebundenen Shader... aber wahrscheinlich gibt's da auch wieder Extensions für, nur halt wieder mit unsicherer Verbreitung und Verlässlichkeit.

Zusammenfassung:

Nur, weil am Ende alles auf der selben Hardware läuft, heißt das noch lange nicht, dass man da auch nur annähernd die selben Abläufe erwarten könnte. Im Gegenteil: hier prallen Welten aufeinander. Die eine Welt besteht aus durchdesignten Gebäuden, die aber unbedingt alles irgendwie anders machen müssen als die mathematischen Standards bisher. Die andere Welt war mal ein Pappteller, auf dem jetzt aber soviele farbige Schichten vorsichtig aufgetragen wurden, dass der Pappteller jetzt ein riesiges komplexes Gemälde ist. Theorethisch ist alles zugleich sichtbar und gutaussehend, praktisch bröckeln ganze Quadratmeter davon ab, sobald man dranfässt.

Falls irgendwer von euch schonmal diesen Mist mitgemacht hat, wäre ich sehr daran interessiert, mit welchen Mitteln er das bewältigt hat. Und mit welchen Extensions. Und welche Erfahrungen dabei gemacht wurden.

[edit] Hmm... was natürlich auch geht, wenn auch unter 15 Jahre Tränen: alles wegschmeißen und durch OpenGL ersetzen. Ob und wie ich da noch die Konsolen mit unterkriege, wenn sie denn mal kommen, ist dann die nächste Frage.
Zuletzt geändert von Schrompf am 29.07.2014, 16:32, insgesamt 1-mal geändert.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Spiele Programmierer »

Bildschirmkoordinaten
Geht umzustellen: layout(pixel_center_integer) und layout(origin_upper_left) heißen die Stichwörter
Sampler ... dafür gibt's ja anscheinend ne Extension, aber wieder keine Garantie, wie verbreitet oder verlässlich die ist.
Sampler Objekte sind Core-Funktionalität ab OpenGL 3.3. Nebenbei einer, wenn für mich auch bisher nicht entscheidender Grund, warum ich OpenGL 3.3 empfehle.
Shader ...
Wieder klingt mir das was du suchst nach OpenGL 3.x:
"Uniform Buffer Object"s sollen etwa das sein was man in DirectX wohl Constant Buffer oder so nennt. Reflection ist gar nicht notwendig. Mit expliziten Vertexattributlayout kann mich sich Reflection nachzu komplett schenken, wenn man möchte.
OpenGL klöppelt alle Shader in ein gemeinsames Programm.
In OpenGL 4.1 gibt es einen Mechanismus für separate Shaderstages oder als Core-Extension: "ARB_separate_shader_objects" Ich habe das aber nie gebraucht.

Das A und O für mich um mit OpenGL glücklich zu werden waren eigentlich 2 Dinge: Mein selbstgebasteltes OpenGL objektorientiertes Interface und die Einsicht das es keinen Sinn macht sich zu sehr mit Legacy Versionen herumzuschlagen. Auch wenn dir das jetzt wahrscheinlich nicht wirklich weiterhilft.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Doch, hilft es schon. Danke dafür. Die ARB_fragment_coord_conventions hatte ich auch schon entdeckt, aber nach meinem Wissen bestimmt die nur, was ich für Zahlen bekomme, wenn ich im Fragment Shader gl_FragCoord auslese. Praktisch in einem solchen Fall, aber sehr selten. Für die Textur-Senkrechtspiegelung dagegen gibt es wohl keine Extension.

Die Buffer Objects sehen auch gut aus. Separate Shader brauch ich gar nicht so sehr, vor allem da ich am liebsten auch gleich eine Kern-Funktionalität hätte, die sich nach Möglichkeit direkt auf Direct3D11 oder gar 12 abbilden lässt. Und der Trend geht da ja zu Immutable State Objects mit immer mehr Inhalt.

Mit Legacy werde ich mich allerdings am Ende doch rumschlagen müssen, weil Apple wohl bis zu einem jüngeren OS-Update nur OpenGL 2.x unterstützt hat. Na mal gucken.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Spiele Programmierer »

Ich kenne mich mit Apple nach zu gar nicht aus, diese Liste lässt aber anderes vermuten:
http://support.apple.com/kb/HT5942

Der Treibertest hier sagt auch etwas anderes aus: (Besonders Pdf unten)
http://www.g-truc.net/post-0655.html#menu
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Sternmull »

Wie in deinem ersten OpenGL Thread würde ich auch hier noch mal darauf hinweisen das die OpenGL-Version garnicht so entscheidend ist. Die Extensions lassen sich leicht einbinden und die wichtigsten dürften auf annähernd aktuellen Systemen vorhanden sein. Natürlich muss man das vorher im Detail recherchieren, aber es gibt keinen Grund sich auf OpenGL 2.x festzunageln. Vor allem wenn man die Möglichkeit hat einige Extensions nur optional zu verwenden und entsprechende Fallbacks zu verwenden wenn die nicht da sind. Aber das entscheidet sich dann auch wieder im Detail.

Du bist ja nicht der erste der D3D und OpenGL hinter einer einheitlichen API verstecken will. Es gibt da sicherlich mehrere Erfolgsgeschichten. Ein prominentes Beispiel ist Ogre3D mit Abstraktion für Direct3D 9, 10 und OpenGL. Da wird übrigens OpenGL 1.2.1 + optinalen Extensions verwendet. Als ich mir Ogre3D vor vielen Jahren mal genauer angeguckt hab fand ich das objektorientierte Monster was die da geschaffen haben zwar abschreckend, aber wenn du dich mit konkreten Fragestellungen in dem Code umsiehst, dann findest du sicherlich die Abstraktionsschichten und die Implentierungsdetails die für dich relevant sind.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von CodingCat »

Schrompf hat geschrieben:DirectX geht von links -1 bis rechts +1, oben -1 bis unten +1 und vorne 0 bis hinten +1. OpenGL geht eigentlich genauso, aber vorne +1 bis hinten -1.
Nicht ganz. Kleine Korrektur: Oben +1 bis unten -1. Große Korrektur: Tatsächlich sind alle Clip-Space-Richtungen für OpenGl und DirectX identisch. Auch OpenGL hat standardmäßig GL_LESS als Depth Comparison Function eingestellt. Der einzige Unterschied besteht in der Konvention, den Kameraraum so aufzuspannen, dass die Z-Achse aus dem Bild heraus zeigt, was jedoch durch die negierten Z-/W-Zeilen der Projektionsmatrix sofort wieder aufgehoben wird. Das Einzige, was bei der Portierung zu tun bleibt, ist folglich eine Skalierung der Projektionsmatrix auf den Z-Werte-Bereich -1...1.
Schrompf hat geschrieben:Theoretisch sollte also alles Texturiertes erstmal auf dem Kopf erscheinen. OpenGL erwartet nun aber Grafikdaten mit der untersten Zeile zuerst, während DirectX mit seinem Lock() / Unlock() Grafikdaten von oben nach unten erwartet. Damit kann ich OpenGL also statische Texturen aus 2D-Grafiken erstmal genauso anbieten wie unter D3D, die beiden senkrechten Spiegelungen heben einander auf. Dafür dürfte mein Programm einen Heldentod sterben, sobald ich was mit Rendertargets mache. Dann steckt da eine Invertierung weniger drin und meine Shadow Map steht plötzlich auf dem Kopf.
Korrekt.

Nachtrag: Satz zur Skalierung des Z-Werte-Bereichs geändert, damit die Portierungsrichtung mit dem Originalpost übereinstimmt.
Zuletzt geändert von CodingCat am 07.07.2014, 21:06, insgesamt 1-mal geändert.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von antisteo »

Schrompf, sind es wirklich die Vorzeichen, die dir so viele Probleme bereiten? Das probiert man doch mal, ob es so oder anders herum gehen muss und dann klappt es.
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von CodingCat »

antisteo hat geschrieben:Schrompf, sind es wirklich die Vorzeichen, die dir so viele Probleme bereiten? Das probiert man doch mal, ob es so oder anders herum gehen muss und dann klappt es.
a) Das war nicht die Frage
b) Verstehen ist bedeutend besser als rumprobieren, gerade weil sich permanent alles gegenseitig aufhebt
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Och naja... die grundlegenden Dinge habe ich durchaus verstanden. Nur wie ich die alle unter einen Hut bekommen soll, weiß ich noch nicht. Aber ich habe ja immer die Option, alles hinzuschmeißen und nur OpenGL zu nehmen. Auch wenn's schade wäre, weil speziell mit DX10 ja die API wirklich konsistent und angenehm geworden ist.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von antisteo »

Ich finde auch, dass Node.js oder Python wesentlich konsistenter und angenehmer sind als PHP. Trotzdem ist PHP der breitere Weg, da man keinen dedizierten Server braucht, sondern einfach ein paar Dateien in einen Ordner schmeißen muss. Mir ist es bei Spielen relativ wurscht, ob die darunterliegende Technologie DirectX oder OpenGL ist. Mit beiden Technologien kann man dasselbe erreichen und ist die Grafik-Logik erst mal fertig, fasst man sie auch nicht mehr so oft an, sondern kümmert sich um ordentliche Levelz.
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Sternmull »

Das hilft Schrompf nun aber wirklich nicht weiter.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von dot »

Genau aus all diesen Gründen würde ich OpenGL < 3.3 niemals freiwillig anfassen oder gar weiterempfehlen. Die Frage ist, ob du mit OpenGL 3.3+ auskommst; wie du bereits festgestellt hast, schränkt das die Zielgruppe doch etwas ein (OpenGL 3.3+ entspricht D3D10+ Hardware und setzt brauchbare Driver voraus).

Wie Cat schon erwähnt hat, ist der Clip Space sowohl in Direct3D als auch in OpenGL linkshändig. Was für ein Koordinatensystem du verwendest, hängt am Ende eh nur von der Projektionsmatrix ab. Weder OpenGL noch D3D zwingen dir da irgendwas auf; dass in OpenGL rechtshändig üblicher ist, hat lediglich historische Gründe; du kannst genausogut in D3D ein rechtshändiges Koordinatensystem verwenden, wie du in OpenGL ein linkshändiges verwenden kannst.

Das mit den Samplekoordinaten ist in der Tat in D3D9 anders als in OpenGL oder D3D10+. Möglicherweise kann man den Viewport einfach um 0.5 Pixel verschieben, um das auszugleichen, hab ich aber noch nie ausprobiert. Sollte aber auch kein Problem sein, da du sowieso weder die Shader noch den Rendering Code zwischen D3D9 und dem Rest wirst teilen können.

Das Layout von Matritzen lässt sich sowohl in D3D als auch in OpenGL switchen.

Meiner Erfahrung nach ist jeder Versuch auf Ebene der Rendering API zu abstrahieren rein prinzipiell keine gute Idee und führt früher oder später in eine Sackgasse. Insbesondere konnte ich noch keinen Weg finden, OpenGL sinnvoll in konventionellen OOP Sprachen abzubilden. Dazu ist das Objektmodell zu...anders...
Ausschließlich auf OpenGL setzen kann funktionieren, so lange du nur am PC laufen willst. Für Konsolen oder mobile Plattformen brauchst du erst wieder was Anderes.

Ich muss gestehen, dass ich weder Erfahrung mit der Entwicklung für Konsolen oder mobile Geräte habe, noch habe ich Erfahrung mit einer Anwendung, die ein dermaßen breites Publikum hat wie dein Spiel. Aber nach aller Erfahrung, die ich mit der Entwicklung von OpenGL und Direct3D Anwendungen habe, bin ich momentan der Meinung, dass die beste Lösung für das Problem ist, auf Ebene des Renderers zu abstrahieren. Definier ein Interface für ein Renderering-System, das genau auf deine Anwendung zugeschnitten ist (also vielleicht auf Ebene von Sprites und Partikelsystemen, besser vermutlich aber sogar schon auf Ebene von Zombies und Explosionen) und implementier dieses dann für jede Plattform/API.
Benutzeravatar
Krishty
Establishment
Beiträge: 8240
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Krishty »

dot hat geschrieben:Definier ein Interface für ein Renderering-System, das genau auf deine Anwendung zugeschnitten ist (also vielleicht auf Ebene von Sprites und Partikelsystemen, besser vermutlich aber sogar schon auf Ebene von Zombies und Explosionen) und implementier dieses dann für jede Plattform/API.
this ^

Nur, dass er dann zwei Baustellen hat statt einer.

Ich wollte nur kurz zwischenfunken um für die Diskussion und insbesondere für Schrompfs Aufzählung zu danken :)

Jetzt könnt ihr weitermachen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Danke, dot. Dass der Clip Space auch bei OGL linkshändig ist, erklärt einiges... [Edit]Und ich sehe grade, dass CodingCat das schon am Anfang auch gesagt hat, ich hab nur nicht vollständig begriffen, was das bedeutet. Sorry, Cat[/edit] Ich hatte ja einfach meine von DX funktionierenden Matrizen eingesetzt und habe vollautomatisch das richtige Ergebnis bekommen. Damit wäre jetzt geklärt: ich habe einfach intern weiter alles in linkshändig gemacht und hatte deswegen kein Problem damit, weil ich das konsequent bis zum Clip Space durchgezogen habe. Bleibt noch die Nachskalierung der Z-Werte auf -1..+1, um das eine Bit Genauigkeit nicht wegzuwerfen.

Auch zur Vermeidung der State-Schieberei gibt es einige gute Extensions. Sampler Objects wurden ja schon genannt. Aus der Valve-GDC-Präsentation zum Thema (hier) kenne ich auch Named Buffer Objects. Und es gab auf den Steam Dev Days glaube ich auch eine Präsentation, in der die Jungs selbst die Shader crosscompilen konnten, indem sie eine eigene Main() definierten und den Boilerplate Code drumrum generiert haben. Und angeblich gibt es funktionierende Shader-Crosscompiler für HLSL4/5, auch wenn ich mich frage, wie die die D3D-inherente Trennung zwischen Sampler und Textur umgesetzt haben, die es ja anscheinend bis heute nicht in OGL gibt. Damit kommen wir dann aber auch schon wieder viel zu nah in aktuelle Gebiete, deren Treiber-Support immernoch dürftig sein dürfte.

Ganz am Ende bleibt als Problem dann immernoch die invertierte Texturkoordinate. Wer weiß, wie die anderen Leute das umgesetzt haben. Mal in die Ogre-Quellen gucken, auch wenn das bei hinreichend großer Komplexität wahrscheinlich eine Übung in Frustration wird.

Ich glaube, ich muss mein Problem umformulieren: ich hätte gern eine Abstraktionsschicht, mit der ich DrawCalls auf den Bildschirm kriege und die für alle 3D-APIs funktioniert. Wenn ich am Ende alle Settings in ein großes DrawCall-Objekt kompilieren muss, dann ist das ok. Wahrscheinlich ist das eh der Standard-Ansatz für DX12 und damit auch für OpenGL in ein paar Jahren. Oder ich werfe halt wirklich die Flinte ins Korn und baue neben mein D3D9-Framework ein API-inkompatibles OGL-Framework. Dann fange ich eine Ebene höher nochmal an mit Abstrahieren. Verdammter Mist.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Es gibt auch so spannende Sachen wie https://github.com/bkaradzic/bgfx - ein Cross Platform Renderer genau wie das, was ich bauen will. Leider wieder heftig überbaut mit Render Queue und allen möglichen Zusatzlibs, aber mal gucken, ob man die rausoperieren kann. Deren Shader-Crosscompiler-Ansatz ist jedenfalls nur ein Rudel Makros für Uniforms, Samplers usw. und dann die Integration eines One-File-Präprozessors zum Vorverarbeiten. Zumindest den Teil kann ich ja einfach benutzen.

Die haben auch alle Texturzugriffe hinter kleinen Inline-Funktionen versteckt. Damit könnte ich selbst das Senkrecht-Spiegel-Koordinatenproblem plätten. Damit wäre allerdings eine minimale Rechenzeitverschwendung auf einer der beiden 3D-APIs verbunden. Wobei ein skalares mad() sicher nicht messbar sein dürfte.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Bevor ich einen neuen Thread anfange, verwende ich mal diesen hier weiter.

DirectX: float4x3 sind 3 Konstantenregister mit je 4 floats
OpenGL: mat4x3 sind anscheinend 4 Konstantenregister mit je 3 floats. Zumindest zeigt es NSight hier gerade sorum an.

Trotzdem: mat4x3 akzeptiert laut GLSL-Compiler als Matrix-Vektor-Multiplikation nur einen vec4 und ergibt einen vec3, so wie man es mathematisch erwarten würde. Aber wenn ich mit die Matrix mit Einheit setze

Code: Alles auswählen

1.0   0.0   0.0
0.0   1.0   0.0
0.0   0.0   1.0
0.0   0.0   0.0
und das Ding im Shader wie folgt benutze:

Code: Alles auswählen

vec3 erg = Diese4x3Matrix * vec4( x, y, z, w) 
dann bekomme ich ... *trommelwirbel* die ZAchse auf die Y-Achse abgebildet und die Y-Achse ist überall 0. MIt einer kopulierenden Einheitsmatrix wohlgemerkt.

Ich würd ja einfach mal durch den Shader durchsteppen, aber beim letzten Versuch dieser Art hat NVidia meinen Rechner so richtig gekillt... nicht mal mehr ausschalten konnte ich ihn. Hat jemand eine Idee?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Nachtrag: wenn ich eine 4x4-Matrix reinreiche, geht alles stressfrei. Nur mit der 4x3-Matrix geschehen seltsame Dinge, die ich nach der Matrix-Multiplikationsregel eigentlich nicht passieren sollten. Konkret werden bei Anwendung der Einheitsmatrix eine oder zwei der Komponenten des Ergebnisvektors 0.

Der Versuch, einen Shader zu debuggen, killt weiterhin zuverlässig meinen Rechner. Das aber nur als Randanekdote.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von CodingCat »

Wie reichst du die Matrix denn rein? Mit Standardeinstellungen sollte das spaltenweise geschehen, wenn ich mich nicht gerade vertue? Insbesondere Y auf Z klingt nach verkehrtem Speicherlayout (zeilenweise), weil sich dann alles so verschiebt dass X->X, Y->X und Z->Y abgebildet werden.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Ja, evtl. ist es nur das.

Shader:

Code: Alles auswählen

#version 330 core
out vec4 color;

in vec2 fragTexKoords;

uniform mat4x3 gLichtTransform; // welt zu Lichtkoords

void main()
{
  vec4 normale = vec4( 0, 0, 1, 0);

  vec3 normInLichtKoords = gLichtTransform * normale; // das hier macht groben Unsinn
  color = 0.5f * normInLichtKoords.xyzz + vec4( 0.5, 0.5, 0.5, 0.5);
}
und hochgeladen wird die Matrix mittels

Code: Alles auswählen

    GLuint lichtTransformId = glGetUniformLocation( shaderId, "gLichtTransform");
    glUniformMatrix4x3fv( lichtTransformId, 1, GL_FALSE, &weltZuLicht.a1);
Da die Tangent Space To World Space-Matrix sauber verarbeitet wird (und sich auch artig an alle Regeln hält, die ich vom Studium noch kenne), vermute ich, dass es das glUniformMatrix4x3 ist, was den Ärger macht. Aber das wundert mich nun wieder. 4x3 sind doch 3 Konstantenregister, oder? Sind es nun drei oder vier? Das ist die entscheidende Frage, und eine, bei der ich auch gegenüber Google noch nicht die richtigen Worte gefunden habe. Ich gebe ihm da mit dem float-Pointer eine Matrix im Zeilen-Layout mit Translationsanteilen in der 4. Spalte. Und er soll diese drei Zeilen zu je 4 floats einfach unverändert hochladen, daher auch das GL_FALSE als Transponieren-Parameter. Aber anscheinend passiert genau da was komisches.

Allgemein: das alles mal auskotzen und dann eine Nacht drüber schlafen hat jedenfalls bewirkt, dass ich schon viel klarer sehe. Danke für Deine Geduld mit mir, liebes Forum :)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von CodingCat »

Schrompf hat geschrieben:Da die Tangent Space To World Space-Matrix sauber verarbeitet wird (und sich auch artig an alle Regeln hält, die ich vom Studium noch kenne), vermute ich, dass es das glUniformMatrix4x3 ist, was den Ärger macht. Aber das wundert mich nun wieder. 4x3 sind doch 3 Konstantenregister, oder? Sind es nun drei oder vier? Das ist die entscheidende Frage, und eine, bei der ich auch gegenüber Google noch nicht die richtigen Worte gefunden habe. Ich gebe ihm da mit dem float-Pointer eine Matrix im Zeilen-Layout mit Translationsanteilen in der 4. Spalte. Und er soll diese drei Zeilen zu je 4 floats einfach unverändert hochladen, daher auch das GL_FALSE als Transponieren-Parameter. Aber anscheinend passiert genau da was komisches.
Vorsicht, in OpenGL wurden hier etwas seltsame Entscheidungen getroffen, durch die sich auf leicht tragische Weise DirectX und OpenGL weit weniger unterscheiden, als auf den ersten Blick anzunehmen wäre.

glUniformMatrix4x3 lädt prinzipiell tatsächlich 3x4-Matrizen, also 3 Zeilen und 4 Spalten, hoch. Genauso speichert der GLSL-Typ mat4x3 tatsächlich 3x4-Matrizen. Soweit passt alles noch mit deiner Beobachtung/Erwartung zusammen.

Überraschender ist nun, dass OpenGL standardmäßig (transpose = GL_FALSE) Matrizen im Spalten-Layout erwartet, d.h. ganze Spalten liegen konsekutiv im Speicher. Ironischerweise bedeutet das, dass die Matrizen im Speicher dadurch genau so aussehen, wie man es von DirectX-Zeiten gewohnt ist, die Transposition aufgrund der OpenGL-konventionellen Präfix-Matrix-Multiplikation und die Transposition des Speicher-Layouts heben sich gegenseitig auf.

Im Kontext deines Problems bedeutet das, dass du

a) in deinem Code mit zeilenweisen 4x3-Matrizen (4 Zeilen, 3 Spalten!) arbeiten kannst, d.h. Translationsteil in der 4. Zeile, darüber zeilenweise die Transformationsbasisvektoren. Diese kannst du dann direkt so an OpenGL (ohne Transposition) übergeben. Durch die nominelle Vertauschung von Zeilen und Spalten in OpenGL/GLSL heissen diese Matrizen dann auch im OpenGL Code tatsächlich konsistent mat4x3, bedeuten aber auf Shader-Seite 3 Zeilen und 4 Spalten.

b) in deinem Code durchweg die OpenGL-Konventionen und das entsprechende Speicherlayout annehmen, d.h. alle Matrizen spaltenweise speichern. Ironischerweise passt das mit den neuen DirectX-Versionen zusammen, die im Shader schon länger standardmäßig spaltenweise Matrizen annehmen. Auf Shader-Seite sind die Typnamen dann immer noch in DirectX und OpenGL identisch, haben aber natürlich weiterhin unterschiedliche Bedeutung.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Uff. Vielen Dank für Deine ausführlichen Erklärungen. Ich habe gerade eine etwa fünf Jahre alte Ahnung, was genau damals schief gegangen ist. Aber sorry, so richtig dämmert mir das noch nicht.

Erstmal normale 4x4-Matrizen:
Meine Matrizen: Zeilen-Layout, also 4 Zeilen zu je 4 floats nacheinander im Speicher, mit dem Translationsanteil jeweils im letzten float jeder Zeile. Damit Präfix-Matrix-Multiplikation.

Die muss ich nun transponieren, wenn ich sie in den OpenGL-Shader hochladen will, ich muss sie aber auch transponieren, wenn ich sie in einen HLSL-Shader hochlade. Demzufolge sind sie im Shader im Spalten-Layout gespeichert, also 4 Zeilen zu je 4 floats nacheinander, mit Translationsanteil geballt in der 4.Zeile. Damit Postfix-Matrix-Multiplikation.

Jetzt also 3x4-Matrizen, also 3 Zeilen zu je 4 floats:
Meine lokale Matrix ist davon unbeeindruckt, weil die Translationsanteile eh an 3., 7. und 11. Stelle kommen. Die sind also natürlich im 3x4 enthalten.

OpenGL und DirectX machen daraus 4 Konstanten zu je 3 floats, die vierte Zeile enthält die Translationen. Ich mach den Spaß ja aber nicht aus Spaß, sondern will unbedingt den 4. Interpolator sparen. Also brauche ich 4x3-Matrizen, also OpenGL mat3x4 oder DirectX float3x4. Damit bin ich dann wohl wieder bei Präfix Multiplikation, oder? Wenn ich also meine Wunsch-Transformation "vec3 = 3x4 * vec4" haben will, muss ich die Matrix transponieren. Das kann ich aber ganz einfach im Shader so hinschreiben, der Shader-Compiler generiert dafür ja keinen Code, sondern wechselt von "mul, mad, mad, mad" auf "dot4, dot4, dot4". Und DAMIT bin ich dann endlich da, wo ich eigentlich hinwollte.

Hab ich das jetzt alles auf die Reihe bekommen?

Randnotiz: als ich damals den Skinning-Code für die Splitterwelten-Engine geschrieben habe, bin ich an dieser Stelle ins Wasser gefallen. Ich habe ne Weile rumprobiert und gegoogelt und dann die Layout Modifier "column_major" und "row_major" gefunden. Und mit Anwendung dessen bekam ich tatsächlich meine Skinning Matrices auf 3 Register reduziert, aber mir wird jetzt erst klar, dass ich damit eigentlich den Compiler dazu gebracht, überall implizit zu transponieren. Puh. Wenn das jetzt so passt, dann hat sich der ganze Linux-Port eigentlich schon gelohnt :)

Ne, das passt alles immernoch nicht zusammen.

Code: Alles auswählen

// GLSL
mat4 dieeine, dieandere;
mat4 erg = dieeine * dieandere;
GLSL und HLSL nehmen Matrizen als row_major, also Translationsanteil unten in der 4. Zeile. Demzufolge müsste das ... ja, was? Präfix oder Postfix-Multiplikation sein? Nach meinem hier gerade live erprobten Versuch ist es Präfix. Das passt zu den Tutorials im Netz, aber nicht zur sonstigen Logik in meinem Shader. Fucknocheins.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von dot »

Code: Alles auswählen

layout(row_major) mat4 blub;
;)
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Ach hau doch ab :-)

Aber im Ernst: Danke, sowas hatte ich auch erwogen bzw. danach gesucht.. Aber mir wär's dann doch lieber, wenn ich auch kapiere, was genau da passiert. Und das ergibt immernoch keinen Sinn. Nehmen wir z.b. eine Translationsmatrix in dieser verdammt falschen Im-Shader-Schreibweise:

Code: Alles auswählen

[1  0  0  0]
[0  1  0  0]
[0  0  1  0]
[-2 -3 -4  1]
Wenn ich damit die Standard-Vorgehensweise für handschriftliche Matrix-Multiplikation durchgehe, kommt völlige Grütze raus. Ist das also ein automatisiertes Entgegenkommen vom Shader-Compiler, dass "Matrix * Vektor" trotzdem das Richtige tut? Oder ist das nur eine Speicherlayout-Frage, an der man sich nicht festhalten darf, und intern "denkt" der Compiler die ganze Zeit andersrum und achtet nur beim Lesen/Schreiben darauf, dass er das richtige tut?

Ich baue ja z.B. meine TangentSpace zu WorldSpace-Matrix im Shadercode so auf:

Code: Alles auswählen

mat4x4 tangMat = mat4x4( 
  vertexTang.x,    vertexTang.y,    vertexTang.z,    0.0f,
  vertexBitang.x,  vertexBitang.y,  vertexBitang.z,  0.0f,
  vertexNormale.x, vertexNormale.y, vertexNormale.z, 0.0f,
  vertexPos.x,     vertexPos.y,     vertexPos.z,     1.0f
  );

// erweitern zu Tangentkoords zu Weltkoords. Fickende Präfix-Multiplikation
tangMat = WeltMatrix * tangMat;
// und dem FragmentShader in die Hand drücken
fragTangZuWeltMatrix = mat4x3( tangMat);
Und was genau passiert hier? Nimmt der jetzt 3 oder 4 Interpolatoren in Anspruch? Laut OpenGL-Doku ist mat4x3 eine Matrix mit 4 columns und 3 rows. Also das, was ich will, nämlich nur 3 anstatt 4 Interpolatoren. Aber das geht ja nicht, denn wenn der bei der mat4x3()-Zuweisung in der letzten Zeile die vierte Zeile abschneidet, verschwindet der Translationsanteil. Und der kommt aber offensichtlich im Fragment-Shader an.

Was zur Hecke passiert hier?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von dot »

Die Schreibweise ist "falsch", weil der Konstruktor in GLSL in alter OpenGL-Manier die Elemente spaltenweise erwartet und nicht zeilenweise. Deine Verwirrung entsteht wohl daraus, dass du Speicherlayout, Transposition und Matrixmultiplikation als irgendwie zusammenhängende Konzepte betrachtest. Dem ist aber nicht so. Die Auswirkungen dieser einzelnen Dinge hängen zwar zusammen, rein konzeptionell handelt es sich da aber um grundverschiedene Dinge.

Auf der einen Seite haben wir die "Multiplikationsreihenfolge", also die Frage ob wir nun Matrix * Vektor oder Vektor * Matrix rechnen. Eigentlich ist nur ersteres "richtig", zweiteres ist lediglich aus historischen Gründen (die erste Auflage des Foley verwendete diese Notation afaik um den Druck bzw. Textsatz zu vereinfachen) in der Computergrafik anzutreffen (noch richtiger müsste man afaik eigentlich z.B. Normalvektoren von links und Richtungs- bzw. Ortsvektoren von rechts multiplizieren, aber wir schweifen ab). Die "Multiplikationsreihenfolge" beeinflusst, wie genau die Matrix aussehen muss, um den gewünschten Effekt zu haben (z.B. ob die Verschiebung in die letzte Spalte oder Zeile gehört und so). Entscheide dich für eine Konvention und halte dich konsistent daran. Matrix * Vektor ist aus mathematischer Sicht die einzig "richtige" Variante. Es ist rein prinzipiell aber völlig egal, welcher Konvention du folgst, so lange du dich dran hälsts. Du kannst natürlich nicht der Vektor * Matrix Konvention folgen und dann deine Matritzen aber so bauen, wie sie für Matrix * Vektor aussehen müssten.

Unabhängig von all diesen Dingen ist das Speicherlayout, also row-major vs. column-major. Diese Konvention regelt, wie genau ein float Array bzw. ein Stück Speicher als Matrix interpretiert wird, also ob wir die Matrix zeilenweise oder spaltenweise im Speicher ablegen.

Wenn du nun eine für die Matrix * Vektor gebaute 4x4 Matrix in row-major Form im Speicher ablegst und dein Shader diesen Speicher dann aber als colum-major Matrix interpretiert, dann liegt der Fehler daran, dass das float-Array falsch interpretiert wird. Diese Fehlinterpretation führt aber effektiv dazu, dass die Matrixelemente in transponierter Reihenfolge aus dem Speicher kommen, weshalb der Effekt sich durch ein zusätzliches transponieren der Matrix an einem Ende bzw. ein Umdrehen der Multiplikationsreihenfolge ausgleichen lässt. Das ändert aber nichts daran, dass der eigentliche Fehler ein Mismatch der "Aufrufkonvention" war und nicht, dass tatsächlich irgendein ominöses Transponieren der Matrix notwendig wäre. Mit nicht quadratischen Matritzen funktioniert das, wie du bereits festgestellt hast, dann auch nicht mehr, weil ein Mismatch nichtmehr nur einfach zu einer Transposition der Reihenfolge der Elemente führt...
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin verwirrt.

Beitrag von Schrompf »

Ok, so langsam kommen wir der Sache näher. Ich habe inzwischen die DX11-Version des kleinen Grafiktests gebaut und fertig bekommen. Was man da z.B. lernt, ist:

OpenGL schreibt Matrixtypen als columns x rows
DirectX schreibt Matrixtypen als rows x columns
Beide behaupten, standardmäßig column_major zu speichern.

Und dank der aussagekräftigen Reflection-Fähigkeiten zu Shadern von DirectX, an denen ich genau ablesen konnte, wieviele Konstanten zu je 4xfloat jedes Element wirklich frisst, habe ich jetzt auch raus, was die ganze Zeit in meinem Kopf verdreht war. Denn beide APIs sagen ja, sie speichern column_major. Also speichern sie spaltenweise. Und eine Matrix mit 4 Spalten belegt demzufolge 4 Konstantenregister oder vier Interpolatoren. Trotzdem ist es nach mathematischer Schreibweise eine dreizeilige Matrix mit 4 Spalten, nimmt also von rechts multipliziert einen Vierervektor an und ergibt einen Dreiervektor. Den Unsinn kann man dem Shader selektiv austreiben mit:

OpenGL: layout(row_major) mat4x3 Matrötzchen;
DirectX: row_major float3x4 Matrötzchen;

Also nur ein weiteres Defines für den Shader-Präprozessor-Header, wenn es dann an den Shader-Crosscompiler geht. Und daraus ergibt sich dann auch das Hochladen der Shaderkonstanten. Nur OpenGL hat da überhaupt dedizierte Schreibfunktionen, bei der man eine im Shader als mat4x4 definierte Matrix auch nur mit glUniformMatrix4x3fv hochladen darf. DirectX dagegen hat Konstantenpuffer, also ganz schlichte Speicherblöcke, da muss man selber drauf achten, Matrizen nur column_major zu schreiben. Da ich wie gesagt meine Matrizen (damals noch aus Unwissen) in mathematischer Schreibweise speichere, also row_major, muss ich also bei beiden APIs transponieren.

Spaßiges Randdetail: GLSL-Matrix-Konstruktoren erwarten die Parameter auch column_major, bei HLSL-Matrix-Konstruktoren werden die Initialdaten dagegen nach mathematischer Schreibweie in row_major erwartet.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin [nicht mehr] verwirrt.

Beitrag von Schrompf »

Einige Monate später: was sich als echter Krampf im Arsch erwiesen hat, sind konstante Arrays.

Code: Alles auswählen

// HLSL / DirectX
static const float2 gOffsets[] = {
  { 1, 2 },
  { 6, 5 }
};

Code: Alles auswählen

// GLSL / OpenGL
const vec2 gOffsets[] = vec2[](
  vec2( 1, 2 ),
  vec2( 6, 5 )
);
Das abstrahiert zu bekommen wird ne Makrowüste :-(
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: OpenGL vs. DirectX - Ich bin [nicht mehr] verwirrt.

Beitrag von Spiele Programmierer »

Vielleicht solltest du den Code selbst parsen und transkompilieren?
Ist natürlich eine Menge mehr arbeit, aber je nachdem was du genau alles erreichen willst kommst du damit wahrscheinlich einfacher weg.
Ich habe gehört, es gibt auch ein GLSL Frontend für LLVM. Vielleicht wäre das eine Idee, dann bekommst du noch gute Optimierungen quasi kostenlos, also ähnlich zu dem.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin [nicht mehr] verwirrt.

Beitrag von Schrompf »

Hm, ich hatte schon gehofft, das irgendwie "contained" abzuhandeln. LLVM als Dependency ansaugen erscheint etwas viel.

Nächstes Ärgernis. In HLSL kann man auch auf Einzelwerten swizzlen:

Code: Alles auswählen

float w = 1.0f;
float4 dings = w.xxxx;
In OpenGL ist das verboten. Die haben extra Code in den Compiler eingebaut, um dafür ne Fehlermeldung zu generieren.

Code: Alles auswählen

float w = 1.0f;
vec4 dings = w.xxxx; // error C7505: OpenGL does not allow swizzles on scalar expressions
Wär ja auch zu einfach gewesen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: OpenGL vs. DirectX - Ich bin [nicht mehr] verwirrt.

Beitrag von Spiele Programmierer »

Das mit der Dependency stimmt schon.
Allerdings könntest du das Parsen der Shader ja einmalig bei dir im Buildprozess ausführen und HLSL und GLSL fertig erzeugt ausliefern.

Zu deinem neuen Problem: Dafür kannst du zumindest in dem Fall "vec4(w.x)" verwenden.

GLSL und HLSL sind halt einfach verschiedene Sprachen. Die sind nicht gleich und du kannst sie auch nicht so einfach gleich machen.
Wie weit du mit einem hässlichen Missbrauch des Präprozessors kommst ist reine Glückssache.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: OpenGL vs. DirectX - Ich bin [nicht mehr] verwirrt.

Beitrag von Schrompf »

Ansichtssache.

Das vec4(w) hatte ich übrigens so eingebaut. Das scheitert jetzt wieder auf Seiten von DirectX mit error X3014: incorrect number of arguments to numeric-type constructor. Also doch ne kleine Inline-Helferfunktion, wie das der Herr von bgfx gemacht hat.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Antworten