const { createCanvas, Image } = require('../../export') const fs = require('fs') const path = require('path'); const out = fs.createWriteStream(path.join(__dirname, "..","..")+ '/rectangle.png'); const canvas = createCanvas(1200, 700); var gl = canvas.getContext("webgl"); var vertexSource = ` attribute vec2 a_position; uniform vec2 u_resolution; void main() { // convert the rectangle from pixels to 0.0 to 1.0 vec2 zeroToOne = a_position / u_resolution; // convert from 0->1 to 0->2 vec2 zeroToTwo = zeroToOne * 2.0; // convert from 0->2 to -1->+1 (clipspace) vec2 clipSpace = zeroToTwo - 1.0; gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); } `; var fragmentSource = ` precision mediump float; uniform vec4 u_color; void main() { gl_FragColor = u_color; } `; // setup program var vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, vertexSource); gl.compileShader(vertexShader); if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { console.log("failed to load shader", " ", gl.getShaderInfoLog(vertexShader)); } var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, fragmentSource); gl.compileShader(fragmentShader); if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { console.log("failed to load shader", " ", gl.getShaderInfoLog(fragmentShader)); } var program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.log("linker failed", " ", gl.getProgramInfoLog(program)); } // look up where the vertex data needs to go. var positionAttributeLocation = gl.getAttribLocation(program, "a_position"); // look up uniform locations var resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution"); var colorUniformLocation = gl.getUniformLocation(program, "u_color"); // Create a buffer to put three 2d clip space points in var positionBuffer = gl.createBuffer(); // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer) gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // Tell WebGL how to convert from clip space to pixels gl.viewport(0, 0, canvas.width, canvas.height); // Clear the canvas gl.clearColor(0, 0, 0, 0); gl.clear(gl.COLOR_BUFFER_BIT); // Tell it to use our program (pair of shaders) gl.useProgram(program); // Turn on the attribute gl.enableVertexAttribArray(positionAttributeLocation); // Bind the position buffer. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER) var size = 2; // 2 components per iteration var type = gl.FLOAT; // the data is 32bit floats var normalize = false; // don't normalize the data var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position var offset = 0; // start at the beginning of the buffer gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset) // set the resolution gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height); // draw 50 random rectangles in random colors for (var ii = 0; ii < 50; ++ii) { // Setup a random rectangle // This will write to positionBuffer because // its the last thing we bound on the ARRAY_BUFFER // bind point // setRectangle(gl, randomInt(300), randomInt(300), randomInt(300), randomInt(300)); setRectangle(gl, ii%10*100+10, ii/10*100+10, 100, 100); // Set a random color. // gl.uniform4f(colorUniformLocation, Math.random(), Math.random(), Math.random(), 1); gl.uniform4f(colorUniformLocation, (ii/10)*0.1+(ii%10)*0.01, (ii/10)*0.1+(ii%10)*0.2, (ii%10)*0.1, 1); // Draw the rectangle. var primitiveType = gl.TRIANGLES; var offset = 0; var count = 6; gl.drawArrays(primitiveType, offset, count); } // Returns a random integer from 0 to range - 1. function randomInt(range) { return Math.floor(Math.random() * range); } // Fill the buffer with the values that define a rectangle. function setRectangle(gl, x, y, width, height) { var x1 = x; var x2 = x + width; var y1 = y; var y2 = y + height; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2, ]), gl.STATIC_DRAW); } var stream = canvas.createPNGStream(); stream.on('data', function (chunk) { out.write(chunk); });