开发者

OpenGL Set Transparent Color for textures

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