С прошлой недели я пытался загрузить и показать PNG на экране. Я использовал библиотеку libpng для копирования png в память, а затем использовал glDrawPixels, чтобы показать ее на экране. Результат следующий:
Оригинальная картина:
Снимок экрана в разделе «игра»:
И код, я использую 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;
}
И, наконец, показать это в OpenGL:
Image* image = Image::images["f.png"]->image;
if( image )
{
glDisable(GL_DEPTH_TEST);
glPushMatrix( );
//glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
float nx = 0.0f;
float ny = 0.0f;
glLoadIdentity( );
glTranslatef( 0, 0, -1 );
if( nx > 0 || ny > 0 )
glRasterPos2f( nx, ny );
else
{
glRasterPos2f( 0, 0 );
glBitmap(0,0,0,0, nx, ny, NULL);
}
glDrawPixels( image->width, image->height, GL_RGBA, GL_UNSIGNED_BYTE, image->image);
glPopMatrix( );
glEnable(GL_DEPTH_TEST);
}
Как видите, цвета разные, чем должны быть. Может ли кто-нибудь помочь мне понять, как решить мою проблему?
Похоже, у вас может быть несколько цветовых каналов. В призыве к glTexImage2D()
попробуйте поменять GL_BGRA_EXT
в GL_RGBA
, Я думаю. Или, если это не сработает, измените GL_UNSIGNED_BYTE
в GL_UNSIGNED_INT_8_8_8_8_REV
,
Мне кажется, что ваше изображение, возможно, рисуется с помощью (умножения?).
У вас есть альфа-смешивание? (у вашего изображения, кажется, есть альфа-канал)
Какой режим смешивания вы установили?
Вероятно, должно быть просто:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);