webgl中的多个对象 [英] Multiple objects in webgl

查看:80
本文介绍了webgl中的多个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将一些对象渲染到画布上,我在理解什么不起作用时遇到了一些麻烦。

I'm trying to render a few objects to a canvas and I'm having a bit of trouble understanding what's not working.

我正在构建两个对象此时代表我想渲染的两个网格。如果我创建一个网格,代码工作得很好,我认为问题是,当我构建两个或更多时,数据被搞砸了。

I'm building two objects at the moment that represent the two meshes that I want to render. If I create one mesh the code works fine so the problem, I think, is that the data gets screwed up when I'm building two or more.

这是一个例子网格数据:

Here's an example of the mesh data:

"name":"cone",
"buffers":{
    "vertexPosition":{}, // Buffer
    "vertexIndex":{} // Buffer
},
"mesh":{
    "vertices":[], // emptied it to fit on page
     "faces":[] // emptied it to fit on page
},
"mvMatrix": Float32Array[16],
"itemSize":3,
"numItems":12,
"program":{
    "vertexPosAttrib":0,
    "mvMatrixUniform":{},
    "pMatrixUniform":{}
}

这是从这个函数构建的:

This is build from this function:

buildMeshData: function(){

this.mvMatrix = mat4.create();

this.buffers.vertexPosition = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers.vertexPosition);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.mesh.vertices), gl.STATIC_DRAW);

this.buffers.vertexIndex = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffers.vertexIndex);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.mesh.faces), gl.STATIC_DRAW);

this.itemSize = 3;
this.numItems = this.mesh.faces.length;

var vertexProps = {

    attributes: ['vec3', 'VertexPosition'],
    uniforms: ['mat4', 'MVMatrix', 'mat4', 'PMatrix'],
    varyings: ['vec3', 'TexCoord']
}
var vertexShaderFunction = 'vTexCoord = aVertexPosition + 0.5; gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1);';
var vshaderInput = utils.buildVertexShader(vertexProps, vertexShaderFunction);

var fragmentProps = {

    attributes: [],
    uniforms: [],
    varyings: ['vec3', 'TexCoord']
}
var fragmentShaderFunction = 'gl_FragColor = vec4(vTexCoord, 1);';
var fshaderInput = utils.buildFragmentShader(fragmentProps, fragmentShaderFunction);

this.program = gl.createProgram();

var vshader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vshader, vshaderInput);
gl.compileShader(vshader);

var fshader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fshader, fshaderInput);
gl.compileShader(fshader);

gl.attachShader(this.program, vshader);
gl.attachShader(this.program, fshader);

gl.linkProgram(this.program);


gl.useProgram(this.program);

this.program.vertexPosAttrib = gl.getAttribLocation(this.program, 'aVertexPosition');
gl.vertexAttribPointer(this.program.vertexPosAttrib, this.itemSize, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(this.program.vertexPosAttrib);

this.program.mvMatrixUniform = gl.getUniformLocation(this.program, "uMVMatrix");
this.program.pMatrixUniform = gl.getUniformLocation(this.program, "uPMatrix");

scene.add(this);
}

,渲染功能如下:

function render(){

currentTime = new Date().getTime();
deltaTime = (currentTime - initialTime) / 1000; // in seconds

gl.viewport(0, 0, stage.width, stage.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

for(var i in scene.meshes){

    (function(mesh){

        mat4.translate(mesh.mvMatrix, mesh.mvMatrix, [0, 2 * i, -10 - (10 * i)]);

        gl.useProgram(mesh.program);

        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.buffers.vertexIndex);

        gl.vertexAttribPointer(mesh.program.vertexPosAttrib, mesh.itemSize, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(mesh.program.vertexPosAttrib);

        gl.uniformMatrix4fv(mesh.program.mvMatrixUniform, false, mesh.mvMatrix);
        gl.uniformMatrix4fv(mesh.program.pMatrixUniform, false, scene.pMatrix);

        gl.drawElements(gl.TRIANGLES, mesh.numItems, gl.UNSIGNED_SHORT, 0);

        gl.disableVertexAttribArray(mesh.program.vertexPosAttrib);

    })(scene.meshes[i])

}

// requestAnimationFrame(render);
}

这样做的结果是第二个对象被正确绘制但第一个导致错误:

The result of this is the second object is drawn correctly but the first causes the error:

[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0

...因此不会被抽出。

...and is therefore not drawn.

问题所在的任何想法。希望从代码中获得足够的信息,我不想忍受太多,但如果你需要看到别的什么我会更新。

Any ideas where the problem lies. Hopefully thats enough information from the code, I didn't want to put up too much, but if you need to see anything else I'll update.

推荐答案

此代码

gl.vertexAttribPointer(this.program.vertexPosAttrib, this.itemSize, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(this.program.vertexPosAttrib);

绘制每个网格时需要调用,而不是现在调用它。此外,在为 this.program.vertexPosAttrib 调用 gl.vertexAttribPointer 之前,您需要致电

Need to be called when drawing each mesh and not where it's called now. Additionally before calling gl.vertexAttribPointer for this.program.vertexPosAttrib you need to call

gl.bindBuffer(gl.ARRAY_BUFFER, mesh.buffers.vertexPosition);

因为 gl.vertexAttribPointer 当前绑定缓冲区绑定到 gl.ARRAY_BUFFER 到指定的属性。

Because gl.vertexAttribPointer binds the buffer currently bound to gl.ARRAY_BUFFER to the specified attribute.

换句话说

gl.bindBuffer(gl.ARRAY_BUFFER, mesh.buffers.vertexPosition);
gl.vertexAttribPointer(mesh.program.vertexPosAttrib, mesh.itemSize, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(mesh.program.vertexPosAttrib);

这篇关于webgl中的多个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