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

Aktuelle Zeit: Fr Jul 18, 2025 08:11

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Transparenzrand
BeitragVerfasst: So Mai 17, 2009 17:51 
Offline
DGL Member

Registriert: Mo Dez 08, 2008 14:26
Beiträge: 17
Hallo!

Ich bin gerade dabei meine eigene Image-Unit zu schreiben (2D).

Ich habe den Alpha-Test aktiviert

Code:
  1. glEnable(GL_ALPHA_TEST);
  2.     glAlphaFunc(GL_GEQUAL , 0.5);


Benutze außerdem glBitmap und Lade dateien wie folgt ein:

Code:
  1.   FTexture.LoadFromFile(FileName);
  2.   FTexture.AddAlphaFromColorKey(255,0,255);
  3.   FTexture.GenTexture;


Wenn ich jetzt mein Bild skaliere und zeichne, sieht man einen Rand der die Farbe der Transparenz hat (clFuchsia). Dies kann man unterdrücken, wenn man GL_TEXTURE_MAG_FILTER auf GL_LINEAR setzt, jedoch sieht die Grafik dann übertrieben verpixelt aus. Wenn ich den GL_GEQUAL erhöhe, zerfrisst es mir Teile meiner Grafik :(
Kennt ihr vielleicht eine Lösung?

Gruß, Taner


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 17, 2009 17:58 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 20, 2005 13:18
Beiträge: 1054
Wohnort: Dresden
Programmiersprache: C, C++, Pascal, OPL
Im Moment scheinst du "normales" RGB zu nutzen. OpenGL bietet dir aber auch super RGBA, was in diesem Fall wo besser zu sein scheint. Denn eine andere Lösung fällt mir in dem Moment nicht ein. Wenn du weiterhin deine clFuchsia-Bilder behalten willst, kannst du die Bilder ja öffnen, in einen RGBA-Speicherbereich packen und überall, wo clFuchsia ist, den Alphawert auf 0 setzen - die Farbe ist dabei dann egal - ist ja eh durchsichtig. ^^
Dann kannst du den FILTER-Werte auch beliebig setzen. :-)

_________________
Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut.
Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’.
Und du schaust mich an und fragst ob ich das kann.
Und ich denk, ich werd' mich ändern irgendwann.

_________________Farin Urlaub - Bewegungslos


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 17, 2009 19:36 
Offline
DGL Member

Registriert: Mo Dez 08, 2008 14:26
Beiträge: 17
Macht das denn nicht "AddAlphaFromColorKey" schon? Oder meinst du mit einem Bildbearbeitungsprogramm öffnen und dort ändern?

Gruß, Taner


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 17, 2009 20:43 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
den alphakanal kannst du direkt in das Bild speichern, du musst natürlich ein Format ählen, dass einen Alphakanal unterstütz .png und .tga sind da zum Beispiel genannt, wobei png die bessere wahl sein sollte (murmelt man). Da kannst du dann deinen alpha wert als graustufen byte angeben und kannst sogar mit tranzparenz stufen arbeiten.

Ein anderes Ding ist, was sein könnte, dass deine Textur/Grafik gestreckt oder gezeert wird auf deinem Quad/Triangle, dabei kann es sein, dass die Außenkante Farbwerte bekommt, die von der gegenüberliegenden Seite kommen. Evtl. mal die Textur Parameter einstellen auf Clamp oder Repeat. vielleicht löst das dein Problem bereits, kann dafür aber nicht garantieren. Hilfreich wäre der genau glcode den du benutzt um dein Image in die Textur zu laden und wie du deine Parameter einstellst.

_________________
Klar Soweit?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 17, 2009 23:58 
Offline
DGL Member

