我創建了一個類,可以將視頻幀(在Mac上)渲染爲自定義幀緩衝區對象。作爲輸入,我有一個YUV紋理,併成功創建了一個片段着色器,該着色器將輸入3個矩形紋理(每個Y,U和V平面分別用glTexSubImage2D使用GL_TEXTURE_RECTANGLE_ARB,GL_LUMINANCE和GL_UNSIGNED_BYTE上傳數據) ,在渲染之前,我將活動紋理設置爲三個不同的紋理單元(0,1和2)併爲每個紋理單元綁定紋理,出於性能原因,我使用了GL_APPLE_client_storage和GL_APPLE_texture_range。然後我使用glUseProgram(myProg),glBegin(GL_QUADS)... glEnd()來渲染它。使用GLSL渲染矩形紋理
工作正常,我得到了預期的結果(除了閃爍的效果,我認爲這與我在兩個不同的線程上使用兩個不同的GL上下文這一事實有關,並且我認爲它們會進入對方的某種程度上[這是後面另一個問題的主題])。無論如何,我決定通過添加一個頂點着色器來進一步改進我的代碼,這樣我就可以跳過glBegin/glEnd - 我讀的過時了,應該避免。
所以作爲下一步我創建了兩個緩衝區對象,一個頂點,一個用於紋理座標:
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");
它給我0爲texCoord和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,它幫助我得到了片段着色器的原始代碼(這就是爲什麼我沒有在這裏發佈它),但是由於添加了頂點着色器,它也不給我任何輸出(想知道如果它不知道位置/ texCoord屬性怎麼知道如何生成輸出?)
對於紋理矩形,座標不應被標準化,但您似乎正在傳遞標準化座標。 – harold
哦,所以對於texCoordData []而不是0.0,1.0等我通過例如1920.0,1080.0(即視頻幀的實際大小)? – Bjoern
死亡的黑屏在圖形中非常常見。我認爲你試圖改變清晰的顏色,以確保你實際上繪製任何東西?如果你是*,那麼它是一個着色器問題,如果不是的話,頂點數組問題。 – imallett