2012-05-18 13 views
9

Creé una clase que convierte videoframes (en Mac) en un objeto framebuffer personalizado. Como entrada tengo una textura YUV, y creé exitosamente un sombreador de fragmentos, que toma como entrada 3 texturas rectangulares (una para planos Y, U y V cada uno, los datos que GLTexSubImage2D carga mediante GL_TEXTURE_RECTANGLE_ARB, GL_LUMINANCE y GL_UNSIGNED_BYTE) , antes de renderizar establecí las texturas activas en tres unidades de textura diferentes (0, 1 y 2) y ligé una textura para cada una, y por razones de rendimiento utilicé GL_APPLE_client_storage y GL_APPLE_texture_range. Luego lo rendericé usando glUseProgram (myProg), glBegin (GL_QUADS) ... glEnd().Textura de rectángulo de representación con GLSL

Eso funcionó bien, y obtuve el resultado esperado (aparte de un efecto parpadeante, que creo que tiene que ver con el hecho de que utilicé dos contextos GL diferentes en dos hilos diferentes, y supongo que se mezclarán entre sí manera en algún momento [ese es el tema de otra pregunta más adelante]). De todos modos, decidí seguir mejorando mi código agregando un sombreador de vértices también, para poder omitir el glBegin/glEND, que he leído que está desactualizado y debería evitarse de todos modos.

Así como el próximo paso que crea dos objetos tampón, uno de los vértices y otro para las coordenadas de textura:

 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); 

A continuación, después de cargar los shaders Trato de recuperar las ubicaciones de los atributos en el vértice sombreado:

 m_attributeTexCoord = glGetAttribLocation(m_shaderProgram, "texCoord"); 
     m_attributePos = glGetAttribLocation(m_shaderProgram, "position"); 

que me da 0 para texCoord y 1 para la posición, que parece estar bien.

Después de conseguir los atributos que también llamo

 glEnableVertexAttribArray(m_attributePos); 
     glEnableVertexAttribArray(m_attributeTexCoord); 

(que estoy haciendo que sólo una vez, o tiene que ser hecho antes de cada glVertexAttribPointer y glDrawArrays? ¿Tiene que ser hecho por unidad de textura? O ? mientras mi shader se activa con glProgram o puedo hacerlo en cualquier sitio)

Después de que he cambiado el código de representación para reemplazar el 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); 

Pero desde que cambié el código a esto, siempre obtengo una pantalla negra como resultado. Así que supongo que me faltan algunos pasos simples, tal vez glEnable/glDisable o establecer algunas cosas correctamente, pero pero como dije, soy nuevo en esto, así que realmente no tengo una idea. Para su referencia, aquí está el vertex shader:

#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; 
} 

Mi conjetura es que me estoy perdiendo algo obvio aquí, o simplemente no tienen una suficiente comprensión profunda de los procesos en curso aquí todavía. Intenté usar OpenGLShaderBuilder también, lo que me ayudó a obtener el código original para el sombreador de fragmentos correctamente (es por eso que no lo publiqué aquí), pero desde que agregué el sombreador de vértices tampoco me dio ningún resultado (se preguntaba cómo podría saber cómo producir la salida, si no conoce los atributos de posición/texCoord de todos modos?)

+1

Para rectángulos de textura, las coordenadas no se deben normalizar, pero parece que pasa en coordenadas normalizadas. – harold

+0

Oh, para el texCoordData [] en lugar de 0.0, 1.0, etc., paso, por ejemplo, 1920.0, 1080.0 (es decir, el tamaño real del cuadro de video)? – Bjoern

+0

La pantalla negra de la muerte es tan común en los gráficos.Supongo que trataste de cambiar el color claro solo para asegurarte de que realmente estás dibujando algo? Si * eres *, entonces es un problema de sombreado, si no, problema de arreglo vértice. – imallett

Respuesta

2

No he estudiado de cerca todas las líneas, pero creo que su lógica es en su mayoría correcta. Lo que veo que falta es glEnableVertexAttribArray. Debe habilitar ambos atributos de vértice antes de llamar a glDrawArrays.

+0

Gracias por su rápida respuesta, y disculpe por eso, pero ya lo estoy haciendo, pero olvidé mencionarlo en la publicación anterior (lo editaré ahora), y no, eso no me ayudó en realidad – Bjoern

+0

Ok, a medida que gira llamé glEnableVertexAttribArray en el lugar equivocado. Antes de llamar después de obtener las ubicaciones de los atributos, ahora lo cambio para llamarlo a cada fotograma, y ​​finalmente funciona. Pero no entiendo por qué tengo que llamar a eso en cada fotograma, ¿pensé que lo recordaría? – Bjoern

+0

@Bjoern, debería recordarlo sin tener que llamarse a cada fotograma, ¿lo estaba deshabilitando en alguna parte? – Tim

Cuestiones relacionadas