关于切换着色器程序的问题(ES 2)
问题描述:
我想写一个相当简单的opengl es 2程序。关于切换着色器程序的问题(ES 2)
我有两个不同的着色器,一个呈现纯色矩形到屏幕,另一个呈现纹理映射的矩形。
我想先绘制纯色矩形,然后在它上面绘制纹理映射的矩形。
glUseProgram(program1);
glUniform1f(shader1_uniforms[UNIFORM_SCREEN_WIDTH], (GLfloat)screenWidth);
glUniform1f(shader1_uniforms[UNIFORM_SCREEN_HEIGHT], (GLfloat)screenHeight);
glDisableVertexAttribArray(ATTRIB_TEX2);
glVertexAttribPointer(ATTRIB_VERTEX2, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX2);
glVertexAttribPointer(ATTRIB_COLOR2, 4, GL_FLOAT, 1, 0, squareColors);
glEnableVertexAttribArray(ATTRIB_COLOR2);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D,1);
glUseProgram(program2);
glUniform1f(shader2_uniforms[UNIFORM_SCREEN_WIDTH], (GLfloat)screenWidth);
glUniform1f(shader2_uniforms[UNIFORM_SCREEN_HEIGHT], (GLfloat)screenHeight);
glUniform1i(shader2_uniforms[UNIFORM_UIMAP], 0);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, 1, 0, squareColors);
glEnableVertexAttribArray(ATTRIB_COLOR);
glVertexAttribPointer(ATTRIB_TEX, 2, GL_FLOAT, 0, 0, squareTexCoords);
glEnableVertexAttribArray(ATTRIB_TEX);
// Draw
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisable(GL_BLEND);
两个着色器正常工作,如果单独执行(例如,使用第一着色评论的部分)。但是当我将它们结合在一起时,纹理贴图就会消失。我花了很长时间试图找出为什么......
有人可以帮助我吗?谢谢。
答
您不能以这种方式组合着色器,只会使用glUseProgram指定的最后一个程序。
要合并着色器,你必须手动生成一个新的着色器,它可以同时执行两个任务。
答
我不知道glBindTexture()是否必须在使用glUseProgram()切换程序后发生。这里是glUseProgram this page的参考。确保在glBegin和glEnd之间没有调用glUseProgram。检查glGetError以查看加载第二个顶点程序时是否导致错误。
我知道这是一个很老的帖子,但我想知道你是否可以扩展这个答案,请?你的意思是你不能使用多个着色器程序,或者你是否说它需要以特定的方式来完成。我正试图在我的应用程序中实现多个着色器 - 我开始只使用一个着色器,但片段着色器中的一个分支导致了严重的减速。谢谢 – Stuart 2011-04-21 05:14:22
@StuDev意思是你不能同时使用多个程序,每次调用glUseProgram都会用传递给函数的程序替换当前程序。请注意,这意味着与此同时,每个具有不同程序的绘图对象都可以毫无问题地工作。 – 2011-04-21 11:50:57
好的谢谢你的回复。所以如果我理解正确,下面的模式应该可以在单帧渲染中工作:glUseProgram(prog1) - > glDrawElements()' - >'glUseProgram(prog2)' - >'glDrawArrays()'(到不同的FBO ) - >呈现渲染缓冲区。希望我正确地理解了这一点。 – Stuart 2011-04-21 12:14:26