文件列表
- index.html
- grid_object.js
- logic.js
index.html
<!doctype html>
<html>
<head>
<style>
canvas {
border: 1px solid #000000;
}
</style>
</head>
<body>
<p>
<b>格子的x方向拉伸:</b>
<input id="gridscalex" type="range" min="0.1" max="1" value="1" step="0.01" oninput="gl_draw()" />
<b id="gridscalexvalue">0</b>
</p>
<p>
<b>格子的y方向拉伸:</b>
<input id="gridscaley" type="range" min="0.1" max="1" value="1" step="0.01" oninput="gl_draw()" />
<b id="gridscaleyvalue">0</b>
</p>
<p>
<b>格子的x方向位移:</b>
<input id="gridposx" type="range" min="-1" max="1" value="0" step="0.01" oninput="gl_draw()" />
<b id="gridposxvalue">0</b>
</p>
<p>
<b>格子的y方向位移:</b>
<input id="gridposy" type="range" min="-1" max="1" value="0" step="0.01" oninput="gl_draw()" />
<b id="gridposyvalue">0</b>
</p>
<p>
<b>格子的旋转(角度):</b>
<input id="gridrotate" type="range" min="0" max="360" value="0" step="10" oninput="gl_draw()" />
<b id="gridrotatevalue">0</b>
</p>
<p>
<b>选取第几个格子</b>
<select id="chosen" oninput="chosen_selected()">
<option value="none">none</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</p>
<p>
<b>显示什么数字</b>
<select id="digit" oninput="">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
</p>
<canvas id="tri" width="600" height="600" style="width:300px; height:300px">
</canvas>
<script id="vertex_shader" type="myshader">
precision mediump int;
precision mediump float;
uniform mat3 u_all;
attribute vec2 a_PointVertex;
void main() {
vec3 coord = u_all * vec3(a_PointVertex, 1.0);
gl_Position = vec4(coord.x, coord.y, 0.0, 1.0);
}
</script>
<script id="fragment_shader" type="myshader">
precision mediump int;
precision mediump float;
uniform vec3 u_color;
void main() {
gl_FragColor = vec4(u_color, 1.0);
}
</script>
<script type="text/javascript" src="grid_object.js"></script>
<script type="text/javascript" src="logic.js"></script>
</body>
</html>
grid_object.js
class GridObject {
constructor(scalex, scaley, posx, posy) {
this.scalex = scalex;
this.scaley = scaley;
this.posx = posx;
this.posy = posy;
this.modelUpdated = false;
this.glbuffer = null;
this.a_PointVertex = null;
this.color = { R: 0, G: 0, B: 0 };
this.rotate = 0;
}
genData(gl) {
this.data = [
-1, -1,
1, -1,
1, 1,
1, 1,
-1, 1,
-1, -1,
];
this.dataArr = new Float32Array(this.data);
this.pointCount = 6;
if (this.glbuffer != null) {
gl.deleteBuffer(this.glbuffer);
this.a_PointVertex = null;
this.a_Color = null;
}
this.glbuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.glbuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.dataArr, gl.STATIC_DRAW);
this.modelUpdated = true;
}
render(gl, program) {
gl.bindBuffer(gl.ARRAY_BUFFER, this.glbuffer);
if (this.modelUpdated) {
this.modelUpdated = false;
if (this.a_PointVertex == null) {
this.a_PointVertex = gl.getAttribLocation(program, 'a_PointVertex');
}
}
gl.vertexAttribPointer(this.a_PointVertex, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(this.a_PointVertex);
gl.uniform3f(u_color, 1 - this.color.R, 1 - this.color.R, 1 - this.color.R);
let rad = ((2 * Math.PI) / 360) * this.rotate;
gl.uniformMatrix3fv(u_all_loc, false, genMat3ForGL(this.scalex,
this.scaley, rad, this.posx, this.posy
));
gl.drawArrays(gl.TRIANGLES, 0, this.pointCount);
}
}
logic.js
var pointCanvas = null;
var gl = null;
var u_all_loc = null;
var u_color = null;
var gridscalexDom = null;
var gridscalexvalueDom = null;
var gridscaleyDom = null;
var gridscaleyvalueDom = null;
var gridposxDom = null;
var gridposxvalueDom = null;
var gridposyDom = null;
var gridposyvalueDom = null;
var gridrotateDom = null;
var gridrotatevalueDom = null;
var digitDom = null;
var gridList = [];
var program = null;
function Main() {
gl_init();
gl_draw();
}
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 generateDigitGrid(gl) {
let idx = 0;
for (; idx <= 6; idx++) {
let digit0 = new GridObject(0.3, 0.1, 0, 0, 0);
gridList.push(digit0);
}
gridList.forEach(element => {
element.genData(gl);
});
}
function gl_init() {
pointCanvas = document.getElementById('tri');
gl = pointCanvas.getContext('webgl', { preserveDrawingBuffer: true });
generateDigitGrid(gl);
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);
const v_compiled = gl.getShaderParameter(vertex_shader, gl.COMPILE_STATUS);
if (!v_compiled) {
const v_theError = gl.getShaderInfoLog(vertex_shader);
console.error(v_theError);
gl.deleteShader(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);
const f_compiled = gl.getShaderParameter(fragment_shader, gl.COMPILE_STATUS);
if (!f_compiled) {
const f_theError = gl.getShaderInfoLog(fragment_shader);
console.error(f_theError);
gl.deleteShader(fragment_shader);
}
program = gl.createProgram();
gl.attachShader(program, vertex_shader);
gl.attachShader(program, fragment_shader);
gl.linkProgram(program);
gl.useProgram(program);
u_all_loc = gl.getUniformLocation(program, "u_all");
u_color = gl.getUniformLocation(program, "u_color");
gridscalexDom = document.getElementById("gridscalex");
gridscalexvalueDom = document.getElementById("gridscalexvalue");
gridscaleyDom = document.getElementById("gridscaley");
gridscaleyvalueDom = document.getElementById("gridscaleyvalue");
gridposxDom = document.getElementById("gridposx");
gridposxvalueDom = document.getElementById("gridposxvalue");
gridposyDom = document.getElementById("gridposy");
gridposyvalueDom = document.getElementById("gridposyvalue");
gridlightDom = document.getElementById("gridlight");
gridlightvalueDom = document.getElementById("gridlightvalue");
gridrotateDom = document.getElementById("gridrotate");
gridrotatevalueDom = document.getElementById("gridrotatevalue");
chosenDom = document.getElementById("chosen");
digitDom = document.getElementById("digit");
}
function chosen_selected() {
console.log(chosenDom.value);
if (chosenDom.value === "none") {
return;
}
gridscalexDom.value = gridList[chosenDom.value].scalex;
gridscaleyDom.value = gridList[chosenDom.value].scaley;
gridposxDom.value = gridList[chosenDom.value].posx;
gridposyDom.value = gridList[chosenDom.value].posy;
gridrotateDom.value = gridList[chosenDom.value].rotate;
gridscalexvalueDom.innerText = gridscalexDom.value;
gridscaleyvalueDom.innerText = gridscaleyDom.value;
gridposxvalueDom.innerText = gridposxDom.value;
gridposyvalueDom.innerText = gridposyDom.value;
gridrotatevalueDom.innerText = gridrotateDom.value;
}
function digitEncode(digit) {
if (digit == 0) {
gridList[0].color.R = 1;
gridList[1].color.R = 1;
gridList[2].color.R = 1;
gridList[3].color.R = 1;
gridList[4].color.R = 1;
gridList[5].color.R = 1;
gridList[6].color.R = 0;
return;
}
if (digit == 1) {
gridList[0].color.R = 0;
gridList[1].color.R = 1;
gridList[2].color.R = 1;
gridList[3].color.R = 0;
gridList[4].color.R = 0;
gridList[5].color.R = 0;
gridList[6].color.R = 0;
return;
}
if (digit == 2) {
gridList[0].color.R = 1;
gridList[1].color.R = 0;
gridList[2].color.R = 1;
gridList[3].color.R = 1;
gridList[4].color.R = 0;
gridList[5].color.R = 1;
gridList[6].color.R = 1;
return;
}
if (digit == 3) {
gridList[0].color.R = 1;
gridList[1].color.R = 1;
gridList[2].color.R = 1;
gridList[3].color.R = 1;
gridList[4].color.R = 0;
gridList[5].color.R = 0;
gridList[6].color.R = 1;
return;
}
if (digit == 4) {
gridList[0].color.R = 0;
gridList[1].color.R = 1;
gridList[2].color.R = 1;
gridList[3].color.R = 0;
gridList[4].color.R = 1;
gridList[5].color.R = 0;
gridList[6].color.R = 1;
return;
}
if (digit == 5) {
gridList[0].color.R = 1;
gridList[1].color.R = 1;
gridList[2].color.R = 0;
gridList[3].color.R = 1;
gridList[4].color.R = 1;
gridList[5].color.R = 0;
gridList[6].color.R = 1;
return;
}
if (digit == 6) {
gridList[0].color.R = 1;
gridList[1].color.R = 1;
gridList[2].color.R = 0;
gridList[3].color.R = 1;
gridList[4].color.R = 1;
gridList[5].color.R = 1;
gridList[6].color.R = 1;
return;
}
if (digit == 7) {
gridList[0].color.R = 0;
gridList[1].color.R = 1;
gridList[2].color.R = 1;
gridList[3].color.R = 1;
gridList[4].color.R = 0;
gridList[5].color.R = 0;
gridList[6].color.R = 0;
return;
}
if (digit == 8) {
gridList[0].color.R = 1;
gridList[1].color.R = 1;
gridList[2].color.R = 1;
gridList[3].color.R = 1;
gridList[4].color.R = 1;
gridList[5].color.R = 1;
gridList[6].color.R = 1;
return;
}
if (digit == 9) {
gridList[0].color.R = 1;
gridList[1].color.R = 1;
gridList[2].color.R = 1;
gridList[3].color.R = 1;
gridList[4].color.R = 1;
gridList[5].color.R = 0;
gridList[6].color.R = 1;
return;
}
}
function gl_draw() {
gridscalexvalueDom.innerText = gridscalexDom.value;
gridscaleyvalueDom.innerText = gridscaleyDom.value;
gridposxvalueDom.innerText = gridposxDom.value;
gridposyvalueDom.innerText = gridposyDom.value;
gridrotatevalueDom.innerText = gridrotateDom.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);
if (chosenDom.value !== "none") {
gridList[chosenDom.value].scalex = gridscalexDom.value;
gridList[chosenDom.value].scaley = gridscaleyDom.value;
gridList[chosenDom.value].posx = gridposxDom.value;
gridList[chosenDom.value].posy = gridposyDom.value;
gridList[chosenDom.value].rotate = gridrotateDom.value;
}
digitEncode(digitDom.value);
gridList.forEach(element => {
element.render(gl, program);
});
}
Main();