Draw a Quad Transparent with Mask Image

Started by
5 comments, last by Corpsman 17 years, 11 months ago
hello, I Try to draw a Bitmap with Transparency in OpenGL. So I createt a Mask File which is black = Transparent and white = solid. I Wrote the Following Code glpushmatrix; glcolor3f(1, 1, 1); // Reset the OpenGL Pen glBindTexture(GL_TEXTURE_2D, Ftexture); // Select the Texture glBegin(GL_QUADS); glTexCoord2f(+0.0, 0.0); glVertex3f(-1.1, -1.1, 0.0); glTexCoord2f(+1.0, 0.0); glVertex3f(1.1, -1.1, 0.0); glTexCoord2f(+1.0, 1.0); glVertex3f(1.1, 1.1, 0.0); glTexCoord2f(+0.0, 1.0); glVertex3f(-1.1, 1.1, 0.0); glEnd(); glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_SRC_COLOR); glBindTexture(GL_TEXTURE_2D, fmaskTexture); // Select the MAsk Texture glBegin(GL_QUADS); glTexCoord2f(+0.0, 0.0); glVertex3f(-1.1, -1.1, 0.0); glTexCoord2f(+1.0, 0.0); glVertex3f(1.1, -1.1, 0.0); glTexCoord2f(+1.0, 1.0); glVertex3f(1.1, 1.1, 0.0); glTexCoord2f(+0.0, 1.0); glVertex3f(-1.1, 1.1, 0.0); glEnd(); glDisable(GL_BLEND); glPopMatrix; Ifter Compilation the PC show's me my Texture but it isnt Transparent in the Black Parts. did anyone Know what i made wrong ?
--You want to know more about me then visit www.Corpsman.de.vu
Advertisement
The problem is that because you draw the textured quad first, you're wiping out the image that was already there. No matter what you then do with your mask quad, you can't get that 'background' back.

Why not use an image format with support for an alpha channel?

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

Lol

I swaped the Ftexture with the Fmasktexture and it worked.

But not always. I can move the Camera in my Programm and if i move Forward and backward ( near and far ) to the Graphik. It was sometimes Transparent and sometimes not. why this ?

Your Idea with Alpha channel is not bad, but i Have to use BMP files, because i am not allowed to change my input data, so i have to use the mask way.
--You want to know more about me then visit www.Corpsman.de.vu
Not quite true. You may have to load a specific format, but you can combine your data in memory, thus applying your mask as the alpha channel.

Modify your BMP loader to load RGBA, RGB from the file and leaving A as a 255.
Then add in the mask, by setting every 4th bit to the mask value.
OR
Make a convert function that, once the BMP is loaded, will take the BMP and Mask data and make a new
image array in RGBA format.
OK what you write sound's realy good.

But i'm a realy beginner with OpenGl I use a standert Loader for BMP Files.

Maybe you understand this, I unluky do not understand.

Here's the Code loading a Bitmap.

Function CreateTexture(Width, Height, Format: Word; pData: Pointer): Integer;
Var
Texture: TGLuint;
Begin
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
glDeleteTextures(1, @Texture);
glGenTextures(1, @Texture);
LastFormat := Format;
LastWidth := Width;
LastHeight := Height;
LastID := Texture;
LastAlpha := False;
If (Format = GL_RGBA) Or (Format = GL_RGBA8) Then
LastAlpha := True;
// 2D-Textur
If Height > 1 Then Begin
glEnable(GL_TEXTURE_2D);
glBindTexture(Target, Texture);
glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); { all of the above can be used }
If Format = GL_RGBA Then
gluBuild2DMipmaps(Target, GL_RGBA8, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, pData)
Else
gluBuild2DMipmaps(Target, GL_RGB8, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData);
LastBinding := Target;
End;
// 1D-Textur
If Height = 1 Then Begin
glEnable(GL_TEXTURE_1D);
glBindTexture(GL_TEXTURE_1D, Texture);
gluBuild1DMipmaps(GL_TEXTURE_1D, Format, Width, Format, GL_UNSIGNED_BYTE, pData);
//glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, Width, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pData);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
LastBinding := GL_TEXTURE_1D;
End;
Result := Texture;
End;
--You want to know more about me then visit www.Corpsman.de.vu
By the time you call that function, you've already got the bitmap data kicking around in memory (the pData pointer). Can you show us the code that actually reads the data in from the file?

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

