使用颜色缓冲区时WebGL渲染失败

时间:2016-04-23 15:33:09

标签: javascript html5 webgl

<!doctype html>
<html>

<body>
<canvas id ="ctx" width = "300" height = "300"></canvas> 
    <script>
        //Getting Webgl Context

        var ctx = document.getElementById("ctx");
        var webgl = ctx.getContext("experimental-webgl");

        /*Creating Shader*/

        //Vertex Code
        var vertexCode =
        'attribute vec3 coordinates;'+
        'attribute vec3 color;'+
        'varying vec3 vColor;'+
        'void main(void) {' +
           ' gl_Position = vec4(coordinates, 1.0);' +
           'vColor = color;'+
        '}';

        //Creating Shader Object    
        var vertexShader = webgl.createShader(webgl.VERTEX_SHADER);

        //Assigning the Source
        webgl.shaderSource(vertexShader, vertexCode);

        //Compiling the Source
        webgl.compileShader(vertexShader);

        //Fragment Shader Code 
         var fragmentCode ='precision mediump float;'+
        'varying vec3 vColor;'+
        'void main(void) {'+
           'gl_FragColor = vec4(vColor, 1.);'+
        '}';

        //Creating Shader Object    
        var fragmentShader = webgl.createShader(webgl.FRAGMENT_SHADER);

        //Assigning the Source
        webgl.shaderSource(fragmentShader, fragmentCode);

        //Compiling the Source
        webgl.compileShader(fragmentShader);

        //Creating Program to store Shader
        var shaderProgram = webgl.createProgram();

        //Attaching the shaders
        webgl.attachShader(shaderProgram, vertexShader);
        webgl.attachShader(shaderProgram, fragmentShader);

        //linking the Program
        webgl.linkProgram(shaderProgram);

        //using the Program
        webgl.useProgram(shaderProgram);

        //Defining geometry
        var vertices = [
        -0.5,0.5,0.0,
        -0.5,-0.5,0.0,
        0.5,-0.5,0.0,
        0.5,0.5,0.0
     ];

     var colors = [0,0,1, 1,0,0, 0,1,0, 1,0,1,];

     indices = [3,2,1,3,1,0];

        //Creating a Buffer
        var VextexBuffer = webgl.createBuffer();
        var IndexBuffer = webgl.createBuffer();
        var colorBuffer = webgl.createBuffer();

        //Binding the Buffer
        webgl.bindBuffer(webgl.ARRAY_BUFFER, VextexBuffer);
        webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, IndexBuffer);
        webgl.bindBuffer(webgl.ARRAY_BUFFER, colorBuffer);

        //Buffer Data
        webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);
        webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), webgl.STATIC_DRAW);
        webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(colors), webgl.STATIC_DRAW);

        /*Associating the shaders to bufferObject*/

        //Getting attribute location
        var coord = webgl.getAttribLocation(shaderProgram,"coordinates");
        var color = webgl.getAttribLocation(shaderProgram, "color");

        //pointing an attribute to the currently bound VBO
        webgl.vertexAttribPointer(coord, 3, webgl.FLOAT, false ,0,0);
        webgl.vertexAttribPointer(color, 3, webgl.FLOAT, false ,0,0);

        //enabling the attributes
        webgl.enableVertexAttribArray(coord);
        webgl.enableVertexAttribArray(color);
        //Unbind Array


        /*Drawing the Triangle*/

        //Clearing the Colour
        webgl.clearColor(.5,.5,.5,1);

        //Enabling the depth test
        webgl.enable(webgl.DEPTH_TEST);

        //Clearing colour nuffer bit
        webgl.clear(webgl.COLOR_BUFFER_BIT);

        //Setting a viewport
        webgl.viewport(0,0,ctx.width,ctx.height);

        //Draw the triangle
            webgl.drawElements(webgl.TRIANGLES,indices.length,webgl.UNSIGNED_SHORT,0);

    </script>
</body>
</html>

如果我删除颜色缓冲区以及与之相关的所有内容,代码会运行但是使用颜色缓冲区,我只看到灰色画布,没有别的。

Chrome控制台也不会显示任何错误或警告。 请帮帮我。

2 个答案:

答案 0 :(得分:2)

这里是working fiddle

代码中最大的错误是使用bindBuffer方法。 WebGL上下文可以一次绑定缓冲区。一次绑定两个或多个缓冲区导致仅绑定最后一个缓冲区。

