Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Sa Dez 21, 2024 16:05

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: Fr Aug 26, 2016 13:16 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
Hallo,
ich seh den Wald vor lauter Bäumen nicht.

Ich habe eine Textur (TglBitmap2d, "Szene"), die ggf. auch bereits einen AlphaKanal mit transparenten Bereichen enthält. Diese Textur wird Vollbild auf ein (anderes Vollbild-)Hintergrundbild ("Landschaft") gezeichnet.

Nun möchte ich -bildlich gesprochen- mit einer "Röntgentaschenlampe" durch die vordere Textur durchsehen können, z.B. mit einem kreisrunden oder sternförmigen Ausschnitt. Diese Textur liegt ebenfalls als TglBitmap2d vor, allerdings soll hier der Helligkeitswert (Schwarz = undurchsichtig, Weiß = voll durchsichtig) des Bitmaps verwendet werden (nicht der Alphakanal der Textur).

Diese "Lightmap" will ich nun (nur!) auf den Alphakanal des Hintergrund-Bildes ("Szene") zeichnen (bevor "Szene" gerendert wird?), damit wenn "Szene" gerendert wird diese bereits dort durchsichtig ist, wo die "Lightmap" es will.

In dem Beitrag viewtopic.php?f=10&t=10888 wird irgendwie mit 3 Texturen gearbeitet, und in https://wiki.delphigl.com/index.php/Tutorial_Lektion_7 kann ich die zwei Texturen zwar überblenden, aber es kommt nicht das bei raus, was ich erwarte.

Ich arbeite im reinen 2D-Modus. Die RGB-Werte der "Szene"-Textur sollen logischerweise nicht verändert werden.

Des weiteren bin ich mir sehr unsicher, wie die einzelnen glBlend-Funktionen sich letztendlich verhalten, und ob die immer gehen, oder nur wenn TiefenTest an/aus ist, oder, oder, oder...?

Code:
  1.  
  2.  
  3.  glColor4f(1, 1, 1, 1);
  4.  
  5.   glDisable(GL_BLEND);
  6.  
  7.       with Landschaft do begin
  8.       Left := 0;
  9.       Top := 0;
  10.       Width := ClientWidth;
  11.       Height := ClientHeight;
  12.       Landschaft.Render;
  13.     end;
  14.  
  15.   glEnable(GL_BLEND);
  16.  
  17.   // Textur 1 setzen
  18.   glActiveTexture(GL_TEXTURE0);
  19.   glEnable(GL_TEXTURE_2D);
  20.   glBindTexture(GL_TEXTURE_2D, HintergrundBild.Textur.ID); // "Szene"
  21.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  22.  
  23.  
  24.   // Alphatextur setzen
  25.   glActiveTexture(GL_TEXTURE1);
  26.   glEnable(GL_TEXTURE_2D);
  27.   glBindTexture(GL_TEXTURE_2D, mask.Textur.ID);
  28.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  29.  
  30.   glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
  31.   glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
  32.   glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); // k.A. was hier für Werte hinkommen?
  33.   glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
  34.  glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
  35.  
  36.  
  37.   glBegin(GL_TRIANGLE_STRIP);
  38.  
  39. //    glColor4f(0, 0, 0, 0);
  40.     glMultiTexCoord2fARB(GL_TEXTURE0, 0, 0);
  41.     glMultiTexCoord2fARB(GL_TEXTURE1, 0, 0);
  42.     glVertex3i(5, Clientheight-5, 0);
  43.  
  44.   //  glColor4f(0, 0, 0, 0);
  45.     glMultiTexCoord2fARB(GL_TEXTURE0, 0, 1);
  46.     glMultiTexCoord2fARB(GL_TEXTURE1, 0, 1);
  47.     glVertex3i(5, 5, 0);
  48.  
  49. //    glColor4f(0, 0, 0, 1);
  50.     glMultiTexCoord2fARB(GL_TEXTURE0, 1, 0);
  51.     glMultiTexCoord2fARB(GL_TEXTURE1, 1, 0);
  52.     glVertex3i(Clientwidth-5, Clientheight-5, 0);
  53.  
  54.   //  glColor4f(0, 0, 0, 1);
  55.     glMultiTexCoord2fARB(GL_TEXTURE0, 1, 1);
  56.     glMultiTexCoord2fARB(GL_TEXTURE1, 1, 1);
  57.     glVertex3i(Clientwidth-5, 5, 0);
  58.  
  59.   glEnd;
  60.  


Aktuell kommt hier nur ein schwarzer Bildschirm raus. Wenn ich den zitierten Code auskommentiere (bis auf Landschaft.Render) klappt wieder Alles.

