Note that there are some explanatory texts on larger screens.

plurals
  1. POWebGL: Adding textures causes DrawElements error (attribute buffers insufficient space)
    text
    copied!<p>I want to draw a 3d model (e.g. a house) from a model.json file. I have no problem drawing the house in a single color like blue. However, when I try to use textures instead of a color, I receive an error:</p> <blockquote> <p>WebGL: DrawElements: bound vertex attribute buffers do not have sufficient size for given indices from the bound element array</p> </blockquote> <p>I've searched the web, and tried hundreds of different alterations, and I simply can't get past this error - I'm not good enough at WebGL to see what's wrong. There is an images folder with multiple texture images, but at this point, if I can just draw one of the textures for the entire house, I'd be ecstatic.</p> <p>The problem lies in renderable.js (attached) but you can access all files at <a href="http://tinyurl.com/mk9vbta" rel="nofollow">http://tinyurl.com/mk9vbta</a>. Any help would be greatly appreciated, don't know where else to go.</p> <p><strong>renderable.js</strong></p> <pre><code> "use strict"; function RenderableModel(gl,model){ function Drawable(attribLocations, vArrays, nVertices, indexArray, drawMode){ // Create a buffer object var vertexBuffers=[]; var nElements=[]; var nAttributes = attribLocations.length; for (var i=0; i&lt;nAttributes; i++){ if (vArrays[i]){ vertexBuffers[i] = gl.createBuffer(); if (!vertexBuffers[i]) { console.log('Failed to create the buffer object'); return null; } // Bind the buffer object to an ARRAY_BUFFER target gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffers[i]); // Write date into the buffer object gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vArrays[i]), gl.STATIC_DRAW); // Texture coords must always be passed as last attribute location (a_Attribute) nElements[i] = (i == (nAttributes - 1))? 2: vArrays[i].length/nVertices; } else{ vertexBuffers[i]=null; } } var indexBuffer=null; if (indexArray){ indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexArray), gl.STATIC_DRAW); } var a_texture = createTexture("texture0.jpg"); // Set the texture unit 0 to the sampler gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, a_texture); this.draw = function (){ nElements[1] = 2; for (var i=0; i&lt;nAttributes; i++){ if (vertexBuffers[i]){ gl.enableVertexAttribArray(attribLocations[i]); // Bind the buffer object to target gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffers[i]); // Assign the buffer object to a_Position variable gl.vertexAttribPointer(attribLocations[i], nElements[i], gl.FLOAT, false, 24, 0); } else{ gl.disableVertexAttribArray(attribLocations[i]); gl.vertexAttrib3f(attribLocations[i],1,1,1); //console.log("Missing "+attribLocations[i]) } } if (indexBuffer){ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.drawElements(drawMode, indexArray.length, gl.UNSIGNED_SHORT, 0); } else{ gl.drawArrays(drawMode, 0, nVertices); } } } // Vertex shader program var VSHADER_SOURCE = 'attribute vec2 textureCoord;\n' + 'attribute vec3 position;\n' + 'uniform mat4 modelT, viewT, projT;\n'+ //'varying vec4 v_Color;\n' + 'varying highp vec2 vTextureCoord;\n' + 'void main() {\n' + ' gl_Position = projT*viewT*modelT*vec4(position,1.0);\n' + //' v_Color = vec4(0, 1.0, 0.0, 1.0);\n' + // use instead of textures for now ' vTextureCoord = textureCoord;\n' + '}\n'; // Fragment shader program var FSHADER_SOURCE = '#ifdef GL_ES\n' + 'precision highp float;\n' + '#endif\n' + 'uniform sampler2D uSampler;\n' + //'varying vec4 v_Color;\n' + // use instead of texture 'varying highp vec2 vTextureCoord;\n' + 'void main() {\n' + // 'vec4 v_Color = vec4(texture2D(uSampler, vTextureCoord).rgb, 1.0);\n'+ ' gl_FragColor = texture2D(uSampler, vTextureCoord);\n' + '}\n'; // create program var program = createProgram(gl, VSHADER_SOURCE, FSHADER_SOURCE); if (!program) { console.log('Failed to create program'); return false; } var a_Position = gl.getAttribLocation(program, 'position'); var a_TextureCoord = gl.getAttribLocation(program, 'textureCoord'); // for texture var a_Locations = [a_Position,a_TextureCoord]; // Get the location/address of the uniform variable inside the shader program. var mmLoc = gl.getUniformLocation(program,"modelT"); var vmLoc = gl.getUniformLocation(program,"viewT"); var pmLoc = gl.getUniformLocation(program,"projT"); // textures var textureLoc = gl.getUniformLocation(program,'uSampler'); var drawables=[]; var modelTransformations=[]; var nDrawables=0; var nNodes = (model.nodes)? model.nodes.length:1; var drawMode=(model.drawMode)?gl[model.drawMode]:gl.TRIANGLES; for (var i= 0; i&lt;nNodes; i++){ var nMeshes = (model.nodes)?(model.nodes[i].meshIndices.length):(model.meshes.length); for (var j=0; j&lt;nMeshes;j++){ var index = (model.nodes)?model.nodes[i].meshIndices[j]:j; var mesh = model.meshes[index]; drawables[nDrawables] = new Drawable( a_Locations,[mesh.vertexPositions, mesh.vertexTexCoordinates], mesh.vertexPositions.length/3, mesh.indices, drawMode ); var m = new Matrix4(); if (model.nodes) m.elements=new Float32Array(model.nodes[i].modelMatrix); modelTransformations[nDrawables] = m; nDrawables++; } } // Get the location/address of the vertex attribute inside the shader program. this.draw = function (cameraPosition,pMatrix,vMatrix,mMatrix) { gl.useProgram(program); gl.uniformMatrix4fv(pmLoc, false, pMatrix.elements); gl.uniformMatrix4fv(vmLoc, false, vMatrix.elements); gl.uniform1i(textureLoc, 0); // pass variables determined at runtime for (var i= 0; i&lt;nDrawables; i++){ // pass model matrix var mMatrix=modelTransformations[i]; gl.uniformMatrix4fv(mmLoc, false, mMatrix.elements); drawables[i].draw(); } gl.useProgram(null); } this.getBounds=function() // Computes Model bounding box { var xmin, xmax, ymin, ymax, zmin, zmax; var firstvertex = true; var nNodes = (model.nodes)?model.nodes.length:1; for (var k=0; k&lt;nNodes; k++){ var m = new Matrix4(); if (model.nodes)m.elements=new Float32Array(model.nodes[k].modelMatrix); //console.log(model.nodes[k].modelMatrix); var nMeshes = (model.nodes)?model.nodes[k].meshIndices.length:model.meshes.length; for (var n = 0; n &lt; nMeshes; n++){ var index = (model.nodes)?model.nodes[k].meshIndices[n]:n; var mesh = model.meshes[index]; for(var i=0;i&lt;mesh.vertexPositions.length; i+=3){ var vertex = m.multiplyVector4(new Vector4([mesh.vertexPositions[i],mesh.vertexPositions[i+1],mesh.vertexPositions[i+2],1])).elements; //if (i==0){ // console.log([mesh.vertexPositions[i],mesh.vertexPositions[i+1],mesh.vertexPositions[i+2]]); // console.log([vertex[0], vertex[1], vertex[2]]); //} if (firstvertex){ xmin = xmax = vertex[0]; ymin = ymax = vertex[1]; zmin = zmax = vertex[2]; firstvertex = false; } else{ if (vertex[0] &lt; xmin) xmin = vertex[0]; else if (vertex[0] &gt; xmax) xmax = vertex[0]; if (vertex[1] &lt; ymin) ymin = vertex[1]; else if (vertex[1] &gt; ymax) ymax = vertex[1]; if (vertex[2] &lt; zmin) zmin = vertex[2]; else if (vertex[2] &gt; zmax) zmax = vertex[2]; } } } } var dim= {}; dim.min = [xmin,ymin,zmin]; dim.max = [xmax,ymax,zmax]; //console.log(dim); return dim; } // Load texture image and create/return texture object function createTexture(imageFileName) { var tex = gl.createTexture(); var img = new Image(); img.onload = function(){ gl.bindTexture(gl.TEXTURE_2D, tex); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); gl.bindTexture(gl.TEXTURE_2D, null); } img.src = imageFileName; return tex; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload