gpt4 book ai didi

opengl-es - WebGL:添加纹理导致 DrawElements 错误(属性缓冲空间不足)

转载 作者:行者123 更新时间:2023-12-04 04:38:20 24 4
gpt4 key购买 nike

我想从 model.json 文件中绘制一个 3d 模型(例如房子)。我用蓝色等单一颜色绘制房子没有问题。但是,当我尝试使用纹理而不是颜色时,我收到一个错误:

WebGL: DrawElements: bound vertex attribute buffers do not have sufficient size for given indices from the bound element array



我在网上搜索过,并尝试了数百种不同的更改,但我根本无法克服这个错误 - 我在 WebGL 方面还不够好,看不出哪里出了问题。有一个包含多个纹理图像的图像文件夹,但在这一点上,如果我可以为整个房子绘制一个纹理,我会欣喜若狂。

问题出在 renderable.js(附件)中,但您可以在 http://tinyurl.com/mk9vbta 访问所有文件.任何帮助将不胜感激,不知道还能去哪里。

renderable.js
    "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<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<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<nNodes; i++){
var nMeshes = (model.nodes)?(model.nodes[i].meshIndices.length):(model.meshes.length);
for (var j=0; j<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<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<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 < nMeshes; n++){
var index = (model.nodes)?model.nodes[k].meshIndices[n]:n;
var mesh = model.meshes[index];
for(var i=0;i<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] < xmin) xmin = vertex[0];
else if (vertex[0] > xmax) xmax = vertex[0];
if (vertex[1] < ymin) ymin = vertex[1];
else if (vertex[1] > ymax) ymax = vertex[1];
if (vertex[2] < zmin) zmin = vertex[2];
else if (vertex[2] > 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;
}
}

最佳答案

该错误意味着您的索引之一对于您当前附加的缓冲区来说太大了。

示例:假设您有一个包含 3 个位置的位置缓冲区

 [0.123, 0.010, 0.233,
0.423, 0.312, 0.344,
0.933, 1.332, 0.101]

现在想象你制作了一个索引缓冲区
 [0, 1, 3]

您只有 3 个位置,因此唯一有效的索引是 0、1 和 2。 3超出范围。这就是你得到的错误。

一些可能性:
  • 您的数据可能很糟糕。检查您的指数
  • 您绘制了一个顶点较少但属性较多的模型,然后绘制了一个顶点较多但属性较少的不同模型。您在绘制第二个模型时保留了前一个模型的属性。

  • 换句话说
    // setup first model with only 3 vertices, both positions and colors.
    gl.enableVertexAttribArray(0);
    gl.bindBuffer(gl.BUFFER_ARRAY, bufferWith3Positions);
    gl.vertexAttribPointer(0, ....);
    gl.enableVertexAttribArray(1);
    gl.bindBuffer(gl.BUFFER_ARRAY, bufferWith3Colors);
    gl.vertexAttribPointer(1, ....);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesForFirstModel);

    // setup first model with 6 vertices but no colors
    gl.bindBuffer(gl.BUFFER_ARRAY, bufferWith6Positions);
    gl.vertexAttribPointer(0, ....);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesForSecondModel);

    你会得到一个错误,因为 attrib #1 仍在引用 bufferWith3Colors .您需要关闭该属性。
    gl.disableVertexAttribArray(1);

    注意:假设着色器仍在使用属性 #1。如果不是,即使 bufferWith3Colors 也不应该出错仍然附加到属性#1。

    关于opengl-es - WebGL:添加纹理导致 DrawElements 错误(属性缓冲空间不足),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19350390/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com