Registriert: Mo Dez 08, 2008 14:26
Beiträge: 17
So habe das auch mal mit "eingespeichertem" Alpha-Kanal und dem TGA-Format probiert.. selbes Ergebnis wie vorher mit AddAlphaFromColorKey :(

GL_CLAMP und GL_REPEAT bringen leider auch nichts..

Hier mein Code:

Code:
  1.  
  2. function TOGLDraw.Initialize: boolean;
  3. begin
  4.   if InitOpenGL then
  5.   begin
  6.     FDC := GetDC(FWinControl.Handle);
  7.     FRC := CreateRenderingContext(FDC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
  8.     ActivateRenderingContext(FDC, FRC);
  9.  
  10.     glEnable(GL_ALPHA_TEST);
  11.     glAlphaFunc(GL_GEQUAL , 0.5);
  12.     glEnable(GL_CULL_FACE);
  13.     glCullFace(GL_BACK);
  14.     glEnable(GL_TEXTURE_2D);
  15.  
  16.     glMatrixMode(GL_PROJECTION);
  17.  
  18.     result := true;
  19.   end else
  20.   begin
  21.     result := false;
  22.   end;
  23. end;
  24.  
  25. procedure TOGLImage.LoadFromFile(FileName: string);
  26. begin
  27.   FTexture.LoadFromFile(FileName);
  28.   FTexture.AddAlphaFromColorKey(255,0,255);
  29.  
  30.   FTexture.GenTexture;
  31. end;
  32.  
  33. procedure TOGLImage.DrawEx(SrcRect: TRect; DestRect: TRect; RotateX, RotateY, Angle: single; PatternIndex: integer=-1);
  34. var SrcLeft, SrcTop, SrcRight, SrcBottom, X, Y, Width, Height, PatternX, PatternY: single;
  35. begin
  36.   glPushMatrix;
  37.  
  38.   X := DestRect.Left;
  39.   Y := DestRect.Top;
  40.   Width := (DestRect.Right-DestRect.Left);
  41.   Height := (DestRect.Bottom-DestRect.Top);
  42.  
  43.   if Angle <> 0 then
  44.   begin
  45.     X := -Width*RotateX;
  46.     Y := -Height*RotateY;
  47.  
  48.     glTranslatef(DestRect.Left-X, DestRect.Top-Y, 0);
  49.     glRotatef(Angle,0,0,1);
  50.   end;
  51.  
  52.   FTexture.Bind;
  53.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  54.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  55.  
  56.  
  57.   if PatternIndex <> -1 then
  58.   begin
  59.     PatternX := PatternIndex mod FPatternCountWidth;
  60.     PatternY := PatternIndex div FPatternCountWidth;
  61.  
  62.     SrcLeft := (PatternX * FPatternWidth) / FTexture.Width;
  63.     SrcRight := ((PatternX * FPatternWidth) + PatternWidth) / FTexture.Width;
  64.     SrcTop := (PatternY * FPatternHeight) / FTexture.Height;
  65.     SrcBottom := ((PatternY * FPatternHeight) + PatternHeight) / FTexture.Height;
  66.   end else
  67.   begin
  68.     SrcRight := (SrcRect.Left) / FTexture.Width;
  69.     SrcTop := (SrcRect.Top) / FTexture.Height;
  70.     SrcLeft := (SrcRect.Right) / FTexture.Width;
  71.     SrcBottom := (SrcRect.Bottom) / FTexture.Height;
  72.   end;
  73.  
  74.   glBegin(GL_QUADS);
  75.  
  76.     glTexCoord2f(SrcRight,SrcBottom); glVertex2f(X, Y+Height);
  77.     glTexCoord2f(SrcLeft,SrcBottom); glVertex2f(X+Width, Y+Height);
  78.     glTexCoord2f(SrcLeft,SrcTop); glVertex2f(X+Width, Y);
  79.     glTexCoord2f(SrcRight,SrcTop); glVertex2f(X, Y);
  80.  
  81.   glEnd;
  82.  
  83.   glPopMatrix;
  84. end;


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 18, 2009 02:59 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
Hast du auch Blending eingestaltet, ansonsten kann das ja mit Transparenz nicht funktionieren?
Der AlphaTest verwirft Pixel ganz, wenn sie den Test nicht bestehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 18, 2009 07:50 
Offline
DGL Member

Registriert: Mo Dez 08, 2008 14:26
Beiträge: 17
Habe es mal mit Alpha-Blending probiert.
Jetzt sieht es doch schon um einiges besser aus :)
(Gibt aber immernoch nen hauchdünnen Rand wenn man weit skaliert)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 18, 2009 12:09 
Offline
DGL Member

Registriert: Mo Dez 08, 2008 14:26
Beiträge: 17
Ach irgendwie funktioniert das alles noch nicht :( Kann man irgendwie einstellen, dass der Alpha-Kanel nicht mit GL_LINEAR sondern mit GL_NEAREST interpoliert wird?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 18, 2009 15:34 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
Taner hat geschrieben:
Ach irgendwie funktioniert das alles noch nicht :( Kann man irgendwie einstellen, dass der Alpha-Kanel nicht mit GL_LINEAR sondern mit GL_NEAREST interpoliert wird?


Ich glaube nicht, dass das geht.

Tritt das Problem an allen Kanten auf? In dem Code-Beispiel hast du "GL_CLAMP" nur für eine Richtung gesetzt. Das sollte vielleicht auch noch für "GL_TEXTURE_WRAP_T" gemacht werden. Wenn das nicht hilft kannst du es ja auch mal mit "GL_CLAMP_TO_EDGE" versuchen.
Aber wenn das Problem nicht den Rand der Textur betrifft sondern auch im inneren bei transparenten Teilen auftritt, hilft das wohl wenig.

"GL_TEXTURE_MAG_FILTER" ist doch für den Fall zuständig, wenn die Textur größer als normal dargestellt wird? Nur damit ich nichts falsch verstehe.
Im Eingangspost erwähntest du das bei "GL_LINEAR" dann alles verpixelt aussieht. Meintest du da "GL_NEAREST", weil "GL_LINEAR" gerade glätten sollte.

Ich nehme mal an, das es ein Problem mit der Art wie die Farbwerte beim Interpolieren verrechnet werden, ist. Idealerweise sollte die Farbe mit dem Alphawert multipliziert werden bevor sie zur resultierenden Farbe hinzugerechnet wird. Dann würde bei voller Transparenz nichts von der Pixelfarbe mit eingehen. Aber ich schätze so wird es nicht gemacht, sodass eben dein Problem entsteht. Viel kann man da aber nicht machen.
Vielleicht kannst du als Transparenzfarbe die Farbe der nicht transparenten Pixel nehmen, sodass die Farbe beim Interpolieren die gleiche bleiben muss. Natürlich ist das nicht gerade toll für "AddAlphaFromColorKey", deshalb müsste man das dann wohl in einem Grafikprogramm machen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 18, 2009 16:08 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich würde vorschlagen, in solchen Fällen wirklich den Alphakanal mit einem geeigneten Programm (z.B. GIMP. Dort dann Farbauswahl (zauberstab), wegradieren) zu erzeugen und dann entsprechend als PNG abzuspeichern. Weiterhin solltest du versuchen, die Pixel, die sich direkt am Rand befinden, noch etwas weiter rauszuziehen, falls du verstehst, was ich meine. Also an dem Punkt, wo es transparent wird, das Lila mit der Farbe des benachbarten Pixels überschreiben. Denn das ist dein Problem: Dass OpenGL sowohl Alpha als auch Farbe zwischen den beiden Punkten interpoliert und daher bekommst du deinen hässlichen Rand. Im Prinzip das, was Schläfer schon gesagt hat. Ansonsten müsste eigentlich auch, wenn du garkeinen Alphakanal hast, der Test GL_EQUAL 1.0 laufen. Dann wird ja alles rausgeschmissen, was kleiner als 1 ist.

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 networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 18, 2009 18:07 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
ich würde da gerne mal ein Bild von sehen.

_________________
Klar Soweit?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 18, 2009 19:15 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich habe dir gleich zwei gemacht ;). Es ist natürlich etwas schwierig beim zweiten, weil da das Alpha an den interessanten Punkten eigentlich 0 sein müsste, aber ich habe um das eigentliche "bild" jetzt mal zwei Pixel mit Alpha 0.5 stehen lassen.

Vorgehen war folgendes:
Alles mit Fuchsia ($FF00FF) auswählen.
Optional: Mit einer Farbe füllen, die im großen und ganzen ähnlich zu dem Bereich innen ist (evtl. an verschiedenen Stellen mit anderer Farbe füllen)
Stempel nehmen und die Farben des nicht-fuchsia bereiches nach außen ziehen.
Optional: Gausscher Weichzeichner von 1.5er Radius angewandt. Nur empfehlenswert, wenn man das mit dem Einfärben gemacht hat. Eigentlich reicht das Stempeln aber.
Den Ausgewählten Bereich wegradiert.

Wichtig ist, dass man immer nur außerhalb des Bildes arbeitet um nicht das Bild selber zu beschädigen.

Im Anhang ein typisches Vorher-Nachher szenario :)

Gruß Lord Horazont

P.S: Das war jetzt natürlich nicht das gründlichste vorgehen. Sieht auch schlimmer aus, als es eigentlich ist, ich habe halt relativ viel Rand stehen lassen. Und die sache mit dem Gaussschen ohne vorher den Hintergrund einzufärben war auch keine gute idee. Aber zur veranschaulichung sollts ja reichen.


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

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy 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


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


Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] und 3 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 | 16 Queries | GZIP : On ]