mirror of https://github.com/01-edu/public.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.6 KiB
133 lines
3.6 KiB
4 years ago
|
const vertexArray = new Float32Array(100 * 100 * 12)
|
||
|
const colorArray = new Float32Array(100 * 100 * 6)
|
||
|
const state = new Float32Array(100 * 100 * 2)
|
||
|
const [canvas] = document.getElementsByTagName('canvas')
|
||
|
const gl = canvas.getContext('webgl2', { antialias: false })
|
||
|
const S = 0.02
|
||
|
|
||
|
const applyState = (x, y, turn) => {
|
||
|
const index = x * 100 + y
|
||
|
const color = state[index * 2 + 0] > turn ? 0 : state[index * 2 + 1]
|
||
|
colorArray[index * 6 + 0] = color
|
||
|
colorArray[index * 6 + 1] = color
|
||
|
colorArray[index * 6 + 2] = color
|
||
|
colorArray[index * 6 + 3] = color
|
||
|
colorArray[index * 6 + 4] = color
|
||
|
colorArray[index * 6 + 5] = color
|
||
|
}
|
||
|
|
||
|
export const colorize = (x, y, color) => state[(x * 100 + y) * 2 + 1] = color
|
||
|
export const move = (x, y, color, turn) => {
|
||
|
const index = (x * 100 + y) * 2
|
||
|
if (state[index]) return state[index]
|
||
|
state[index] = turn
|
||
|
state[index + 1] = color
|
||
|
}
|
||
|
|
||
|
const loop = fn => {
|
||
|
let x = -1, y = -1
|
||
|
while (++x < 100) {
|
||
|
y = -1
|
||
|
while (++y < 100) fn(x, y)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const compileShader = (type, script) => {
|
||
|
const shader = gl.createShader(type)
|
||
|
gl.shaderSource(shader, script.trim())
|
||
|
gl.compileShader(shader)
|
||
|
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||
|
throw gl.getShaderInfoLog(shader)
|
||
|
}
|
||
|
return shader
|
||
|
}
|
||
|
|
||
|
// program
|
||
|
const program = gl.createProgram()
|
||
|
gl.attachShader(program, compileShader(gl.VERTEX_SHADER, `
|
||
|
#version 300 es
|
||
|
|
||
|
in vec2 a_position;
|
||
|
in float a_color;
|
||
|
out float v_color;
|
||
|
|
||
|
void main() {
|
||
|
gl_Position = vec4(a_position * vec2(1, -1), 0, 1);
|
||
|
v_color = a_color;
|
||
|
}`))
|
||
|
|
||
|
gl.attachShader(program, compileShader(gl.FRAGMENT_SHADER, `
|
||
|
#version 300 es
|
||
|
|
||
|
precision mediump float;
|
||
|
in float v_color;
|
||
|
out vec4 outColor;
|
||
|
|
||
|
vec4 unpackColor(float f) {
|
||
|
vec4 color;
|
||
|
color.r = floor(f / 65536.0);
|
||
|
color.g = floor((f - color.r * 65536.0) / 256.0);
|
||
|
color.b = floor(f - color.r * 65536.0 - color.g * 256.0);
|
||
|
color.a = 256.0;
|
||
|
return color / 256.0;
|
||
|
}
|
||
|
|
||
|
void main() {
|
||
|
outColor = unpackColor(v_color);
|
||
|
}`))
|
||
|
|
||
|
gl.linkProgram(program)
|
||
|
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
||
|
throw gl.getProgramInfoLog(program)
|
||
|
}
|
||
|
|
||
|
gl.useProgram(program)
|
||
|
|
||
|
// initialize state
|
||
|
loop((x, y) => {
|
||
|
const x1 = ((x + 1) - 50) / 50 - S
|
||
|
const y1 = ((y + 1) - 50) / 50 - S
|
||
|
const x2 = x1 + S
|
||
|
const y2 = y1 + S
|
||
|
const index = (x * 100 + y) * 12
|
||
|
vertexArray[index + 0x0] = x1
|
||
|
vertexArray[index + 0x1] = y1
|
||
|
vertexArray[index + 0x2] = x2
|
||
|
vertexArray[index + 0x3] = y1
|
||
|
vertexArray[index + 0x4] = x1
|
||
|
vertexArray[index + 0x5] = y2
|
||
|
vertexArray[index + 0x6] = x1
|
||
|
vertexArray[index + 0x7] = y2
|
||
|
vertexArray[index + 0x8] = x2
|
||
|
vertexArray[index + 0x9] = y1
|
||
|
vertexArray[index + 0xa] = x2
|
||
|
vertexArray[index + 0xb] = y2
|
||
|
})
|
||
|
|
||
|
const vertexBuffer = gl.createBuffer()
|
||
|
const a_position = gl.getAttribLocation(program, 'a_position')
|
||
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
|
||
|
gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 0, 0)
|
||
|
gl.enableVertexAttribArray(a_position)
|
||
|
gl.bufferData(gl.ARRAY_BUFFER, vertexArray, gl.STATIC_DRAW)
|
||
|
gl.drawArrays(gl.TRIANGLES, 0, 60000)
|
||
|
|
||
|
// color buffer
|
||
|
const colorBuffer = gl.createBuffer()
|
||
|
const a_color = gl.getAttribLocation(program, 'a_color')
|
||
|
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
|
||
|
gl.vertexAttribPointer(a_color, 1, gl.FLOAT, false, 0, 0)
|
||
|
gl.enableVertexAttribArray(a_color)
|
||
|
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
|
||
|
|
||
|
export const update = (turn) => {
|
||
|
loop((x, y) => applyState(x, y, turn))
|
||
|
gl.bufferData(gl.ARRAY_BUFFER, colorArray, gl.STATIC_DRAW)
|
||
|
gl.drawArrays(gl.TRIANGLES, 0, 60000)
|
||
|
}
|
||
|
|
||
|
export const reset = () => {
|
||
|
state.fill(0)
|
||
|
update(0)
|
||
|
}
|