webgl着色问题

时间:2017-11-14 14:12:01

标签: webgl

我首先要说的是我是webgl的新手,几天前才拿起它用于计算机图形课程,而且我在使用dat的应用程序时遇到问题。 GUI。它应该做的是通过2次点击绘制一个矩形,并使用dat.gui控制器选择的颜色对其进行着色,但我得到的颜色是从绿色,黄色,红色和左下角是黑色的。如果我评论gl.enableVertexAttribArray(_color);矩形线都是黑色的,所以我能想到的是我没有正确存储颜色信息。如果有人能指出我的解决方案或至少解决问题,我将非常感激。 `



<html>

<body>
  <canvas width="570" height="570" id="my_Canvas"></canvas>
  <script src="../lib/dat.gui.js"></script>
  <script>
    var canvas = document.getElementById('my_Canvas');
    gl = canvas.getContext('experimental-webgl');
    var vertCode =
      'attribute vec3 coordinates;' +
      'varying vec3 vColor;' +
      'attribute vec3 color;' +
      'void main(void){' +
      '	gl_Position=vec4(coordinates, 1.0);' +
      'vColor=color;' +
      '}';

    var vertShader = gl.createShader(gl.VERTEX_SHADER);

    gl.shaderSource(vertShader, vertCode);
    gl.compileShader(vertShader);

    var fragCode =
      'precision highp float;' +
      'varying vec3 vColor;' +
      'void main(void){' +
      '	gl_FragColor=vec4(vColor, 1.0);' +
      '}';

    var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragShader, fragCode);
    gl.compileShader(fragShader);

    var shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertShader);
    gl.attachShader(shaderProgram, fragShader);
    gl.linkProgram(shaderProgram);

    console.log(gl.getShaderInfoLog(vertShader));
    console.log(gl.getProgramInfoLog(shaderProgram));

    var gui = new dat.GUI();

    var colore = {
      colorv: [200, 200, 0]
    };

    gui.addColor(colore, 'colorv');

    gl.clearColor(0.5, 0.5, 0.5, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);

    var g_indices = [0, 1, 2, 0, 1, 3];
    var colors = [];
    var p_counter = 0; //this counter is used to detect if the point clicked is the 2nd point
    var g_counter = 0; //this is a global counter, used as a multiplier for g_points
    var quad_g_counter;
    var dodeca_g_counter;
    var g_points = []; // the array for mousepress
    var indices = [];
    var vertex_buffer = gl.createBuffer();
    var Index_Buffer = gl.createBuffer();
    var color_Buffer = gl.createBuffer();

    function click(ev, gl, canvas) {
      var x = ev.clientX;
      var y = ev.clientY;
      var rect = ev.target.getBoundingClientRect();
      x = ((x - rect.left) - canvas.height / 2) / (canvas.height / 2);
      y = (canvas.width / 2 - (y - rect.top)) / (canvas.width / 2);

      //store the coords in g_points array
      g_points.push(x);
      g_points.push(y);
      g_points.push(0);

      // clear <canvas>
      gl.clear(gl.COLOR_BUFFER_BIT);

      p_counter += 1;
      if (p_counter == 2) {
        //g_points
        dodeca_g_counter = g_counter * 12;

        g_points.push(g_points[dodeca_g_counter + 3]);
        g_points.push(g_points[dodeca_g_counter + 1]);
        g_points.push(0);

        g_points.push(g_points[dodeca_g_counter]);
        g_points.push(g_points[dodeca_g_counter + 4]);
        g_points.push(0);

        //indices
        quad_g_counter = g_counter * 4;

        indices.push(g_indices[0] + quad_g_counter);
        indices.push(g_indices[1] + quad_g_counter);

        indices.push(g_indices[2] + quad_g_counter);
        indices.push(g_indices[3] + quad_g_counter);

        indices.push(g_indices[4] + quad_g_counter);
        indices.push(g_indices[5] + quad_g_counter);

        //colors
        for (var i = 0; i < 4; i += 1) {

          colors.push(colore.colorv[0] / 255);
          colors.push(colore.colorv[1] / 255);

          colors.push(colore.colorv[2] / 255);

        }

        p_counter = 0;
        g_counter += 1;
      }

      gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(g_points), gl.STATIC_DRAW);
      //gl.bindBuffer(gl.ARRAY_BUFFER, null);

      //gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

      //gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
      gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

      draw();
    }

    canvas.onmousedown = function(ev) {
      click(ev, gl, canvas);
    }

    function draw() {
      gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

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

      gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(coord);

      var _color = gl.getAttribLocation(shaderProgram, "color");
      gl.vertexAttribPointer(_color, 3, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(_color);

      gl.useProgram(shaderProgram);

      gl.enable(gl.DEPTH_TEST);

      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);

      gl.viewport(0, 0, canvas.width, canvas.height);

      gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
    }
  </script>

</body>

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

1 个答案:

答案 0 :(得分:0)

在调用gl.vertexAttribPointer

之前,必须绑定正确的顶点缓冲区
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
var _color = gl.getAttribLocation(shaderProgram, "color");

.....

gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord);

gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
gl.vertexAttribPointer(_color, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(_color);


注意,gl.vertexAttribPointer定义了一个引用当前绑定ARRAY_BUFFER的通用顶点属性数据的数组。见gl.bindBuffer

在为"coordinates"指定顶点属性之前,绑定vertex_buffer。但是,如果您为color_Buffer指定顶点属性,则不要绑定"color"
因此,顶点坐标缓冲区也用于颜色属性。因为颜色是从一点到另一点插值的,所以他会产生彩色线条和区域。


请参阅代码段:

&#13;
&#13;
    var canvas = document.getElementById('my_Canvas');
     gl = canvas.getContext('experimental-webgl');
    
    var vertCode=
    'attribute vec3 coordinates;' +
    'varying vec3 vColor;' +
    'attribute vec3 color;' +
    'void main(void){' +
    '   gl_Position=vec4(coordinates, 1.0);' +
    'vColor=color;' +
    '}';
  
    var vertShader=gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertShader, vertCode);
    gl.compileShader(vertShader);
    
    var fragCode=
    'precision highp float;' +
    'varying vec3 vColor;' +
    'void main(void){' +
    '   gl_FragColor=vec4(vColor, 1.0);' +
    '}';
    
    var fragShader=gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragShader, fragCode);
    gl.compileShader(fragShader);
    
    var shaderProgram=gl.createProgram();
    gl.attachShader(shaderProgram, vertShader);
    gl.attachShader(shaderProgram, fragShader);
    gl.linkProgram(shaderProgram);
    console.log(gl.getShaderInfoLog(vertShader));
    console.log(gl.getProgramInfoLog(shaderProgram));
    
    //var gui = new dat.GUI();
    var colore={
        colorv: [200,200,0]
    };
    
    //gui.addColor(colore, 'colorv');
    gl.clearColor(0.5, 0.5, 0.5, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);
    
    var g_indices=[0,1,2,0,1,3];
    var colors=[];
    var p_counter=0; //this counter is used to detect if the point clicked is the 2nd point
    var g_counter=0; //this is a global counter, used as a multiplier for g_points
    var quad_g_counter;
    var dodeca_g_counter;
    var g_points = []; // the array for mousepress
    var indices=[];
    var vertex_buffer=gl.createBuffer();
    var Index_Buffer=gl.createBuffer();
    var color_Buffer=gl.createBuffer();
    
    function click(ev,gl,canvas){
    
        var x = ev.clientX;
        var y = ev.clientY;   
        var rect = ev.target.getBoundingClientRect();
    
        x = ((x - rect.left) - canvas.height/2)/(canvas.height/2);
        y = (canvas.width/2 - (y - rect.top))/(canvas.width/2);
    
        //store the coords in g_points array
    
        g_points.push(x);g_points.push(y); g_points.push(0);

        // clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);
        p_counter+=1;
    
        if(p_counter==2){
    
            //g_points
            dodeca_g_counter=g_counter*12;
            g_points.push(g_points[dodeca_g_counter+3]);g_points.push(g_points[dodeca_g_counter+1]);g_points.push(0);
            g_points.push(g_points[dodeca_g_counter]);g_points.push(g_points[dodeca_g_counter+4]);g_points.push(0);
    
            //indices
            quad_g_counter=g_counter*4;
            indices.push(g_indices[0]+quad_g_counter);indices.push(g_indices[1]+quad_g_counter);
            indices.push(g_indices[2]+quad_g_counter);indices.push(g_indices[3]+quad_g_counter);
            indices.push(g_indices[4]+quad_g_counter);indices.push(g_indices[5]+quad_g_counter);
    
            //colors
    
            for(var i=0; i<4; i+=1){
                colors.push(colore.colorv[0]/255);colors.push(colore.colorv[1]/255);
                colors.push(colore.colorv[2]/255);
            } 
            p_counter=0;
            g_counter+=1;
        }
    
            gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(g_points), gl.STATIC_DRAW);
    
            //gl.bindBuffer(gl.ARRAY_BUFFER, null);    
            //gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
  
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
  
            //gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
            gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
            draw();
    }
    
    canvas.onmousedown = function(ev) {click(ev,gl,canvas);}
    
    function draw(){
    
        gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
        var coord=gl.getAttribLocation(shaderProgram, "coordinates");
        gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(coord);

        gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
        var _color=gl.getAttribLocation(shaderProgram, "color");
        gl.vertexAttribPointer(_color, 3, gl.FLOAT, false, 0,0);
        gl.enableVertexAttribArray(_color);
        gl.useProgram(shaderProgram);
    
        gl.enable(gl.DEPTH_TEST);
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
        gl.viewport(0, 0, canvas.width, canvas.height);
        gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
    }    
&#13;
<canvas width="570" height="570" id="my_Canvas"></canvas>
&#13;
&#13;
&#13;