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

Aktuelle Zeit: Mi Jul 16, 2025 21:37

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



Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ] 
Autor Nachricht
BeitragVerfasst: So Mär 06, 2005 15:13 
Offline
DGL Member
Benutzeravatar

Registriert: Do Feb 24, 2005 22:44
Beiträge: 29
Hallöchen,

ich habe vor, ein kleines 2D-Spiel mittels OpenGL zu erstellen. Dabei bin ich auf eine Vielzahl von Problemen gestoßen. Zum einen erstmal, dass Texturen immer recht verwaschen aussehen. Also etwas unscharf. Wäre ja nicht so schlimm, wenn dadurch nicht die Konturen der Grafiken mit der transparenten Farbe überlaufen würde. Dadurch entstehen dann schwarze Ränder die man nicht wegbekommt:

Bild

Links die Szene mit NEAREST-Filter, mittig mit LINEAR-Filter und links so wie es sein soll, ohne glättung, ohne daraus folgende schwarze Ränder.

Es muss doch irgendeine Möglichkeit geben, die Grafiken (übrigends im Targa-Format) 1 : 1 auf den Schirm zu bringen und nicht so per Textur wo alles verwischt. Im 2D-Grafik-Tutorial wird zwar beschrieben, dass es bei solchen Grafiken leider so ist, dass es etwas schwammig wird, aber das kann's doch nicht sein. Sollte OpenGL tatsächlich nicht in der Lage sein, ein Bitmap korrekt ohne Verzug anzuzeigen?

Bisher mach ich das so: (C Code)
Code:
  1. int DrawGLScene(void)                                   // Here's Where We Do All The Drawing
  2. {
  3.  
  4.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  5.     glColor4f(1.0, 1.0, 1.0, 1.0);
  6.  
  7.     glEnable(GL_TEXTURE_2D);
  8.     glEnable(GL_ALPHA_TEST);
  9.     glAlphaFunc(GL_GREATER, 0.1f);
  10.     glEnable(GL_DEPTH_TEST);
  11.  
  12.     glLoadIdentity();
  13.     glOrtho(0, 1024, 0, 768, 0, 128);
  14.     glBindTexture(GL_TEXTURE_2D, texture[1].texID);
  15.  
  16.     for (int x = 0; x<=32; x++)
  17.     {
  18.         for (int y = 0; y<=24; y++)
  19.         {
  20.             for (int z = 0; z<=1; z++)
  21.             {
  22.                 if (mapdata[x][y][z].image_x != -1 && mapdata[x][y][z].image_y != -1)    // Vortfahren wenn Tile nicht ohne Textur ist
  23.                 {
  24.                     glLoadIdentity();
  25.                     glOrtho(0, 1024, 0, 768, 0, 128);
  26.                     glTranslatef(x * 32, 768 - (32 + (y * 32)), -10);
  27.                     glBegin(GL_QUADS);
  28.                         glTexCoord2f( ((mapdata[x][y][z].image_x * 32.0f) / 640),          1.0f - ((mapdata[x][y][z].image_y * 32.0f)        / 640));   glVertex3f(0, 0, 0);
  29.                         glTexCoord2f( (((mapdata[x][y][z].image_x * 32.0f) + 32) / 640),   1.0f - ((mapdata[x][y][z].image_y * 32.0f)        / 640));   glVertex3f(32, 0, 0);
  30.                         glTexCoord2f( (((mapdata[x][y][z].image_x * 32.0f) + 32) / 640),   1.0f - (((mapdata[x][y][z].image_y * 32.0f) + 32) / 640));   glVertex3f(32, -32, 0);
  31.                         glTexCoord2f( ((mapdata[x][y][z].image_x * 32.0f) / 640),          1.0f - (((mapdata[x][y][z].image_y * 32.0f) + 32) / 640));   glVertex3f(0, -32, 0);
  32.                     glEnd();
  33.                 }
  34.             }
  35.         }
  36.     }
  37.  
  38.     return true;                                        // Everything Went OK
  39. }



