cringe-studios.com/arrayser/script.js
2024-03-08 19:00:58 +01:00

324 lines
10 KiB
JavaScript

"use strict"
var gl;
var program;
var initialClickPositionX = 0;
var initialClickPositionY = 0;
var isMouseDown = false;
var clickedGridBlockX = 0;
var clickedGridBlockY = 0;
var fieldElements;
var dispositionInformation = new Int32Array(3);
const blockSize = 64;
function main(evt){
window.removeEventListener(evt.type, setupWebGL, false);
setupControls();
setupWebGL();
}
function setupWebGL () {
if (!(gl = getRenderingContext()))
return;
// setup GLSL program
var source = document.querySelector("#vertex-shader").innerHTML;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader,source);
gl.compileShader(vertexShader);
source = document.querySelector("#fragment-shader").innerHTML;
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader,source);
gl.compileShader(fragmentShader);
program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.detachShader(program, vertexShader);
gl.detachShader(program, fragmentShader);
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
var linkErrLog = gl.getProgramInfoLog(program);
cleanup();
console.log("Shader program did not link successfully. "
+ "Error log: " + linkErrLog);
return;
}
//const vertexIdLoc = gl.getAttribLocation(program, 'vertexId');
const resolutionLoc = gl.getUniformLocation(program, 'resolution');
const fieldLayoutLoc = gl.getUniformLocation(program, 'fieldLayout');
const dispositionInformationLoc = gl.getUniformLocation(program, 'dispositionInformation');
// Make a buffer with just a count in it.
const numVerts = 4;
//const vertexIds = new Float32Array(numVerts);
//vertexIds.forEach((v, i) => {
// vertexIds[i] = i;
//});
fieldElements = new Float32Array(16);
fieldElements.forEach((v, i) => {
fieldElements[i] = i;
});
Shuffle(fieldElements);
dispositionInformation[0] = 1;
dispositionInformation[1] = 0;
dispositionInformation[2] = 0;
//const idBuffer = gl.createBuffer();
//gl.bindBuffer(gl.ARRAY_BUFFER, idBuffer);
//gl.bufferData(gl.ARRAY_BUFFER, vertexIds, gl.STATIC_DRAW);
// draw
function render(timeStamp) {
var canvas = document.getElementById("canvas");
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.useProgram(program);
//{
// // Turn on the attribute
// gl.enableVertexAttribArray(vertexIdLoc);
//
// // Bind the id buffer.
// gl.bindBuffer(gl.ARRAY_BUFFER, idBuffer);
//
// // Tell the attribute how to get data out of idBuffer (ARRAY_BUFFER)
// const size = 1; // 1 components per iteration
// const type = gl.FLOAT; // the data is 32bit floats
// const normalize = false; // don't normalize the data
// const stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
// const offset = 0; // start at the beginning of the buffer
// gl.vertexAttribPointer(vertexIdLoc, size, type, normalize, stride, offset);
//}
// tell the shader the resolution
gl.uniform2f(resolutionLoc, gl.canvas.width, gl.canvas.height);
gl.uniformMatrix4fv(fieldLayoutLoc, false, fieldElements);
gl.uniform3iv(dispositionInformationLoc, dispositionInformation);
gl.drawArrays(gl.TRIANGLE_FAN, 0, numVerts);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
return;
// gl.disable(gl.BLEND);
// gl.disable(gl.CULL_FACE);
// gl.disable(gl.DEPTH_TEST);
// gl.disable(gl.DITHER);
// gl.disable(gl.POLYGON_OFFSET_FILL);
// gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
// gl.disable(gl.SAMPLE_COVERAGE);
// gl.disable(gl.SCISSOR_TEST);
// gl.disable(gl.STENCIL_TEST);
cleanup();
}
var buffer;
function initializeAttributes() {
// gl.enableVertexAttribArray(0);
// buffer = gl.createBuffer();
// gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
}
function Shuffle(array2D) {
for (var i = 0; i < array2D.length; i++) {
var randomIdx1 = Math.floor(Math.random() * (i + 1));
var temp = array2D[i];
array2D[i] = array2D[randomIdx1];
array2D[randomIdx1] = temp;
}
return array2D
}
function iMod(x, N){
return (x % N + N) %N;
}
function setupControls(){
function onMouseMove(e) {
if(window.TouchEvent && e instanceof TouchEvent){
e = e.touches[0];
}
if(!isMouseDown) return;
const rect = canvas.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;
if(Math.abs(mouseX - initialClickPositionX) > Math.abs(mouseY - initialClickPositionY)){
dispositionInformation[0] = 1;
dispositionInformation[1] = clickedGridBlockY;
dispositionInformation[2] = mouseX - initialClickPositionX;
}else{
dispositionInformation[0] = 0;
dispositionInformation[1] = clickedGridBlockX;
dispositionInformation[2] = mouseY - initialClickPositionY;
}
// initialClickPositionX = mouseX;
// initialClickPositionY = mouseY;
}
function onMouseDown(e) {
if(window.TouchEvent && e instanceof TouchEvent){
e = e.touches[0];
}
const rect = canvas.getBoundingClientRect();
initialClickPositionX = e.clientX - rect.left;
initialClickPositionY = e.clientY - rect.top;
var xFragCoord = Math.trunc(initialClickPositionX - Math.trunc(rect.width / 2.0));
var yFragCoord = Math.trunc(initialClickPositionY - Math.trunc(rect.height / 2.0));
var xGridIndex = Math.trunc(xFragCoord / 64);
xGridIndex = (xFragCoord) < 0 ? xGridIndex - 1 : xGridIndex;
var yGridIndex = Math.trunc(yFragCoord / 64);
yGridIndex = (yFragCoord) < 0 ? yGridIndex - 1 : yGridIndex;
clickedGridBlockX = iMod(xGridIndex, 4);
clickedGridBlockY = iMod(yGridIndex, 4);
isMouseDown = true;
}
function onMouseUp(e) {
if(window.TouchEvent && e instanceof TouchEvent){
e = e.touches[0];
}
function vecRot(arr, rotateAmount, length){
// Storing rotated version of array
var temp = new Int32Array(length);
// Keeping track of the current index
// of temp[]
var k = 0;
// Storing the n - d elements of
// array arr[] to the front of temp[]
for (var i = rotateAmount; i < length; i++) {
temp[k] = arr[i];
k++;
}
// Storing the first d elements of array arr[]
// into temp
for (var i = 0; i < rotateAmount; i++) {
temp[k] = arr[i];
k++;
}
// Copying the elements of temp[] in arr[]
// to get the final rotated array
for (var i = 0; i < length; i++) {
arr[i] = temp[i];
}
}
function matRot(matrix, columnOrRow, rowIndex, rotateAmount){
// Storing rotated version of array
var temp = new Int32Array(4);
if(columnOrRow != 0){
for(var i = 0; i < 4; i++){
temp[i] = matrix[rowIndex * 4 + i];
}
vecRot(temp, rotateAmount, 4);
for(var i = 0; i < 4; i++){
matrix[rowIndex * 4 + i] = temp[i];
}
}else{
for(var i = 0; i < 4; i++){
temp[i] = matrix[i * 4 + rowIndex];
}
vecRot(temp, rotateAmount, 4);
for(var i = 0; i < 4; i++){
matrix[i * 4 + rowIndex] = temp[i];
}
}
}
isMouseDown = false;
var rotateAmount = Math.round(-dispositionInformation[2] / 64);
rotateAmount = iMod(rotateAmount, 4);
matRot(fieldElements, dispositionInformation[0], dispositionInformation[1], rotateAmount);
dispositionInformation[0] = 0;
dispositionInformation[1] = 0;
dispositionInformation[2] = 0;
}
canvas.addEventListener('mousemove', onMouseMove);
canvas.addEventListener('mousedown', onMouseDown);
canvas.addEventListener('mouseup', onMouseUp);
canvas.addEventListener('touchmove', onMouseMove);
canvas.addEventListener('touchstart', onMouseDown);
canvas.addEventListener('touchend', onMouseUp);
}
function cleanup() {
gl.useProgram(null);
if (buffer)
gl.deleteBuffer(buffer);
if (program)
gl.deleteProgram(program);
}
function getRenderingContext() {
var canvas = document.getElementById("canvas");
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
var gl = canvas.getContext("webgl2")
if(gl == null){
gl = canvas.getContext("experimental-webgl");
}
if (gl == null) {
return null;
}
//gl.viewport(0, 0);
//gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
//gl.clipControl(gl.UPPER_LEFT, gl.ZERO_TO_ONE)
return gl;
}