diff --git a/README.md b/README.md
index d72ad87..af87cb5 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ https://art.mekanoe.com
## Artworks
- [./001-platform-provenance](https://art.mekanoe.com/001-platform-provenance)
-- [./002-webgpu-instead](https://art.mekanoe.com/002-webgpu-instead)
+- [./002-webgl-engine](https://art.mekanoe.com/002-webgl-engine)
## Development
diff --git a/bun.lockb b/bun.lockb
index d673135..dfa1ae7 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/hack/build.ts b/hack/build.ts
index b34486d..309f048 100644
--- a/hack/build.ts
+++ b/hack/build.ts
@@ -13,19 +13,28 @@ const works = globSync("src/*/main.ts");
console.log(chalk.green`>> Building ...`);
console.log(chalk.yellow(` Found ${works.length} works.`));
+console.log(chalk.yellow(` Running Bun.build()`));
-await Bun.build({
+const results = await Bun.build({
entrypoints: works,
outdir: "html",
splitting: true,
loader: {
".glsl": "text",
".wgsl": "text",
+ ".vert": "text",
+ ".frag": "text",
},
- minify: true,
+ minify: process.env.MINIFY === "false" ? false : true,
plugins: [glslPlugin],
});
+if (!results.success) {
+ console.error(chalk.red("XX Bun.build() Failed."));
+ console.error(chalk.red(JSON.stringify(results.logs, null, 2)));
+ process.exit(1);
+}
+
console.log(chalk.green`>> Generating HTML and Markdown ...`);
await generate(works);
diff --git a/hack/convert-meshes.ts b/hack/convert-meshes.ts
index 17af076..69c90c6 100644
--- a/hack/convert-meshes.ts
+++ b/hack/convert-meshes.ts
@@ -9,6 +9,16 @@ export const convertMeshes = async () => {
const [header, body] = ply.split("end_header");
const colorSize = header.includes("red") ? 4 : 0;
+ const headerLines = header.split("\n");
+ const vertexCount = Number(
+ headerLines
+ .find((header) => header.startsWith("element vertex"))
+ ?.replace("element vertex ", "")
+ );
+
+ if (!vertexCount) {
+ throw new Error("couldn't get vertex count...");
+ }
const values: number[] = [];
@@ -43,13 +53,16 @@ export const convertMeshes = async () => {
import { Mesh } from "../renderer/mesh";
// prettier-ignore
-const mesh = new Float32Array(${JSON.stringify(values, null, 2)});
+const mesh = new Float32Array(${JSON.stringify(values)});
export default new Mesh({
mesh,
- positionSize: 4 * 4,
- colorSize: ${colorSize} * 4,
- uvSize: 2 * 4,
+ positionSize: 4,
+ colorSize: ${colorSize},
+ uvSize: 2,
+ vertexCount: ${vertexCount},
+ stride: ${4 + colorSize + 2},
+ name: ${JSON.stringify(file)}
});
`;
diff --git a/hack/glsl-plugin.ts b/hack/glsl-plugin.ts
index 133ff84..8e0ed76 100644
--- a/hack/glsl-plugin.ts
+++ b/hack/glsl-plugin.ts
@@ -1,5 +1,5 @@
import glsl from "esbuild-plugin-glsl";
export default glsl({
- minify: true,
+ minify: process.env.MINIFY === "false" ? false : true,
});
diff --git a/hack/templates/work.html.txt b/hack/templates/work.html.txt
index 876b6e9..19ee715 100644
--- a/hack/templates/work.html.txt
+++ b/hack/templates/work.html.txt
@@ -22,10 +22,4 @@
XX.X FPS (XX.X ms)
-
diff --git a/html/001-platform-provenance/index.html b/html/001-platform-provenance/index.html
index 3887477..a2be8f8 100644
--- a/html/001-platform-provenance/index.html
+++ b/html/001-platform-provenance/index.html
@@ -22,10 +22,4 @@
XX.X FPS (XX.X ms)
-
diff --git a/html/001-platform-provenance/main.js b/html/001-platform-provenance/main.js
index bef0278..77d392a 100644
--- a/html/001-platform-provenance/main.js
+++ b/html/001-platform-provenance/main.js
@@ -1 +1 @@
-import{b as Y} from"../chunk-818093f0cbbefec3.js";class k{constructor(v){this.gl=v.gl,this.app=v,this.program=this.gl.createProgram()}attach(v,R){console.log("attaching shader",{type:v,source:R});const _=this.gl.createShader(v);if(this.gl.shaderSource(_,R),this.gl.compileShader(_),!this.gl.getShaderParameter(_,this.gl.COMPILE_STATUS))throw new Error("An error occurred compiling the shaders: "+this.gl.getShaderInfoLog(_));return this.gl.attachShader(this.program,_),this}link(){if(this.gl.linkProgram(this.program),!this.gl.getProgramParameter(this.program,this.gl.LINK_STATUS))throw new Error("Unable to initialize the shader program: "+this.gl.getProgramInfoLog(this.program));return console.log("shader linked"),this}location(v){if(v[0]==="a")return this.gl.getAttribLocation(this.program,v);else if(v[0]==="u")return this.gl.getUniformLocation(this.program,v)}updateTime(){const v=this.app.now(),R=Math.sin(v),_=Math.cos(v);this.gl.uniform1f(this.location("uTime"),v),this.gl.uniform1f(this.location("uSinTime"),R),this.gl.uniform1f(this.location("uCosTime"),_)}activate(v,R){this.gl.useProgram(this.program),this.gl.uniformMatrix4fv(this.location("uProjectionMatrix"),!1,v),this.gl.uniformMatrix4fv(this.location("uModelViewMatrix"),!1,R),this.updateTime()}}class q{constructor(v){this.gl=v.gl,this.app=v,this.vertexPositions=new Float32Array([]),this.positionBuffer=null,this.textureBuffer=null}initBuffer(v,R=this.gl.STATIC_DRAW){const _=this.gl.createBuffer();return this.gl.bindBuffer(this.gl.ARRAY_BUFFER,_),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(v),R),_}attachShader(v){return this.shader=v,this.vertexPosition=v.location("aVertexPosition"),this.textureCoord=v.location("aTextureCoord"),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.gl.vertexAttribPointer(this.vertexPosition,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.vertexPosition),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.textureBuffer),this.gl.vertexAttribPointer(this.textureCoord,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.textureCoord),this}draw2D(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.shader.activate(this.app.projectionMatrix,this.app.modelViewMatrix),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,this.vertexPositions.length/2)}draw3D(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.shader.activate(this.app.projectionMatrix,this.app.modelViewMatrix),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,this.vertexPositions.length/3)}}class C extends q{constructor(v){super(v);this.vertexPositions=new Float32Array([-1,-1,1,-1,-1,1,1,1]),this.positionBuffer=this.initBuffer(this.vertexPositions),this.textureBuffer=this.initBuffer(new Float32Array([0,0,1,0,0,1,1,1])),this.app.onUpdate(()=>this.draw2D())}}class K{constructor(v={fov:45}){if(this._now=0,this.registry={onStart:[],onUpdate:[],onBeforeUpdate:[],onAfterUpdate:[]},this.config=v,this.canvas=document.querySelector("canvas"),this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight,this.gl=this.canvas.getContext("webgl2"),this.gl===null)throw document.querySelector("main").innerHTML="your browser didn't let me set up webgl
",new Error("Unable to initialize WebGL. Your browser or machine may not support it.");const R=this.gl,_=this.config.fov*Math.PI/180,H=R.canvas.clientWidth/R.canvas.clientHeight,J=0.1,L=100,X=glMatrix.mat4.create();glMatrix.mat4.perspective(X,_,H,J,L);const I=glMatrix.mat4.create();glMatrix.mat4.translate(I,I,[-0,0,-6]),this.projectionMatrix=X,this.modelViewMatrix=I,this.clear(),this.onBeforeUpdate(()=>this.clear()),this.telemetry=new Y(this)}clear(){const v=this.gl;v.clearColor(0,0,0,1),v.clearDepth(1),v.enable(v.DEPTH_TEST),v.depthFunc(v.LEQUAL),v.clear(v.COLOR_BUFFER_BIT|v.DEPTH_BUFFER_BIT)}onStart(v){this.registry.onStart.push(v)}onUpdate(v){this.registry.onUpdate.push(v)}onBeforeUpdate(v){this.registry.onBeforeUpdate.push(v)}onAfterUpdate(v){this.registry.onAfterUpdate.push(v)}start(){this.registry.onStart.forEach((v)=>v(this))}update(){this.registry.onBeforeUpdate.forEach((v)=>v(this)),this.registry.onUpdate.forEach((v)=>v(this)),this.registry.onAfterUpdate.forEach((v)=>v(this))}oneShot(){requestAnimationFrame((v)=>{this._now=v,this.start(),this.update()})}loop(){const v=(R)=>{this._now=R,this.update(),requestAnimationFrame(v)};requestAnimationFrame(v)}now(){return this._now}}var B="precision highp float;uniform float uTime;uniform float uSinTime;uniform float uCosTime;varying highp vec2 vTextureCoord;vec3 rgb2hsv(vec3 c){vec4 K=vec4(0.0,-1.0/3.0,2.0/3.0,-1.0);vec4 p=mix(vec4(c.bg,K.wz),vec4(c.gb,K.xy),step(c.b,c.g));vec4 q=mix(vec4(p.xyw,c.r),vec4(c.r,p.yzx),step(p.x,c.r));float d=q.x-min(q.w,q.y);float e=1.0e-10;return vec3(abs(q.z+(q.w-q.y)/(6.0*d+e)),d/(q.x+e),q.x);}vec3 hsv2rgb(vec3 c){vec4 K=vec4(1.0,2.0/3.0,1.0/3.0,3.0);vec3 p=abs(fract(c.xxx+K.xyz)*6.0-K.www);return c.z*mix(K.xxx,clamp(p-K.xxx,0.0,1.0),c.y);}void main(){float zComponent=uSinTime*0.001*0.5+0.5;vec3 hsv=rgb2hsv(vec3(vTextureCoord,zComponent));hsv.x+=uTime*0.0001;hsv.y=1.0;hsv.z=1.0;vec3 rgb=hsv2rgb(hsv);gl_FragColor=vec4(rgb,1.0);gl_FragColor=clamp(gl_FragColor,0.0,1.0);}";var E="attribute vec4 aVertexPosition;attribute vec2 aTextureCoord;uniform mat4 uModelViewMatrix;uniform mat4 uProjectionMatrix;varying highp vec2 vTextureCoord;void main(){gl_Position=uProjectionMatrix*uModelViewMatrix*aVertexPosition;vTextureCoord=aTextureCoord;}";var D=new K({fov:20}),G=D.gl,Q=new k(D).attach(G.VERTEX_SHADER,E).attach(G.FRAGMENT_SHADER,B).link(),U=new C(D);U.attachShader(Q);D.loop();
+import{b as X,c as R} from"../chunk-1da54319833c650d.js";class I{constructor(v){this.gl=v.gl,this.app=v,this.program=this.gl.createProgram()}attach(v,_){console.log("attaching shader",{type:v,source:_});const D=this.gl.createShader(v);if(this.gl.shaderSource(D,_),this.gl.compileShader(D),!this.gl.getShaderParameter(D,this.gl.COMPILE_STATUS))throw new Error("An error occurred compiling the shaders: "+this.gl.getShaderInfoLog(D));return this.gl.attachShader(this.program,D),this}link(){if(this.gl.linkProgram(this.program),!this.gl.getProgramParameter(this.program,this.gl.LINK_STATUS))throw new Error("Unable to initialize the shader program: "+this.gl.getProgramInfoLog(this.program));return console.log("shader linked"),this}location(v){if(v[0]==="a")return this.gl.getAttribLocation(this.program,v);else if(v[0]==="u")return this.gl.getUniformLocation(this.program,v)}updateTime(){const v=this.app.now(),_=Math.sin(v),D=Math.cos(v);this.gl.uniform1f(this.location("uTime"),v),this.gl.uniform1f(this.location("uSinTime"),_),this.gl.uniform1f(this.location("uCosTime"),D)}activate(v,_){this.gl.useProgram(this.program),this.gl.uniformMatrix4fv(this.location("uProjectionMatrix"),!1,v),this.gl.uniformMatrix4fv(this.location("uModelViewMatrix"),!1,_),this.updateTime()}}class K{constructor(v){this.gl=v.gl,this.app=v,this.vertexPositions=new Float32Array([]),this.positionBuffer=null,this.textureBuffer=null}initBuffer(v,_=this.gl.STATIC_DRAW){const D=this.gl.createBuffer();return this.gl.bindBuffer(this.gl.ARRAY_BUFFER,D),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(v),_),D}attachShader(v){return this.shader=v,this.vertexPosition=v.location("aVertexPosition"),this.textureCoord=v.location("aTextureCoord"),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.gl.vertexAttribPointer(this.vertexPosition,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.vertexPosition),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.textureBuffer),this.gl.vertexAttribPointer(this.textureCoord,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.textureCoord),this}draw2D(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.shader.activate(this.app.projectionMatrix,this.app.modelViewMatrix),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,this.vertexPositions.length/2)}draw3D(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.shader.activate(this.app.projectionMatrix,this.app.modelViewMatrix),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,this.vertexPositions.length/3)}}class L extends K{constructor(v){super(v);this.vertexPositions=new Float32Array([-1,-1,1,-1,-1,1,1,1]),this.positionBuffer=this.initBuffer(this.vertexPositions),this.textureBuffer=this.initBuffer(new Float32Array([0,0,1,0,0,1,1,1])),this.app.onUpdate(()=>this.draw2D())}}class P{constructor(v={fov:45}){if(this._now=0,this.registry={onStart:[],onUpdate:[],onBeforeUpdate:[],onAfterUpdate:[]},this.config=v,this.canvas=document.querySelector("canvas"),this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight,this.gl=this.canvas.getContext("webgl2"),this.gl===null)throw document.querySelector("main").innerHTML="your browser didn't let me set up webgl
",new Error("Unable to initialize WebGL. Your browser or machine may not support it.");const _=this.gl,D=this.config.fov*Math.PI/180,E=_.canvas.clientWidth/_.canvas.clientHeight,G=0.1,H=100,U=R.create();R.perspective(U,D,E,G,H);const C=R.create();R.translate(C,C,[-0,0,-6]),this.projectionMatrix=U,this.modelViewMatrix=C,this.clear(),this.onBeforeUpdate(()=>this.clear()),this.telemetry=new X(this)}clear(){const v=this.gl;v.clearColor(0,0,0,1),v.clearDepth(1),v.enable(v.DEPTH_TEST),v.depthFunc(v.LEQUAL),v.clear(v.COLOR_BUFFER_BIT|v.DEPTH_BUFFER_BIT)}onStart(v){this.registry.onStart.push(v)}onUpdate(v){this.registry.onUpdate.push(v)}onBeforeUpdate(v){this.registry.onBeforeUpdate.push(v)}onAfterUpdate(v){this.registry.onAfterUpdate.push(v)}start(){this.registry.onStart.forEach((v)=>v(this))}update(){this.registry.onBeforeUpdate.forEach((v)=>v(this)),this.registry.onUpdate.forEach((v)=>v(this)),this.registry.onAfterUpdate.forEach((v)=>v(this))}oneShot(){requestAnimationFrame((v)=>{this._now=v,this.start(),this.update()})}loop(){const v=(_)=>{this._now=_,this.update(),requestAnimationFrame(v)};requestAnimationFrame(v)}now(){return this._now}}var Y="precision highp float;uniform float uTime;uniform float uSinTime;uniform float uCosTime;varying highp vec2 vTextureCoord;vec3 rgb2hsv(vec3 c){vec4 K=vec4(0.0,-1.0/3.0,2.0/3.0,-1.0);vec4 p=mix(vec4(c.bg,K.wz),vec4(c.gb,K.xy),step(c.b,c.g));vec4 q=mix(vec4(p.xyw,c.r),vec4(c.r,p.yzx),step(p.x,c.r));float d=q.x-min(q.w,q.y);float e=1.0e-10;return vec3(abs(q.z+(q.w-q.y)/(6.0*d+e)),d/(q.x+e),q.x);}vec3 hsv2rgb(vec3 c){vec4 K=vec4(1.0,2.0/3.0,1.0/3.0,3.0);vec3 p=abs(fract(c.xxx+K.xyz)*6.0-K.www);return c.z*mix(K.xxx,clamp(p-K.xxx,0.0,1.0),c.y);}void main(){float zComponent=uSinTime*0.001*0.5+0.5;vec3 hsv=rgb2hsv(vec3(vTextureCoord,zComponent));hsv.x+=uTime*0.0001;hsv.y=1.0;hsv.z=1.0;vec3 rgb=hsv2rgb(hsv);gl_FragColor=vec4(rgb,1.0);gl_FragColor=clamp(gl_FragColor,0.0,1.0);}";var q="attribute vec4 aVertexPosition;attribute vec2 aTextureCoord;uniform mat4 uModelViewMatrix;uniform mat4 uProjectionMatrix;varying highp vec2 vTextureCoord;void main(){gl_Position=uProjectionMatrix*uModelViewMatrix*aVertexPosition;vTextureCoord=aTextureCoord;}";var k=new P({fov:20}),B=k.gl,W=new I(k).attach(B.VERTEX_SHADER,q).attach(B.FRAGMENT_SHADER,Y).link(),Z=new L(k);Z.attachShader(W);k.loop();
diff --git a/html/002-webgpu-instead/index.html b/html/002-webgl-engine/index.html
similarity index 53%
rename from html/002-webgpu-instead/index.html
rename to html/002-webgl-engine/index.html
index da5bf5d..8c1c287 100644
--- a/html/002-webgpu-instead/index.html
+++ b/html/002-webgl-engine/index.html
@@ -1,6 +1,6 @@
-com.mekanoe.art // 002-webgpu-instead
+com.mekanoe.art // 002-webgl-engine