gpt4 book ai didi

webgl - 在 WebGL 中渲染球体时遇到问题

转载 作者:行者123 更新时间:2023-12-02 19:38:54 28 4
gpt4 key购买 nike

我正在学习 WebGL 并尝试显示一个球体。没有纹理,只有每个顶点着色,但我在 Opera 和 Chrome 中收到以下错误消息:“[.WebGLRenderingContext]GL 错误:GL_INVALID_OPERATION:glDrawElements:尝试访问属性 1 中超出范围的顶点”

我不明白我做错了什么,因为代码对我来说看起来很好,但我显然遗漏了一些东西。

谢谢!迈克尔

(改编自 http://learningwebgl.com 的第 4 课和第 11 课。)

    var gl;

function initGL(canvas) {
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} catch (e) {
}
if (!gl) {
alert("Could not initialise WebGL, sorry :-(");
}
}


function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}

var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}

var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}

gl.shaderSource(shader, str);
gl.compileShader(shader);

if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}

return shader;
}


var shaderProgram;

function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");

shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);

if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}

gl.useProgram(shaderProgram);

shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);

shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
}


var mvMatrix = mat4.create();
var mvMatrixStack = [];
var pMatrix = mat4.create();

function mvPushMatrix() {
var copy = mat4.create();
mat4.copy(copy, mvMatrix);
mvMatrixStack.push(copy);
}

function mvPopMatrix() {
if (mvMatrixStack.length == 0) {
throw "Invalid popMatrix!";
}
mvMatrix = mvMatrixStack.pop();
}


function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}


function degToRad(degrees) {
return degrees * Math.PI / 180;
}

var sphereVertexPositionBuffer;
var sphereVertexColorBuffer;
var sphereVertexIndexBuffer;

function initBuffers() {
var latitudeBands = 10;
var longitudeBands = 10;
var radius = 2;

sphereVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexPositionBuffer);
sphereVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexColorBuffer);
sphereVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereVertexIndexBuffer);

var vertexPositionData = [];
var colors = [];
var indexData = [];
for (var latNumber=0; latNumber <= latitudeBands; latNumber++) {
var theta = latNumber * Math.PI / latitudeBands;
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta);

for (var longNumber=0; longNumber <= longitudeBands; longNumber++) {
var phi = longNumber * 2 * Math.PI / longitudeBands;
var sinPhi = Math.sin(phi);
var cosPhi = Math.cos(phi);

var x = cosPhi * sinTheta;
var y = cosTheta;
var z = sinPhi * sinTheta;

colors = [[1.0, 1.0, 0.3, 1.0]];
vertexPositionData.push(radius * x);
vertexPositionData.push(radius * y);
vertexPositionData.push(radius * z);

var first = (latNumber * (longitudeBands + 1)) + longNumber;
var second = first + longitudeBands + 1;
indexData.push(first);
indexData.push(second);
indexData.push(first + 1);

indexData.push(second);
indexData.push(second + 1);
indexData.push(first + 1);
}
}

var unpackedColors = [];
for (var i in colors) {
var color = colors[i];
for (var j=0; j < 4; j++) {
unpackedColors = unpackedColors.concat(color);
}
}

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), gl.STATIC_DRAW);
sphereVertexPositionBuffer.itemSize = 3;
sphereVertexPositionBuffer.numItems = vertexPositionData.length / 3;

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(unpackedColors), gl.STATIC_DRAW);
sphereVertexColorBuffer.itemSize = 4;
sphereVertexColorBuffer.numItems = unpackedColors.length / 4;

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), gl.STATIC_DRAW);
sphereVertexIndexBuffer.itemSize = 1;
sphereVertexIndexBuffer.numItems = indexData.length;

}


var rSphere = 0;

function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

mat4.perspective(pMatrix, 60, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);

mat4.identity(mvMatrix);

mat4.translate(mvMatrix, mvMatrix, [0.0, 0.0, -5.0]);

mvPushMatrix();
mat4.rotate(mvMatrix, mvMatrix, degToRad(rSphere), [1, 1, 1]);

gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, sphereVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, sphereVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereVertexIndexBuffer);
setMatrixUniforms();
gl.drawElements(gl.TRIANGLES, sphereVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

mvPopMatrix();

}


var lastTime = 0;

function animate() {
var timeNow = new Date().getTime();
if (lastTime != 0) {
var elapsed = timeNow - lastTime;

rSphere -= (75 * elapsed) / 1000.0;
}
lastTime = timeNow;
}


function tick() {
requestAnimFrame(tick);
drawScene();
animate();
}


function webGLStart() {
var canvas = document.getElementById("lesson04-canvas");
initGL(canvas);
initShaders()
initBuffers();

gl.clearColor(0.0, 0.0, 0.1, 1.0);
gl.enable(gl.DEPTH_TEST);

tick();
}

最佳答案

我发现问题了!

我在循环中包含了索引创建(小于或等于):

for (var latNumber=0; latNumber <= latitudeBands; latNumber++)
for (var longNumber=0; longNumber <= longitudeBands; longNumber++)

而不是它自己的循环(小于):

for (var latNumber=0; latNumber < latitudeBands; latNumber++) 
for (var longNumber=0; longNumber < longitudeBands; longNumber++)

关于webgl - 在 WebGL 中渲染球体时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20353339/

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