import { createWindow, getProcAddress, gl, } from "./deps.ts"; export {mainloop} from "./deps.ts"; const window = createWindow({ title: "Faux", width: 1024, height: 1024, resizable: false, glVersion: [3, 2], gles: true, }); gl.load(getProcAddress); function loadShader(type: number, src: string) { const shader = gl.CreateShader(type); gl.ShaderSource( shader, 1, new Uint8Array( new BigUint64Array([ BigInt( Deno.UnsafePointer.value( Deno.UnsafePointer.of(new TextEncoder().encode(src)), ), ), ]).buffer, ), new Int32Array([src.length]), ); gl.CompileShader(shader); const status = new Int32Array(1); gl.GetShaderiv(shader, gl.COMPILE_STATUS, status); if (status[0] === gl.FALSE) { const logLength = new Int32Array(1); gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, logLength); const log = new Uint8Array(logLength[0]); gl.GetShaderInfoLog(shader, logLength[0], logLength, log); console.log(new TextDecoder().decode(log)); gl.DeleteShader(shader); return 0; } return shader; } const vShaderSrc = ` attribute vec4 vPosition; attribute vec4 vCol; varying vec4 color; void main() { gl_Position = vPosition; color = vCol; } `; const fShaderSrc = ` precision mediump float; varying vec4 color; void main() { gl_FragColor = color; } `; const vShader = loadShader(gl.VERTEX_SHADER, vShaderSrc); const fShader = loadShader(gl.FRAGMENT_SHADER, fShaderSrc); const program = gl.CreateProgram(); gl.AttachShader(program, vShader); gl.AttachShader(program, fShader); gl.BindAttribLocation(program, 0, new TextEncoder().encode("vPosition\0")); gl.BindAttribLocation(program, 1, new TextEncoder().encode("vCol\0")); gl.LinkProgram(program); const status = new Int32Array(1); gl.GetProgramiv(program, gl.LINK_STATUS, status); if (status[0] === gl.FALSE) { const logLength = new Int32Array(1); gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, logLength); const log = new Uint8Array(logLength[0]); gl.GetProgramInfoLog(program, logLength[0], logLength, log); console.log(new TextDecoder().decode(log)); gl.DeleteProgram(program); Deno.exit(1); } gl.ClearColor(0.0, 0.0, 0.0, 1.0); addEventListener("resize", (event) => { gl.Viewport(0, 0, event.width, event.height); }); const pixelsPerRow = 128; const top = 1; const left = -1; const cell = 2/pixelsPerRow; const px = (x: number, y: number) => { // deno-fmt-ignore return [ left + x*cell, top - y*cell, 0, left + (x+1)*cell, top - y*cell, 0, left + x*cell, top - (y+1)*cell, 0, left + (x+1)*cell, top - y*cell, 0, left + x*cell, top - (y+1)*cell, 0, left + (x+1)*cell, top - (y+1)*cell, 0, ]; } const palette: Array<[number, number, number, number]> = [ [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 1], [1, 0, 0, 1], [1, 1, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1], ]; const paletteX6 = palette.map(rgba => [...rgba, ...rgba, ...rgba, ...rgba, ...rgba, ...rgba]); const c = (n: number) => { return paletteX6[n]; } const allPixelTriangles = new Float32Array( Array(pixelsPerRow*pixelsPerRow).fill(null).flatMap((_, i) => px(i%pixelsPerRow,Math.floor(i/pixelsPerRow))) ) const allPixelColors = new Float32Array( Array(pixelsPerRow*pixelsPerRow).fill(null).flatMap(() => c(1)) ) export const setPixelColor = (x: number, y: number, color: number) => { if (x < 0 || y < 0 || x > 127 || y > 127) { return; } if (color !== 0) { const col = c(color); allPixelColors.set(col, 4*6*(128*y+x)); } } export const setPixelsInRect = (x: number, y: number, w: number, pixels: Array) => { for (let i = 0; i < pixels.length; i++) { setPixelColor(x+i%w, y+Math.floor(i/w), pixels[i]); } } export const clearScreen = () => { allPixelColors.fill(0); } export const frame = () => { gl.Clear(gl.COLOR_BUFFER_BIT); gl.UseProgram(program); gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, allPixelTriangles); gl.VertexAttribPointer(1, 4, gl.FLOAT, gl.FALSE, 0, allPixelColors); gl.EnableVertexAttribArray(0); gl.EnableVertexAttribArray(1); gl.DrawArrays(gl.TRIANGLES, 0, 6*pixelsPerRow*pixelsPerRow); window.swapBuffers(); }