使用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");

这给了我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,它帮助我得到了片段着色器的原始代码(这就是为什么我没有在这里发布它),但是由于添加了顶点着色器,它也不给我任何输出(想知道如果它不知道位置/ texCoord属性如何知道如何产生输出?)


我没有仔细研究过每一行,但我认为你的逻辑基本上是正确的。 我看到缺少的是glEnableVertexAttribArray 。 您需要在调用glDrawArrays之前启用两个顶点属性。

链接地址: http://www.djcxy.com/p/33981.html

上一篇: Rendering rectangle texture with GLSL

下一篇: OpenGL texture loading issue