2011-11-03 58 views
3

我正在用C++寫一個渲染器。我看到類似的問題已經得到解答,我只是在尋找更多的信息。我有一個256色位圖,我加載到內存中,然後加載到OpenGL中。我無法事先轉換文件,需要在內存中進行轉換。我希望能夠將其轉換爲RGBA位圖以使用Alpha通道。有沒有人有任何關於圖書館的代碼或建議可以幫助我?將256色位圖轉換爲RGBA位圖

回答

4

我在某處有一些代碼,但它只有20行或更少。 BMP格式非常簡單,只需讀取標題,然後讀取每個顏色,即用作調色板數組中的索引。而且要記住,BMP是顛倒:

//load a bmp texture, with the specified global alpha 
GLuint load_bmp8_fixed_alpha(char * FileName, Uint8 a) 
{ 
    int x,y,x_padding,x_size,y_size,colors_no,r,g,b,current_pallete_entry; //i unused? 
    Uint8 * file_mem; 
    Uint8 * file_mem_start; 
    Uint8 * texture_mem; 
    Uint8 * read_buffer; 
    Uint8 * color_pallete; 
    FILE *f = NULL; 
    GLuint texture; 

    f = fopen (FileName, "rb"); 
    if (!f) return 0; 
    file_mem = (Uint8 *) calloc (20000, sizeof(Uint8)); 
    file_mem_start=file_mem; 
    fread (file_mem, 1, 50, f);//header only 
    //now, check to see if our bmp file is indeed a bmp file, and if it is 8 bits, uncompressed 
    if(*((short *) file_mem)!=19778)//BM (the identifier) 
     { 
      free(file_mem_start); 
      fclose (f); 
      return 0; 
     } 
    file_mem+=18; 
    x_size=*((int *) file_mem); 
    file_mem+=4; 
    y_size=*((int *) file_mem); 
    file_mem+=6; 
    if(*((short *)file_mem)!=8)//8 bit/pixel? 
     { 
      free(file_mem_start); 
      fclose (f); 
      return 0; 
     } 

    file_mem+=2; 
    if(*((int *)file_mem)!=0)//any compression? 
     { 
      free(file_mem_start); 
      fclose (f); 
      return 0; 
     } 
    file_mem+=16; 

    colors_no=*((int *)file_mem); 
    if(!colors_no)colors_no=256; 
    file_mem+=8;//here comes the pallete 

    color_pallete=file_mem+4; 
    fread (file_mem, 1, colors_no*4+4, f);//header only 
    file_mem+=colors_no*4; 

    x_padding=x_size%4; 
    if(x_padding)x_padding=4-x_padding; 

    //now, allocate the memory for the file 
    texture_mem = (Uint8 *) calloc (x_size*y_size*4, sizeof(Uint8)); 
    read_buffer = (Uint8 *) calloc (2000, sizeof(Uint8)); 


    for(y=0;y<y_size;y++) 
     { 
      //fread (texture_mem+y*x_size, 1, x_size-x_padding, f); 
      fread (read_buffer, 1, x_size-x_padding, f); 

      for(x=0;x<x_size;x++) 
       { 
        current_pallete_entry=*(read_buffer+x); 
        b=*(color_pallete+current_pallete_entry*4); 
        g=*(color_pallete+current_pallete_entry*4+1); 
        r=*(color_pallete+current_pallete_entry*4+2); 
        *(texture_mem+(y*x_size+x)*4)=r; 
        *(texture_mem+(y*x_size+x)*4+1)=g; 
        *(texture_mem+(y*x_size+x)*4+2)=b; 
        *(texture_mem+(y*x_size+x)*4+3)=a; 
       } 

     } 

    free(file_mem_start); 
    free(read_buffer); 
    fclose (f); 
    //ok, now, hopefully, the file is loaded and converted... 
    //so, assign the texture, and such 

    glGenTextures(1, &texture); 
    glBindTexture(GL_TEXTURE_2D, texture); //failsafe 
    bind_texture_id(texture); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

    if(poor_man) 
     { 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
     } 
    else if(use_mipmaps) 
     { 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 
      glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); 
     } 
    else 
     { 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     } 

    if(have_arb_compression) 
     { 
      if(have_s3_compression) 
      glTexImage2D(GL_TEXTURE_2D,0,COMPRESSED_RGBA_S3TC_DXT5_EXT,x_size, y_size,0,GL_RGBA,GL_UNSIGNED_BYTE,texture_mem); 
      else 
      glTexImage2D(GL_TEXTURE_2D,0,COMPRESSED_RGBA_ARB,x_size, y_size,0,GL_RGBA,GL_UNSIGNED_BYTE,texture_mem); 

     } 
    else 
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,x_size, y_size,0,GL_RGBA,GL_UNSIGNED_BYTE,texture_mem); 

    check_gl_errors(); 
    free(texture_mem); 
    return texture; 
} 
+0

這20條線現在會非常有用。只是尋找一個關於如何去做以及256色位圖不同的想法。 –

+0

給我你的電子郵件,我會把它發給你。 – Radu

+0

我的電子郵件是[email protected] –

3

你可以使用most of these libraries做到這一點(和你能使用任意數量的其他格式)。我會建議非官方的OpenGL SDK。但後來我寫了,所以拿它的價值;)

我想能夠將其轉換爲RGBA位圖,以利用alpha通道。

這會很困難,因爲BMP格式實際上並沒有alpha通道。我們正在討論BMP格式的圖像,是的?

+0

我的印象是可能存在RGBA位圖。如果不是,我想將其轉換爲具有紅色,綠色,藍色和alpha組件並且與OpenGL兼容的任何格式。謝謝Nicol。你一直是這個網站上最野獸程序員之一。 –

+0

8b BMPs沒有alpha通道。但根據您的需要,您可以根據圖像對比度設置Alpha。或者你可以有一個單獨的BMP與alpha。儘管我會建議儘可能使用DDS格式。 – Radu

+0

@PladniusBrooks:如果你的意思是BMP格式的圖像,請停止稱他們爲「位圖」。術語「位圖」是光柵圖像的通用術語;它並不總是意味着.bmp文件。另外,OpenGL不會讀取圖像格式;取決於用戶代碼將它們變成「與OpenGL兼容」的東西;這就是我指出的圖書館所做的。您的工作應該是生成具有所需顏色通道的圖像,並且可以由其中一個庫加載。與大多數其他格式一樣,TGA圖像可以具有alpha通道。 –