Problem mit Blendingmodien [C++ | OpenGL | WinAPI]
Hallöchen,
ich hab ein kleines Problemchen mit einem OpenGL Programm. Und zwar sollen dabei 2 Sprites per Blending transparent dargestellt werden, so dass die schwarzen Ränder verschwinden. Das klappt soweit nur mit einem der beiden Sprites. Also eines wird so schön transparent dargestellt, das andere bleibt unverändert.
Das Ganze hab ich in der Dev C++ IDE geschrieben und hier gibts das Zeug zum Download: http://derfeind2k.de/daten/Open GL Kreis.rar
Einfach per Curosrtasten mal horizontal drehen lassen, dann seht ihr was ich meine. Eines ist transparent und überblendet mit dem anderen, das andere bleibt unverändert.
Ach ja, ich bin noch am Anfang und orientiere mich gerade an folgenden Tutorials: http://nehe.gamedev.net/
Ich hoffe es gibt hier ein paar OpenGL kundige Menschen die mir helfen können.
Da ich hier Linux laufen habe, kann ich mit deinem Programm nichts anfangen...
Vielleicht wäre es nützlich, wenn du deinen OpenGL-Code postest. Sowohl die Einstellungen was das Blending angeht (glEnable) und den eigentlichen Rendercode..
Davon abgesehen, wenn es dir nur darum geht, Teile einer Textur transparent darzustellen brauchst du kein kompliziertes Blending..
Dafür gibt es den Alpha-Test. Du musst dann natürlich nur eine Textur mit Alpha-kanal laden, dann funktioniert das ganze. Blending wird benutzt, wenn du mehrere Texturen miteinander vermischen willst, um zB Überläufe oder Lightmaps darzustellen.
Edit:
So hab gesehn, das auch der Quellcode im Packet war, hab mal einen Blick darauf geworfen. Ich weiß ehrlich gesagt nicht genau, wann die Vertex-Informationen in den Framebuffer geschrieben (direkt, oder erst bei glEnd) werden, aber beim Blending spielt die Reihnfolge eine wichtige Rolle. Geblendet wird immer die Informationen, die du in den Framebuffer schreiben willst, zusammen mit der Information, die bereits im Framebuffer steht.
Beim ersten Quad, wird die Textur mit einem quasi leeren Framebuffer geblendet, was den gewünschten Effekt bringt. Das zweite Quad blendet mit der Textur des ersten, die in dem Fall identisch sind. Da die Textur keinen Alpha-Wert besitzt hat die Blendingeinstellung, in dem Fall keine Auswirkung und es wird nur komplett die Texturinformation benutzt, was logischerweise zu keiner Transparenz führt. (Da mögen kleinere Fehler in der Erklärung sein, habe noch nicht wirklich Erfahrung mim Blending, aber das scheint mir die logischste Erklärung zu sein, bzw. ich bin überzeugt, das es an der Reinfolge liegt.)
Wie gesagt, für das was du möchtest ist der Alphatest viel nützlicher. Vernünftige Formate sind PNG oder besser TGA (gibt mehr Loader dafür). Ich würde sowieso gucken, daß du dir einen neueren Loader besorgst, bzw. selbst schreibst, glaux ist ein wenig veraltet.
Ich persönlich bin mit SDL und SDL_Image sehr zufrieden. (www.libsdl.org)
Danke erstmal für die Antworten.
Ich schätze das bedeutet, ich muss mich mehr mit OpenGL und Buffers befassen bevor ich das verstehe.^^
Allerdings frage ich mich dann, wieso folgendes Tutorial ohne Probleme funktioniert: http://nehe.gamedev.net/data/lessons....asp?lesson=09
(Quellcode gibts am unteren Ende der Website, auch für Linux und andere Systeme / Compiler)
Gibt es vielleicht online ein Nachschlagewerk wo die OpenGL Befehle möglichst genau erklärt werden? Bisher hab ich nur die Microsoft-MSDN Hilfe (http://msdn.microsoft.com/library/de...unc01_3bad.asp) wo ich nachsehen kann, was es da so in etwa gibt. Aber die Beschreibung ist extrem knapp und ohne Grundwissen schlecht nachzuvollziehen.
Oder kennt ihr ein paar gute Einstiegswerke (Bücher) die man sich mal ansehen sollte? Ich bin erst seit ein paar Tagen dabei und es fehlt wohl noch eine ganze Menge Wissen in Sachen OpenGL.
Noch eine andere Sache, lohnt es sich überhaupt, OpenGL zu lernen? Ist vielleicht DirectX viel effizienter? Bessere Grafik oder schneller / leistungsfähiger? Besser mit C++ zu integrieren oder einfach leichter zu erlernen? So wie es auf der OpenGL Seite steht, ist OGL ja ein besonders deshalb beliebt weil es portabel ist, im Gegensatz zu DirectX. Hat es denn auch die gleiche Leistung? So Spiele wie Far Cry und Doom III kann man ja wahlweise in DX oder OGL rendern lassen, demnach müsste beides doch in etwa gleich leistungsfähig sein, oder?
www.delphigl.com hat einige sehr gute deutsche Tutorials zum Thema OpenGL, vor allem was den technischen Hintergrund (Buffer&Co) angeht. Da GL-Programmierung unter allen sprachen identisch ist, kannst du auch als c'ler damit was anfangen.
Ansonsten ist das Redbook (OpenGL Programming Guide) und das Blue Book (Reference) zu empfehlen. Beide gibt es in einer etwas älteren Version unter www.opengl.org zum Download.
Was die Sache OpenGL vs. Direct3D angeht. Technisch gesehen geben sich beide APIs nichts. Es gibt glaube ich nichts großartiges, was die eine API kann und die andere nicht. Performancetechnisch eigentlich auch kein Unterschied zu nennen, oder falls es einen gibt, ist er zu vernachlässigen (Performanceverluste sind sowieso eher auf den Programmierer zurückzuführen, aber das kennen wir ja *g*).
Ich habe im Grunde keine Erfahrung was DirectX / Direct3D angeht, aber ich meine gehört zu haben, die OpenGL-API sei leichter zu lernen und zu verstehen als DirectX, aber das ist wie gesagt dritte Quelle.
Was, bei der Entscheidung, eine Rolle spielen kann sind die Fakten, daß DirectX Windows-only ist, während OpenGL cross-kompatibel ist. Daneben muss natürlich ein entsprechender Treiber vorhanden sein. DirectX kann man im Grunde auf jedem PC vorraussetzen, auf dem jemand ein Spiel spielen will. Für OpenGL reicht meistens der mitgelieferte Treiber von Windows nicht mehr aus. Das bedeutet wenn du ein Spiel in OpenGL schreibst, muss der Spieler einen aktuellen Treiber für seine Grafikkarte installiert haben. Hardcore-Gamer haben das mit Sicherheit, andere Gelegenheitsspieler vielleicht eher nicht. Das ist dann wohl eher eine Frage der Zielgruppe und welche Features du sowieso benutzen willst. (Ob jetzt OpenGL 1.2 oder 2.0 bzw. DirectX 8.0 oder 9.0)
Was den Code des Nehe-Tuts angeht, kann ich nur vermuten (as said keine eigene Erfahrung mit Blending), aber hier wird jeder Stern in einem eigenen glBegin() glEnd() Block gerendert, während du beide Quads in einem solchen Block hattest, vielleicht liegt es daran.
Ich bleib aber dabei, um Stellen transparent darzustellen ist Blending mMn mit Kanonen auf Spatzen zu schießen. Guck ob du einen Loader für Formate mit Alpha-Kanal findest, und benutz den Alpha-Test. Blending ist ein spezieller netter Effekt, der glaube ich kaum zum Basiswissen für OpenGL gehört.
Ich kann mir dein Programm leider auch Linux-bedingt nicht ansehen, ganz zu schweigen davon, dass ich wenig Zeit habe... nichtsdestotrotz schmeiss ich dir noch ein paar Links rein, fyi.
Erstmal vielen Dank euch allen für die Links und Tipps. Ich hab jetzt (dank der Tutorials von delphigl.com) eine Möglichkeit gefunden, korrekt zu blenden:
Zitat von delphigl.com
[...]sehen wir zwei sich überlappende Lichtquellen mit einem normalerweise verwendetem Tiefentest (GL_LEQUAL oder GL_LESS). Das die grüne Lichtquelle die zweite verdeckt ist reiner Zufall und liegt wohl daran das diese als erstes gerendert wurde. Wie oben gesagt (vereinfacht) steht dann im Z-Puffer drin das an dieser Stelle (des grünen Lichtes) bereits ein Objekt im Z-Puffer liegt. Danach wird dann irgendwann die zweite (blaue) Lichtquelle gerendert, aber die Stellen an denen bereits steht das dort im Z-Puffer ein Fragment liegt werden nicht mehr gerendert, aufgrund des Tiefentests. Das zweite Bild ist hingegen korrekt, einzig der Tiefentest wurde auf GL_ALWAYS umgestellt. Dann werden die mit der Lichttextur belegten Quads immer gezeichnet, egal ob sich an der Z-Position bereits ein Fragment befindet oder nicht, und bei Lichtquellen ist das reichlich egal welche zuerst gerendert wird. Denn ob ich jetzt Blau mit Grün addiere, oder Grün mit Blau ist egal, denn beides ergibt im Ende Türkis. Das dürfte dann hoffentlich verstanden worden sein, wenn nicht dann einfach mal das Beispielprogramm öffnen und den Tiefetest wie hier angesprochen ändern; Probieren geht je bekannter weise meist über Studieren.
Abschließend auch noch kurz zum verwendeten Blendmodus :
glBlendFunc(GL_ONE, GL_ONE);
Wer sich schon mal ein wenig mit dem Thema Blending beschäftigt hat, wird schnell erkennen was hier abläuft. Sowohl der Quellfaktor als auch der Zielfaktor stehen auf GL_ONE, was bedeutet das bei unserer Blendoperation die bereits im Framepuffer befindliche Farbe mit der Farbe unseres Lichtes addiert wird (additives Blending genannt). Bei einer grünen Lichtquelle haben wir in der Mitte also RGB = 0/1/0 und wenn wir das dann auf einen Pixel legen würden der halb grau ist (RGB = 0,5/0,5/0,5) hätten wir als Ergebnis RGB = 0,5/1/0,5 (1+0,5 ist eigentlich 1,5 , aber OpenGL zwängt Farbwerte in den Bereich 0..1).
...
Wenn ich das korrekt verstanden habe, bedeutet das also einfach, dass mit einer verwendeten Einstellung "glDepthFunc(GL_LEQUAL)" nur das zuerst gerenderte Objekt geblendet wurde und das 2te nicht mehr (weil an dieser Stelle bereits das erste Objekt liegt). Mit der Modie "glDepthFunc(GL_ALWAYS)" funktioniert es dann korrekt und überblendet so wie es soll. Hat also indirekt doch etwas mit der Tiefe (Tiefenbuffer und was zuerst gezeichnet wird) zu tun. Dank dir MagicMagor, die empfohlene Seite hat mir besonders in diesem Problemfall sehr weitergeholfen.