当您必须将数据复制到缓冲区时,需要绑定它然后调用bufferData函数。

同样适用于vertexAttribPointer功能。首先绑定要绑定属性的缓冲区,然后调用vertexAttribPointer,依此类推其他缓冲区。

&#13;
&#13;
//Getting Webgl Context

var ctx = document.getElementById("ctx");
var webgl = ctx.getContext("experimental-webgl");

/*Creating Shader*/

//Vertex Code
var vertexCode =
        'attribute vec3 coordinates;' +
        'attribute vec3 color;' +
        'varying vec3 vColor;' +
        'void main(void) {' +
        ' gl_Position = vec4(coordinates, 1.0);' +
        'vColor = color;' +
        '}';

//Creating Shader Object    
var vertexShader = webgl.createShader(webgl.VERTEX_SHADER);

//Assigning the Source
webgl.shaderSource(vertexShader, vertexCode);

//Compiling the Source
webgl.compileShader(vertexShader);

//Fragment Shader Code 
var fragmentCode = 'precision mediump float;' +
        'varying vec3 vColor;' +
        'void main(void) {' +
        'gl_FragColor = vec4(vColor, 1.);' +
        '}';

//Creating Shader Object    
var fragmentShader = webgl.createShader(webgl.FRAGMENT_SHADER);

//Assigning the Source
webgl.shaderSource(fragmentShader, fragmentCode);

//Compiling the Source
webgl.compileShader(fragmentShader);

//Creating Program to store Shader
var shaderProgram = webgl.createProgram();

//Attaching the shaders
webgl.attachShader(shaderProgram, vertexShader);
webgl.attachShader(shaderProgram, fragmentShader);

//linking the Program
webgl.linkProgram(shaderProgram);

//using the Program
webgl.useProgram(shaderProgram);

//Defining geometry
var vertices = [
    -0.5, 0.5, 0.0,
    -0.5, -0.5, 0.0,
    0.5, -0.5, 0.0,
    0.5, 0.5, 0.0
];

var colors = [0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, ];

indices = [3, 2, 1, 3, 1, 0];

var coord = webgl.getAttribLocation(shaderProgram, "coordinates");
var color = webgl.getAttribLocation(shaderProgram, "color");

webgl.enableVertexAttribArray(coord);
webgl.enableVertexAttribArray(color);

//Creating a Buffer
var VextexBuffer = webgl.createBuffer();
var IndexBuffer = webgl.createBuffer();
var colorBuffer = webgl.createBuffer();

//Binding the Buffer
webgl.bindBuffer(webgl.ARRAY_BUFFER, VextexBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);

webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, IndexBuffer);
webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), webgl.STATIC_DRAW);

webgl.bindBuffer(webgl.ARRAY_BUFFER, colorBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(colors), webgl.STATIC_DRAW);

webgl.bindBuffer(webgl.ARRAY_BUFFER, VextexBuffer);
webgl.vertexAttribPointer(coord, 3, webgl.FLOAT, false, 0, 0);

webgl.bindBuffer(webgl.ARRAY_BUFFER, colorBuffer);
webgl.vertexAttribPointer(color, 3, webgl.FLOAT, false, 0, 0);
/*Drawing the Triangle*/
//Clearing the Colour
webgl.clearColor(.5, .5, .5, 1);
//Enabling the depth test
webgl.enable(webgl.DEPTH_TEST);
//Clearing colour nuffer bit
webgl.clear(webgl.COLOR_BUFFER_BIT);
//Setting a viewport
webgl.viewport(0, 0, ctx.width, ctx.height);
//Draw the triangle
webgl.drawElements(webgl.TRIANGLES, indices.length, webgl.UNSIGNED_SHORT, 0);
&#13;
<canvas id ="ctx" width = "300" height = "300"></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

你用你的颜色覆盖你的顶点位置:

 webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);
 webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(colors), webgl.STATIC_DRAW);

在任何给定时间,每种类型(ARRAY_BUFFERELEMENT_ARRAY_BUFFER)只能绑定一个缓冲区,所以 流程是绑定缓冲区并设置其数据,然后设置特定缓冲区的顶点属性指针,然后继续下一个缓冲区:

// setup positions
var VextexBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ARRAY_BUFFER, VextexBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);
var coord = webgl.getAttribLocation(shaderProgram,"coordinates");
webgl.vertexAttribPointer(coord, 3, webgl.FLOAT, false ,0,0);

