C++ OpenGL&x2B;libpng:图像上的颜色错误
从上周开始,我一直在尝试在屏幕上加载并显示PNG。我使用libpng库将png复制到内存中,然后使用glDrawPixels在屏幕上显示它。结果如下:C++ OpenGL&x2B;libpng:图像上的颜色错误,c++,opengl,colors,png,gldrawpixels,C++,Opengl,Colors,Png,Gldrawpixels,从上周开始,我一直在尝试在屏幕上加载并显示PNG。我使用libpng库将png复制到内存中,然后使用glDrawPixels在屏幕上显示它。结果如下: bool Image::loadPNG( std::string _image, FILE * file, unsigned char header[ 54 ] ) { fseek( file, 8, SEEK_SET ); ImageData* imageData = new ImageData( ); Image* i
bool Image::loadPNG( std::string _image, FILE * file, unsigned char header[ 54 ] )
{
fseek( file, 8, SEEK_SET );
ImageData* imageData = new ImageData( );
Image* image = new Image( );
image->type = IMAGETYPE_PNG;
imageData->image = image;
png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
if( !png_ptr )
{
std::cout << "png_create_read_struct failed. " << std::endl;
return false;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if( !info_ptr )
{
std::cout << "png_create_info_struct failed. " << std::endl;
return false;
}
if( setjmp( png_jmpbuf( png_ptr ) ) )
{
std::cout << "Error during init_io. " << std::endl;
return false;
}
png_init_io( png_ptr, file );
png_set_sig_bytes( png_ptr, 8 );
png_read_info( png_ptr, info_ptr );
png_set_strip_16( png_ptr );
png_read_update_info(png_ptr, info_ptr);
int bit_depth;
int color;
png_get_IHDR(png_ptr, info_ptr, &image->width, &image->height, &bit_depth, &color, NULL, NULL, NULL);
png_read_update_info(png_ptr, info_ptr);
int pitch = png_get_rowbytes(png_ptr, info_ptr);
image->image = new unsigned char[pitch * image->height];
png_bytep* row_pointers = new png_bytep[image->height];
for (int y = 0; y < image->height; y++)
row_pointers[image->height - 1 - y] = image->image + y * pitch;
png_read_image(png_ptr, row_pointers);
delete[] row_pointers;
// tym na razie dupy sobie nie zawracam
Image::images.insert( std::pair< std::string, ImageData* >( _image, imageData ) );
glGenTextures(1, &imageData->texture);
glBindTexture( GL_TEXTURE_2D, imageData->texture );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->width, image->height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->image);
gluBuild2DMipmaps( GL_TEXTURE_2D, 4, image->width, image->height, GL_RGBA, GL_UNSIGNED_BYTE, image->image );
return true;
}
原图:
“游戏”中的屏幕截图:
代码中,我使用static Image::loadPNG将PNG加载到地图中,如下所示:
bool Image::loadPNG( std::string _image, FILE * file, unsigned char header[ 54 ] )
{
fseek( file, 8, SEEK_SET );
ImageData* imageData = new ImageData( );
Image* image = new Image( );
image->type = IMAGETYPE_PNG;
imageData->image = image;
png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
if( !png_ptr )
{
std::cout << "png_create_read_struct failed. " << std::endl;
return false;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if( !info_ptr )
{
std::cout << "png_create_info_struct failed. " << std::endl;
return false;
}
if( setjmp( png_jmpbuf( png_ptr ) ) )
{
std::cout << "Error during init_io. " << std::endl;
return false;
}
png_init_io( png_ptr, file );
png_set_sig_bytes( png_ptr, 8 );
png_read_info( png_ptr, info_ptr );
png_set_strip_16( png_ptr );
png_read_update_info(png_ptr, info_ptr);
int bit_depth;
int color;
png_get_IHDR(png_ptr, info_ptr, &image->width, &image->height, &bit_depth, &color, NULL, NULL, NULL);
png_read_update_info(png_ptr, info_ptr);
int pitch = png_get_rowbytes(png_ptr, info_ptr);
image->image = new unsigned char[pitch * image->height];
png_bytep* row_pointers = new png_bytep[image->height];
for (int y = 0; y < image->height; y++)
row_pointers[image->height - 1 - y] = image->image + y * pitch;
png_read_image(png_ptr, row_pointers);
delete[] row_pointers;
// tym na razie dupy sobie nie zawracam
Image::images.insert( std::pair< std::string, ImageData* >( _image, imageData ) );
glGenTextures(1, &imageData->texture);
glBindTexture( GL_TEXTURE_2D, imageData->texture );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->width, image->height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->image);
gluBuild2DMipmaps( GL_TEXTURE_2D, 4, image->width, image->height, GL_RGBA, GL_UNSIGNED_BYTE, image->image );
return true;
}
正如你所看到的,这些颜色与它们应该的颜色不同。有人能帮我找出解决问题的办法吗 看起来您可能交换了一些颜色通道。我想,在调用
glTexImage2D()
时,尝试将GL\u BGRA\u EXT
更改为GL\u RGBA
。或者,如果这不起作用,将GL\u UNSIGNED\u BYTE
更改为GL\u UNSIGNED\u INT\u 8\u 8\u REV
看起来您可能已交换了一些颜色通道。我想,在调用glTexImage2D()
时,尝试将GL\u BGRA\u EXT
更改为GL\u RGBA
。或者,如果这不起作用,将GL_UNSIGNED_BYTE
更改为GL_UNSIGNED_INT_8_8_REV
在我看来,您的图像可能是使用(乘法?)混合绘制的
是否启用了alpha混合?(您的图像似乎有一个alpha通道)
你设置了什么混合模式
它可能只是:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
在我看来,您的图像可能是使用(乘法?)混合绘制的 是否启用了alpha混合?(您的图像似乎有一个alpha通道) 你设置了什么混合模式 它可能只是:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
当
GL\u TEXTURE\u MIN\u FILTER
设置为GL\u NEAREST
时,为什么要生成mipmap?如果你只是想使用glDrawPixels()
,为什么还要生成纹理呢?谢谢你在我的应用程序中发现了一些小问题,我已经解决了你说的第一件事,但是相对你的第二点,你可能会看到我的评论,在谷歌翻译中会说“我现在不在乎下面的行”。我想请大家把注意力集中在标题中的一个主要问题上。Image::images.insert也应该在注释上方,不管怎样。当GL\u TEXTURE\u MIN\u FILTER
设置为GL\u NEAREST
时,为什么要生成mipmap?如果你只是想使用glDrawPixels()
,为什么还要生成纹理呢?谢谢你在我的应用程序中发现了一些小问题,我已经解决了你说的第一件事,但是相对你的第二点,你可能会看到我的评论,在谷歌翻译中会说“我现在不在乎下面的行”。我会要求集中在标题中的一个主要问题上。Image::images.insert也应该在注释上方,不用担心。我有这个,它已经在GLUT的函数“init”中。您是否为drawpixels设置了任何比例和偏差值?如何设置?你能解释一下吗?你必须设置GL_红色_刻度等等。如果你还没有设置它,我真的认为这不是问题。PNG的深度是多少位?属性窗口显示它是64x64 px,32位图像,所以我认为它可能是24位+alpha。我正好有这个,它已经在GLUT的函数“init”中了。你为drawpixels设置了任何比例和偏差值吗?如何设置?你能解释一下吗?你必须设置GL_红色_刻度等等。如果你还没有设置它,我真的认为这不是问题。PNG的深度是多少位?属性窗口显示它是64x64 px,32位图像,因此我认为它可能是24位+alpha。我根据您的提示进行了更改,但什么也没有发生。我根据您的提示进行了更改,但什么也没有发生。