Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL Set Transparent Color for textures

Tags:

opengl

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 needed 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);
        }

    }
like image 604
Tenev Avatar asked Jan 01 '26 22:01

Tenev


2 Answers

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.

like image 133
Calvin1602 Avatar answered Jan 04 '26 00:01

Calvin1602


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).

like image 33
Ellison Chan Avatar answered Jan 04 '26 02:01

Ellison Chan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!