首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WebGL多色机

WebGL多色机
EN

Stack Overflow用户
提问于 2015-03-30 20:22:51
回答 1查看 7.2K关注 0票数 6

我以前读过StackOverflow关于这个问题的文章,在让两个不同的着色器集在一个WebGL程序中正确工作时仍然有问题。

下面是代码的框架框架。我有两套不同的着色器,不同的名字,以防止交叉污染。我创建了两个initShader()函数,一个对应于每组着色器,然后调用initBuffers()和()函数。其结果是,只有第二个着色器生效,并且只显示使用此着色器绘制的项目,尽管对着色器进行了单独标识,并在绞盘()中调用。

如有任何关于如何解决这个问题的建议,将不胜感激。

代码语言:javascript
复制
Declare: vertexShaderA
Declare: fragmentShaderA
Declare: vertexShaderB (use distinct variable names to that of vertexShaderA)
Declare: fragmentShaderB (use distinct variable names to that of fragmentShaderA)

// main script

initShadersA(){
…
    gl.useProgram(shaderProgramA);
…
}
initShadersB(){
…
    gl.useProgram(shaderProgramB);
…
}
…
setMatrixUniformsA();
setMatrixUniformsB();

function initBuffers(){
…
}

function drawScene(){
…
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.vertexAttribPointer(shaderProgramA.vertexPositionAttributeA, vertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
…
 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
 gl.uniform1i(shaderProgramA.samplerUniform, 0);
 setMatrixUniformsA();
 gl.drawElements(gl.TRIANGLES, vertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

…

gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.vertexAttribPointer(shaderProgramB.vertexPositionAttributeB, vertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
…
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
gl.uniform1i(shaderProgramB.samplerUniform, 0);
setMatrixUniformsB();
gl.drawElements(gl.TRIANGLES, vertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
}

 function draw() {
        requestAnimFrame(draw);
        animate(); 
        drawScene();
    }       
function animate() { 
    …
} 
function webGLStart() {
        initGL(canvas);
        initShadersA();
        initShadersB();
        initBuffers();
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.enable(gl.DEPTH_TEST);
        draw();
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-30 23:19:43

gl.useProgram(shaderProgram);基本上说:“好的,从现在开始,我会用这个材料来遮阳物体”。

尽管如此,在webGLStart()中,您所做的是: initGL,使用A材料,使用B材料,创建对象,用当前的材料绘制对象(也就是材料B)。

OpenGL/webGL作为状态机工作。当您尝试呈现某物时,它是用当前设置的状态机的参数绘制的。例如,您说draw到OpenGL,但是该方法正在寻找绑定到状态机的缓冲区,它还查找当前使用的材质(着色器).等等,所以你把一切都安排好了,这就开始了一些行动。

因此,如果您想用两个不同的着色器呈现两个对象,您应该绑定一个对象(实际上是缓冲区),使用第一个材质(gl.useProgram(shaderProgramA))并进行分派绘制。然后绑定第二个对象,设置第二个材料(gl.useProgram(shaderProgramB))并发出另一个调用。这就是OpenGL/WebGL的工作方式。

还有一个建议。尝试以不同的方式命名函数。initShadersA应该做一些事情,比如获取源字符串、创建顶点和片段着色器、创建程序和链接所有东西,而一些像useShadersA这样的函数应该设置当前的材质来精确着色程序。

我希望这能帮到你!

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29355582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档