webgl之绘制点

434 阅读2分钟
绘制单个点
var vertexShaderSource = '' +
    'void main(){' +
    //给内置变量gl_PointSize赋值像素大小
    '   gl_PointSize=20.0;' +
    //顶点位置,位于坐标原点
    '   gl_Position =vec4(0.0,0.0,0.0,1.0);' +
    '}';

//片元着色器源码
var fragmentShaderSource = '' +
    'void main(){' +
    //定义片元颜色
    '   gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
    '}';
var canvas = document.getElementById('canvas');
// 通过方法getContext()获取WebGL上下文
var gl= canvas.getContext('webgl');
var program = initShader(gl, vertexShaderSource, fragmentShaderSource)
gl.clearColor(0,0,0,1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.drawArrays(gl.POINTS,0,1);

function initShader(gl,vertexShaderSource,fragmentShaderSource){
  //创建顶点着色器对象
  var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  //创建片元着色器对象
  var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  //引入顶点、片元着色器源代码
  gl.shaderSource(vertexShader,vertexShaderSource);
  gl.shaderSource(fragmentShader,fragmentShaderSource);
  //编译顶点、片元着色器
  gl.compileShader(vertexShader);
  gl.compileShader(fragmentShader);

  //创建程序对象program
  var program = gl.createProgram();
  //附着顶点着色器和片元着色器到program
  gl.attachShader(program,vertexShader);
  gl.attachShader(program,fragmentShader);
  //链接program
  gl.linkProgram(program);
  //使用program
  gl.useProgram(program);
  //返回程序program对象
  return program;
}

这是最基本的绘制点的方法,同时这里的顶点数据:gl_PointSize和gl_Position,都是固定值,可以通过js对这两个属性进行单独赋值:

var vertexShaderSource = '' +
    'attribute vec4 a_Position'
    'void main(){' +
    //给内置变量gl_PointSize赋值像素大小
    '   gl_PointSize=20.0;' +
    //顶点位置,位于坐标原点
    '   gl_Position = a_Position;' +
    '}';
......
var a_Position = gl.getAttribLocation(program, 'a_Position')
gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0)

以上是绘制单个点的方法,之前一直不明白attribute vec4 a_Position,为什么a_Position要定义为vec4,原因在这个链接里做了解释:zhidao.baidu.com/question/94… 当然这里的gl.vertexAttrib3f,作用就是往着色器代码中设置属性值,其同族函数有很多,gl.vertexAttrib[1|2|3|4]f,后面会单独针对这些方法进行总结。

绘制多个点
 // 顶点着色器
 var vertexSource = '' + 
 'attribute vec4 a_Position;' + 
 'attribute float a_PointSize;' + 
 'void main(){' + 
 '   gl_PointSize = a_PointSize;' + 
 '   gl_Position = a_Position;' + 
 '}';

// 片元着色器
var fragmentSource = '' + 
'void main(){' + 
'   gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);' + 
'}';

var canvas = document.getElementById('canvas')

var gl = canvas.getContext('webgl')

// 创建对象
var vertexShader = gl.createShader(gl.VERTEX_SHADER)
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)

// 传入着色器代码
gl.shaderSource(vertexShader, vertexSource)
gl.shaderSource(fragmentShader, fragmentSource)

// 编译着色器
gl.compileShader(vertexShader)
gl.compileShader(fragmentShader)

// 创建着色器程序
var program = gl.createProgram()
// 程序绑定着色器对象
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)

// 链接程序
gl.linkProgram(program)
// 使用程序
gl.useProgram(program)

// 顶点位置
var n = 3
var vertices = new Float32Array([
	0.0, 0.5, -0.5, -0.5, 0.5, -0.5
])
// 创建缓冲区对象
var vertexBuffer = gl.createBuffer()

//绑定缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)

// 向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

// 拿到着色器中的attribute
var a_position = gl.getAttribLocation(program, 'a_Position')

// 用缓冲区的数据(gl.FLOAT) 赋值  a_position
gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 0, 0)
// a_position变量与对应的 缓冲区对象 建立关联
gl.enableVertexAttribArray(a_position)

var sizes = new Float32Array([
    10.0, 20.0, 30.0
])
var sizeBuffer = gl.createBuffer()

gl.bindBuffer(gl.ARRAY_BUFFER, sizeBuffer)
gl.bufferData(gl.ARRAY_BUFFER, sizes, gl.STATIC_DRAW)

var a_PointSize = gl.getAttribLocation(program, 'a_PointSize')

gl.vertexAttribPointer(a_PointSize, 1, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(a_PointSize)

// 设置绘制区背景
gl.clearColor(0, 0, 0, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.drawArrays(gl.POINTS, 0, n)