SDL Color Key für openGL-Textur
-
Irgendwie bin ich nicht mehr fähig, sowas hinzubekommen..
Also ich nutze Alpha Blending. Die Darstellungsfunktion sieht so aus :
int cAniImg::draw(int Ani, int Frame) { glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // Select The Type Of Blending glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2f((1.0/cntrow) * Frame, (1.0/cntrow) * Ani); glVertex2i(x, y); glTexCoord2f((1.0/cntrow) * Frame, (1.0/cntrow) * (Ani +1)); glVertex2i(x, y + h); glTexCoord2f((1.0/cntrow) * (Frame + 1), (1.0/cntrow) * (Ani +1)); glVertex2i(x + w, y + h); glTexCoord2f((1.0/cntrow) * (Frame + 1), (1.0/cntrow) * Ani); glVertex2i(x+ w, y); glEnd(); glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); }
Mein Problem ist nun, dass das Alphablending nicht funktioniert.
Ich beziehe die Daten aus einem BMP - ergo nix alpha channel
Den muss ich ja nun selbst erstellen. Das geht laut SDL so:void cTextureManager::loadTexture() { SDL_Surface *image, *bitmap ; int i; bitmap = IMG_Load(name); if (!bitmap) { fprintf(stderr, "%s: konnte nicht geladen werden\n", name); exit(1); } image = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCCOLORKEY, bitmap->w, bitmap->h, 32, #if SDL_BYTEORDER == SDL_BIG_ENDIAN 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); #else 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); #endif SDL_SetColorKey (image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 0, 0, 0)); SDL_BlitSurface(bitmap, 0, image, 0); glGenTextures (1, &id); glBindTexture (GL_TEXTURE_2D, id); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glPixelStorei (GL_UNPACK_ROW_LENGTH, image->pitch / image->format->BytesPerPixel); glTexImage2D (GL_TEXTURE_2D, 0, 3, image->h, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); texsize = image->h; SDL_FreeSurface(image); SDL_FreeSurface(bitmap); }
Allerdings scheint der Colorkey nicht wirklich erfasst zu werden, aber warum?
Wie mach ich nun den ColorKey (im o.g. Fall <0,0,0>) unsichtbar?
-
-
ColorKey existieren nicht im oGL.
Also möchte ich per SDL nen ColorKey erstellen um daraus dann den Alphakanal zu erstellen.
Sollte eigentlich mit SDL_SetColorKey() und SDL_SetAlpha() funktionieren. (wobei mir auffällt, dass ich SetAlpha() unten nicht mit reingepostet hab - hat's zeitweise rausgeworfen.)
Ansonsten müsste ich beim Laden meiner Textur von Hand den Alphakanal setzen, aber das fiinde nicht wirklich sinnvoll..
-
Ich denke schon, das es zumindest mal per PS geht.
Aber du willst ja wohl doch eher Alphablending. Keine Ahnung, was die ganzen SDL Aufrufe machen. aber im Grunde brauchst du doch nur alle Pixel durch gehen und die Alpha auf durchsichtig setzen, wenn er die entspr. Farbe hat.
Bye, TGGC (Ein Jahr Helden)
-
wird mir wohl nicht übrig bleiben, wobei das eigentlich die Sequenz
SDL_SetAlpha(bitmap, SDL_SRCCOLORKEY, 0); SDL_SetColorKey(bitmap, SDL_SRCCOLORKEY, SDL_MapRGB(bitmap->format, 0, 0, 0));
tun sollte..
Allerdings ist dann mein "ausgeblendeter" Hintergrund dann weiß...
-
Was du machen musst damit das ganze funktioniert:
1.)
Im Pixelformat-Deskriptor sollte das Farbformat auf PFD_TYPE_RGBA stehen
(Das ist AFAIK aber nichtmal erforderlich - Machs zur Sicherheit trotzdem)2.)
In der Funktion in der du die Texturen erzeugst:
Nachdem du das Bitmap geladen hast, legst du einen neuen Buffer für die Bilddaten an und fügst einen zusätzlichen Kanal hinzu. Dann kopierst du jedes Byte vom Original-Buffer in den neuen und setzt den vierten Kanal auf 0, wenn die RGB Werte des jeweiligen Pixels deinem "Colorkey" entsprechen. An sonsten setzt du Kanal Vier immer auf 255.
Bei mir sieht das so aus (Kein SDL / reines OGL)... glGenTextures(1, pAdr); int TSizeX = TextureImage[0]->sizeX; int TSizeY = TextureImage[0]->sizeY; BYTE *buffer = new BYTE[TSizeX * TSizeY * 4]; int TSizeXY = TSizeX * TSizeY * 3; int BufferOffset = 0; for (int x = 0; x < TSizeXY; x+= 3) { unsigned char Red = TextureImage[0]->data[x]; unsigned char Green = TextureImage[0]->data[x + 1]; unsigned char Blue = TextureImage[0]->data[x + 2]; unsigned char Alpha = 0; if (Red == 0 && Green == 0 && Blue == 0) Alpha = 0; else Alpha = 255; buffer[BufferOffset] = Red; buffer[BufferOffset + 1] = Green; buffer[BufferOffset + 2] = Blue; buffer[BufferOffset + 3] = Alpha; BufferOffset += 4; } glBindTexture(GL_TEXTURE_2D, *pAdr); glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, FilterMode ); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, FilterMode ); delete[] buffer; }
In der Init-Funktion muss dann noch dies hinzugefügt werden:
glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.0f);
Anschliessend wird alles mit Alpha-Kanal == 0 nicht mehr gerendert, was dem Effekt des Colorkeys gleichkommt.