freeimage зареждане на png с прозрачност c++

Заредих PNG изображение в моята сцена. Докато самото изображение се зарежда правилно (това, което искам да се показва), проблемът, който имам, е с прозрачността около изображението. Там, където трябва да има прозрачност, има бели и черни петна, изпълващи това пространство.

void Renderer::loadTexture()
{
    const char textName[64] = ".\\foo.png";

    FIBITMAP *dib = FreeImage_Load(FIF_PNG, textName, PNG_DEFAULT);
    dib = FreeImage_ConvertTo24Bits(dib);


    if (FreeImage_GetBPP(dib) != 32) 
    {
        FIBITMAP* tempImage = dib;
        dib = FreeImage_ConvertTo32Bits(tempImage);
    }

    if (dib != NULL)
    {
        glGenTextures(1, &g_textureID);
        glBindTexture(GL_TEXTURE_2D, g_textureID);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        BYTE *bits = new BYTE[FreeImage_GetWidth(dib) * FreeImage_GetHeight(dib) * 4];

        BYTE *pixels = (BYTE*) FreeImage_GetBits(dib);

        for (int pix = 0; pix<FreeImage_GetWidth(dib) * FreeImage_GetHeight(dib); pix++)
        {
            bits[pix * 4 + 0] = pixels[pix * 4 + 2];
            bits[pix * 4 + 1] = pixels[pix * 4 + 1];
            bits[pix * 4 + 2] = pixels[pix * 4 + 0];
        }

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FreeImage_GetWidth(dib), FreeImage_GetHeight(dib), 0,
        GL_RGBA, GL_UNSIGNED_BYTE, bits);

        cout << textName << " loaded." << endl;

        FreeImage_Unload(dib);
        delete bits;
    }


}

person Community    schedule 09.11.2013    source източник
comment
Не съм запознат с FreeImage, но защо копирате само 3 байта във вашия for цикъл? Вярно ли е? Не трябва ли да копирате и алфата?   -  person acfrancis    schedule 09.11.2013
comment
@acfrancis Актуализирах кода и го тествах със същите резултати   -  person    schedule 09.11.2013
comment
Можете ли да актуализирате кода във въпроса, моля?   -  person acfrancis    schedule 09.11.2013


Отговори (1)


Първо, GL_RGBA има по един байт за всяко червено, зелено, синьо и алфа (алфа=прозрачност). Вашият код очевидно не се занимава с алфа (4-тия байт на пиксел). Опитайте да добавите следния ред:

    for (int pix = 0; pix<FreeImage_GetWidth(dib) * FreeImage_GetHeight(dib); pix++)
    {
        bits[pix * 4 + 0] = pixels[pix * 4 + 2];
        bits[pix * 4 + 1] = pixels[pix * 4 + 1];
        bits[pix * 4 + 2] = pixels[pix * 4 + 0];
        bits[pix * 4 + 3] = pixels[pix * 4 + 3]; // Add this line to copy Alpha
    }

Второ, ако все още не работи, опитайте да премахнете реда FreeImage_ConvertTo24Bits (дори да работи, моля, опитайте да премахнете и това):

// dib = FreeImage_ConvertTo24Bits(dib); // Remove this line
if (FreeImage_GetBPP(dib) != 32) 
{
    FIBITMAP* tempImage = dib;
    dib = FreeImage_ConvertTo32Bits(tempImage);
}

Странно е да конвертирате изображението в 24 бита и след това обратно в 32 бита. Може би ще отхвърли алфа канала.

Не се опитах да стартирам цялата програма и да я отстраня. Просто предоставя някои съвети, които можете да опитате.

person miaout17    schedule 09.11.2013
comment
Все още имам същите резултати... Ако всичко това е правилно, следващото ми предположение би било, че пропускам нещо в моята функция Init() в OpenGL, където имам glEnable(GL_TEXTURE_2D). - person ; 09.11.2013
comment
Намерих последната част, която ми липсваше. Забравих да активирам GL_BLEND, след това използвам glBlendFunc() точно преди да начертая изображението, след което деактивирам GL_BLEND след това. - person ; 09.11.2013
comment
Така че мисля, че моето предложение е правилно за вашия кодов фрагмент? :) - person miaout17; 10.11.2013