- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想从 model.json 文件中绘制一个 3d 模型(例如房子)。我用蓝色等单一颜色绘制房子没有问题。但是,当我尝试使用纹理而不是颜色时,我收到一个错误:
WebGL: DrawElements: bound vertex attribute buffers do not have sufficient size for given indices from the bound element array
"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
超出范围。这就是你得到的错误。
// 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);
bufferWith3Colors
.您需要关闭该属性。
gl.disableVertexAttribArray(1);
bufferWith3Colors
也不应该出错仍然附加到属性#1。
关于opengl-es - WebGL:添加纹理导致 DrawElements 错误(属性缓冲空间不足),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19350390/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!