Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript WebGL中的开关着色器程序_Javascript_Glsl_Shader_Webgl - Fatal编程技术网

Javascript WebGL中的开关着色器程序

Javascript WebGL中的开关着色器程序,javascript,glsl,shader,webgl,Javascript,Glsl,Shader,Webgl,我有一个现有的WebGL渲染器(代码太多,无法共享),它过去非常简单:它只有一个顶点着色器、一个片段着色器和一个同时使用这两个着色器的着色器程序。它是用来渲染四边形的 我正在尝试扩展它,使其具有第二个着色器程序,用于渲染点精灵。它有自己的顶点属性数组和第二个顶点着色器、片段着色器和着色器程序 我似乎无法在两者之间正确地切换:我不断地出现显示故障、随机消失的对象等等。这是我必须在它们之间切换的两个函数。知道我错过了什么吗 GLWrapProto.switchQuadProgram = functi

我有一个现有的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);
};

从这段代码中很难判断问题出在哪里,但让我给出一些建议,尝试帮助您找到问题

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

(事实上,有没有人知道有一个像样的引文,我正试图找到一个,但目前无法找到。)

考虑到这一点,您可以将上述代码简化为:

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);
};

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

感谢您的帮助-它们自己工作得很好,当场景在两合一渲染之间切换时,某些东西会消失。所以我认为,正如你所说的,这两者之间的国家管理存在问题。我很好奇你对DisableVertexAttributeArray的评论——我假设程序的状态持续存在!调用useProgram时会丢失什么状态?我找不到关于它的任何文档,我想是某些状态丢失导致了这个问题!