[英]Basic GLSL: Two fragment shaders behind each other, but first one (drawing a texture) is overwritten
我是OpenGL ES的新手,似乎缺少一个基本概念。 我在代码中使用了一些QT类,但是它接近普通的OpenGL ES。
我想对每个渲染帧执行以下操作:
我的问题是: 这两个步骤一起不起作用。 我仅从(2.)中看到屏幕底部的小矩形,但是纹理消失了。 应该显示纹理的区域将填充有清晰的颜色。
我的假设是,两个Frament着色器之间都存在某种冲突,或者我完全缺少与状态有关的东西。我很高兴为您提供有关此处缺少的内容的提示。
提前致谢!
这是我的一些代码:
这是步骤(1)的顶点和框架着色器代码:
static const char* vertexShaderSource =
"attribute highp vec4 triangleCoords;\n"
"attribute lowp vec2 textureCoords;\n"
"varying lowp vec2 v_textureCoords;\n"
"void main() {\n"
" v_textureCoords = textureCoords;\n"
" gl_Position = triangleCoords;\n"
"}\n";
static const char* fragmentShaderSource =
"varying lowp vec2 v_textureCoords;\n"
"uniform sampler2D sampler;\n"
"void main() {\n"
" gl_FragColor = vec4(texture2D(sampler, v_textureCoords).rgb, 1.0);\n"
"}\n";
m_textureProgram = new QOpenGLShaderProgram();
m_textureProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
m_textureProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
这是步骤(2)的顶点和框架着色器代码:
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);
由于您是说这两个步骤可以独立正确地工作,所以我想说问题必须出在其他地方。
您的问题可能不清楚,但是以下情况是否成立:
然后,我看到2个可能的问题。 首先(我很确定您必须检查过)可能是您要清除两次渲染调用之间的颜色缓冲区。 仍然要仔细检查。
第二个原因是这两个程序存在某种冲突。 如果此代码在每个帧上执行,则可能有意义。 一种快速的测试是仅绘制一次,然后查看结果是否正确绘制。
因此,可能发生的情况是在第二部分中设置了一些值,这破坏了第一部分。 例如:
如果纹理被第二部分破坏,则下次调用时,提取的每个纹理像素可能会返回(0,0,0,0)的颜色,通过混合可能会产生透明背景,并且您认为您看到了背景清除颜色。 您可以通过修改纹理着色器以仅输出纯色以查看是否在此处绘制来轻松测试。
另一个问题可能是将某些值设置为错误的程序,并且第一次调用的顶点数据被第二次调用覆盖。 在这种情况下,纹理将恰好在小矩形后面。 您可以通过使一个小的矩形(半透明)透明来进行测试,并查看纹理是否显示在其后面。
唯一在代码中引起注意的是
m_textureProgram->release();
m_shapeProgram->release();
这个对吗? 我希望着色器能够持久存在。 如果不是,那么它们在哪里创建?
您的假设似乎是第二部分以某种方式覆盖了其他像素以清除缓冲区。 我向你保证这是不可能的。 当绘制三角形时,没有办法影响其他像素(至少我猜没有几何着色器),只有点内的像素将分配有片段着色器,并且只有那些可以更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.