2011-02-10 4 views
2

私は、Mac OS> = 10.6のために、ディスクから読み込まれた画像からOpenGLテクスチャを作成するアプリを書いています。ARGB NSImageからOpenGLテクスチャをスウィズルすることなくロードするにはどうすればいいですか?

まず、イメージをNSImageにロードします。次に、画像からNSBitmapImageRepを取得し、glTexImage2Dを使用してピクセルデータをテクスチャにロードします。

RGBまたはRGBAイメージの場合、完全に動作します。 RGBの3バイト/ピクセル、またはRGBAの4バイトのいずれかを渡して、4バイト/ピクセルのRGBAテクスチャを作成することができます。

しかし、私はちょうどテスターに​​、ARGBバイトオーダーを持っていると思われるJPEG画像(Canon EOS 50Dで撮影し、どのようにインポートされたかわかりません)を送ってきました。

私はこのスレッドに記事を見つけました:(http://www.cocoabuilder.com/archive/cocoa/12782-coregraphics-over-opengl.html)私は glTexImage2DにGL_BGRAのフォーマットパラメータを指定することを示唆しています、GL_UNSIGNED_INT_8_8_8_8_REVの種類があります。

これは論理的で、動作するはずのようですが、そうではありません。私は違っていますが、それでも色の値は間違っています。

ARGB画像データを新しいRGBAバッファにシャッフルする「スウィズル」(手作業のバイトスワップ)コードを書きましたが、このバイト単位のスウィズルは大きな画像では遅くなります。

この作品を「正しい方法」にする方法も理解したいと思います。

ARGBデータをRGBA OpenGLテクスチャに読み込む方法は何ですか? XXXへ

私の現在の呼び出しは次のようになります。

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, newWidth, newHeight, 0, format, GL_UNSIGNED_BYTE, pixelBuffer); 

どこRGBまたはRGBAのいずれかです。

私が使用してみました:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, newWidth, newHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer); 

それは「アルファ最初」の順番であるというのが私のイメージの担当者のレポート。

2番目の質問として、ほとんどのグラフィックスカードの「ネイティブ」フォーマットがGL_BGRAであることも読んでいます。そのフォーマットでテクスチャを作成すると、テクスチャの描画が速くなります。テクスチャの描画速度はテクスチャの読み込み速度よりも重要です。そのため、データをBGRA形式にスウィズルすることは価値があります。 GL_RGBAの "internalformat"を指定してBGRAテクスチャを作成するようにOpenGLに依頼してみましたが、結果として完全に黒い画像になりました。私の解釈では、ソースと内部のフォーマットが違うとglTexImage2Dがデータをバイトスワップすることが予想されますが、代わりに "internalformat"を指定しようとするとOpenGLエラー0x500(GL_INVALID_ENUM)が出ますGL_RGBA。私は何が欠けていますか?

答えて

3

ARGBデータをテクスチャに直接ロードする方法はわかりませんが、CPU上でスウィズルを実行するよりも優れた回避策があります。

  1. 一時的なRGBAテクスチャにARGBデータをロードしてください。
  2. シンプルなピクセルシェーダを使用して、このテクスチャを使用してターゲットテクスチャにレンダリングしながらフルスクリーンクワッドを描画します。
  3. 他のリソースを引き続きロードし、GPUパイプラインを停止する必要はありません。

例のピクセルシェーダ:

#version 130 
uniform sampler2DRect unit_in; 
void main() { 
    gl_FragColor = texture(unit_in, gl_FragCoord.xy).gbar; 
} 
+0

私のアプリは、固定パイプラインOpenGL(フラグメントシェーダーなし)を使って書かれています。私は今、iOS上でシェーダベースのプログラミングを行ってきましたが、Mac OSでそれに取り組んでいません。どのようにして、固定パイプラインのOpenGLと、私のうねりしかないフラグメントシェーダを混在させるのですか? –

+0

私は長い間固定機能GLを使用していませんが、ピクセルシェーダをバインドしたことを思い出して、固定機能状態の一部をオーバーライドするだけです。このシェーダは、 〜にスウィズリングだけでなく、。 – kvark

+0

私はnoob @kvarkです。例を共有してください。 – anuj

1

あなたは正しい、OpenGLのでそれをレンダリングしていますか? 簡単なやり方をしたいのであれば、ピクセルシェーダーで色をリアルタイムでスウィズルさせることができます。これはグラフィックカードにとってまったく問題ではなく、もっと複雑なものを作るように作られています:)。あなたは、シェーダについて知っているここで、このぇを読んでいない場合は

uniform sampler2D image; 
void main() 
{ 
    gl_FragColor = texture2D(image, gl_FragCoord.xy).gbar; 
} 

http://www.lighthouse3d.com/opengl/glsl/

+0

あなたの答えがどのように広がっているのか分からないので、何がポイントですか?さらに、あなたのコードは間違っています:gl_FragCoordは正規化されていないウィンドウ座標ですので、 'sampler2D'をサンプリングすることはできません:P – kvark

1

をこの質問は古いですが、場合に誰が探している

あなたはこのようにシェーダを使用することができますこれは私が厳密には安全ではないが有効な解決策を見つけました。問題は、各32ビットRGBA値が最後のバイトではなく最初のバイトとしてAを持つことです。

NBitmapImageRep.bitmapDataは、OpenGLにそのピクセルへのポインタとして与える最初のバイトへのポインタを与えます。そのポインタに1を加えるだけで、次のピクセルのAを最後にして、正しい順序でRGB値を指します。

この問題は、最後のピクセルが1バイトからイメージの終わりを超えてA値をとり、A値がすべて1ピクセルアウトであることです。しかし、質問者のように、JPGを読み込んでいる間にこれを取得するので、アルファは関係がありません。これは問題を引き起こすようには見えませんが、私はその「安全」とは主張しません。

関連する問題