web-dev-qa-db-ja.com

OpenGLテクスチャの透明度が機能しない

単純なクワッドにバインドされたOpenGLテクスチャがあります。

私の問題は:私のテクスチャは128x128ピクセルの画像です。その画像では約100x60ピクセルしか埋めていませんが、他のピクセルは透明です。 .pngファイルに保存しました。描画しているとき、バインドされたテクスチャの透明な部分は白です。

私にはバックグラウンドがあるとしましょう。この背景にこの新しいクワッドを描画すると、テクスチャの透明な部分が透けて見えません。

助言がありますか?

コード:

// Init code...
gl.glEnable(gl.GL_TEXTURE_2D);
gl.glDisable(gl.GL_DITHER);
gl.glDisable(gl.GL_LIGHTING);   
gl.glDisable(gl.GL_DEPTH_TEST);

gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE); 

// Drawing code...
gl.glBegin(gl.GL_QUADS);
gl.glTexCoord2d(0.0, 0.0);
gl.glVertex3f(0.0f, 0.0f, 0.0f);
gl.glTexCoord2d(1.0, 0.0);
gl.glVertex3f(1.0f, 0.0f, 0.0f);
gl.glTexCoord2d(1.0, 1.0);
gl.glVertex3f(1.0f, 1.0f, 0.0f);
gl.glTexCoord2d(0.0, 1.0);
gl.glVertex3f(0.0f, 1.0f, 0.0f);
gl.glEnd();

ブレンディングの有効化からGL_REPLACEへの変更まで、ほとんどすべてを試しましたが、機能させることができません。

編集:

// Texture. Have tested both gl.GL_RGBA and gl.GL_RGB8.
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, (int)gl.GL_RGBA, imgWidth, imgHeight,
            0, gl.GL_BGR_EXT, gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
21
Curtain

テクスチャがRGBA形式であることを確認し、ブレンドを有効にして、ブレンド機能を設定します。

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

そして、テクスチャを描きます。テクスチャがRGBAでない場合、アルファはなく、ブレンディングは何もしません。

編集:あなたがあなたのコードを投稿したので、私は深刻なエラーを見つけることができます:

glTexImage2D(gl.GL_TEXTURE_2D, 0, (int)gl.GL_RGBA, imgWidth, imgHeight,  0, gl.GL_BGR_EXT, gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);

GLテクスチャにはinternalFormatRGBAがありますが、ビットマップデータにはBGR形式があるため、テクスチャデータからのアルファはありません。これはalpha = 1.0を想定しています。

これを修正するには、PNGをRGBA形式でロードし、GL_RGBAをinternalFormatおよびglTexImage2Dの形式パラメーターとして使用します。

35

_When I'm drawing, the transparent part of the binded texture is white._

これは、PNGパーサーが透明な領域を白の値に変換したことを意味します。 OpenGLで透明なレイヤーをレンダリングする場合、通常、透明度を保持するためにテクスチャファイルに依存するのではなく、GLBlendFunc()を使用します。詳細はこちら:

http://www.opengl.org/resources/faq/technical/transparency.htm

1
Bernd Elkemann

また、フレームバッファーにレンダリングして結果をテクスチャにコピーする場合は、フレームバッファーでアルファがオンになっていることを確認してください。たとえば、osgViewerを使用する場合、これは次の方法で実現できます(setUpViewInWindowを呼び出す前にこれを実行します)。

osg::DisplaySettings *pSet = myviewer.getDisplaySettings();
if(pSet == NULL)
   pSet = new osg::DisplaySettings();
pSet->setMinimumNumAlphaBits(8);
myviewer.setDisplaySettings(pSet);

そしてqtの下でそれは( http://forum.openscenegraph.org/viewtopic.php?t=6411 から)で動作するはずです:

QGLFormat f;
f.setAlpha( true ); //enables alpha channel for this format
QGLFormat::setDefaultFormat( f ); //set it as default before instantiations
setupUi(this); //instantiates QGLWidget (ViewerQT)

通常はフレームバッファーに直接レンダリングする方が良いですが、レガシーコードを準備しているときにこれに遭遇し、最初はこれを見つけるのが非常に困難でした。

1
Oliver Zendel