1

Since last week I've been trying to load and show a PNG on the screen. I used a library libpng to copy png into memory and then used glDrawPixels to show it on screen. The result is following:

The original picture:

enter image description here

Screenshot in the "game":

enter image description here

And the code, I'm using static Image::loadPNG to load PNG into map and it's like the following:

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;
}

And finally showing it in 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);
}

As you can see, the colors are different than they should be. Could anyone help me to figure out how to solve my problem?

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • 2
    Why are you generating mipmaps when `GL_TEXTURE_MIN_FILTER` is set to `GL_NEAREST`? Why are you generating textures *at all* if you're just going to use `glDrawPixels()`? – genpfault Dec 13 '12 at 21:12
  • Thank you for finding minor issues in my application, I have fixed the first thing which you said, but relatively your second point, you might see my comment which in google translate would say something like "I don't care about following lines now". I would ask to concentrate in a major problem in the title. – Radosław Wójciak Dec 13 '12 at 22:29
  • The Image::images.insert should be above the comment also, nevermind that. – Radosław Wójciak Dec 13 '12 at 22:31

2 Answers2

1

It looks like you may have some color channels swapped. In the call to glTexImage2D(), try changing the GL_BGRA_EXT to GL_RGBA, I think. Or, if that doesn't work, change GL_UNSIGNED_BYTE to GL_UNSIGNED_INT_8_8_8_8_REV.

user1118321
  • 25,567
  • 4
  • 55
  • 86
0

It looks to me like your image is perhaps being drawn using a (multiply?) blend.

Do you have alpha blending enabled? (your image seems to have an alpha channel)

What blend mode have you set?

It should probably just be:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
JasonD
  • 16,464
  • 2
  • 29
  • 44