In den 3-For-Schleifen wird die Szene aufgebaut, dabei besteht's aus Tiles welche aus einer 640 x 640 Pixel großen Textur entstehen. Diese Textur wird dann immer so zurecht gelegt, dass das passende Teil auf dem 32 x 32 Pixel großen Block angezeigt wird.

mfg.

Sunny


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 06, 2005 16:33 
Offline
DGL Member
Benutzeravatar

Registriert: Do Mär 06, 2003 15:27
Beiträge: 281
Wohnort: Bochum
wo kommt die transparenz her ? ist die in den dateien gespeichert, also wie viel alpha ein jedes pixel des bildes hat ? oder machst du das im code ?
die schwarzen render kommen ja daher, dass an der stelle durch das filtering nichtmehr ganz die farbe ist, die als transparente farbe gilt, deshalb wird dort die farbe(ein wenig verwaschen) angezeigt die eigentlich durchsichtig seinen sollte.

PS:das gane ist aber ein standard problem, nimm ma die suchfunktion und du wirst sicher fündig.

_________________
www.extrawurst.org


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 06, 2005 17:35 
Offline
DGL Member
Benutzeravatar

Registriert: Do Feb 24, 2005 22:44
Beiträge: 29
Das ist eine Targa-Datei, also mit Selektion, was dann später als transparente Farbe nicht angezeigt wird. 4 bit pro Pixel, die transparents entspringt also direkt aus der Datei. Die Alpha-Daten werden ja auch korrekt eingeladen, sieht man da, da nicht alles schwarz ist.
(Die Suchfunktion hat zwar ne Menge ausgespuckt, allerdings meist Sachen die in Verbindung mit Blending stehen, und das wollt ich eigentlich ohne Blending machen).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 06, 2005 18:36 
Offline
DGL Member
Benutzeravatar

Registriert: Do Mär 06, 2003 15:27
Beiträge: 281
Wohnort: Bochum
so, hab eben nachgeschaut, wenn du auf das filtern verzichten kannst mach nach dem binden der texture:
Code:
  1.  
  2.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
  3.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
  4.  

dann ist das schwammige weg und die alpha-verläufe ebenfalls. hab ich bei mir genauso gemacht

_________________
www.extrawurst.org


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 06, 2005 18:58 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 17, 2002 12:07
Beiträge: 976
Wohnort: Tübingen
Wenns ned hilft, versuchs mal mit Anisotropischer Filterung.
Die kannst du auch im Treiber schrittweise erhöhen, schau mal, obs damit vielleicht besser wird. Kostet aber relativ viel Performance.

_________________
"Du musst ein Schwein sein in dieser Welt, sangen die Prinzen, das ist so 1.0. Du musst auf YouTube zeigen, dass dir dein Schweinsein gefällt, das ist leuchtendes, echtes Web 2.0."
- Hal Faber

Meine Homepage: http://laboda.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 06, 2005 22:13 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Also das mit den schwarzen Rändern:
Entweder:
glAlphaFunc(GL_GEQUAL, 1.0f);

Oder:
Versuche die Hintergrundfarbe nicht schwarz zu machen sondern möglichst den Farben der Ränder anzupassen. ZB indem du bei allen Texeln wo ein Übergang zwischen Undurchsichtig und durchsichtig existiert einfach die Farbe des sichtbaren Nachbarpixels verwenden.

Deine Texturcoordinatenberechnungen lassen darauf schließen, dass du ne 640x640 Textur verwendest?
Ich nehme an du verwendest zum erstellen der Textur die gluBuild2DMipmaps-Funktion? Dir ist klar das bei dieser Funktion die Texturen auf die nächst höhere 2er-Potenz gescaled werden? Und da du beim Zeichnen nun wiederum 1024/640 = 1,6 Texel / Pixel hast wird er wahrscheinlich das 1te Texturlevel mit geringerem Level of Detail verwenden anstatt des 0ten. Also wenn möglich versuch sattdessen zB 512x512 Texturen zu verwenden.

