C++ 基本GLSL:两个片段着色器彼此后面,但第一个(绘制纹理)被覆盖

C++ 基本GLSL:两个片段着色器彼此后面,但第一个(绘制纹理)被覆盖,c++,qt,opengl-es,C++,Qt,Opengl Es,我是OpenGL ES的新手,看起来我缺少了一个基本概念。 我在代码中使用了一些QT类,但它接近于普通的OpenGL ES 我希望对每个渲染帧执行以下操作: 渲染一个带有纹理的全屏简单Triange_条形矩形。您可以将其视为背景图像。这项技术已经可以自己工作了。使用自己的顶点和片段着色器(由QOpenGLShaderProgram包装)进行渲染。纹理最初来自QOpenGLFramebufferObject,它本身有时会重新渲染,但不是每一帧 绘制完(1.)中的三角形_条后,我想在顶部渲染另一个基

我是OpenGL ES的新手,看起来我缺少了一个基本概念。 我在代码中使用了一些QT类,但它接近于普通的OpenGL ES

我希望对每个渲染帧执行以下操作:

  • 渲染一个带有纹理的全屏简单Triange_条形矩形。您可以将其视为背景图像。这项技术已经可以自己工作了。使用自己的顶点和片段着色器(由QOpenGLShaderProgram包装)进行渲染。纹理最初来自QOpenGLFramebufferObject,它本身有时会重新渲染,但不是每一帧
  • 绘制完(1.)中的三角形_条后,我想在顶部渲染另一个基本形状。目前底部还有一个小矩形。这将使用另一个顶点和帧着色器。这一部分本身也可以工作
  • 我的问题是:两个步骤都不起作用。我只看到(2.)屏幕底部的小矩形,但纹理消失了。应该显示纹理的区域用清晰的颜色填充

    我的假设是,两个frament着色器以某种方式相互冲突,或者我完全忽略了状态。。 我很高兴你能给我一个提示,告诉我这里缺少什么

    提前谢谢

    以下是我的一些代码:

    这是步骤(1)的顶点和帧着色器代码:

    这是步骤(2)的顶点和帧着色器代码:

    还有主渲染功能,有点精简(我跳过初始化部分,在初始化部分中设置着色器程序并绑定属性位置):


    既然你是说这两个步骤独立地正确工作,我想说问题一定在其他地方

    您的问题可能有点不清楚,但如果以下情况属实:

    • 您正在绘制一个带有纹理的全屏矩形,该纹理在单独绘制时正确显示(填充整个屏幕)
    • 您正在绘制一个非全屏较小的形状,该形状在单独绘制时可以正确显示(在未绘制形状的位置可以看到清晰的颜色)
    • 当您尝试渲染两者时,您应该在背景中看到全屏纹理,并且具有小形状的部分应该显示小形状
    • 您的结果与仅执行第二步时的结果完全相同(在未绘制形状的位置可以看到清晰的颜色)
    然后我看到两个可能的问题。首先(我确信您一定已经检查过)可能是您正在清除两次渲染调用之间的颜色缓冲区。无论如何,仔细检查一下

    第二个原因是这两个项目在某种程度上存在冲突。如果这段代码在每一帧上执行,它可能会有意义。一个快速的测试是只画一次,看看结果画得是否正确

    因此,可能发生的情况是,在第二部分中设置了一些值,这会破坏第一部分。例如:

    如果纹理被第二部分破坏,那么下次调用时,可能会返回一种颜色(0,0,0,0),通过混合可以生成透明背景,并且您认为看到的是背景清除的颜色。您可以通过修改纹理着色器以仅输出纯色来轻松测试这一点,以查看是否在那里绘制纯色

    另一个问题可能是某些值设置为错误的程序,并且第一次调用的顶点数据被第二次调用覆盖。在这种情况下,纹理正好位于小矩形的后面。你可以用一个小矩形(半透明)来测试它,看看它后面是否有纹理

    但是,在代码中唯一吸引注意的是

    m_textureProgram->release();
    m_shapeProgram->release();
    
    这是正确的吗?我希望着色器是持久的。如果没有,那么它们是在哪里创建的


    似乎您的假设是,第二部分以某种方式覆盖其他像素以清除缓冲区。我向你保证这是不可能的。绘制三角形时,无法影响其他像素(至少我想没有几何体着色器),只有点内的像素具有指定的片段着色器,并且只有那些可以更改

    谢谢,现在已经解决了&正在工作。步骤(2.)中的第二个缓冲区从未释放。因此缺少一个m_buffer->release();在第二个三角形被画出来之后。我仍然不知道你为什么一直在创建和释放这些缓冲区。创建一个保存矩形数据的缓冲区,然后使用矩阵调整其大小。缓冲区应该是持久的,直到您不再需要它为止。在您的情况下,渲染应该停止。是的,您是对的。这部分只是一些原型,但肯定需要按照您的建议进行更改。
    static const char* vertexShaderSource =
        "attribute highp vec4 position;\n"
        "uniform lowp vec4 color;\n"
        "void main() {\n"
        "   gl_Position = position;\n"
        "}\n";
    
    static const char* fragmentShaderSource =
        "uniform lowp vec4 color;\n"
        "void main() {\n"
        "   gl_FragColor = color;\n"
        "}\n";
    
    m_shapeProgram->addShaderFromSourceCode( QOpenGLShader::Vertex, vertexShaderSource );
    m_shapeProgram->addShaderFromSourceCode( QOpenGLShader::Fragment, fragmentShaderSource );
    
    m_context->makeCurrent(w);
    glClear( GL_COLOR_BUFFER_BIT );
    
    // Step (1.) begins here
    m_textureProgram->bind();
    glBindTexture(GL_TEXTURE_2D, textureId);
    m_textureProgram->enableAttributeArray( LocationTriangleTextureCoords );
    m_textureProgram->enableAttributeArray( LocationTextureCoords );
    m_textureProgram->setAttributeArray( LocationTriangleTextureCoords, GL_FLOAT, s_triangleStripCoords, 2 );
    m_textureProgram->setAttributeArray( LocationTextureCoords, GL_FLOAT, s_textureCoords, 2);
    f.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    m_textureProgram->disableAttributeArray( LocationTriangleTextureCoords );
    m_textureProgram->disableAttributeArray( LocationTextureCoords );
    m_textureProgram->release();
    
    // Step (2.) begins here:
    m_shapeProgram->bind();
    m_shapeProgram->setUniformValue( m_colorUniformId, m_color1 );
    QPointF p0( -1, -0.7);
    QPointF p1( -1, -1.0 );
    QPointF p2( 0, -1.0 );
    QPointF p3( 0, -0.7 );
    GLfloat vertices[12] = { GLfloat(p0.x()), GLfloat(p0.y()),
                             GLfloat(p1.x()), GLfloat(p1.y()),
                             GLfloat(p2.x()), GLfloat(p2.y()),
                             GLfloat(p0.x()), GLfloat(p0.y()),
                             GLfloat(p3.x()), GLfloat(p3.y()),
                             GLfloat(p2.x()), GLfloat(p2.y())
                          };
    
    m_buffer->bind();
    m_buffer->write( 0, vertices, sizeof(vertices) );
    m_shapeProgram->setAttributeBuffer( LocationShapePosition, GL_FLOAT, 0, 2 );
    m_shapeProgram->enableAttributeArray( LocationShapePosition );
    f.glDrawArrays( GL_TRIANGLES, 0, 6 );
    m_shapeProgram->release();
    
    // Done frame.
    m_context->swapBuffers(w);
    
    m_textureProgram->release();
    m_shapeProgram->release();