Рендеринг прямоугольной текстуры с помощью GLSL

Я создал класс, который визуализирует видеокадры (на 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().

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

9
задан genpfault 18 May 2012 в 15:02
поделиться