2010-08-02 218 views
2

我的問題 - >如何使顏色255,200,255在OpenGL中透明? (由透明我的意思是除去像素顏色255200255或任何作品...)OpenGL設置紋理的透明顏色

我的紋理加載函數從該教程 - >http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=33

注意,我沒有使用Alpha通道,我有用定製顏色(255200255),其必須是透明的/移除的像素的一組預先製作的圖像..

我的節目的一些的.tga加載函數:

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

    } 

回答

2

如果texture-> bpp == 24而不是32(表示沒有內置的alpha通道),則必須生成一個32位的openGL紋理,並將每個texel的alpha值設置爲255 iif tga像素是255,200,255。

+0

,我該怎麼做..?以及如何啓用alpha透明度? – Tenev 2010-08-03 15:33:43

+0

在glTexImage2D()中用GL_RGBA替換GL_RGB。這樣,即使它沒有在PNG中指定,你也將始終擁有一個Alpha通道。但是現在openGL會期望x * h * 4 texels,所以要分配另一個緩衝區,就像(GLubyte *)malloc(tga.imageSize);但帶有x * h * 4個字節。然後對於每個紋理元素,將R,G和B組件從texture-> imageData複製到新緩衝區。如果這些RGB與您想要的值相匹配,請將A設置爲255. – Calvin1602 2010-08-03 15:58:13

+0

只需非常清楚:如果texture-> imageData是RGBARGBARGBARGBA ....(即texture-> bpp == 32),請不要更改您的代碼;如果texture-> imageData是RGBRGBRGBRGB ....(即texture-> bpp == 24),則必須將其轉換爲RGBARGBARGBARGBA,然後自己計算A – Calvin1602 2010-08-03 16:00:20

0

OpenGL和色彩鍵控可以是有點棘手。使用1位alpha可能更容易,但我已經看到SDL用於像您所描述的顏色鍵控。 This thread可能會幫助你。

+0

我不會使用「tricky」這個詞,我會說在OpenGL中直接不支持顏色鍵控,並且您需要採用手動方式,使用着色器或在上傳之前使用alpha = 0.0設置透明像素glTexImage2D。 – 2010-08-02 23:39:34

0

那麼,如果你使用紋理,那麼我假設你已經有一個片段着色器。 其實很簡單。

首先在主程序中打開alpha混合: glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

然後,在片段着色器添加以下代碼:

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

上面的代碼將設置黑色作爲色度鍵。 (在0.01的閾值內)您可以通過查找其RGB值來選擇另一種顏色。如果不是色度鍵顏色,則將alpha設置爲full(1.0)。