// setup indices
var IndexBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, IndexBuffer);
webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), webgl.STATIC_DRAW);

// setup colors
var colorBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ARRAY_BUFFER, colorBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(colors), webgl.STATIC_DRAW);
var color = webgl.getAttribLocation(shaderProgram, "color");
webgl.vertexAttribPointer(color, 3, webgl.FLOAT, false ,0,0);

对于使用多个不同缓冲区且打算实时的应用程序,流程是在初始化阶段创建和设置缓冲区,然后仅绑定缓冲区并在动画循环期间设置顶点属性指针。

&#13;
&#13;
<!doctype html>
<html>

<body>
<canvas id ="ctx" width = "300" height = "300"></canvas> 
    <script>
        //Getting Webgl Context

        var ctx = document.getElementById("ctx");
        var webgl = ctx.getContext("experimental-webgl");

        /*Creating Shader*/

        //Vertex Code
        var vertexCode =
        'attribute vec3 coordinates;'+
        'attribute vec3 color;'+
        'varying vec3 vColor;'+
        'void main(void) {' +
           ' gl_Position = vec4(coordinates, 1.0);' +
           'vColor = color;'+
        '}';

        //Creating Shader Object    
        var vertexShader = webgl.createShader(webgl.VERTEX_SHADER);

        //Assigning the Source
        webgl.shaderSource(vertexShader, vertexCode);

        //Compiling the Source
        webgl.compileShader(vertexShader);

        //Fragment Shader Code 
         var fragmentCode ='precision mediump float;'+
        'varying vec3 vColor;'+
        'void main(void) {'+
           'gl_FragColor = vec4(vColor, 1.);'+
        '}';

        //Creating Shader Object    
        var fragmentShader = webgl.createShader(webgl.FRAGMENT_SHADER);

        //Assigning the Source
        webgl.shaderSource(fragmentShader, fragmentCode);

        //Compiling the Source
        webgl.compileShader(fragmentShader);

        //Creating Program to store Shader
        var shaderProgram = webgl.createProgram();

        //Attaching the shaders
        webgl.attachShader(shaderProgram, vertexShader);
        webgl.attachShader(shaderProgram, fragmentShader);

        //linking the Program
        webgl.linkProgram(shaderProgram);

        //using the Program
        webgl.useProgram(shaderProgram);

        //Defining geometry
        var vertices = [
        -0.5,0.5,0.0,
        -0.5,-0.5,0.0,
        0.5,-0.5,0.0,
        0.5,0.5,0.0
     ];

     var colors = [0,0,1, 1,0,0, 0,1,0, 1,0,1,];

     indices = [3,2,1,3,1,0];

       // setup positions
       var VextexBuffer = webgl.createBuffer();
       webgl.bindBuffer(webgl.ARRAY_BUFFER, VextexBuffer);
       webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);
       var coord = webgl.getAttribLocation(shaderProgram,"coordinates");
       webgl.vertexAttribPointer(coord, 3, webgl.FLOAT, false ,0,0);

       // setup indices
       var IndexBuffer = webgl.createBuffer();
       webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, IndexBuffer);
       webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), webgl.STATIC_DRAW);

       // setup colors
       var colorBuffer = webgl.createBuffer();
       webgl.bindBuffer(webgl.ARRAY_BUFFER, colorBuffer);
       webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(colors), webgl.STATIC_DRAW);
       var color = webgl.getAttribLocation(shaderProgram, "color");
       webgl.vertexAttribPointer(color, 3, webgl.FLOAT, false ,0,0);

        //enabling the attributes
        webgl.enableVertexAttribArray(coord);
        webgl.enableVertexAttribArray(color);
        //Unbind Array


        /*Drawing the Triangle*/

        //Clearing the Colour
        webgl.clearColor(.5,.5,.5,1);

        //Enabling the depth test
        webgl.enable(webgl.DEPTH_TEST);

        //Clearing colour nuffer bit
        webgl.clear(webgl.COLOR_BUFFER_BIT);

        //Setting a viewport
        webgl.viewport(0,0,ctx.width,ctx.height);

        //Draw the triangle
            webgl.drawElements(webgl.TRIANGLES,indices.length,webgl.UNSIGNED_SHORT,0);

    </script>
</body>
</html>
&#13;
&#13;
&#13;