0

私のこの質問から生じます:画像を回転しようとするとアーティファクトが表示されます

そこのソース コードでは、TIF を読み込んでいます。これは、透明部分を正しく読み込むための他の画像形式を取得できないためです。PNG、GIF、および TGA を試しました。PNGをロードできるようにしたいと思います。上記の質問にあるソース コードで十分だと思いますが、そうでない場合はお知らせください。

他の形式を読み込もうとしたときに何が起こるかをよりよく説明するために、試していた画像の 1 つは 128*128 のオレンジ色の三角形でした。フォーマットに応じて、128*128 の正方形全体がオレンジ色になるか、画像の透明な部分が白くなります。

4

3 に答える 3

2

アルファブレンディングが有効になっていることを確認してください

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

それ以外の場合、プリミティブは透明であるべき場所に単色を描画します。別のblendfuncが必要になる場合があります。これは一般的な設定です。

于 2009-07-28T02:22:07.643 に答える
1

OK、私は OpenGL + SDL の初心者ですが、ここに私が持っているものがあります..すべてロードしますか? .xcf を動作させることができず、テストする .lbm がないことを除いて、SDL_image がサポートするフォーマット。

//called earlier..
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

//load texture
SDL_Surface* tex = IMG_Load(file.c_str());
if (tex == 0) {
    std::cout << "Could not load " << file << std::endl;
    return false;
}

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

//nearest works but linear is best when scaled?
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

width = tex->w;
height = tex->h;

//IMG_is* doesn't seem to work right, esp for TGA, so use extension instead..
std::string ext = file.substr(file.length() - 4);
bool isBMP = (ext.compare(".bmp") == 0) || (ext.compare(".BMP") == 0);
bool isPNG = (ext.compare(".png") == 0) || (ext.compare(".PNG") == 0);
bool isTGA = (ext.compare(".tga") == 0) || (ext.compare(".TGA") == 0);
bool isTIF = ((ext.compare(".tif") == 0) || (ext.compare(".TIF") == 0) ||
              (ext.compare("tiff") == 0) || (ext.compare("TIFF") == 0));

//default is RGBA but bmp and tga use BGR/A
GLenum format = GL_RGBA;
if(isBMP || isTGA)
    format = (tex->format->BytesPerPixel == 4 ? GL_BGRA : GL_BGR);

//every image except png and bmp need to be converted
if (!(isPNG || isBMP || isTGA || isTIF)) {
    SDL_Surface* fixedSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
    SDL_BlitSurface(tex, 0, fixedSurface, 0);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, GL_UNSIGNED_BYTE, fixedSurface->pixels);
    SDL_FreeSurface(fixedSurface);
} else {
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, GL_UNSIGNED_BYTE, tex->pixels);
}

SDL_FreeSurface(tex);

list = glGenLists(1);
glNewList(list, GL_COMPILE);
    GLint vertices[] = {
            0,0, 0,0,
            0,1, 0,height,
            1,1, width,height,
            1,0, width,0
        };

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    glBindTexture(GL_TEXTURE_2D, texture);
    glTexCoordPointer(2, GL_INT, 4*sizeof(GLint), &vertices[0]);
    glVertexPointer(2, GL_INT, 4*sizeof(GLint), &vertices[2]);
    glDrawArrays(GL_POLYGON, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEndList();

そして、描画するには、色を不透明な白に設定し (透明度には影響しませんか?)、リストを呼び出すだけです..

glColor4f(1,1,1,1);
glCallList(list);

そしてもちろん、私のコードの助けも大歓迎です! :)

于 2009-07-28T05:54:50.667 に答える
1

私は SDL には詳しくありませんが、イメージをロードするのは SDL であるため、彼らのドキュメントを詳しく調べます。私は自分の作品で OpenGL と一緒に .png を使用していますが、透明度は問題なく動作します。(私はLightZPngという .png パーサーを使用しています。)

また、リンクされた投稿に次のものが含まれていることに気付きました。

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

それ以外の:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

これは、背景にあるものに透明であるべきピクセルを追加するという影響があります (これらのテクセルのアルファが 0 であると仮定します)。

于 2009-07-28T01:58:14.930 に答える