代码之家  ›  专栏  ›  技术社区  ›  Dmytro

WebGL颜色缓冲区问题:[GL\u INVALID\u操作:glDrawArrays]

  •  1
  • Dmytro  · 技术社区  · 7 年前

    我正在尝试开始学习WebGL;我在没有颜色的情况下得到了概念验证,但当我尝试通过添加颜色来添加颜色时

    colorBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    
    gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
        1, 0, 0, 1,
        0, 1, 0, 1,
        0, 0, 1, 1,
    ), gl.STATIC_DRAW);
    
    ColorAttribute = gl.getAttribLocation(program, 'color');
    gl.enableVertexAttribArray(ColorAttribute);
    gl.vertexAttribPointer(ColorAttribute, 4, gl.FLOAT, false, 0, 0);
    

    • gl 是WebGLRenderingContext,
    • program 已成功编译的程序是否连接了顶点和片段着色器
    • colorBuffer ColorAttribute 是空变量

    gl_FragColor = vec4(0.2, 0.4, 0.6, 1);
    

    gl_FragColor = vcolor;    
    

    这很奇怪,因为我的颜色缓冲区中有3种颜色,三角形的每个顶点一种:

    gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
        1, 0, 0, 1,
        0, 1, 0, 1,
        0, 0, 1, 1,
    ), gl.STATIC_DRAW);
    

    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        0, 0, 0,
        0, 1, 0,
        1, 1, 0
    ]), gl.STATIC_DRAW);
    

    我确保在调用中将颜色缓冲区的项目大小设置为4,将顶点缓冲区的项目大小设置为3 vertexAttribPointer ,所以我不确定什么可能超出范围。

    下面是一个可以工作的代码,注释掉了颜色变化,然后是一个不适用于中颜色变化的代码。这两个示例都是通过将其粘贴到任何窗口的浏览器开发人员控制台中来实现的,但截图是在“about:blank”中拍摄的。

    这是工作版本:

    (function() {
        "use strict";
    
        var hWnd;
        var src_vertexShader;
        var src_fragmentShader;
        var canvas;
        var gl;
        var program;
        var vertexShader;
        var fragmentShader;
        var vertexBuffer;
        var colorBuffer;
        var PositionAttribute;
        var ColorAttribute;
    
        // | canvas container.
        hWnd = document.createElement("div");
        hWnd.style.position = "fixed";
        hWnd.style.top = "0px";
        hWnd.style.left = "0px";
        hWnd.style.border = "1px solid #000000";
        hWnd.addEventListener("click", function() {
            this.outerHTML = '';
        });
    
        // | vertex shader source.
        src_vertexShader = `
    attribute vec3 position;
    attribute vec4 color;
    
    varying vec4 vcolor;
    
    void main() {
        gl_Position = vec4(position, 1.0);
        vcolor = color;
    }`;
    
        // | fragment shader source.
        src_fragmentShader = `       
    varying lowp vec4 vcolor;
    
    void main() {
        gl_FragColor = vec4(0.2, 0.4, 0.6, 1);
    
        //gl_FragColor = vcolor;    
    }`;
    
        // | our WebGL canvas.
        canvas = document.createElement('canvas');
        canvas.width = 320;
        canvas.height = 200;       
    
        // | our WebGLRenderingContext.
        gl = canvas.getContext('webgl', {antialias: false});
    
        // | setting up our program using a Vertex and a Fragment shader.
        program = gl.createProgram();
        vertexShader = gl.createShader(gl.VERTEX_SHADER);
        fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    
        gl.shaderSource(vertexShader, src_vertexShader);
        gl.shaderSource(fragmentShader, src_fragmentShader);
    
        gl.compileShader(vertexShader);
        console.log('Shader compiled successfully: ' + gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS));
        console.log('Shader compiler log: ' + gl.getShaderInfoLog(vertexShader));    
    
        gl.compileShader(fragmentShader);
        console.log('Shader compiled successfully: ' + gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
        console.log('Shader compiler log: ' + gl.getShaderInfoLog(fragmentShader));    
    
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);
        gl.linkProgram(program);
        gl.useProgram(program);
    
        console.log(gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));    
    
        // | create and attach a vertex buffer with data for one triangle.
        vertexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
            0, 0, 0,
            0, 1, 0,
            1, 1, 0
        ]), gl.STATIC_DRAW);
    
        PositionAttribute = gl.getAttribLocation(program, 'position');
        gl.enableVertexAttribArray(PositionAttribute);
        gl.vertexAttribPointer(PositionAttribute, 3, gl.FLOAT, false, 0, 0);
    
        /*
        // | create and attach a color buffer with color data for our triangle.
        colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    
        gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
            1, 0, 0, 1,
            0, 1, 0, 1,
            0, 0, 1, 1,
        ), gl.STATIC_DRAW);
    
        ColorAttribute = gl.getAttribLocation(program, 'color');
        gl.enableVertexAttribArray(ColorAttribute);
        gl.vertexAttribPointer(ColorAttribute, 4, gl.FLOAT, false, 0, 0);
        */
    
        // | clear the screen.
        gl.clearColor(0.93, 0.93, 0.93, 1);
        gl.clear(gl.COLOR_BUFFER_BIT);
    
        // | draw the triangle.
        gl.drawArrays(gl.TRIANGLES, 0, 3);
    
        hWnd.appendChild(canvas)
        document.body.appendChild(hWnd);
    })();

    enter image description here

    这是投诉的版本:

    (function() {
        "use strict";
    
        var hWnd;
        var src_vertexShader;
        var src_fragmentShader;
        var canvas;
        var gl;
        var program;
        var vertexShader;
        var fragmentShader;
        var vertexBuffer;
        var colorBuffer;
        var PositionAttribute;
        var ColorAttribute;
    
        // | canvas container.
        hWnd = document.createElement("div");
        hWnd.style.position = "fixed";
        hWnd.style.top = "0px";
        hWnd.style.left = "0px";
        hWnd.style.border = "1px solid #000000";
        hWnd.addEventListener("click", function() {
            this.outerHTML = '';
        });
    
        // | vertex shader source.
        src_vertexShader = `
    attribute vec3 position;
    attribute vec4 color;
    
    varying vec4 vcolor;
    
    void main() {
        gl_Position = vec4(position, 1.0);
        vcolor = color;
    }`;
    
        // | fragment shader source.
        src_fragmentShader = `       
    varying lowp vec4 vcolor;
    
    void main() {
        gl_FragColor = vcolor;    
    }`;
    
        // | our WebGL canvas.
        canvas = document.createElement('canvas');
        canvas.width = 320;
        canvas.height = 200;       
    
        // | our WebGLRenderingContext.
        gl = canvas.getContext('webgl', {antialias: false});
    
        // | setting up our program using a Vertex and a Fragment shader.
        program = gl.createProgram();
        vertexShader = gl.createShader(gl.VERTEX_SHADER);
        fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    
        gl.shaderSource(vertexShader, src_vertexShader);
        gl.shaderSource(fragmentShader, src_fragmentShader);
    
        gl.compileShader(vertexShader);
        console.log('Shader compiled successfully: ' + gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS));
        console.log('Shader compiler log: ' + gl.getShaderInfoLog(vertexShader));    
    
        gl.compileShader(fragmentShader);
        console.log('Shader compiled successfully: ' + gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
        console.log('Shader compiler log: ' + gl.getShaderInfoLog(fragmentShader));    
    
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);
        gl.linkProgram(program);
        gl.useProgram(program);
    
        console.log(gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));    
    
        // | create and attach a vertex buffer with data for one triangle.
        vertexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
            0, 0, 0,
            0, 1, 0,
            1, 1, 0
        ]), gl.STATIC_DRAW);
    
        PositionAttribute = gl.getAttribLocation(program, 'position');
        gl.enableVertexAttribArray(PositionAttribute);
        gl.vertexAttribPointer(PositionAttribute, 3, gl.FLOAT, false, 0, 0);
    
        // | create and attach a color buffer with color data for our triangle.
        colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    
        gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
            1, 0, 0, 1,
            0, 1, 0, 1,
            0, 0, 1, 1,
        ), gl.STATIC_DRAW);
    
        ColorAttribute = gl.getAttribLocation(program, 'color');
        gl.enableVertexAttribArray(ColorAttribute);
        gl.vertexAttribPointer(ColorAttribute, 4, gl.FLOAT, false, 0, 0);
    
        // | clear the screen.
        gl.clearColor(0.93, 0.93, 0.93, 1);
        gl.clear(gl.COLOR_BUFFER_BIT);
    
        // | draw the triangle.
        gl.drawArrays(gl.TRIANGLES, 0, 3);
    
        hWnd.appendChild(canvas)
        document.body.appendChild(hWnd);    
    })();

    enter image description here

    enter image description here

    提前谢谢。

    1 回复  |  直到 7 年前
        1
  •  2
  •   gman    7 年前

    问题是定义颜色时代码缺少方括号

     gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
        1, 0, 0, 1,
        0, 1, 0, 1,
        0, 0, 1, 1,
      ), gl.STATIC_DRAW);
    

     gl.bufferData (gl.ARRAY_BUFFER, new Float32Array([
        1, 0, 0, 1,
        0, 1, 0, 1,
        0, 0, 1, 1,
     ]), gl.STATIC_DRAW);
    

    (function() {
        "use strict";
    
        var hWnd;
        var src_vertexShader;
        var src_fragmentShader;
        var canvas;
        var gl;
        var program;
        var vertexShader;
        var fragmentShader;
        var vertexBuffer;
        var colorBuffer;
        var PositionAttribute;
        var ColorAttribute;
    
        // | canvas container.
        hWnd = document.createElement("div");
        hWnd.style.position = "fixed";
        hWnd.style.top = "0px";
        hWnd.style.left = "0px";
        hWnd.style.border = "1px solid #000000";
        hWnd.addEventListener("click", function() {
            this.outerHTML = '';
        });
    
        // | vertex shader source.
        src_vertexShader = `
    attribute vec3 position;
    attribute vec4 color;
    
    varying vec4 vcolor;
    
    void main() {
        gl_Position = vec4(position, 1.0);
        vcolor = color;
    }`;
    
        // | fragment shader source.
        src_fragmentShader = `       
    varying lowp vec4 vcolor;
    
    void main() {
        gl_FragColor = vcolor;    
    }`;
    
        // | our WebGL canvas.
        canvas = document.createElement('canvas');
        canvas.width = 320;
        canvas.height = 200;       
    
        // | our WebGLRenderingContext.
        gl = canvas.getContext('webgl', {antialias: false});
    
        // | setting up our program using a Vertex and a Fragment shader.
        program = gl.createProgram();
        vertexShader = gl.createShader(gl.VERTEX_SHADER);
        fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    
        gl.shaderSource(vertexShader, src_vertexShader);
        gl.shaderSource(fragmentShader, src_fragmentShader);
    
        gl.compileShader(vertexShader);
        console.log('Shader compiled successfully: ' + gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS));
        console.log('Shader compiler log: ' + gl.getShaderInfoLog(vertexShader));    
    
        gl.compileShader(fragmentShader);
        console.log('Shader compiled successfully: ' + gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
        console.log('Shader compiler log: ' + gl.getShaderInfoLog(fragmentShader));    
    
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);
        gl.linkProgram(program);
        gl.useProgram(program);
    
        console.log(gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));    
    
        // | create and attach a vertex buffer with data for one triangle.
        vertexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
            0, 0, 0,
            0, 1, 0,
            1, 1, 0
        ]), gl.STATIC_DRAW);
    
        PositionAttribute = gl.getAttribLocation(program, 'position');
        gl.enableVertexAttribArray(PositionAttribute);
        gl.vertexAttribPointer(PositionAttribute, 3, gl.FLOAT, false, 0, 0);
    
        // | create and attach a color buffer with color data for our triangle.
        colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    
        gl.bufferData (gl.ARRAY_BUFFER, new Float32Array([
            1, 0, 0, 1,
            0, 1, 0, 1,
            0, 0, 1, 1,
        ]), gl.STATIC_DRAW);
    
        ColorAttribute = gl.getAttribLocation(program, 'color');
        gl.enableVertexAttribArray(ColorAttribute);
        gl.vertexAttribPointer(ColorAttribute, 4, gl.FLOAT, false, 0, 0);
    
        // | clear the screen.
        gl.clearColor(0.93, 0.93, 0.93, 1);
        gl.clear(gl.COLOR_BUFFER_BIT);
    
        // | draw the triangle.
        gl.drawArrays(gl.TRIANGLES, 0, 3);
    
        hWnd.appendChild(canvas)
        document.body.appendChild(hWnd);    
    })();