相关内容 :在attribute变量传递参数的基础上,通过JavaScript获取鼠标事件的坐标,再经过坐标转换传递给attribute变量;Web颜色缓冲区每次绘制之后都会重置
相关函数:JavaScript鼠标事件onmousedown/onmouseup/onclick
html代码还是老一套
js代码:
javascript
// ClickedPoints.js
// 顶点着色器
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'void main() {\n' +
' gl_Position = a_Position;\n' +
' gl_PointSize = 10.0;\n' +
'}\n'
// 片元着色器
var FSHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + // 设置颜色
'}\n'
// 主函数
function main() {
// 获取<canvas>元素
let canvas = document.getElementById('webgl')
// 获取WebGL绘图上下文
let gl = getWebGLContext(canvas)
if (!gl) {
console.log('Failed to get the rendering context for WebGL')
return
}
// 初始化着色器
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to initialize shaders')
return
}
// 获取a_Position变量的存储位置
let a_Position = gl.getAttribLocation(gl.program, 'a_Position')
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position')
}
// 注册鼠标点击事件响应函数
canvas.onmousedown = function (ev) {
// console.log(ev)
click(ev, gl, canvas, a_Position)
}
// 设置背景色
gl.clearColor(0.0, 0.0, 0.0, 1.0)
// 清空绘图区域
gl.clear(gl.COLOR_BUFFER_BIT)
}
var g_points = [] // 鼠标点击位置数组
function click(ev, gl, canvas, a_Position) {
let x = ev.clientX // 鼠标点击处的x坐标
let y = ev.clientY // 鼠标点击处的y坐标
let rect = ev.target.getBoundingClientRect() //cnavas边界坐标
// 坐标转换
x = (x - rect.left - canvas.width / 2) / (canvas.width / 2)
y = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2)
// 将坐标存储到g_points数组中
g_points.push(x)
g_points.push(y)
// 清空绘图区
gl.clear(gl.COLOR_BUFFER_BIT)
// 绘制数组中的点
let len = g_points.length
for (let i = 0; i < len; i += 2) {
// 将点的位置传递到变量中a_Position
gl.vertexAttrib3f(a_Position, g_points[i], g_points[i + 1], 0.0)
// 绘制点
gl.drawArrays(gl.POINTS, 0, 1)
}
}
此处将x和y坐标通过JavaScript自带的鼠标点击事件来获取,通过坐标转换传递到着色器中。
注册事件响应函数:
javascript
// 注册鼠标点击事件响应函数
canvas.onmousedown = function (ev) {
// console.log(ev)
click(ev, gl, canvas, a_Position)
}
此处用**ev
** 作为函数的形参接收,**ev
**中挂载了许多关于这一事件的属性,包括触发对象(target)、坐标等,不同事件传递的事件对象不同
改变点的颜色与uniform变量(动态设置片元着色器)
相关内容:JavaScript设置点的颜色;JavaScript传递点的颜色给片元着色器(通过uniform 变量)
相关函数:gl.getUniformLocation(), gl.uniform4f()
- 在片元着色器中准备 uniform 变量
- 用这个 uniform 变量向 gl_FragColor 赋值
- 将颜色数据从 JavaScript 传给 uniform 变量
根据位置不同显示不同地颜色
javascript
// ClickedPoints.js
// 顶点着色器
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'void main() {\n' +
' gl_Position = a_Position;\n' +
' gl_PointSize = 10.0;\n' +
'}\n'
// 片元着色器
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' +
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + // 设置颜色
'}\n'
// 主函数
function main() {
// 获取<canvas>元素
let canvas = document.getElementById('webgl')
// 获取WebGL绘图上下文
let gl = getWebGLContext(canvas)
if (!gl) {
console.log('Failed to get the rendering context for WebGL')
return
}
// 初始化着色器
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to initialize shaders')
return
}
// 获取a_Position变量的存储位置
let a_Position = gl.getAttribLocation(gl.program, 'a_Position')
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position')
}
//获取u_FragColor 变量的存储位置
let u_FragColor = gl.getUniformLocation(gl.program,'u_FragColor');
if(u_FragColor < 0) {
console.log('Failed to get the storage location of u_FragColor');
}
// 注册鼠标点击事件响应函数
canvas.onmousedown = function (ev) {
// console.log(ev)
click(ev, gl, canvas, a_Position,u_FragColor);
}
// 设置背景色
gl.clearColor(0.0, 0.0, 0.0, 1.0)
// 清空绘图区域
gl.clear(gl.COLOR_BUFFER_BIT)
}
var g_points = [] // 鼠标点击位置数组
var g_colors = [];// 存储点颜色的数组
function click(ev, gl, canvas, a_Position,u_FragColor) {
let x = ev.clientX // 鼠标点击处的x坐标
let y = ev.clientY // 鼠标点击处的y坐标
let rect = ev.target.getBoundingClientRect() //cnavas边界坐标
// 坐标转换
x = (x - rect.left - canvas.width / 2) / (canvas.width / 2)
y = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2)
// 将坐标存储到g_points数组中
g_points.push(x)
g_points.push(y)
// 将点的颜色存储到g_colors中
if (x >= 0.0 && y >= 0.0) {
// 第一象限
g_colors.push([1.0, 0.0, 0.0, 1.0]) // 红色
} else if (x < 0.0 && y < 0.0) {
// 第三象限
g_colors.push([0.0, 0.0, 1.0, 1.0]) // 绿色
} else {
// 其他
g_colors.push([1.0, 1.0, 1.0, 1.0]) // 白色
}
// 清空绘图区
gl.clear(gl.COLOR_BUFFER_BIT)
// 绘制数组中的点
let len = g_points.length
for (let i = 0; i < len; i += 2) {
let rgba = g_colors[i/2];
// 将点的位置传递到变量中a_Position
gl.vertexAttrib3f(a_Position, g_points[i], g_points[i + 1], 0.0);
gl.uniform4fv(u_FragColor,rgba);
// 绘制点
gl.drawArrays(gl.POINTS, 0, 1)
}
}
uniform 变量
javascript
// 片元着色器
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // uniform变量
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' +
'}\n'
- uniform变量的声明遵循与attribute变量相同的格式<存储限定符><类型><变量名>
获取uniform变量的存储地址
javascript
// 获取u_FragColor变量的存储位置
let u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (!u_FragColor) {
console.log('Failed to get the storage location of u_FragColor')
}
指定变量不存在时,返回的是null而不是-1 。所以在检查的时候,需要**用'!'(取反)**操作符而不是'<0'
向 uniform 变量赋值