3

OpenGLでレンダリングされた画像を、の助けを借りてムービーファイルに記録したいと思いますAVAssetWriter。OpenGLフレームバッファからピクセルにアクセスする唯一の方法は、iOSでRGBAピクセル形式のみをサポートするglReadPixelsを使用することであるという問題が発生します。ただし、AVAssetWriterこの形式はサポートされていません。ここでは、ARGBまたはBGRAのいずれかを使用できます。アルファ値は無視できるので、RGBAをARGBに変換する最も速い方法は、glReadPixelsに1バイトシフトしたバッファーを与えることであるという結論に達しました。

UInt8 *buffer = malloc(width*height*4+1);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer+1);

問題は、呼び出しがクラッシュglReadPixelsにつながることです。EXC_BAD_ACCESSバッファを1バイトシフトしないと、完全に機能します(ただし、ビデオファイルの色が間違っていることは明らかです)。ここでの問題は何ですか?

4

5 に答える 5

5

RGBAをARGBに変換する最も速い方法は、glReadPixelsに1バイトシフトされたバッファーを与えることであるという結論に達しました。

ただし、これによりアルファ値も1ピクセルシフトします。別の提案があります:

画像をテクスチャにレンダリングします(そのテクスチャをカラーアタッチメントとして使用するFBOを使用します)。次に、スウィズリングフラグメントシェーダーを使用して、そのテクスチャを別のフレームバッファーにレンダリングします。

#version ...
uniform sampler2D image;
uniform vec2 image_dim;
void main() 
{
    // we want to address texel centers by absolute fragment coordinates, this
    // requires a bit of work (OpenGL-ES SL doesn't provide texelFetch function).
    gl_FragColor.rgba = 
        texture2D(image, vec2( (2*gl_FragCoord.x + 1)/(2*image_dim.y), 
                               (2*gl_FragCoord.y + 1)/(2*image_dim.y) )
        ).argb; // this swizzles RGBA into ARGB order if read into a RGBA buffer
}
于 2012-01-07T18:35:19.533 に答える
1

バッファの最後に128バイトのスラックを追加するとどうなりますか?OpenGLがパフォーマンスのために一度に4/8/16/etcバイトを埋めようとしている可能性があり、バッファが整列されていないなどの場合にバグがあります。OpenGLのパフォーマンス最適化でエッジケースに問題が発生したのはこれが初めてではありません:)

于 2012-01-07T17:20:33.450 に答える
1

電話してみてください

glPixelStorei(GL_PACK_ALIGNMENT,1) 

glReadPixelsの前。

ドキュメントから:

GL_PACK_ALIGNMENT

メモリ内の各ピクセル行の開始の配置要件を指定します。許容値は、1(バイト整列)、2(偶数バイトに整列された行)、4(ワード整列)、および8(行はダブルワード境界で開始)です。

デフォルト値は4です(glGetを参照)。これは、さまざまな「 OpenGLの落とし穴」タイプリストでトラブルメーカーとしてよく言及されますが、これは通常、バッファの配置よりも行のパディング効果に関係しています。

別のアプローチとして、4バイト余分にmallocし、glReadPixelsをbuffer + 4から開始して4バイトで整列し、次にAVAssetWriter buffer + 3を渡すとどうなりますか(AVAssetWriterが整列に対してより寛容であるかどうかはわかりませんが)問題) ?

于 2012-01-07T18:12:36.480 に答える
0

memcpyまたは他のコピー操作を実行してバイトをシフトする必要があります。ポインターを変更すると、ポインターが整列されないままになります。これは、基盤となるハードウェアの機能(DMAバス幅、タイルの粒度など)の範囲内である場合とそうでない場合があります。

于 2012-01-07T17:18:43.177 に答える
-1

を使用buffer+1すると、データはmallocされたメモリの先頭ではなく、1バイトで書き込まれるため、mallocされたメモリの最後に書き込まれ、クラッシュが発生します。

iOSのglReadPixelsがGL_RGBAのみを受け入れる場合は、自分で調べて再配置する必要があると思います。

更新、申し訳ありませんが、あなたのmallocで+1を逃しました、StilesCrisisはおそらくクラッシュの原因について正しいです。

于 2012-01-07T17:21:14.400 に答える