dポイントプレゼントキャンペーン実施中!

こんにちは。お知恵をお借りしたく質問致します。

OpenGLのglTexImage2D関数でテクスチャを作り、Windowsフォームアプリケーション上に表示する際に起きた問題です。
なお、GLSLフラグメントシェーダでテクスチャは編集されています。

そのシェーダを利用した結果を表示すると、dot by dotで表示した際は正常に表示されるのですが、縮小して表示するとモアレと言いますか、縞模様が出てしまいます。※画像参照
また、縮小と言いますのはWindowsFormアプリ内のOpenGL描画用コントロール(glControl)そのものをリサイズするという意味で、テクスチャを作成する際に何か縮小操作を行ったというわけではありません。

テクスチャの貼付は以下のように行っています。
GL.Viewport(0, 0, glControl.Width, glControl.Height);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.Texture2D);
GL.Begin(BeginMode.Quads);
{
GL.TexCoord2(0, 0); GL.Vertex2(-1, 1);
GL.TexCoord2(1, 0); GL.Vertex2(1, 1);
GL.TexCoord2(1, 1); GL.Vertex2(1, -1);
GL.TexCoord2(0, 1); GL.Vertex2(-1, -1);
}
GL.End();
GL.Disable(EnableCap.Texture2D);
glControl.SwapBuffers();

テクスチャ(1920x1080、RGBA)自体の作成が(理由は不明ですが)縮小時のみおかしくなっている、又はテクスチャの貼り方やビューポート周りの設定不足のように思って居るのですが、原因が掴めていない状況です。

参考までに、補間方法を変えた際の違いも一応スクリーンショットに撮りましたのでよろしければご覧ください。

たった今、glGetTexImageという関数で、作成したテクスチャを取得できるらしいということが分かり、これを用いて縮小表示している際もテクスチャそのものが正常に作成されているかどうかを確認しようと思っています。(が、環境が手元に無く、この確認は明日の朝となります。)

この原因及び対処法など、解決の手助けとなるようなことがありましたら何でも構いませんので教えていただきたいです。
その他、説明不足な点がありましたら随時追記致しますので、ご指摘願います。
どうかよろしくお願いいたします。

「OpenGL テクスチャを縮小表示すると」の質問画像

A 回答 (2件)

なるほど。

16bit1画素ということはrgba画像の1ピクセルに2画素が入っているということでしょうか。

それは少し特殊な状況ですね。

たとえば、(255,0,0,255),(0,0,255,255)のチェック模様のテクスチャをズームアウトする場合、
OpenGL標準のサンプリングでは、NEAREST以外で縮小すると、(127,0,127,255)に近い値になります。

そこから独自のサンプリングを行うと確かに横縞が出たりする可能性が高そうです。

このような場合、OpenGLのサンプリングはNEARESTにして、自前のサンプリングする、という処理にする必要があります。
    • good
    • 0
この回答へのお礼

まず、自分の補足を訂正です
> テクスチャの作成には、16bitで1画素情報が得られるという状態ですので
16bitで1画素と間違えていいましたが、16bitからRGBA2画素分を得られる が正しかったです。
ちなみにやっていることは、YUV422フォーマットをRGBAに変換するという処理です。

で、結論を先に言いますと無事に解決できました。

これは自分の勉強不足を痛感する次第ですが、別のテクセルをピンポイントで参照するためにはピクセルに換算して0.5の補正をしてあげる必要があるらしく、私はその処理をしていませんでした。

結局それが全てだったようで、テクセル座標の取得に補正をすることで一気に解決できました。

この度はアドバイスしていただき、本当にありがとうございました。
大変参考になりました。

お礼日時:2013/04/04 09:26

貼り付ける画像が縦縞の模様があるものでしょうか。



そうであれば、完全にモアレを除去するのは難しいですが、ミップマップを使えばある程度は改善できます。


Native CのOpenGLのAPIの場合、

glTexImage2D



gluBuild2DMipmaps

に変更する。

また、min, mag filter を

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

に変更するとミップマップを使用できます。

この回答への補足

回答ありがとうございます。

貼り付ける元画像に縦縞はありません。

アドバイス通りMIPMAPを用いてみましたが、やはり縦縞は出てしまいました。

参考画像の中に3枚の画像がありますが、全てテクスチャとして作成したものをglControlに貼り付けた結果です。
左上はテクスチャの幅・高さと、glControlの幅・高さが一致している状態で、この場合は縞模様は出ずきれいに表示されるのですが、少しでも横幅を変えると、左上や右下のように縞々模様が出てしまいます。

ちなみに幅を変えると、縞々の間隔も伸縮して、dot by dot時以外でも縦縞が出なくなる幅があります。
今思うと、高さは変えても横縞が出ないということも気になります。
どうして幅を変えた時だけ、縞々が出てしまうのでしょう・・・。

テクスチャの作成には、16bitで1画素情報が得られるという状態ですので、以下のように作成しています。(※16bitの色情報の並びは少し特殊です。)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, srcWidth, srcHeight, 0, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, *src);
これを、ピクセルシェーダを用いて、16bitから一定の変換処理を行ってRGBに変換しています。
ちなみに変換処理を行わず、そのまま表示しても縞々は出るので変換アルゴリズム等に問題はないと思います。(そもそも、dot by dotでの表示は正常ですのでピクセルシェーダに異常は無いと考えております。)

補足日時:2013/04/02 13:12
    • good
    • 0
この回答へのお礼

この度はありがとうございました。回答No2にて詳細を記します。

お礼日時:2013/04/05 23:00

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!