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

在WebGL中渲染球体时遇到问题,webgl,Webgl,我正在学习WebGL,并试图显示一个球体。没有纹理,只是每个顶点都有颜色,但我在Opera和Chrome中收到以下错误消息: “[.WebGLRenderingContext]GL错误:GL\u无效\u操作:GLDraweElements:尝试访问属性1中超出范围的顶点” 我不明白我做错了什么,因为代码在我看来很好,但我显然遗漏了一些东西 谢谢! 迈克尔 (它改编自第4课和第11课。) var-gl; 函数initGL(画布){ 试一试{ gl=canvas.getContext(“实验性web

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

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

谢谢! 迈克尔

(它改编自第4课和第11课。)

var-gl;
函数initGL(画布){
试一试{
gl=canvas.getContext(“实验性webgl”);
gl.viewportWidth=canvas.width;
gl.viewportHeight=canvas.height;
}捕获(e){
}
如果(!gl){
警报(“无法初始化WebGL,抱歉:-(”);
}
}
函数getShader(gl,id){
var shaderScript=document.getElementById(id);
如果(!shaderScript){
返回null;
}
var str=“”;
var k=shaderScript.firstChild;
while(k){
if(k.nodeType==3){
str+=k.textContent;
}
k=k.nextSibling;
}
var着色器;
if(shaderScript.type==“x-shader/x-fragment”){
着色器=gl.createShader(gl.FRAGMENT\u着色器);
}else if(shaderScript.type==“x-shader/x-vertex”){
着色器=gl.createShader(gl.VERTEX\u着色器);
}否则{
返回null;
}
gl.shaderSource(着色器,str);
gl.compileShader(着色器);
if(!gl.getShaderParameter(着色器,gl.COMPILE_状态)){
警报(gl.getShaderInfoLog(着色器));
返回null;
}
返回着色器;
}
var着色器程序;
函数initShaders(){
var fragmentShader=getShader(gl,“着色器fs”);
var vertexShader=getShader(gl,“着色器vs”);
shaderProgram=gl.createProgram();
gl.attachShader(着色器程序、顶点着色器);
gl.attachShader(着色器程序、碎片着色器);
gl.linkProgram(着色器程序);
if(!gl.getProgramParameter(着色器程序,gl.LINK_状态)){
警报(“无法初始化着色器”);
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute=gl.GetAttributeLocation(shaderProgram,“aVertexPosition”);
gl.enableVertexAttributeArray(shaderProgramm.vertexPositionAttribute);
shaderProgram.vertexColorAttribute=gl.getAttributeLocation(shaderProgram,“aVertexColor”);
gl.EnableVertexAttribute数组(着色器程序vertexColorAttribute);
shaderProgram.pMatrixUniform=gl.getUniformLocation(shaderProgram,“uPMatrix”);
shaderProgram.mvMatrixUniform=gl.getUniformLocation(shaderProgram,“uMVMatrix”);
}
var mvMatrix=mat4.create();
var mvMatrixStack=[];
var pMatrix=mat4.create();
函数mvPushMatrix(){
var copy=mat4.create();
mat4.副本(副本,mvMatrix);
mvMatrixStack.push(复制);
}
函数mvPopMatrix(){
if(mvMatrixStack.length==0){
抛出“无效的popMatrix!”;
}
mvMatrix=mvMatrixStack.pop();
}
函数setMatrixUniforms(){
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform,false,pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform,false,mvMatrix);
}
函数degToRad(度){
返回度*Math.PI/180;
}
var-spherevertex缓冲区;
var sphereVertexColorBuffer;
var sphereVertexIndexBuffer;
函数initBuffers(){
var纬度带=10;
var longitudeBands=10;
var半径=2;
sphereVertexPositionBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,sphereVertexPositionBuffer);
sphereVertexColorBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,sphereVertexColorBuffer);
SphereEvertexIndexBuffer=gl.createBuffer();
gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,sphereVertexIndexBuffer);
var vertexPositionData=[];
var颜色=[];
var indexData=[];
对于(var-latNumber=0;latNumber我发现了问题

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

for(var-latNumber=0;latNumber
    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++)