PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : OpenGL Masken


Einfachkrank
2002-09-04, 15:46:14
Hi,

kann mir jemand das Maskensystem in Kurzform erklären? Zum Beispiel wie ich in einem Bitmap die schwarze oder weiße Farbe transparent mache, so dass ich sie dann auf ein Polygon 'mappen' kann und sie mit glOrtho() oder glOrhto2D anzeigen lasse.

Oder ist es nicht sogar egal, welche Projektionsart man wählt, was die Masken betrifft? In 3D kann man damit doch dann so Effekte wie ein Sniper Scope darstellen?

MFG Einfachkrank

Xmas
2002-09-04, 16:07:32
Die Projektionsart ist völlig egal. Aber in OpenGL gibt es kein Chroma Keying. Transparenz geht über den Alphakanal, also brauchst du eine Textur mit Alpha (wenn du nur zwischen einer Farbe und Durchsichtig unterscheiden willst, reicht sogar eine Textur nur mit Alpha), oder du benutzt eine der Register Combiner/Fragment Shader Extensions, um aus der Farbe den Alpha-Kanal zu berechnen.

Einfachkrank
2002-09-04, 16:17:23
@Xmas
Transparenz geht über den Alphakanal, also brauchst du eine Textur mit AlphaJa afaik besitzt das tga File Format einen Alpha Kanal, gibt es da noch mehr Formate und mit welchen Bildbearbeitungsprogrammen kann ich das Format speichern?
oder du benutzt eine der Register Combiner/Fragment Shader Extensions, um aus der Farbe den Alpha-Kanal zu berechnenWie bekomme ich das hin?

Xmas
2002-09-04, 16:29:04
Originally posted by Einfachkrank
@Xmas
Ja afaik besitzt das tga File Format einen Alpha Kanal, gibt es da noch mehr Formate und mit welchen Bildbearbeitungsprogrammen kann ich das Format speichern?
Das kann ich dir nicht genau sagen, allerdings hast du immer die Möglichkeit, Alpha als Graustufenbild extra zu speichern und in deinem Programm wieder zusammenzufügen. Oder wenn du Chroma Keying simulieren willst, beim Laden der Textur die entsprechende Farbe rausfiltern und dort Alpha auf 0 setzen.


Das Errechnen eines Alpha-Werts ist IMHO den Aufwand (und den Performanceverlust) nicht wert. Alpha in der Textur bekommst du praktisch "for free".

Das solltest du dir vielleicht anschauen:
http://developer.nvidia.com/docs/IO/1313/ATT/Alphatest_tricks.pdf

Einfachkrank
2002-09-04, 18:13:43
@Xmas
allerdings hast du immer die Möglichkeit, Alpha als Graustufenbild extra zu speichern und in deinem Programm wieder zusammenzufügenWie mache ich denn das? Also wie speichere ich das Bild und wie füge ich es dann mit welcher Art von Bild wieder wie zusammen?
Oder wenn du Chroma Keying simulieren willst, ...Zunächst, ist "Chroma Keying" dasselbe wie "Color Keying"?

Xmas
2002-09-05, 14:43:22
Originally posted by Einfachkrank
@Xmas
Wie mache ich denn das? Also wie speichere ich das Bild und wie füge ich es dann mit welcher Art von Bild wieder wie zusammen?
Ich weiß nicht welches Grafikprogramm du verwendest und ob du da die Möglichkeit hast den Alpha-Kanal herauszusplitten. Du kannst aber immer Alpha als zusätzliches Graustufenbild zu deinem RGB-Bild malen und getrennt abspeichern, in dem Format das du am besten gebrauchen kannst.

Dann öffnest du in deinem Programm beide Dateien und allokierst einen Puffer für die RGBA-Daten, wobei du die RGB- und A-Daten Pixel für Pixel aus beiden Dateien liest und zusammensetzt.

Wenn du aber sowieso nur eine bestimmte Farbe transparent machen willst, so brauchst du kein extra Alpha-Bitmap, sondern kannst beim laden des RGB-Bitmap pro Pixel den Farbwert prüfen und entsprechend den Alpha-Wert setzen.

Zunächst, ist "Chroma Keying" dasselbe wie "Color Keying"?
Ja.

Einfachkrank
2002-09-05, 15:19:36
Wenn du aber sowieso nur eine bestimmte Farbe transparent machen willst, so brauchst du kein extra Alpha-Bitmap, sondern kannst beim laden des RGB-Bitmap pro Pixel den Farbwert prüfen und entsprechend den Alpha-Wert setzenJa ist schon klar, aber wie mache ich das genau. Also meine Bilddaten sind nach meine Ladefunktion durch "unsigned int *bild;" gespeichert. Kann ich da noch was machen, oder muss das schon früher sein und wenn wie? Vielleicht kannst du mir das im Detail erklären :eyes:

