关于切换着色器程序的问题(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指定的最后一个程序。

要合并着色器,你必须手动生成一个新的着色器,它可以同时执行两个任务。

+0

我知道这是一个很老的帖子,但我想知道你是否可以扩展这个答案,请?你的意思是你不能使用多个着色器程序,或者你是否说它需要以特定的方式来完成。我正试图在我的应用程序中实现多个着色器 - 我开始只使用一个着色器,但片段着色器中的一个分支导致了严重的减速。谢谢 – Stuart 2011-04-21 05:14:22

+2

@StuDev意思是你不能同时使用多个程序,每次调用glUseProgram都会用传递给函数的程序替换当前程序。请注意,这意味着与此同时,每个具有不同程序的绘图对象都可以毫无问题地工作。 – 2011-04-21 11:50:57

+0

好的谢谢你的回复。所以如果我理解正确,下面的模式应该可以在单帧渲染中工作:glUseProgram(prog1) - > glDrawElements()' - >'glUseProgram(prog2)' - >'glDrawArrays()'(到不同的FBO ) - >呈现渲染缓冲区。希望我正确地理解了这一点。 – Stuart 2011-04-21 12:14:26

我不知道glBindTexture()是否必须在使用glUseProgram()切换程序后发生。这里是glUseProgram this page的参考。确保在glBegin和glEnd之间没有调用glUseProgram。检查glGetError以查看加载第二个顶点程序时是否导致错误。