ich stehe gerade vor dem Problem, dass ich mehrere Texturen übereinander blenden möchte.
Ich habe eine Ebene gerastert in 512x512 große Gras - Texturen. Auf die möchte ich jetzt, wie zB. in Gimp mit dem Muster-Tool möglich, andere Texturen blenden. Das ganze mit weichen Kanten. Das sollte etwa so aussehen:
Das bild ist mit Gimp erstellt (auch das Blenden). Ich will das ganze jetzt aber mit OpenGL machen. Die Texturen habe ich, nur fehlt mir der Ansatz.
Ich habe mir schon ein paar Gedanken gemacht, und bin auf die "FastLib" (FastDIB, FastBlend...) gestoßen. Damit kann man aber leider nur Bitmaps blenden, und da ich nen Alphakanal dafür brauche scheint diese Methode auszuscheiden.
Die zweite Möglichkeit ist das ganze per RenderToTexture zu machen, aber das ist ein bisschen umständlich.
Kennt jemand einen Weg das irgendwie eleganter zu machen?
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Hab ich das richtig Verstanden. Du hast eine Grastextur und eine Steintextur und möchtest dort mit der Maus drauf rummalen und wo du gemalt hast soll die Steintextur sichtbar werden. Und als Pinsel zum Malen soll die dritte schwarz weiß Textur benutzt werden?
Nur unter Vorraussetzung, dass ich das richtig verstanden habe. Meiner Meinung nach solltest du die Steintextur mit einem Alphakanal versehen. Idealerweise eine extra Textur die nur den Alphakanal enthält. Und in diesen Alphakanal kannst du entweder die Werte der anderen Textur auf der CPU einrechnen und die Daten neu zur Textur übertragen. Oder aber du machst etwas wie RenderToTexture und blendest die dritte Textur dann Addaptiv dort mit rein. Da stellt sich dann die Frage ob du FrameBufferObjects benutzen kannst oder nicht.
ja, du hast das richtig verstanden. Ich denke ich teste mal das von Hand Pixel für Pixel auf der CPU zu berechnen. Ich hab aber bedenken, dass da die Performance stimmt.
Ansonsten bliebe ja noch Render to Texture übrig. FramebufferObjects habe ich noch nicht genutzt, wäre aber kein Problem für mich, mich da einzulesen. Welche Vorteile hätte das denn?
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Framebufferobjects erlauben dir das Rendern in Texturen ohne zwischenschritt im "echten" Framebuffer. Wenn du so ein ding aktiviert hast, dann zeichnet er nicht aufs Fenster sondern direkt in eine Textur. Alternativ hat man beim RenderToTexture die möglichkeit mit glCopyTexImage2D die möglichkeit, den Inhalt des Framebuffers in eine Textur zu kopieren.
Framebufferobjects sind allerdings verhältnissmäßig neu, daher ist das mit dem Hardwaresupport immer so eine Sache.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Markus: Ja so etwas auf der CPU zu berechnen ist nicht gerade harmlos. Vor allem, wenn du bei reinem Pascal bleibst. Denn dort bräuchte man für jedes Pixel noch eine Bereichsprüfung. Auch wenn die Rechnung (addition) recht einfach ist summiert sich das mit den Abfragen auf einen gigantischen Berg Arbeit. Wenn Assembler machbar wäre kann ich zu MMX raten. Wenn ich mich nicht vertue (hab mein schlaues buch gerade nicht), dann unterstützt es einen Befehl um 8 Felder zu addieren und dabei automatisch eine Bereichsprüfung durchzuführen. Entsprechend kannst du dir ausmalen wie schnell es sein dürfte.
FBO: Wie Lord Horazont schon sagte. Sehr mächtig aber auch sehr neu. Was die Hardwareanforderungen ziemlich in die Höhe treiben würde.
glCopyTexImage2D: Das ist der Weg den ich mit RenderToTexture angegeben habe. Aber ich habe mir vorhin die Probleme gesparrt, da ich nicht wusste ob ich es verstanden hatte. Du brauchst eigentlich eine Alphatextur um den Stein durchsichtig zu machen. Aber mit glCopyTexImage2D kannst du nur Daten kopieren. Alpha aus dem Framebuffer. Was nicht immer funktioniert, dass der Framebuffer auch einen Alpha hat. Da müsste man dann ziemlich stark mit den Formaten rumtricksen um das Sinnvoll umgehen zu können.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Benutzt du Delphi oder FreePascal? FreePascal hat eine Unit mmx mit der du den MMX-Support ohne direkten Inline-Assembler nutzen kannst.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Das hört sich ja alles eher suboptimal an. Wenn es mit Render to Texture nicht so einfach mit dem Alphakanal geht.. ist das mit FrameBufferObjects besser? Ist es damit möglich den AlphaChannel gleich in die Textur zu bekommen, oder muss man da auch tricksen?
Die Hardwareanforderungen stehen erstmal an zweiter Stelle.
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
dank eurer Tipps bin ich jetzt schon weiter vorangekommen.
Ich habe eine "Brush" Textur, in die ich die Pinseltextur mittels glBlendFunc(GL_SRC_ALPHA, GL_ONE) immer wieder rendere.
Dann rendere ich in die zweite Textur meine Brushtextur und blende mit glBlendFunc(GL_ZERO, GL_SRC_COLOR) meine Steintextur drüber. Das funktioniert auch sehr gut soweit:
Jetzt möchte ich aber noch meine Grastextur darunter haben, und da hab ich ein paar Probleme das richtige Blending zu benutzen. Im Moment rendere ich die Grastextur in eine dritte Textur und dann mit
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR) die Textur oben auf dem Bild darüber. Das hat aber leider nicht den gewünschten Effekt (siehe richtige Grastextur in erstem Posting).
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Die Idee ist zwar ganz nett aber du solltest bedenken was passiert, wenn das jemand mal 30-45 Minutenlang benutzt. Willst du dann 2000-30000 mal immer wieder ein und die selbe Textur zeichnen? Wenn so etwas sein kann, dann musst du da etwas zum Cachen finden. Aber das bringt mich zu einer anderen Frage. Was hast du damit insgesammt vor? Je nachdem wie komplex es werden soll kann es sein, dass du von hause aus etwas komplexer ansetzen solltest. Es nützt ja nichts, wenn du für das eine Problem jetzt eine Lösung findest aber beim nächsten feature wieder ins Trudeln gerätst.
Eine Möglichkeit wäre, dass du deine Pinselstriche so zeichnest wie jetzt und anschließend das gezeichnete in eine Textur kopierst. Sollte schon etwas in dieser Textur sein so würdest du diese vorher auch noch mal zeichnen und nur die Pinselstriche seit dem letzten mal "Textur aktualisieren" ausführen. Damit hättest du dann eine Textur in der alle Pinselstriche als RGB Werte enthalten sind.
Dann würde es sich anbieten via Multitexturing alle 3 Texturen auf ein Quad zu zeichnen. Und diese mit GL_ARB_texture_env_combine oder mit Shadern zu verrechnen. Wenn du später noch so ein paar Sachen mit brauchst. So andere Modis als nur normale Transparenz würde ich lieber gleich zu Shadern raten. Denn siehe oben. Es nützt nichts, wenn du später wieder an grenzen stößt.
Wie viele Ebenen sollen es denn später mal werden? Evtl solltest du dann auch von Hause aus auf FBOs setzen.
also das ganze soll das Terrain für ein 2D Spiel werden. Die unterste Textur ist eben die Grastextur und darauf soll man mehrere verschiedene andere Texturen zeichnen können. Das ganze hab ich mit einem FBO gerendert. Geplant ist eigentlich nicht mehr, also nur das zeichnen mit dem Pinsel und verschiedenen Texturen. Ich glaube nicht, dass ich länger als 5 min pro Map mit dem zeichnen verbrauchen werde.
Ich bin jetzt nicht ganz sicher, ob meine Variante mit den FBOs dafür ausreicht, bzw ob es was besseres gibt. Eigentlich habe ich ja jetzt nurnoch das Problem mit dem letzten Blending, weil ich ja nicht mehr Features einbauen möchte, oder habe ich da was falsch verstanden? Oder wäre es besser statt Blending Multitexturing mit GL_ARB_texture_env_combine zu verwenden?
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Soll die Textur eigentlich zur Laufzeit erzeugt werden oder willst du sie dann abspeichern und dann nur eine fertig erzeugt Textur benutzen?
Multitexturing. Mit dem Multipassverfahren kannst du nicht alles machen, denn was im Framebuffer ist kannst du nicht mehr verändern sondern mehr oder weniger nur noch überschreiben. Und mit GL_ARB_texture_env_combine kannst du beeinflussen wie die einzelnen Texturen miteinander verrechnet werden.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Mir ging es nur darum ob du das offline machen willst oder nicht.
Mit GL_ARB_texture_env_combine habe ich noch nicht so viel gemacht. In deinem Falle ist es aber dann so, dass du eine ganz normale Blendfunc hast. Identisch mit GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA. Und das wäre GL_INTERPOLATE_ARB mit dem EnvCombiner. Du musst dann nur noch festlegen welche Quellen du für die 3 Operanden benutzen möchtest. In dem Anwendungsbeispiel unten wurde das alles so weit schon gemacht. Nur, dass dort als dritte Alphaquelle eine konstante Farbe zum Einsatz kommt. Du müsstest (denke ich) bei einer RGB Textur als SOURCE2_RGB dann GL_TEXTURE1 oder 2 angeben. Die in der sich das gezeichnete befindet. So weit ich mich gerade nicht vollkommen vertue.
PS: Wäre es nicht einfacher direkt Gimp zu benutzen?
sicherlich wäre es einfacher Gimp zu benutzen, dann würde im Gegenzug aber auch sehr viel Komfortablität des Editors entfallen. Aber ich glaube genau das werde ich machen, denn ich bin hier gerade total verwirrt .
Eigentlich müsste es mit ganz normalem Blending doch auch gehen, aber es kommt nicht mehr dabei raus, als die Ergebnisse im obigen Post.
Trotzdem danke für die Hilfe!
Edit: Ich müsste es irgendwie schaffen, alles weiße in einer Textur in einen Alphawert umzuändern. Ist das mit GL_ARB_texture_env_combine möglich?
Mitglieder in diesem Forum: 0 Mitglieder und 16 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.