My question-> How do i make color 255,200,255 transparent in OpenGL? (by transparent i mean removing the pixels color 255,200,255 or whatever works...)
my texture loading functions are from this tutorial-> http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=33
note that i don't have to use Alpha Channels, i have a set of pre-made images with custom color (255,200,255) which must be transparent/removed pixels..
some .tga loading functions of my program:
Texture AllTextures[1000];
typedef struct
{
GLubyte * imageData; // Image Data (Up To 32 Bits)
GLuint bpp; // Image Color Depth In Bits Per Pixel
GLuint width; // Image Width
GLuint height; // Image Height
GLuint texID; // Texture ID Used To Select A Texture
GLuint type; // Image Type (GL_RGB, GL_RGBA)
} Texture;
bool LoadUncompressedTGA(Texture * texture, char * filename, FILE * fTGA) // Load an uncompressed TGA (note, much of this code is based on NeHe's
{ // TGA Loading code nehe.gamedev.net)
if(fread(tga.header, sizeof(tga.header), 1, fTGA) == 0) // Read TGA header
{
MessageBox(NULL, "Could not read info header", "ERROR", MB_OK); // Display error
if(fTGA != NULL) // if file is still open
{
fclose(fTGA); // Close it
}
return false; // Return failular
}
texture->width = tga.header[1] * 256 + tga.header[0]; // Determine The TGA Width (highbyte*256+lowbyte)
texture->height = tga.header[3] * 256 + tga.header[2]; // Determine The TGA Height (highbyte*256+lowbyte)
texture->bpp = tga.header[4]; // Determine the bits per pixel
tga.Width = texture->width; // Copy width into local structure
tga.Height = texture->height; // Copy height into local structure
tga.Bpp = texture->bpp; // Copy BPP into local structure
if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32))) // Make sure all information is valid
{
MessageBox(NULL, "Invalid texture information", "ERROR", MB_OK); // Display Error
if(fTGA != NULL) // Check if file is still open
{
fclose(fTGA); // If so, close it
}
return false; // Return failed
}
if(texture->bpp == 24) //If the BPP of the image is 24...
{
texture->type = GL_RGBA; // Set Image type to GL_RGB
}
else // Else if its 32 BPP
{
texture->type = GL_RGBA; // Set image type to GL_RGBA
}
tga.bytesPerPixel = (tga.Bpp / 8); // Compute the number of BYTES per pixel
tga.imageSize = (tga.bytesPerPixel * tga.Width * tga.Height); // Compute the total amout ofmemory neede开发者_开发知识库d to store data
texture->imageData = (GLubyte *)malloc(tga.imageSize); // Allocate that much memory
if(texture->imageData == NULL) // If no space was allocated
{
MessageBox(NULL, "Could not allocate memory for image", "ERROR", MB_OK); // Display Error
fclose(fTGA); // Close the file
return false; // Return failed
}
if(fread(texture->imageData, 1, tga.imageSize, fTGA) != tga.imageSize) // Attempt to read image data
{
MessageBox(NULL, "Could not read image data", "ERROR", MB_OK); // Display Error
if(texture->imageData != NULL) // If imagedata has data in it
{
free(texture->imageData); // Delete data from memory
}
fclose(fTGA); // Close file
return false; // Return failed
}
// Byte Swapping Optimized By Steve Thomas
for(GLuint cswap = 0; cswap < (int)tga.imageSize; cswap += tga.bytesPerPixel)
{
texture->imageData[cswap] ^= texture->imageData[cswap+2] ^=texture->imageData[cswap] ^= texture->imageData[cswap+2];
}
fclose(fTGA); // Close file
return true; // Return success
}
void LoadMyTextureTGA(int id,char* texturename)
{
//texturename ex: "Data/Uncompressed.tga"
if(LoadTGA(&AllTextures[id], texturename))
{
//success
glGenTextures(1, &AllTextures[id].texID); // Create The Texture ( CHANGE )
glBindTexture(GL_TEXTURE_2D, AllTextures[id].texID);
glTexImage2D(GL_TEXTURE_2D, 0, 3, AllTextures[id].width, AllTextures[id].height, 0, GL_RGB, GL_UNSIGNED_BYTE, AllTextures[id].imageData);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
if (AllTextures[id].imageData) // If Texture Image Exists ( CHANGE )
{
free(AllTextures[id].imageData); // Free The Texture Image Memory ( CHANGE )
}
}
else
{
MessageBoxA(0,"Textures Loading Fail! Game will close now","Game Problem",0);
exit(1);
}
}
if texture->bpp == 24 instead of 32 (which means there is no built-in alpha channel), you have to generate a 32-bit openGL texture, and set the alpha value of each texel to 255 iif the tga pixel is 255,200,255.
Well, if you're using textures, then I'm assuming you already have a fragment shader. It's pretty easy actually.
First in the main program turn on alpha blending: glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Then in the fragment shader add this code:
vec3 chromaKeyColor = texture(myTextureSampler,UV.xy).xyz;
float alpha;
if ((chromaKeyColor.x <= 0.01) && (chromaKeyColor.y <= 0.01) && (chromaKeyColor.z <= 0.01)){
alpha = 0.;
}
else
{
alpha = 1.0;
}
color = vec4(texture(myTextureSampler,VertexOut.texCoord.xy).xyz,alpha);
The above code will set black as the chroma key. (within a threshold of 0.01) You can choose another colour by looking up its RGB value. If it's not the chroma key colour, then set the alpha to full (1.0).
OpenGL and color-keying can be a little tricky. Using 1-bit alpha is probably easier, but I've seen SDL used for color-keying like you describe. This thread might help you out.
精彩评论