Zusätzlich sollte dir (vor allem bei den Gras Tiles und dergleichen) bewusst sein, dass eine derartige Texturcoordinatenangabe auch einen kleinen Teil der Farben des nachbar-Tiles innerhalb der Textur verwendet, das würd jetz aber wohl den Rahmen sprengen da es etwas kompliziert zum erklären ist ...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 07, 2005 00:25 
Offline
DGL Member
Benutzeravatar

Registriert: Do Feb 24, 2005 22:44
Beiträge: 29
Ah, vielen Dank, es war tatsächlich die Tatsache, dass meine Textur keine 2er Potenz hatte und deshalb gestretcht wurde. Dann wurden die Ränder eben alle schwarz. Wenn ich jetzt 512 x 512er Sprites verwende klappts. Damit hat sich jetzt das Problem mit der Unschärfe und den schwarzen Rändern zugleich gelöst. Zwar etwas dumm, dass es immer 2er Potenzen sein müssen, aber da kann man wohl nichts machen, wie?
Rein Interessehalber, muss es in DirectX auch ein Bild in 2er Potenzen sein?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 07, 2005 01:40 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Zitat:
Zwar etwas dumm, dass es immer 2er Potenzen sein müssen, aber da kann man wohl nichts machen, wie?

Du könntest eine 1024x1024 Textur verwenden wo nur ein 640x640 Teil verwendet wird ... wär halt etwas Ressourcen-verschwenderisch.

Zitat:
Rein Interessehalber, muss es in DirectX auch ein Bild in 2er Potenzen sein?

Wie heißts so schön? Die kochen auch nur mit Wasser. Das es 2er Potenzen sein müssen hängt mit der Hardware zusammen. In OGL gibt es eine Extension wo du Rechteckige / nicht 2er Potenz - Texturen verwenden kannst, in den neueren DX Versionen wirds das sicher auch geben. Aber nur damit es ein bisschen komfortabler zum zeichnen oder programmieren wird, Grafikkarten mit speziellen Features voraussetzen halte ich persönlich nicht für sonderlich toll.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 07, 2005 01:56 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
(ARB|NV|EXT)_texture_rectangle werden doch von fast allen Karten unterstützt. Allerdings hat man kein Mipmapping und muß die Koordinaten in Pixeln und nicht von 0..1 angeben, was bei 2D Bilder auch von Vorteil sein könnte. Man verwendet dann GL_TEXTURE_RECTANGLE statt GL_TEXTURE_2D, als Paramter beim Texture Target. Der Wert dieser Konstante ist für alle drei Extensions gleich.
In Direct3D gibt es ein Caps Bit, dass angibt ob solche Texturen akzeptiert werden. Dort übergibt man die rechteckige Texture dann als normale Texture. Da sich bei OpenGL aber die Addressierung ändert, wurde ein extra Texture Target eingerichtet, dass man übrigens auch mit glEnable aktivieren muß.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 07, 2005 12:28 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Lyr hat geschrieben:
Zusätzlich sollte dir (vor allem bei den Gras Tiles und dergleichen) bewusst sein, dass eine derartige Texturcoordinatenangabe auch einen kleinen Teil der Farben des nachbar-Tiles innerhalb der Textur verwendet, das würd jetz aber wohl den Rahmen sprengen da es etwas kompliziert zum erklären ist ...


Könntest du dazu noch paar Worte verlieren. Das interessiert mich, da meine Texturen immer leichte Ränder haben. :?

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 07, 2005 17:08 
Offline
DGL Member

Registriert: Sa Jan 22, 2005 21:10
Beiträge: 225
Will an dieser stelle nur mal eben nen Link reinwerfen:

Zitat:
Versuche die Hintergrundfarbe nicht schwarz zu machen sondern möglichst den Farben der Ränder anzupassen. ZB indem du bei allen Texeln wo ein Übergang zwischen Undurchsichtig und durchsichtig existiert einfach die Farbe des sichtbaren Nachbarpixels verwenden.


Ich hatte auch mal das Problem, und dieses Tut war mir auf ne große Hilfe:

:http://www.vterrain.org/Plants/Alpha/index.html

