[英]Basic GLSL: Two fragment shaders behind each other, but first one (drawing a texture) is overwritten
I'm semi-new to OpenGL ES and looks like I'm missing one basic concept. 我是OpenGL ES的新手,似乎缺少一个基本概念。 I'm using some QT classes in my code, but it's near plain OpenGL ES.
我在代码中使用了一些QT类,但是它接近普通的OpenGL ES。
I want to do the following per rendered frame: 我想对每个渲染帧执行以下操作:
My problem is: Both steps together don't work. 我的问题是: 这两个步骤一起不起作用。 I only see the the small rectangle on the bottom of the screen from (2.), but the texture is gone.
我仅从(2.)中看到屏幕底部的小矩形,但是纹理消失了。 The area, where the texture should be shown, is filled with the clear color.
应该显示纹理的区域将填充有清晰的颜色。
My assumption is, the both frament shaders conflict somehow with each other or I'm missing something completely with states.. I'd be pleased for a hint on what is missing here. 我的假设是,两个Frament着色器之间都存在某种冲突,或者我完全缺少与状态有关的东西。我很高兴为您提供有关此处缺少的内容的提示。
Thanks in advance! 提前致谢!
Here's some of my code: 这是我的一些代码:
This is the vertex and frament shader code of step (1): 这是步骤(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);
This is the vertex and frament shader code of step (2): 这是步骤(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 );
And the main rendering function, a little bit stripped down (I'm skipping the initialization part, where the shader programs are setup and attribute locations bound): 以及主要的渲染功能,将其简化了一些(我跳过了初始化部分,在那儿设置了着色器程序并绑定了属性位置):
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);
Since you are saying that the two steps work correctly independently I would say the issue must be somewhere else. 由于您是说这两个步骤可以独立正确地工作,所以我想说问题必须出在其他地方。
It might be a bit unclear from your question but if the following is true: 您的问题可能不清楚,但是以下情况是否成立:
Then I see 2 possible issues. 然后,我看到2个可能的问题。 First (I am pretty sure you must have checked) might be that you are clearing the color buffer in between the 2 rendering calls.
首先(我很确定您必须检查过)可能是您要清除两次渲染调用之间的颜色缓冲区。 Double check for that anyway.
仍然要仔细检查。
The second is that the 2 programs are somehow in conflict. 第二个原因是这两个程序存在某种冲突。 If this code executes on every frame it might make sense.
如果此代码在每个帧上执行,则可能有意义。 A quick test would be to only draw it once and see if the result is drawn correctly.
一种快速的测试是仅绘制一次,然后查看结果是否正确绘制。
So what may happen is that some value is being set in the second part which destroys the first part. 因此,可能发生的情况是在第二部分中设置了一些值,这破坏了第一部分。 For instance:
例如:
If texture is destroyed by the second part then the next time you call it would be possible that each texel fetched returns a color of (0,0,0,0) which with blending may produce a transparent background and you think you see a background cleared color. 如果纹理被第二部分破坏,则下次调用时,提取的每个纹理像素可能会返回(0,0,0,0)的颜色,通过混合可能会产生透明背景,并且您认为您看到了背景清除颜色。 You may easily test this by modifying the textured shader to only output a solid color just to see if it gets drawn there.
您可以通过修改纹理着色器以仅输出纯色以查看是否在此处绘制来轻松测试。
Another problem might be some values are set to a wrong program and the vertex data for the first call gets overwritten by the second call. 另一个问题可能是将某些值设置为错误的程序,并且第一次调用的顶点数据被第二次调用覆盖。 In this case the texture would be exactly behind the small rectangle.
在这种情况下,纹理将恰好在小矩形后面。 You could test that by having a small rectangle (semi) transparent and see if the texture shows behind it.
您可以通过使一个小的矩形(半透明)透明来进行测试,并查看纹理是否显示在其后面。
The only thing that draws attention in your code though is 唯一在代码中引起注意的是
m_textureProgram->release();
m_shapeProgram->release();
Is this correct? 这个对吗? I would expect the shaders to be persistent.
我希望着色器能够持久存在。 If not then where are they created?
如果不是,那么它们在哪里创建?
It seems your assumption is that the second part somehow overwrites other pixels to clear buffer. 您的假设似乎是第二部分以某种方式覆盖了其他像素以清除缓冲区。 I assure you that is not possible.
我向你保证这是不可能的。 When drawing triangles there is no way to influence other pixels (at least without geometry shader I guess), ONLY the pixels within the points will have assigned fragment shaders and only those may be changed.
当绘制三角形时,没有办法影响其他像素(至少我猜没有几何着色器),只有点内的像素将分配有片段着色器,并且只有那些可以更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.