2012-05-18 3 views
9

Я создал класс, который отображает видеокарты (на Mac) в пользовательский объект framebuffer. В качестве входных данных у меня есть текстура 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); 

Затем после загрузки шейдеров я стараюсь, чтобы получить расположение атрибутов в вершине shader:

 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, который помог мне правильно получить исходный код для фрейдирующего шейдера (вот почему я его здесь не публиковал), но с добавлением вершинного шейдера он тоже не дает мне никакого результата (было интересно как он мог знать, как производить вывод, если он вообще не знает атрибутов position/texCoord?)

+1

Для текстурных прямоугольников координаты не должны быть нормализованы, но вы, кажется, проходите в нормализованных координатах. – harold

+0

О, так для texCoordData [] вместо 0.0, 1.0 и т. Д. Я прохожу, например, 1920.0, 1080.0 (т.е. фактический размер видео кадра)? – Bjoern

+0

Черный экран смерти настолько распространен в графике.Я полагаю, вы пытались изменить четкий цвет, чтобы убедиться, что вы на самом деле рисуете что-нибудь? Если вы * *, то это проблема с шейдером, если нет, проблема с массивом вершин. – imallett

ответ

2

Я не изучал каждую строчку, но я думаю, что ваша логика в основном правильная. То, что я вижу, отсутствует glEnableVertexAttribArray. Вам нужно включить оба атрибута вершины перед вызовом glDrawArrays.

+0

Спасибо за ваш быстрый ответ и извините за это, но я уже делаю это, но забыл упомянуть об этом в вышеприведенном сообщении (сейчас отредактирует), и нет, это не помогло мне на самом деле – Bjoern

+0

Хорошо, я вызвал glEnableVertexAttribArray в неправильном месте. Прежде чем я позвонил ему после того, как получил атрибуты, так что теперь я изменил его для вызова в каждом фрейме, и он, наконец, работает. Но я не понимаю, почему мне нужно вызывать это в каждом фрейме, я думал, что он будет помнить, что он включен? – Bjoern

+0

@Bjoern, он должен помнить об этом без необходимости называть каждый кадр, возможно, вы его отключили? – Tim

Смежные вопросы