Das beschreibt genau dieses Ränderverwischen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 07, 2005 21:30 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Flash hat geschrieben:
Könntest du dazu noch paar Worte verlieren. Das interessiert mich, da meine Texturen immer leichte Ränder haben. :?

Ok ich werds mal kurz und bündig versuchen :-).

Generell werd ich mich nur auf 1D Texturen beziehen, ist genau so für alle weiteren Dimensionen anwendbar.

Stell dir deine Textur mal als Funktion von s-Koordinate auf Farbwert vor. Du hast bei deiner Textur nur für Texturgröße s-Koordinaten den genauen Farbwert gegeben, die s-Koordinate soll jedoch beliebig sein (zB float Genauigkeit).
Wenn du nun bei einer Nearest-Funktion das Bedürfniss hast, das jeder Texel einen gleich großen Bereich abdeckt, dann nimmt jedes Texel einen Bereich von 1 / Texturgröße ein. Bei einem Nearest erwartest du, dass 0.0 ganz links und 1.0 ganz rechts in der Textur ist, das ist jedoch zusammen mit den oberen Voraussetzungen nur dann möglich, wenn sich das Zentrum (also die s-Koordinate für den das 1. Texel der Textur bestimmt ist) genau an der Position (1 / Texturgröße) / 2, also in der Mitte des Bereiches den es abdecken soll befindet.
Bei Texturen die sich wiederholen sollen (das GL_REPEAT) bedeutet das wiederum, dass die Coordinate 0.0 und auch 1.0 eine 50:50 Interpolation des 1. und des letzten Texels der Textur ist.

D.h:
Der X.te Wert deiner Textur die Y Texel groß ist, ist der Wert für die s-Koordinate: (X + 0.5) / Y

Beim linearen Interpolieren werden alle anderen Werte aus den 2 Nachbartexeln interpoliert, es sei denn du hast GL_CLAMP eingestellt und befindest dich im Bereich [-unendlich|0.5/Y] oder [(Y-0.5)/Y|+unendlich] dann gilt für diesen Bereich nur das eine Nachbartexel.

Obwohl es auf den ersten Blick etwas verwirrend ausschaut ist es bei näherer Betrachtung die beste Lösung, da damit jede Art der Texturierung (Wiederholung, Interpolationen, Tiles, ...) ohne allzu große Umstände ermöglicht wird.

Hoffe es war wenigstens halbwegs verständlich :-).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Mär 08, 2005 00:35 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Denke das hab ich verstanden. (Irgendow hatte ich das vermutet) Wenn ich allerdings weiß wie groß meine Texel maximal sind, könnte ich ja genau den nötigen Spielraum von meinen Koordinaten abziehen um z.B. die Weisen Ränder zu vermeiden, oder?

Der artikel AL war auch sehr interessant.


Wenn du dich mit den Texelberechnungen gut auskennst, könntest du ja mal (deine Artikel sehn immer so doll aus, mit Bildern unds so 8) ) den Artikel "Texelberechnung" schreiben. Der würde dem Technikpfad sicherlich gut tun. :P

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Mär 15, 2005 18:48 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Ich hatte das Problem auch mal, als ich ein paar Fenster im 2D Modus von OpenGL darstellen wollte.
Meine Texturen waren auch immer leicht unscharf...

Das ganze passiert aber nicht, wenn die OpenGL-Koordinaten in 2D absolut exakt die Pixel auf dem Bildschrim darstellen.
Auf sulaco gibt es ein Beispiel-Programm, welches ein paar Fenster darstellt. Dort werden die Fenster auch so exakt positioniert, dass die Filterung (die die Textur ja leicht unschärfer macht) zwar theoretisch gefiltert hat, im Endeffekt jedoch bekam man von der Filterung nichts mit, weil ja jeder Texel einen eigenen Pixel hatte. Und umgekehrt.

Aber dieser Artikel ist auch sehr interessant...

EDIT:
Und die Ränder von Texturen bekommt man oft mit GL_CLAMP bzw. GL_CLAMP_TO_EDGE weg.

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 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.009s | 14 Queries | GZIP : On ]