2012-12-13 72 views
1

自從上個星期以來,我一直在試圖加載並在屏幕上顯示PNG。我使用庫libpng將png複製到內存中,然後使用glDrawPixels在屏幕上顯示它。結果如下:OpenGL + libpng:圖像顏色錯誤

原始照片:

enter image description here

截圖中的 「遊戲」:

enter image description here

和代碼,我使用的是靜態圖片:: 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); 
} 

正如你所看到的,顏色是不同的比他們應。任何人都可以幫我弄清楚如何解決我的問題?

+2

當'GL_TEXTURE_MIN_FILTER'設置爲'GL_NEAREST'你爲什麼要生成的貼圖?你爲什麼要生成紋理*?如果你只是要使用'glDrawPixels()'? – genpfault

+0

感謝您在我的應用程序中發現小問題,我已經修復了您所說的第一件事,但相對您的第二點,您可能會在Google翻譯中看到我的評論,如「我現在不在意跟隨行」。我會要求專注於標題中的一個重大問題。 –

+0

Image :: images.insert也應該在註釋之上,不要那麼想。 –

回答

1

它看起來像你可能有一些顏色通道交換。在致glTexImage2D()的電話中,我認爲請嘗試將GL_BGRA_EXT更改爲GL_RGBA。或者,如果這不起作用,請將GL_UNSIGNED_BYTE更改爲GL_UNSIGNED_INT_8_8_8_8_REV

+0

我根據你的提示改變了,但沒有任何反應。 –

0

它在我看來像你的圖像可能正在使用(乘法?)混合繪製。

您是否啓用了Alpha混合? (你的圖像似乎有一個alpha通道)

你設置了什麼混合模式?

應該可能只是:

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
+0

我有這個,它已經在GLUT的函數「init」中。 –

+0

您是否爲繪圖像素設置了任何比例和偏差值? – JasonD

+0

如何?你能解釋一下嗎? –