mirror of
https://github.com/alibaba/GCanvas.git
synced 2025-12-08 17:36:42 +00:00
124 lines
4.7 KiB
JavaScript
124 lines
4.7 KiB
JavaScript
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);
|
|
}); |