ビデオフレーム (Mac の場合) をカスタム フレームバッファ オブジェクトにレンダリングするクラスを作成しました。入力として YUV テクスチャがあり、入力として 3 つの長方形テクスチャ (Y、U、および V プレーンごとに 1 つ、データは GL_TEXTURE_RECTANGLE_ARB、GL_LUMINANCE、および GL_UNSIGNED_BYTE を使用して glTexSubImage2D によってアップロードされる) を受け取るフラグメント シェーダを正常に作成しました。レンダリングする前に、アクティブなテクスチャを 3 つの異なるテクスチャ ユニット (0、1、2) に設定し、それぞれにテクスチャをバインドします。パフォーマンス上の理由から、GL_APPLE_client_storage と GL_APPLE_texture_range を使用しました。次に、glUseProgram(myProg)、glBegin(GL_QUADS) ... glEnd() を使用してレンダリングしました。
それはうまく機能し、期待どおりの結果が得られました (ちらつき効果は別として、これは、2 つの異なるスレッドで 2 つの異なる GL コンテキストを使用したという事実に関係していると思います。 [それは後で別の質問のトピックです])。とにかく、頂点シェーダーも追加してコードをさらに改善することにしました。これにより、glBegin/glEnd をスキップできるようになりました。これは時代遅れであり、とにかく避けるべきです。
次のステップとして、2 つのバッファ オブジェクトを作成しました。1 つは頂点用、もう 1 つはテクスチャ座標用です。
const GLsizeiptr posSize = 4 * 4 * sizeof(GLfloat);
const GLfloat posData[] =
{
-1.0f, -1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f,
1.0f, 1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 1.0f
};
const GLsizeiptr texCoordSize = 4 * 2 * sizeof(GLfloat);
const GLfloat texCoordData[] =
{
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0
};
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, posSize, posData, GL_STATIC_DRAW);
glGenBuffers(1, &m_texCoordBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
glBufferData(GL_ARRAY_BUFFER, texCoordSize, texCoordData, GL_STATIC_DRAW);
次に、シェーダーをロードした後、頂点シェーダーの属性の場所を取得しようとします。
m_attributeTexCoord = glGetAttribLocation( m_shaderProgram, "texCoord");
m_attributePos = glGetAttribLocation( m_shaderProgram, "position");
これにより、texCoord が 0 になり、位置が 1 になり、問題ないようです。
属性を取得した後、私も呼び出します
glEnableVertexAttribArray(m_attributePos);
glEnableVertexAttribArray(m_attributeTexCoord);
(私はそれを一度だけ行っていますか、それともすべての glVertexAttribPointer と glDrawArrays の前に行う必要がありますか?テクスチャ ユニットごとに行う必要がありますか?またはシェーダーが glProgram でアクティブ化されている間に行う必要がありますか?それとも、どこでも行うことができますか?)
その後、glBegin/glEnd を置き換えるようにレンダリング コードを変更しました。
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID_Y);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID_U);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID_V);
glUseProgram(myShaderProgID);
// new method with shaders and buffers
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexAttribPointer(m_attributePos, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
glVertexAttribPointer(m_attributeTexCoord, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays(GL_QUADS, 0, 4);
glUseProgram(0);
しかし、コードをこれに変更して以来、結果として常に黒い画面しか表示されません。だから私はいくつかの簡単な手順を欠いていると思います.glEnable/glDisableやいくつかの設定を適切に行っているかもしれません. 参考までに、頂点シェーダーは次のとおりです。
#version 110
attribute vec2 texCoord;
attribute vec4 position;
// the tex coords for the fragment shader
varying vec2 texCoordY;
varying vec2 texCoordUV;
//the shader entry point is the main method
void main()
{
texCoordY = texCoord;
texCoordUV = texCoordY * 0.5; // U and V are only half the size of Y texture
gl_Position = gl_ModelViewProjectionMatrix * position;
}
私の推測では、ここで明らかな何かが欠けているか、進行中のプロセスをまだ十分に理解していないだけです。OpenGLShaderBuilder も使用してみましたが、フラグメント シェーダーの元のコードを正しく取得するのに役立ちました (これが、ここに投稿していない理由です)。とにかく position/texCoord 属性がわからない場合、どのように出力を生成するかを知ることができますか?)