Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL&x2B;libpng:图像上的颜色错误_C++_Opengl_Colors_Png_Gldrawpixels - Fatal编程技术网

C++ OpenGL&x2B;libpng:图像上的颜色错误

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

从上周开始,我一直在尝试在屏幕上加载并显示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* 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。我根据您的提示进行了更改,但什么也没有发生。我根据您的提示进行了更改,但什么也没有发生。