2014-02-17 47 views
2

我想呈现几个对象到画布上,并且我在理解什么不工作时有点麻烦。webgl中的多个对象

我在构建两个对象时代表我要呈现的两个网格物体。如果我创建了一个网格,代码就可以正常工作,所以我认为这个问题是,当我构建两个或多个网格时,数据会被搞乱。

这里的网格数据的例子:

"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":{} 
} 

这是从这个功能建设:

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

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

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

...因此不绘制。

问题出在哪里。希望从代码中获得足够的信息,我不想忍受太多,但如果您需要查看其他信息,我会更新。

回答

6

此代码

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

需要绘制每个网格时被调用,而不是在那里的现在叫。另外呼吁gl.vertexAttribPointerthis.program.vertexPosAttrib之前,你需要调用

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

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

换句话说

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); 
+0

感谢GMAN,它现在正常工作。 – adamdaly