2012-02-05 147 views
4

我有一个现有的WebGL渲染器(太多代码可用于共享),过去非常简单:它只有一个顶点着色器,一个片段着色器和一个着色器程序。这是为了渲染四边形。WebGL中的开关着色器程序

我试图扩展它有一个第二个着色器程序,它切换到和来自渲染点精灵。它有自己的顶点属性数组,第二个顶点着色器,片段着色器和着色器程序。

我似乎无法正确切换两者之间:我不断收到显示故障,随机消失的对象等。这是我必须在它们之间切换的两个功能。任何想法我失踪?

GLWrapProto.switchQuadProgram = function() 
{ 
    var gl = this.gl; 

    gl.useProgram(this.shaderProgramPoint); 

    gl.disableVertexAttribArray(this.locAPosPoint); 

    gl.useProgram(this.shaderProgram); 

    gl.enableVertexAttribArray(this.locAPos); 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); 
    gl.vertexAttribPointer(this.locAPos, 2, gl.FLOAT, false, 0, 0); 

    gl.enableVertexAttribArray(this.locATex); 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer); 
    gl.vertexAttribPointer(this.locATex, 2, gl.FLOAT, false, 0, 0); 
}; 

GLWrapProto.switchPointProgram = function() 
{ 
    var gl = this.gl; 

    gl.useProgram(this.shaderProgram); 

    gl.disableVertexAttribArray(this.locAPos); 
    gl.disableVertexAttribArray(this.locATex); 

    gl.useProgram(this.shaderProgramPoint); 

    gl.enableVertexAttribArray(this.locAPosPoint); 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer); 
    gl.vertexAttribPointer(this.locAPosPoint, 4, gl.FLOAT, false, 0, 0); 
}; 

回答

3

这段代码很难说出问题是什么,但让我提出一些建议来尝试帮助您找到问题。

首先,您不必过多担心每次切换着色器时都会执行disableVertexAttribArray。启用/禁用的数组是与着色器关联的状态,因此,更改绑定的程序会使先前启用的数组无效。

(实际上,没有人知道应该是一个不错的引文,我正在试图找到一个并不能在此刻。)

考虑到这一点,你可以简化上面的代码:

GLWrapProto.switchQuadProgram = function() 
{ 
    var gl = this.gl; 

    gl.useProgram(this.shaderProgram); 

    gl.enableVertexAttribArray(this.locAPos); 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); 
    gl.vertexAttribPointer(this.locAPos, 2, gl.FLOAT, false, 0, 0); 

    gl.enableVertexAttribArray(this.locATex); 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer); 
    gl.vertexAttribPointer(this.locATex, 2, gl.FLOAT, false, 0, 0); 
}; 

GLWrapProto.switchPointProgram = function() 
{ 
    var gl = this.gl; 

    gl.useProgram(this.shaderProgramPoint); 

    gl.enableVertexAttribArray(this.locAPosPoint); 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer); 
    gl.vertexAttribPointer(this.locAPosPoint, 4, gl.FLOAT, false, 0, 0); 
}; 

虽然我很好奇你提到的“显示故障”的问题。我想不出为什么切换着色器会导致对象随机停止并开始渲染的任何原因。尝试首先仅使用一个着色器渲染几何图形,然后仅切换并渲染使用另一个着色器的几何图形。如果其中任何一个都有问题,那么你知道这不是导致你的问题的着色器切换。如果仅在将两组几何图形渲染在一起时出现问题,则两者之间的状态管理可能会有一些错误。

+1

感谢您试图提供帮助 - 它们可以自行工作,当一个场景在两个场景之间切换时,一个场景会呈现出某些东西消失。所以我认为,正如你所说,两国之间在国家管理方面存在问题。 我很好奇你对disableVertexAttribArray的评论 - 我认为状态坚持程序!准确调用useProgram时会丢失什么状态?我找不到任何文档,我想有些状态正在丢失导致问题! – AshleysBrain 2012-02-06 01:24:26