二十四课代码:
index.html:
<!doctype html>
<html>
<head>
<style>
canvas {
border: 1px solid
}
</style>
<script type="text/javascript" src="models_tri.js"></script>
</head>
<body>
<p>
<b>scale value:</b>
<input id="scalex" type="range" min="-2" max="2" value="1" step="0.1" oninput="updatefunc()" />
<b id="scalevaluex">0</b>
<input id="scaley" type="range" min="-2" max="2" value="1" step="0.1" oninput="updatefunc()" />
<b id="scalevaluey">0</b>
</p>
<p>
<b>offset value:</b>
<input id="offsetx" type="range" min="-1" max="1" value="0" step="0.1" oninput="updatefunc()" />
<b id="offsetvaluex">0</b>
<input id="offsety" type="range" min="-1" max="1" value="0" step="0.1" oninput="updatefunc()" />
<b id="offsetvaluey">0</b>
</p>
<p>
<b>rotate value:</b>
<input id="rotate" type="range" min="0" max="6.28" value="0" step="0.01" oninput="updatefunc()" />
<b id="rotatevalue">0</b>
</p>
<p>
<b>N边形:</b>
<input id="N" type="range" min="3" max="100" value="3" step="1" oninput="updatefunc()" />
<b id="Nvalue">0</b>
</p>
<canvas id="tri" width="600" height="600" style="width:300px; height:300px">
</canvas>
<script id="vertex_shader" type="myshader">
// Vertex Shader
precision mediump int
precision mediump float
uniform mat3 u_all
attribute vec2 a_PointVertex
attribute vec3 a_PointColor
varying vec3 color
void main() {
vec3 coord = u_all * vec3(a_PointVertex, 1.0)
gl_Position = vec4(coord.x, coord.y, 0.0, 1.0)
color = a_PointColor
}
</script>
<script id="fragment_shader" type="myshader">
// Fragment shader
precision mediump int
precision mediump float
varying vec3 color
void main() {
gl_FragColor = vec4(color, 1.0)
}
</script>
<script type="text/javascript">
var pointCanvas = document.getElementById('tri')
var gl = pointCanvas.getContext('webgl', { preserveDrawingBuffer: true })
var data
var dataArr
var pointCount
var buffer_point = null
var buffer_color = null
//
var vertex_shader_code = document.getElementById('vertex_shader').textContent
var vertex_shader = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vertex_shader, vertex_shader_code)
gl.compileShader(vertex_shader)
//
var fragment_shader_code = document.getElementById('fragment_shader').textContent
var fragment_shader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fragment_shader, fragment_shader_code)
gl.compileShader(fragment_shader)
//
var program = gl.createProgram()
gl.attachShader(program, vertex_shader)
gl.attachShader(program, fragment_shader)
gl.linkProgram(program)
gl.useProgram(program)
//
var a_PointVertex = gl.getAttribLocation(program, 'a_PointVertex')
var a_PointColor = gl.getAttribLocation(program, 'a_PointColor')
//
</script>
<script>
var u_all_loc = gl.getUniformLocation(program, "u_all")
var scaleDomX = document.getElementById("scalex")
var scaleValueDomX = document.getElementById("scalevaluex")
var scaleDomY = document.getElementById("scaley")
var scaleValueDomY = document.getElementById("scalevaluey")
var offsetDomX = document.getElementById("offsetx")
var offsetValueDomX = document.getElementById("offsetvaluex")
var offsetDomY = document.getElementById("offsety")
var offsetValueDomY = document.getElementById("offsetvaluey")
var rotateDom = document.getElementById("rotate")
var rotateValueDom = document.getElementById("rotatevalue")
var NDom = document.getElementById("N")
var NValueDom = document.getElementById("Nvalue")
function genMat3ForGL(a, b, alpha, A, B) {
let mat3 = [
a * Math.cos(alpha), a * Math.sin(alpha), 0,
-b * Math.sin(alpha), b * Math.cos(alpha), 0,
A, B, 1,
]
return new Float32Array(mat3)
}
function updatefunc() {
if (buffer_point) {
gl.deleteBuffer(buffer_point)
}
if (buffer_color) {
gl.deleteBuffer(buffer_color)
}
data = GetPolyN([0, 0], 0.5, NDom.value)
dataArr = new Float32Array(data)
pointCount = data.length / 2
buffer_point = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, buffer_point)
gl.bufferData(gl.ARRAY_BUFFER, dataArr, gl.STATIC_DRAW)
gl.vertexAttribPointer(a_PointVertex, 2, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(a_PointVertex)
data = GetRandomColor(pointCount)
dataArr = new Float32Array(data)
buffer_color = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, buffer_color)
gl.bufferData(gl.ARRAY_BUFFER, dataArr, gl.STATIC_DRAW)
gl.vertexAttribPointer(a_PointColor, 3, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(a_PointColor)
gl.uniformMatrix3fv(u_all_loc, false, genMat3ForGL(scaleDomX.value,
scaleDomY.value, rotateDom.value, offsetDomX.value, offsetDomY.value
))
scaleValueDomX.innerText = scaleDomX.value
offsetValueDomX.innerText = offsetDomX.value
scaleValueDomY.innerText = scaleDomY.value
offsetValueDomY.innerText = offsetDomY.value
rotateValueDom.innerText = rotateDom.value
NValueDom.innerText = NDom.value
gl.enable(gl.CULL_FACE)
gl.enable(gl.DEPTH_TEST)
gl.clearColor(0, 0, 0, 0)
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
gl.drawArrays(gl.TRIANGLES, 0, pointCount)
}
updatefunc()
</script>
</script>
</body>
</html>
models_tri.js
function GetTri(A, B, C) {
return [A[0], A[1], B[0], B[1], C[0], C[1]]
}
function GetPolyN(center, R, N) {
// 1. 先在圆周上,均匀获取 N 个点
let idx = 0
let x = 0
let y = 0
let rad = 0
let pointArr = []
for (
rad = ((2 * Math.PI) / N) * idx
x = R * Math.cos(rad) + center[0]
y = R * Math.sin(rad) + center[1]
pointArr.push([x, y])
}
// 2. 将这N个点,每两个一组,与中心,正好是三个点,组成N个三角形
let res = []
for (idx = 0
res.push(...GetTri(pointArr[idx], pointArr[(idx + 1) % N], center))
}
return res
}
// 获取随机颜色 RGB
function GetRandomColor(pointCount) {
let res = []
let idx = 0
for (
res.push(Math.random())
res.push(Math.random())
res.push(Math.random())
}
return res
}
将上面两个文件放在一个目录里,用任意http服务器监听此目录即可