Xmas
2002-09-05, 17:18:44
Ich hab mir mal deine Texturladefunktion als Vorlage genommen.


typedef unsigned int RGBA;

#define MakeRGBA(r,g,b,a) ((RGBA)((r << 24) + (g << 16) + (b << 8) + a))

RGBA *LoadColorKeyBitmap (char *filename, BITMAPINFOHEADER *bitmapInfoHeader, RGBA ColorKey)
{
FILE *BMPfile;
BITMAPFILEHEADER bitmapFileHeader;
unsigned char *RGBImage;
RGBA *RGBAImage;
RGBA Pixel;

// BMP-Datei öffnen
BMPfile= fopen(filename, "rb");
if (BMPfile== NULL)
return NULL;

// BMP Header lesen
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, BMPfile);
if (bitmapFileHeader.bfType != BITMAP_ID)
{
fclose(BMPfile);
return NULL;
}
fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, BMPfile);

// Puffer allokieren
RGBImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
if (!RGBImage)
{
fclose(BMPfile);
return NULL;
}

RGBAImage = (RGBA*)malloc(bitmapInfoHeader->biHeight * bitmapInfoHeader->biWidth);
if (!RGBImage)
{
free(RGBImage);
fclose(BMPfile);
return NULL;
}

// Bitmap aus Datei lesen
fseek(BMPfile, bitmapFileHeader.bfOffBits, SEEK_SET);
if (bitmapInfoHeader->biSizeImage != fread(RGBImage, 1, bitmapInfoHeader->biSizeImage, BMPfile))
{
free(RGBImage);
free(RGBAImage);
fclose(BMPfile);
return NULL;
}

// BGR in RGB tauschen und Alpha anhängen. Alpha = 255 soll hier transparent sein, entsprechend
// muss glBlendFunc angepasst werden
for (int i = 0; i < bitmapInfoHeader->biHeight * bitmapInfoHeader->biWidth; i++)
{
Pixel = MakeRGBA( RGBImage[3*i+2], RGBImage[3*i+1], RGBImage[3*i], 0);
if (Pixel == ColorKey)
Pixel += 255;
RGBAImage[i] = Pixel;
}

free(RGBImage);
fclose(BMPfile);

// Der Rückgabewert muss später freigegeben werden!!!
return RGBAImage;
}

Exxtreme
2002-09-05, 17:49:56
Hat sich erledigt.

Gruß
Alex

Xmas
2002-09-05, 17:57:50
Originally posted by Exxtreme
@ Xmas
Anstatt:

unsigned char *RGBImage;

wäre AFAIK dieses besser:

static unsigned char *RGBImage;

Es kann nämlich sein, daß der Rückgabewert nach dem Verlassen der Funktion gelöscht wird.

Gruß
Alex
???

Erstmal ist RGBImage nicht der Rückgabewert, sondern RGBAImage. Und wieso sollte ich den Pointer auf den RGBA-Buffer innerhalb dieser Funktion aufheben? Nicht der Rückgabewert wird gelöscht wenn die Funktion verlassen wird, sondern die in der Funktion deklarierten Variablen. Das ist ein riesiger Unterschied.

Der Rückgabewert ist ein Pointer auf ein RGBA-Array, und muss natürlich einer Variable zugewiesen werden, sonst ist er ja verloren.

Der Aufruf muss also so aussehen, dann funktioniert das perfekt:
BITMAPINFOHEADER bih;
RGBA * Textur = LoadColorKeyBitmap("Textur.bmp", &bih, 0xFFFFFF00);

// hier was mit der Textur machen...

free (Textur);

zeckensack
2002-09-05, 18:03:11
@XMas

Du benutzt filePtr, deklarierst es aber nicht. Tausch das mal gegen BMPfile aus ;)

Xmas
2002-09-05, 18:12:14
Originally posted by zeckensack
@XMas

Du benutzt filePtr, deklarierst es aber nicht. Tausch das mal gegen BMPfile aus ;)
Schon korrigiert =)

Einfachkrank
2002-09-05, 20:59:55
Hey,

danke, damit werde ich erst mal experimentieren ;)

MFG Einfachkrank

Einfachkrank
2002-09-06, 19:09:06
Hi,

ich hätte da nochmal ne kleine Nebenfrage zu den TGA`s. Ich habe jetzt ein TGA mit transparenten Hintergrung gespeichert und nach dem Laden auf meinen Quad gerendert. Aber das was normalerweise transparent sein sollte, ist jetzt weiß. GL_BLEND ist enabled. Was muss ich noch einstellen?

MFG Einfachkrank

zeckensack
2002-09-06, 19:17:30
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

oder

glBlendFunc(GL_SRC_ALPHA,GL_ONE); //additives Blending