Warum müssen wieder so viele glTexEnvi(GL_TEXTURE_ENV, ... gesetzt werden? (Muss wohl nicht, aber in dem anderen Thread ist es benannt)

Ich tät' mich auch damit zufrieden geben, die Textur "Szene" zuerst auf eine neue TglBitmap2d Textur zu rendern, die "Lightmap" dann drüber zu rendern und diese neue Textur dann letztendlich später erst darstellen zu lassen, aber ich glaube, das ist unnötig viel Arbeit, bzw. ich weiß trotzdem nicht wie es geht.

TglBitmap.AddAlphaFromBitmap oder TglBitmap.AddAlphaFromglBitmap schlägt leider immer fehl mit AssertionFailed, wenn ich ein z.B. TBitmap zuweisen will...

Danke im Vorraus für Antworten.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: Fr Aug 26, 2016 20:33 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Meinst du so wie die Wolken auf dem Globus von meiner Demo ?

http://mathias1000.bplaced.net/VLI/index.html

Wen du OpenGL 3.3 verwendest, würde ich dafür einfach einen passenden Shader schreiben.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: Sa Aug 27, 2016 10:19 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
Ja, generell schon sowas wie die Wolken, mein mir würde ich halt gerne die "Wolken" zu laufzeit verändern.

Ich gehe das nochmal von einer anderen Seite an:

Ich habe ein TglBitmap2D und möchte nur den Alphakanal auslesen oder ersetzen. Wie geht das am besten?

(Wie gesagt, .AssignAlphaFromBitmap löst bei mit eine Assertion aus... Warum auch immer?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: So Aug 28, 2016 16:25 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Verwendest du Lazarus oder Delphi.

Willst du die Textur zur Laufzeit ändern, oder ist dies eine einmalige Sache bei Programmstart ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: So Aug 28, 2016 16:33 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
Delphi 2010.

Das Bild das ich "durchleuchten" will kommt (vom jeweiligen Benutzer) von Festplatte, halt also teilweise auch schon AlphaKanal mit drin.

Mit einem anderen Bild will ich diese Textur an machen stellen zusätzlich durchsichtig machen.

Wenn's geht die "Maske" als Lightmap (Weiß = Alpha Nicht verändern, Schwarz = Aufm Zielbild alles durchsichtig; Alpha der "Maske" wird ignoriert), ansonsten einfach das Alpha der Maske rüberkopieren (Maske hat andere Größe als das eigentliche Bild und soll nur in einem bestimmten bereich gezeichnet werden.

AddAlphaFromglBitmap geht halt wie gesagt leider nicht.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: So Aug 28, 2016 16:41 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Das Bild das ich "durchleuchten" will kommt (vom jeweiligen Benutzer) von Festplatte, halt also teilweise auch schon AlphaKanal mit drin.

So wie es aussieht, willst du das machen, bevor du das ganze an OpenGL übergibst ?

Zitat:
Mit einem anderen Bild will ich diese Textur an machen stellen zusätzlich durchsichtig machen.

Verstehe ich das jetzt richtig, du hast irgend ein Foto, auf diese willst du einen Scherenschnitt legen und rendern willst du nur dies, was man durch den Scherenschnitt sieht ?

Zitat:
Delphi 2010.

Da kenne ich leider zu wenig.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: Mo Aug 29, 2016 09:00 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
Ich habe in den Anhang nun einmal ein Beispiel gelegt.

Der Hintergrund ("Landschaft") ist hier das grau-weiße Raster. Man beachte, dass die Szene (das blaue "Bild") bereits einen transparenten Bereich enthält (weil .png-Datei), mit dem man durch den viereckigen Kasten das Raster sehen kann. Nun möchte ich beispielhaft ein "Guckloch" in sternenform haben (mask.bmp, rechts unten in der Ecke beispielhaft dargestellt). Ob ich von der Maske die Transparentwerte über Helligkeit (Schwarz/Weiss abstufung) oder den Alphakanal (.png-Datei) bekomme ist mir egal, es muss nur funktionieren. Diese sternenförmige Transparenz muss ich nun so auf die Szene (Blaues Bild) bekommen, dass man das dahinterliegende Raster sehen kann. Das Sternenmuster soll hier später z.B. von links nach rechts durch den Bildschirm laufen, so dass man immer andere Bereiche vom Hintergrundbild (Raster) sehen kann, oder mit Kopplung an die Maus, dass der Benutzer selbst das Hintergrundbild (Raster) "ausleuchten" oder "röntgen" kann.

Ob ich nun für jeden Frame eine neue Textur erstelle, oder auf die vorhandene Textur (Szene) einen transparentwert drauflegen kann ist mir egal, es muss nur funktionieren.

Generell könnte ich über die Canvas.Pixels[x,y] die Alphawerte manuell kombinieren, aber das dauert zu lange. Scanline kann nur die kompletten werte übernehmen (also auch die "sichtbaren" Farben RGB), deshalb scheidet das aus(?).

TL;DR: Wie kann ich bei TglBitmap2D nachträglich den AlphaKanal verändern?


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: Di Aug 30, 2016 17:36 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Meinst du so etwas wie in meinem Anhang ?

http://mathias1000.bplaced.net/diverses ... g_Fenster/

_________________
OpenGL


Zuletzt geändert von mathias am Di Aug 30, 2016 19:48, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: Di Aug 30, 2016 18:07 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
Ja, genau das ist das, was ich meine, vielen Dank für das Beispiel!

Ich gehe davon aus, dass man das Schwarz durch ein anderes Bild ersetzen kann (sollte ja kein Problem sein). Auch der Stern ist an den Seiten blau "ausgefranst", liegt ggf. aber auch einfach an der Textur.

Wie ich das sehe hast du das mit Shadern gemacht. Das ist natürlich nochmal ein großer Schritt im Bereich OpenGL, der mir nach einem Neueinstieg natürlich nicht einfach fällt. Dürfe ich evtl. den Code dazu sehen, weil in der Wiki zwar detailliert Shader erklärt werden, aber ein kleines Beispielprogramm sich aber doch leider missen lässt...

Frage: Kommt dabei ein "neue" Textur raus, die du dann renderst, oder sagst du sowas wie Rendere_Uebereinander(Sampler0, Sampler1)?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: Di Aug 30, 2016 19:46 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Frage: Kommt dabei ein "neue" Textur raus, die du dann renderst, oder sagst du sowas wie Rendere_Uebereinander(Sampler0, Sampler1)?

Einfach gesagt, ich verknüpfe die beiden.

Das passiert hier:
Code:
  1. void main()
  2. {
  3.   if (texture( Sampler1, UV1 ).a == 0.0){
  4.     FragColor=vec4(0.0, 0.0, 0.0, 1.0);
  5.   }
  6.   else {
  7.     FragColor = texture( Sampler0, UV0 );
  8.   }
  9. }

Ich prüfe, ob der Pixel des Sternes gesetzt ist, wen ja, Pixel des Fotos übernehmen, ansonsten Pixel schwarz.
Der Stern kann auch eine Bitmap ohne Alpha-Kanal sein, dann muss aber anstelle von ".a", zB. ".r" sein.

Zitat:
Auch der Stern ist an den Seiten blau "ausgefranst", liegt ggf. aber auch einfach an der Textur.

Nein, da hat sich in der schnelle im Fragment-Shader ein Fehler eingeschlichen. :oops:
Ersetze in "Fragmentshader.glsl" die main Function mit obigen Code, dann sieht es viel besser aus.

PS: Im obigen Link sollte jetzt der richtige Shader vorhanden sein.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glBitmap.AlphaKanal zeichnen
BeitragVerfasst: Di Aug 30, 2016 20:08 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Wie ich das sehe hast du das mit Shadern gemacht. Das ist natürlich nochmal ein großer Schritt im Bereich OpenGL, der mir nach einem Neueinstieg natürlich nicht einfach fällt. Dürfe ich evtl. den Code dazu sehen, weil in der Wiki zwar detailliert Shader erklärt werden, aber ein kleines Beispielprogramm sich aber doch leider missen lässt...


Ich habe da 3 sehr einfache Beispiele reingestellt, welche mit Lazarus laufen, egal ob Windows oder Linux.
Die ersten 2 Beispiele sollten auf Anhieb laufen.
Beim dritten habe ich die Shader-Funktionen ausgelagert, diese sollten aber anhand von den obigen Beispiele gut übernommen werden können.

http://mathias1000.bplaced.net/OpenGL_3.3_Tutorial/

Ich hoffe dir hilft das für den Einstieg in die Shader-Materie. :wink:

Im übrigen habe ich die Texturen in einem TImage, welche ich direkt, ohne Umweg über glBitmap, direkt in den Textur-Buffer schreibe.
Wie schon oben beschrieben könnte man ganz auf Alpha-Blending verzichten.

Code:
  1.   // ------------ Texturen laden --------------
  2.  
  3.   with ImageWald.Picture.Bitmap do begin
  4.     glGenTextures(1, @textureIDWald);
  5.     glBindTexture(GL_TEXTURE_2D, textureIDWald);
  6.  
  7.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Width, Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, RawImage.Data);
  8.  
  9.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  10.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  11.     glGenerateMipmap(GL_TEXTURE_2D);
  12.   end;
  13.  
  14.   with ImageStern.Picture.Bitmap do begin
  15.     glGenTextures(1, @textureIDStern);
  16.     glBindTexture(GL_TEXTURE_2D, textureIDStern);
  17.  
  18.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, RawImage.Data);
  19.  
  20.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  // Die ist wichtig,
  21.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  // ansonsten hast du mehrere Sterne auf dem Bild.
  22.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  23.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  24.  
  25.     glGenerateMipmap(GL_TEXTURE_2D);
  26.   end;


Das sieht man, mit Shader ist man sehr flexibel und kann OpenGL eigene Funktionen spendieren. :wink:

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 18 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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 15 Queries | GZIP : On ]