nidza
Version:
Nidza.js is ultimate canvas2d+3d solution. In context of 3d graphics it is used for GLSL manipulation. Objective is low CPU usage price.
232 lines (195 loc) • 7.36 kB
JavaScript
import {BaseShader} from './base-shader-component.js';
import { Osc } from "./operations.js";
export class ShaderComponent extends BaseShader {
constructor( arg ) {
super();
this.gl = arg.gl;
console.log('Arg -> ', arg);
// Just alias
this.reloadBuffers = this.initBuffers;
// params
this.rotationX = new Osc(0, 360, 0.1, 'oscMin');
this.rotationX.setDelay(5)
this.rotationY = new Osc(0, 360, 0.1, 'oscMin');
this.rotationY.setDelay(5)
this.rotationZ = new Osc(0, 360, 0.1, 'oscMin');
this.rotationZ.setDelay(5)
this.rotationX.regimeType = "CONST";
this.rotationZ.regimeType = "CONST";
this.rotationY.regimeType = "CONST";
this.rotator = {
x: () => this.rotationX.getValue(),
y: () => this.rotationY.getValue(),
z: () => this.rotationZ.getValue()
};
this.background = [0.5, 0.0, 0.0, 1.0];
this.vertexCount = 4; // cube default
this.position = [-0.0, 0.0, -2.0];
this.geometry = [
1.0, 1.0,
-1.0, 1.0,
1.0, -1.0,
-1.0, -1.0,
];
this.colors = [
1.0, 1.0, 1.0, 1.0, // white
1.0, 0.0, 0.0, 1.0, // red
0.0, 1.0, 0.0, 1.0, // green
0.0, 0.0, 1.0, 1.0, // blue
];
const shaderProgram = this.initShaderProgram(this.gl, this.initDefaultVSShader(), this.initDefaultFSShader());
this.programInfo = {
program: shaderProgram,
attribLocations: {
vertexPosition: this.gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
vertexColor: this.gl.getAttribLocation(shaderProgram, 'aVertexColor'),
},
uniformLocations: {
projectionMatrix: this.gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
modelViewMatrix: this.gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),
},
};
this.buffers = this.initBuffers(this.gl);
this.draw();
console.log('ShaderComponent init default shader with single call draw.');
}
// move it to common latter
degToRad(degrees) {
return degrees * Math.PI / 180;
}
reload() {
this.buffers = this.reloadBuffers(this.gl);
this.draw();
}
initDefaultFSShader() {
const fsSource = `
varying lowp vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
`;
return fsSource;
}
initDefaultVSShader() {
const vsSource = `
attribute vec4 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
varying lowp vec4 vColor;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
vColor = aVertexColor;
}
`;
return vsSource;
}
initBuffers(gl) {
const positionBuffer = gl.createBuffer();
// Select the positionBuffer as the one to apply buffer
// operations to from here out.
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Now create an array of positions/geometry for the square.
// geometry
gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array(this.geometry),
gl.STATIC_DRAW);
// Colors
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.colors), gl.STATIC_DRAW);
return {
position: positionBuffer,
color: colorBuffer,
}
}
draw() {
this.gl.clearColor(this.background[0], this.background[1], this.background[2], this.background[3]);
// Clear to black, fully opaque
this.gl.clearDepth(1.0); // Clear everything
this.gl.enable( this.gl.DEPTH_TEST ); // Enable depth testing
this.gl.depthFunc( this.gl.LEQUAL ); // Near things obscure far things
// Clear the canvas before we start drawing on it.
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
// Create a perspective matrix, a special matrix that is
// used to simulate the distortion of perspective in a camera.
// Our field of view is 45 degrees, with a width/height
// ratio that matches the display size of the canvas
// and we only want to see objects between 0.1 units
// and 100 units away from the camera.
const fieldOfView = 45 * Math.PI / 180; // in radians
const aspect = this.gl.canvas.clientWidth / this.gl.canvas.clientHeight;
const zNear = 0.1;
const zFar = 100.0;
const projectionMatrix = mat4.create();
// note: glmatrix.js always has the first argument
// as the destination to receive the result.
mat4.perspective(projectionMatrix,
fieldOfView,
aspect,
zNear,
zFar);
// Set the drawing position to the "identity" point, which is
// the center of the scene.
const modelViewMatrix = mat4.create();
// Now move the drawing position a bit to where we want to
// start drawing the square.
mat4.translate(modelViewMatrix, // destination matrix
modelViewMatrix, // matrix to translate
this.position ); // amount to translate
mat4.rotate(modelViewMatrix, modelViewMatrix, this.degToRad(this.rotator.x()), [1,0,0]);
mat4.rotate(modelViewMatrix, modelViewMatrix, this.degToRad(this.rotator.y()), [0,1,0]);
mat4.rotate(modelViewMatrix, modelViewMatrix, this.degToRad(this.rotator.z()), [0,0,1]);
// Tell WebGL how to pull out the positions/geometry from the position
// buffer into the vertexPosition attribute.
{
const numComponents = 2;
const type = this.gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.position);
this.gl.vertexAttribPointer(
this.programInfo.attribLocations.vertexPosition,
numComponents,
type,
normalize,
stride,
offset);
this.gl.enableVertexAttribArray(this.programInfo.attribLocations.vertexPosition);
}
// Tell WebGL how to pull out the colors from the color buffer
// into the vertexColor attribute.
{
const numComponents = 4;
const type = this.gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.color);
this.gl.vertexAttribPointer(
this.programInfo.attribLocations.vertexColor,
numComponents,
type,
normalize,
stride,
offset);
this.gl.enableVertexAttribArray(this.programInfo.attribLocations.vertexColor);
}
// Tell WebGL to use our program when drawing
this.gl.useProgram(this.programInfo.program);
// Set the shader uniforms
this.gl.uniformMatrix4fv(
this.programInfo.uniformLocations.projectionMatrix,
false,
projectionMatrix );
this.gl.uniformMatrix4fv(
this.programInfo.uniformLocations.modelViewMatrix,
false,
modelViewMatrix );
{
const offset = 0;
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, offset, this.geometry.length / 2);
}
}
}