c2
Version:
d3 component canvas
191 lines (171 loc) • 5.35 kB
JavaScript
const canvas = document.querySelector('canvas');
gl = canvas.getContext('webgl'),
vertex_shader = gl.createShader(gl.VERTEX_SHADER),
fragment_shader = gl.createShader(gl.FRAGMENT_SHADER),
shader_program = gl.createProgram(),
vbuffer = gl.createBuffer(),
cbuffer = gl.createBuffer(),
ibuffer = gl.createBuffer(),
dbuffer = gl.createBuffer(),
pMatrix = mat4.perspective(mat4.create(),45,window.innerWidth/window.innerHeight,0.1,10),
mvMatrix = mat4.scale(mat4.create(),mat4.create(),[1,1,0.01]),
model = new Float32Array([
// front
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// back
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
]),
colors = new Float32Array([
// front colors
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 1.0,
// back colors
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 1.0,
]),
indices = new Uint16Array( [
// front
0, 1, 2,
2, 3, 0,
// top
1, 5, 6,
6, 2, 1,
// back
7, 6, 5,
5, 4, 7,
// bottom
4, 0, 3,
3, 7, 4,
// left
4, 5, 1,
1, 0, 4,
// right
3, 2, 6,
6, 7, 3,
]),
itemSize = 3,
numItems = model.length / itemSize;
var locations = {},
data = new Float32Array([
]);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight,
mat4.translate(pMatrix,pMatrix,[0,0,-5]);
mat4.rotate(pMatrix,pMatrix,0.9,[1,0,0]);
gl.shaderSource(vertex_shader,`
attribute vec3 aVertexPosition;
attribute vec3 aData;
uniform mat4 uPMatrix;
varying float t;
void main () {
mat4 clone = mat4(uPMatrix);
clone[0][2] = clone[0][2] + aData.x;
clone[0][0] = clone[0][0] + aData.y;
clone[1][1] = clone[1][1] + aData.z;
gl_Position = clone*vec4(aVertexPosition,1.0);
t = aVertexPosition.y*aVertexPosition.z;
}
`);
gl.shaderSource(fragment_shader,`
#ifdef GL_ES
precision highp float;
#endif
varying float t;
void main () {
gl_FragColor=vec4(0,0,1.0,0.5);
//gl_FragColor = vec4(0,0,1.0-t,0.3);
}
`);
gl.compileShader(vertex_shader);
gl.compileShader(fragment_shader);
gl.attachShader(shader_program,vertex_shader);
gl.attachShader(shader_program,fragment_shader);
gl.linkProgram(shader_program);
if (!gl.getProgramParameter(shader_program,gl.LINK_STATUS)) {
console.error('unable to link shader');
}
locations = {
aVertexPosition : gl.getAttribLocation(shader_program,'aVertexPosition'),
aData : gl.getAttribLocation(shader_program,'aData'), //aData is vec3 and [posx,width,height]
uPMatrix : gl.getUniformLocation(shader_program,'uPMatrix')
};
gl.useProgram(shader_program);
gl.uniformMatrix4fv(locations.uPMatrix,false,pMatrix);
gl.bindBuffer(gl.ARRAY_BUFFER,vbuffer);
gl.bufferData(gl.ARRAY_BUFFER,model,gl.STATIC_DRAW);
gl.vertexAttribPointer(locations.aVertexPosition,3,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(locations.aVertexPosition);
gl.bindBuffer(gl.ARRAY_BUFFER,dbuffer);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1,0,2,1]),gl.STATIC_DRAW);
gl.vertexAttribPointer(locations.aData,3,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(locations.aData);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,ibuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW);
gl.enable(gl.BLEND);
gl.enable(gl.DEPTH_TEST);
gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);
gl.viewport(0,0,window.innerWidth,window.innerHeight);
class Model {
constructor () {
if (!this.constructor.vertices || !this.constructor.indices) {
throw "Invalid Model";
}
}
}
class ShaderProgram {
constructor ({vertex,fragment}) {
this.modelMap = {};
this.models = [];
this.vertices = [];
this.indices = [];
}
appendChild (modelInstance) {
const result = super.appendChild(modelInstance)
if (result) {
if (!this.modelMap[modelInstance.constructor]) {
this.modelMap[modelInstance.constructor] = 1;
this.models.push(modelInstance.constructor);
this.rebuild = true;
} else {
this.modelMap[modelInstance.constructor] ++;
}
}
}
removeChild (modelInstance) {
if (this.modelMap[modelInstance.constructor]) {
this.modelMap[modelInstance.constructor] = undefined;
const index = this.models.indexOf(modelInstance.constructor);
index !== -1 && this.models.splice(index,1);
this.rebuild = true;
}
return super.removeChild(modelInstance);
}
render () {
if (this.rebuild) {
this.rebuild = false;
}
}
createModel ({vertices,indices}) {
}
}
function IndexBuffer (gl,indices) {
this.buffer = gl.createBuffer();
this.current_indices = this.original_indices = indices;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,this.buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW);
}
IndexBuffer.prototype.add = function () {
}
function map_attribute_data (model) {
}
gl.drawElements(gl.TRIANGLES,36,gl.UNSIGNED_SHORT,0);