【发布时间】:2011-12-20 21:00:00
【问题描述】:
我正在用 C++ 编写渲染器。我看到已经回答了类似的问题,我只是在寻找更多信息。我有一个 256 色位图,我将其加载到内存中,然后加载到 OpenGL 中。我无法事先转换文件,需要在内存中进行。我希望能够将其转换为 RGBA 位图以使用 Alpha 通道。有没有人有任何关于库的代码或建议可以帮助我解决这个问题?
【问题讨论】:
我正在用 C++ 编写渲染器。我看到已经回答了类似的问题,我只是在寻找更多信息。我有一个 256 色位图,我将其加载到内存中,然后加载到 OpenGL 中。我无法事先转换文件,需要在内存中进行。我希望能够将其转换为 RGBA 位图以使用 Alpha 通道。有没有人有任何关于库的代码或建议可以帮助我解决这个问题?
【问题讨论】:
我在某处有一些代码,但只有 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;
}
【讨论】:
您可以使用most of these libraries 来执行此操作(并且您可以使用任意数量的其他格式)。我建议使用非官方的 OpenGL SDK。但话又说回来,我写了它,所以把它当作它的价值;)
我希望能够将其转换为 RGBA 位图以使用 Alpha 通道。
这将是相当困难的,因为 BMP 格式实际上没有 Alpha 通道。我们说的是 BMP 格式的图像,是吗?
【讨论】: