我的webgl学习之路 (8) 设置各点的颜色

方法与上面一样,唯一的区别就是颜色设置;

颜色的设置必须在片元着色器中,gl_FragColor

我们attribute 只能在顶点着色器中使用;那么怎么办;

Varying用于两个着色器之间通信;

如图:

如下:

<scriptid="vs"type="x-shader/x-vertex">
    attribute vec4 a_Position;
    attribute vec4 a_Color;
    varying vec4 v_Color;
    void main(void){
        v_Color = a_Color;
        gl_Position = a_Position;
        gl_PointSize = 10.0;
    }

</
script>
<scriptid="fs"type="x-shader/x-fragment">
    precision mediump float;
    varying vec4 v_Color;
    void main(void){
        gl_FragColor = v_Color;
    }

</
script>

 

在顶点中申明一个

varying vec4 v_Color;

然后在片元着色器中声明一个同样的

varying vec4 v_Color;他们必须一样;这样机器着色器才能识别;可这样不代表他们是同一个;

把得到的颜色数据给顶点中的v_Color,绘制的时候就会绘制你想要的颜色

代码如下:

<!DOCTYPEhtml>
<htmllang="en">
<head>
    <metacharset="UTF-8">
    <title>用交叉数据设置各个点的颜色</title>
    <scriptid="vs"type="x-shader/x-vertex">
        attribute vec4 a_Position;
        attribute vec4 a_Color;
        varying vec4 v_Color;
        void main(void){
            v_Color = a_Color;
            gl_Position = a_Position;
            gl_PointSize = 10.0;
        }

    </
script>
    <scriptid="fs"type="x-shader/x-fragment">
        precision mediump float;
        varying vec4 v_Color;
        void main(void){
            gl_FragColor = v_Color;
        }

    </
script>
</head>
<body>
<canvasid="canvas"style="background-color:black"></canvas>
<!--创建多个缓冲区,向着色器传值;这只适合数据量少的情况-->
<script>
    onload=function() {
       
varcanvas=document.getElementById("canvas");
       
canvas.width=500;
       
canvas.height=500;
       
vargl=canvas.getContext("webgl");

       
/*清空画板上的颜色,并初始化颜色*/
       
gl.clearColor(0.0,0.0,0.0,1.0);
       
//设定canvas初始化时候的深度
       
gl.clearDepth(1.0);
       
//清空画面上的颜色
       
gl.clear(gl.COLOR_BUFFER_BIT |gl.DEPTH_BUFFER_BIT);

       
//顶点着色器和片段着色器生成
       
varv_shader= create_shader("vs");
       
varf_shader= create_shader("fs");

       
//程序对象的生成和连接
       
varprogram= create_program(v_shader,f_shader);
       
//获取a_Position变量的存储位置
       
vara_Position=gl.getAttribLocation(program,"a_Position");
       
vara_Color=gl.getAttribLocation(program,"a_Color");
       
//顶点和点的尺寸
       
varverticesColors=newFloat32Array([
           
0.0,0.5,1.0,0.0,0.0,
            -
0.5, -0.5,1.0,1.0,0.0,
           
0.5, -0.5,0.0,0.0,1.0
       
]);


       
varn=3;//点的个数

        //创建缓冲区
       
varvertexColorBuffer=gl.createBuffer();

       
if(!vertexColorBuffer) {
           
console.log("Failed to create the buffer object");//缓冲区创建失败
           
return-1;
        }

       
//将缓冲区绑定到目标对象
       
gl.bindBuffer(gl.ARRAY_BUFFER,vertexColorBuffer);
       
//向缓冲区写入数据
       
gl.bufferData(gl.ARRAY_BUFFER,verticesColors,gl.STATIC_DRAW);

       
varFSIZE=verticesColors.BYTES_PER_ELEMENT;//得到数组中每个元素的大小(字节数)

        //将缓冲区对象分配给a_Position; 参数一:传入数据;参数二:指定每个顶点传入多少个数(2表示只取两个数传入,剩下的两个数0.0和1.0补上;1.0是透明度,跟vertexAttrib2f()类似)
        //参数五:相邻两个点字节数;传入的相当于一个点属性的字节大小,然后着色器根据这个获取;参数六:偏移数,从哪个开始;
       
gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,FSIZE*5,0);

       
//连接a_Position变量与分配给它的缓冲区对象
       
gl.enableVertexAttribArray(a_Position);

       
/*------点尺寸的数据传入------*/
       
gl.bindBuffer(gl.ARRAY_BUFFER,vertexColorBuffer);
       
gl.bufferData(gl.ARRAY_BUFFER,verticesColors,gl.STATIC_DRAW);
       
gl.vertexAttribPointer(a_Color,3,gl.FLOAT,false,FSIZE*5,FSIZE*2);
       
gl.enableVertexAttribArray(a_Color);


       
gl.clearColor(0.0,0.0,0.0,1.0);
       
gl.clear(gl.COLOR_BUFFER_BIT);
       
//开始绘制,显示器显示结果;参数二:从哪个点开始绘制;参数三:绘制几个点

       
gl.drawArrays(gl.POINT,0,n);

       
functioncreate_program(v_shader, f_shader) {
           
varprogram=gl.createProgram();

           
gl.attachShader(program, v_shader);
           
gl.attachShader(program, f_shader);

           
gl.linkProgram(program);
           
gl.useProgram(program);
           
returnprogram;
        }

       
functioncreate_shader(id) {
           
//用来保存着色器的变量
           
varshader;

           
//根据id从HTML中获取指定的script标签
           
varscriptElement=document.getElementById(id);

           
//如果指定的script标签不存在,则返回
           
if(!scriptElement) {
               
return;
            }

           
//判断script标签的type属性
           
switch(scriptElement.type) {

                
//顶点着色器的时候
               
case'x-shader/x-vertex':
                   
shader=gl.createShader(gl.VERTEX_SHADER);//生成顶点着色器
                   
break;

               
//片段着色器的时候
               
case'x-shader/x-fragment':
                    
shader=gl.createShader(gl.FRAGMENT_SHADER);//生成片元着色器
                   
break;
               
default:
                   
return;
            }

           
//将标签中的代码分配给生成的着色器
           
gl.shaderSource(shader,scriptElement.text);

           
//编译着色器
           
gl.compileShader(shader);

           
//判断一下着色器是否编译成功
           
if(gl.getShaderParameter(shader,gl.COMPILE_STATUS)) {

               
//编译成功,则返回着色器
               
returnshader;
            }
else{

               
//编译失败,弹出错误消息
               
alert(gl.getShaderInfoLog(shader));
            }
        }

       
functioncreate_program(vs, fs) {
           
//程序对象的生成
           
varprogram=gl.createProgram();

           
//向程序对象里分配着色器
           
gl.attachShader(program, vs);
           
gl.attachShader(program, fs);

           
//将着色器连接
           
gl.linkProgram(program);

           
//判断着色器的连接是否成功
           
if(gl.getProgramParameter(program,gl.LINK_STATUS)) {

               
//成功的话,将程序对象设置为有效
               
gl.useProgram(program);

               
//返回程序对象
               
returnprogram;
            }
else{

               
//如果失败,弹出错误信息
               
alert(gl.getProgramInfoLog(program));
            }
        }
    }
</
script>
</body>
</html>

 

 

前面彩色三角形的原理也是这样的,在彩色三角形中已经详细介绍了;我就不多说了;

我是写完demo很久再把这些东西放上来的,本想复习一遍,结果感觉都理解,太简单了,也就没好好整理,抱歉;其实这些东西你先了解一遍,然后试着默写一遍,这样才不多你就明白了,前面的我就是这样,由于我是安卓突然转学webgl一脸懵逼,于是我在前几节的时候逼着背下来,这样概念就变得清晰很多。后面也好学很多;


版权声明:本文为qq_25909453原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。