I Think you mean this ?

Procedure SwapRGB(data: Pointer; Size: Integer);
Asm
mov ebx, eax
mov ecx, size

@@loop :
mov al,[ebx+0]
mov ah,[ebx+2]
mov [ebx+2],al
mov [ebx+0],ah
add ebx,3
dec ecx
jnz @@loop
End;

Function LoadBMPTexture(Filename: String; Var Texture: TGLuint; LoadFromResource: Boolean): Boolean;
Var
FileHeader: BITMAPFILEHEADER;
InfoHeader: BITMAPINFOHEADER;
Palette: Array Of RGBQUAD;
BitmapFile: THandle;
BitmapLength: LongWord;
PaletteLength: LongWord;
ReadBytes: LongWord;
Width, Height: Integer;
pData: Pointer;

// used for loading from resource
ResStream: TResourceStream;
Begin
result := FALSE;

If LoadFromResource Then {// Load from resource} Begin
Try
ResStream := TResourceStream.Create(hInstance, PChar(copy(Filename, 1, Pos('.', Filename) - 1)), 'BMP');
ResStream.ReadBuffer(FileHeader, SizeOf(FileHeader)); // FileHeader
ResStream.ReadBuffer(InfoHeader, SizeOf(InfoHeader)); // InfoHeader
PaletteLength := InfoHeader.biClrUsed;
SetLength(Palette, PaletteLength);
ResStream.ReadBuffer(Palette, PaletteLength); // Palette

Width := InfoHeader.biWidth;
Height := InfoHeader.biHeight;

BitmapLength := InfoHeader.biSizeImage;
If BitmapLength = 0 Then
BitmapLength := Width * Height * InfoHeader.biBitCount Div 8;

GetMem(pData, BitmapLength);
ResStream.ReadBuffer(pData^, BitmapLength); // Bitmap Data
ResStream.Free;
Except On
EResNotFound Do Begin
MessageBox(0, PChar('File not found in resource - ' + Filename), PChar('BMP Texture'), MB_OK);
Exit;
End
Else Begin
MessageBox(0, PChar('Unable to read from resource - ' + Filename), PChar('BMP Unit'), MB_OK);
Exit;
End;
End;
End
Else Begin // Load image from file
BitmapFile := CreateFile(PChar(Filename), GENERIC_READ, FILE_SHARE_READ, Nil, OPEN_EXISTING, 0, 0);
If (BitmapFile = INVALID_HANDLE_VALUE) Then Begin
MessageBox(0, PChar('Error opening ' + Filename), PChar('BMP Unit'), MB_OK);
Exit;
End;

// Get header information
ReadFile(BitmapFile, FileHeader, SizeOf(FileHeader), ReadBytes, Nil);
ReadFile(BitmapFile, InfoHeader, SizeOf(InfoHeader), ReadBytes, Nil);

// Get palette
PaletteLength := InfoHeader.biClrUsed;
SetLength(Palette, PaletteLength);
ReadFile(BitmapFile, Palette, PaletteLength, ReadBytes, Nil);
If (ReadBytes <> PaletteLength) Then Begin
MessageBox(0, PChar('Error reading palette'), PChar('BMP Unit'), MB_OK);
Exit;
End;

Width := InfoHeader.biWidth;
Height := InfoHeader.biHeight;
BitmapLength := InfoHeader.biSizeImage;
If BitmapLength = 0 Then
BitmapLength := Width * Height * InfoHeader.biBitCount Div 8;

// Get the actual pixel data
GetMem(pData, BitmapLength);
ReadFile(BitmapFile, pData^, BitmapLength, ReadBytes, Nil);
If (ReadBytes <> BitmapLength) Then Begin
MessageBox(0, PChar('Error reading bitmap data'), PChar('BMP Unit'), MB_OK);
Exit;
End;
CloseHandle(BitmapFile);
End;

// Bitmaps are stored BGR and not RGB, so swap the R and B bytes.
SwapRGB(pData, Width * Height);

Texture := CreateTexture(Width, Height, GL_RGB, pData);
FreeMem(pData);
result := TRUE;
End;
--You want to know more about me then visit www.Corpsman.de.vu

This topic is closed to new replies.

Advertisement