003 fucking RENDERS models YAAAAAAAAA
This commit is contained in:
parent
28faa03ac6
commit
23d7810ab6
30 changed files with 16955 additions and 221 deletions
27
README.md
27
README.md
|
@ -24,19 +24,24 @@ https://art.mekanoe.com
|
|||
|
||||
### Infrastructure
|
||||
|
||||
- The "generator" does
|
||||
- **Output generation**
|
||||
|
||||
- Generates a work list from .js files within `html`
|
||||
- Creates this README.md file
|
||||
- Creates the index.html file
|
||||
- Creates individual HTML files for each work
|
||||
- Bun renders TypeScript and GLSL to html/
|
||||
- src/public/ is copied to html/
|
||||
- This doubles as an "archival" system to preserve scuffedness
|
||||
- .ply files are converted to JS typed arrays and Mesh objects
|
||||
- .html files (and README.md) are generated from rendered TypeScript main.ts files.
|
||||
|
||||
- The platform supplies
|
||||
- Shader types
|
||||
- Primitive objects
|
||||
- A canvas to draw on
|
||||
- WebGL hooks
|
||||
- Helpers, etc
|
||||
- **Platform**
|
||||
|
||||
- WebGLApp provides render loop, canvas, and other stuff
|
||||
- Behavior provides automatic registration of WebGLApp events (like Unity MonoBehaviors)
|
||||
- Shader provides GLSL shader tooling
|
||||
- Mesh is a DTO with vertex position, color, UVs, and faces
|
||||
- MeshRenderer sends WebGL instructions for rendering a Mesh object with a Shader object.
|
||||
- Renderable is a container of a Transform and Renderer (like a Unity GameObject)
|
||||
- Transform is a tuplet of a position vec3, rotation quat, and scale vec3; to be used anywhere needed.
|
||||
- Scene is a group of Renderables
|
||||
|
||||
## License
|
||||
|
||||
|
|
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
@ -11,6 +11,9 @@ mkdirSync("html");
|
|||
|
||||
const works = globSync("src/*/main.ts");
|
||||
|
||||
console.log(chalk.green`>> Convert meshes ...`);
|
||||
await convertMeshes();
|
||||
|
||||
console.log(chalk.green`>> Building ...`);
|
||||
console.log(chalk.yellow(` Found ${works.length} works.`));
|
||||
console.log(chalk.yellow(` Running Bun.build()`));
|
||||
|
@ -44,6 +47,3 @@ const { stdout, stderr, exitCode } = Bun.spawnSync([
|
|||
"-c",
|
||||
"cp -r src/public/* html/",
|
||||
]);
|
||||
|
||||
console.log(chalk.green`>> Convert meshes ...`);
|
||||
await convertMeshes();
|
||||
|
|
|
@ -1,6 +1,54 @@
|
|||
import chalk from "chalk";
|
||||
import { globSync } from "glob";
|
||||
|
||||
const w = 1;
|
||||
|
||||
type Vertex = {
|
||||
position: {
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
};
|
||||
color?: {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
a: number;
|
||||
};
|
||||
uv?: {
|
||||
u: number;
|
||||
v: number;
|
||||
};
|
||||
normal?: {
|
||||
nx: number;
|
||||
ny: number;
|
||||
nz: number;
|
||||
};
|
||||
};
|
||||
|
||||
type Face = {
|
||||
a: number;
|
||||
b: number;
|
||||
c: number;
|
||||
};
|
||||
|
||||
type Triangle = {
|
||||
a: Vertex;
|
||||
b: Vertex;
|
||||
c: Vertex;
|
||||
};
|
||||
|
||||
// const vertToArray = ({ x, y, z, w, r, g, b, a, u, v }: Vertex): number[] => {
|
||||
// if (!r) return [x, y, z, u, v];
|
||||
// else return [x, y, z, r, g as number, b as number, a as number, u, v];
|
||||
// };
|
||||
|
||||
// const triangleToArray = (t: Triangle): number[] => [
|
||||
// ...vertToArray(t.a),
|
||||
// ...vertToArray(t.b),
|
||||
// ...vertToArray(t.c),
|
||||
// ];
|
||||
|
||||
export const convertMeshes = async () => {
|
||||
const meshes = globSync("src/meshes/*.ply");
|
||||
|
||||
|
@ -8,8 +56,47 @@ export const convertMeshes = async () => {
|
|||
const ply = await Bun.file(file).text();
|
||||
|
||||
const [header, body] = ply.split("end_header");
|
||||
const colorSize = header.includes("red") ? 4 : 0;
|
||||
|
||||
const propertyList: [string, "float" | "uchar"][] = [];
|
||||
const vertexConfig = {
|
||||
colors: false,
|
||||
uvs: false,
|
||||
normals: false,
|
||||
};
|
||||
const headerLines = header.split("\n");
|
||||
|
||||
for (const property of headerLines.filter((header) =>
|
||||
header.startsWith("property")
|
||||
)) {
|
||||
const [, propType, name] = property.split(" ");
|
||||
|
||||
if (propType === "list") {
|
||||
continue;
|
||||
}
|
||||
|
||||
propertyList.push([name, propType as any]);
|
||||
|
||||
switch (name) {
|
||||
case "red":
|
||||
case "green":
|
||||
case "blue":
|
||||
case "alpha":
|
||||
vertexConfig.colors = true;
|
||||
break;
|
||||
case "nx":
|
||||
case "ny":
|
||||
case "nz":
|
||||
vertexConfig.normals = true;
|
||||
break;
|
||||
case "s":
|
||||
case "t":
|
||||
vertexConfig.uvs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log({ propertyList });
|
||||
|
||||
const vertexCount = Number(
|
||||
headerLines
|
||||
.find((header) => header.startsWith("element vertex"))
|
||||
|
@ -20,49 +107,152 @@ export const convertMeshes = async () => {
|
|||
throw new Error("couldn't get vertex count...");
|
||||
}
|
||||
|
||||
const values: number[] = [];
|
||||
const vertexes: Vertex[] = [];
|
||||
const faces: Face[] = [];
|
||||
|
||||
for (const line of body.split("\n")) {
|
||||
// line looks like
|
||||
// x y z r g b a u v
|
||||
// We need to convert it to
|
||||
// x y z 1 r g b a u v
|
||||
const components = line.split(" ");
|
||||
|
||||
const [x, y, z, r, g, b, a, u, v] = line.split(" ");
|
||||
|
||||
if (!g) {
|
||||
if (!components || !components[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
values.push(
|
||||
parseFloat(x),
|
||||
parseFloat(y),
|
||||
parseFloat(z),
|
||||
1,
|
||||
parseFloat(r),
|
||||
parseFloat(g)
|
||||
);
|
||||
// do we only have 4 components?
|
||||
if (components[0] === "3" || components.length === 4) {
|
||||
const [, a, b, c] = components;
|
||||
|
||||
if (colorSize > 0) {
|
||||
values.push(parseFloat(b), parseFloat(a), parseFloat(u), parseFloat(v));
|
||||
// We do??!?! 🥺👉👈
|
||||
faces.push({ a: Number(a), b: Number(b), c: Number(c) });
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const vertex: Required<Vertex> = {
|
||||
position: {
|
||||
x: -1,
|
||||
y: -1,
|
||||
z: -1,
|
||||
},
|
||||
color: {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
a: 255,
|
||||
},
|
||||
normal: {
|
||||
nx: -1,
|
||||
ny: -1,
|
||||
nz: -1,
|
||||
},
|
||||
uv: {
|
||||
u: -1,
|
||||
v: -1,
|
||||
},
|
||||
};
|
||||
|
||||
for (const idx in components) {
|
||||
const component = components[idx];
|
||||
const [propName, propType] = propertyList[idx];
|
||||
|
||||
const p = parser[propType] ?? parseFloat;
|
||||
|
||||
switch (propName) {
|
||||
case "x":
|
||||
vertex.position.x = p(component);
|
||||
break;
|
||||
case "y":
|
||||
vertex.position.y = p(component);
|
||||
break;
|
||||
case "z":
|
||||
vertex.position.z = p(component);
|
||||
case "s":
|
||||
vertex.uv.u = p(component);
|
||||
break;
|
||||
case "t":
|
||||
vertex.uv.v = p(component);
|
||||
break;
|
||||
case "red":
|
||||
vertex.color.r = p(component);
|
||||
break;
|
||||
case "green":
|
||||
vertex.color.g = p(component);
|
||||
break;
|
||||
case "blue":
|
||||
vertex.color.b = p(component);
|
||||
break;
|
||||
case "nx":
|
||||
vertex.normal.nx = p(component);
|
||||
break;
|
||||
case "ny":
|
||||
vertex.normal.ny = p(component);
|
||||
break;
|
||||
case "nz":
|
||||
vertex.normal.nz = p(component);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vertexes.push(vertex);
|
||||
}
|
||||
|
||||
const positions: number[] = vertexes.flatMap((v) => [
|
||||
v.position.x,
|
||||
v.position.y,
|
||||
v.position.z,
|
||||
]);
|
||||
const normals: number[] = vertexConfig.normals
|
||||
? vertexes.flatMap((v: any) => [v.normal.nx, v.normal.ny, v.normal.nz])
|
||||
: [];
|
||||
const colors: number[] = vertexConfig.colors
|
||||
? vertexes.flatMap((v: any) => [
|
||||
v.color.r,
|
||||
v.color.g,
|
||||
v.color.b,
|
||||
v.color.a,
|
||||
])
|
||||
: [];
|
||||
const uvs: number[] = vertexConfig.uvs
|
||||
? vertexes.flatMap((v: any) => [v.uv.u, v.uv.v])
|
||||
: [];
|
||||
|
||||
const facesArray: number[] = faces.flatMap((f) => [f.a, f.b, f.c]);
|
||||
|
||||
const outFile = file.replace(".ply", ".ts");
|
||||
const outString = `
|
||||
import { Mesh } from "../renderer/mesh";
|
||||
|
||||
// prettier-ignore
|
||||
const mesh = new Float32Array(${JSON.stringify(values)});
|
||||
const positions = new Float32Array(${JSON.stringify(positions)});
|
||||
|
||||
export default new Mesh({
|
||||
mesh,
|
||||
positionSize: 4,
|
||||
colorSize: ${colorSize},
|
||||
uvSize: 2,
|
||||
vertexCount: ${vertexCount},
|
||||
stride: ${4 + colorSize + 2},
|
||||
name: ${JSON.stringify(file)}
|
||||
// prettier-ignore
|
||||
const colors = ${
|
||||
vertexConfig.colors ? `new Uint8Array(${JSON.stringify(colors)})` : "null"
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
const uvs = ${
|
||||
vertexConfig.uvs ? `new Float32Array(${JSON.stringify(uvs)})` : "null"
|
||||
};
|
||||
|
||||
|
||||
// prettier-ignore
|
||||
const normals = ${
|
||||
vertexConfig.normals
|
||||
? `new Float32Array(${JSON.stringify(normals)})`
|
||||
: "null"
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
const faces = new Uint32Array(${JSON.stringify(facesArray)});
|
||||
|
||||
export default new Mesh({
|
||||
colors,
|
||||
faces,
|
||||
name: ${JSON.stringify(file)},
|
||||
normals,
|
||||
positions,
|
||||
uvs,
|
||||
vertexCount: ${vertexCount}
|
||||
});
|
||||
`;
|
||||
|
||||
|
@ -70,3 +260,8 @@ export default new Mesh({
|
|||
console.log(chalk.yellow(` -> ${file}...`));
|
||||
}
|
||||
};
|
||||
|
||||
const parser = {
|
||||
float: (x: string) => parseFloat(x),
|
||||
uchar: (x: string) => Number(x),
|
||||
};
|
||||
|
|
|
@ -22,19 +22,24 @@ https://art.mekanoe.com
|
|||
|
||||
### Infrastructure
|
||||
|
||||
- The "generator" does
|
||||
- **Output generation**
|
||||
|
||||
- Generates a work list from .js files within `html`
|
||||
- Creates this README.md file
|
||||
- Creates the index.html file
|
||||
- Creates individual HTML files for each work
|
||||
- Bun renders TypeScript and GLSL to html/
|
||||
- src/public/ is copied to html/
|
||||
- This doubles as an "archival" system to preserve scuffedness
|
||||
- .ply files are converted to JS typed arrays and Mesh objects
|
||||
- .html files (and README.md) are generated from rendered TypeScript main.ts files.
|
||||
|
||||
- The platform supplies
|
||||
- Shader types
|
||||
- Primitive objects
|
||||
- A canvas to draw on
|
||||
- WebGL hooks
|
||||
- Helpers, etc
|
||||
- **Platform**
|
||||
|
||||
- WebGLApp provides render loop, canvas, and other stuff
|
||||
- Behavior provides automatic registration of WebGLApp events (like Unity MonoBehaviors)
|
||||
- Shader provides GLSL shader tooling
|
||||
- Mesh is a DTO with vertex position, color, UVs, and faces
|
||||
- MeshRenderer sends WebGL instructions for rendering a Mesh object with a Shader object.
|
||||
- Renderable is a container of a Transform and Renderer (like a Unity GameObject)
|
||||
- Transform is a tuplet of a position vec3, rotation quat, and scale vec3; to be used anywhere needed.
|
||||
- Scene is a group of Renderables
|
||||
|
||||
## License
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
12
package.json
12
package.json
|
@ -4,13 +4,14 @@
|
|||
"main": "./hack/build.ts",
|
||||
"scripts": {
|
||||
"build": "bun $BUNFLAGS .",
|
||||
"build:watch": "BUNFLAGS=--watch bun run build",
|
||||
"build:watch": "nodemon -e ts,js,frag,vert,glsl,ply",
|
||||
"serve": "serve ./html",
|
||||
"dev": "run-p serve build:watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bun-types": "latest",
|
||||
"npm-run-all2": "^6.1.1",
|
||||
"nodemon": "^3.0.1",
|
||||
"prettier": "^3.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -23,5 +24,14 @@
|
|||
"glob": "^10.3.10",
|
||||
"serve": "^14.2.1",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"nodemonConfig": {
|
||||
"ignore": [
|
||||
"html/",
|
||||
"README.md",
|
||||
"src/meshes/*.ts"
|
||||
],
|
||||
"delay": 1000,
|
||||
"exec": "bun run . --"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
// This one is archived.
|
||||
// // This one is archived.
|
||||
|
||||
import { Shader } from "./shader";
|
||||
import { BasicPlane } from "./basic-plane";
|
||||
import { App } from "./app";
|
||||
import fragment from "./fragment.glsl";
|
||||
import vertex from "./vertex.glsl";
|
||||
// import { Shader } from "./shader";
|
||||
// import { BasicPlane } from "./basic-plane";
|
||||
// import { App } from "./app";
|
||||
// import fragment from "./fragment.glsl";
|
||||
// import vertex from "./vertex.glsl";
|
||||
|
||||
const app = new App({ fov: 20 });
|
||||
const gl = app.gl;
|
||||
// const app = new App({ fov: 20 });
|
||||
// const gl = app.gl;
|
||||
|
||||
const shader = new Shader(app)
|
||||
.attach(gl.VERTEX_SHADER, vertex)
|
||||
.attach(gl.FRAGMENT_SHADER, fragment)
|
||||
.link();
|
||||
// const shader = new Shader(app)
|
||||
// .attach(gl.VERTEX_SHADER, vertex)
|
||||
// .attach(gl.FRAGMENT_SHADER, fragment)
|
||||
// .link();
|
||||
|
||||
const plane = new BasicPlane(app);
|
||||
plane.attachShader(shader);
|
||||
// const plane = new BasicPlane(app);
|
||||
// plane.attachShader(shader);
|
||||
|
||||
app.loop();
|
||||
// app.loop();
|
||||
|
|
|
@ -1,42 +1,43 @@
|
|||
// This one is archived.
|
||||
import { MeshRenderer } from "../renderer/mesh-renderer";
|
||||
import plane from "../meshes/plane";
|
||||
import { WebGLApp } from "../renderer/webgl";
|
||||
import { Renderable } from "../renderer/renderable";
|
||||
import { Transform } from "../renderer/transform";
|
||||
import { uvRainbow } from "../common-shaders/uv-rainbow";
|
||||
import { quat } from "gl-matrix";
|
||||
import torus from "../meshes/torus";
|
||||
// // This one is archived.
|
||||
|
||||
const app = new WebGLApp({ fov: 45 });
|
||||
// import { MeshRenderer } from "../renderer/mesh-renderer";
|
||||
// import plane from "../meshes/plane";
|
||||
// import { WebGLApp } from "../renderer/webgl";
|
||||
// import { Renderable } from "../renderer/renderable";
|
||||
// import { Transform } from "../renderer/transform";
|
||||
// import { uvRainbow } from "../common-shaders/uv-rainbow";
|
||||
// import { quat } from "gl-matrix";
|
||||
// import torus from "../meshes/torus";
|
||||
|
||||
const camera = new Transform(
|
||||
[0, 0, -6],
|
||||
quat.fromEuler(quat.create(), 15, 0, 0)
|
||||
);
|
||||
// const app = new WebGLApp({ fov: 45 });
|
||||
|
||||
const modelTransform = new Transform([0, 0, 4]);
|
||||
// const camera = new Transform(
|
||||
// [0, 0, -6],
|
||||
// quat.fromEuler(quat.create(), 15, 0, 0)
|
||||
// );
|
||||
|
||||
app.onUpdate((time: number) => {
|
||||
const cameraStride = 3;
|
||||
const x = Math.sin(time * 0.0001) * (cameraStride * 2 - cameraStride * 0.5);
|
||||
// const modelTransform = new Transform([0, 0, 4]);
|
||||
|
||||
camera.rotation = quat.fromEuler(quat.create(), x, 0, 0);
|
||||
// modelTransform.rotation = quat.fromEuler(quat.create(), x, 0, 0);
|
||||
});
|
||||
// app.onUpdate((time: number) => {
|
||||
// const cameraStride = 3;
|
||||
// const x = Math.sin(time * 0.0001) * (cameraStride * 2 - cameraStride * 0.5);
|
||||
|
||||
new Renderable(
|
||||
app,
|
||||
modelTransform,
|
||||
new MeshRenderer(app, torus, uvRainbow(app), camera, {
|
||||
drawMode: app.gl.TRIANGLE_FAN,
|
||||
})
|
||||
);
|
||||
// camera.rotation = quat.fromEuler(quat.create(), x, 0, 0);
|
||||
// // modelTransform.rotation = quat.fromEuler(quat.create(), x, 0, 0);
|
||||
// });
|
||||
|
||||
// new Renderable(
|
||||
// app,
|
||||
// new Transform([1, 0, 0]),
|
||||
// new MeshRenderer(app, plane, uvRainbow(app))
|
||||
// modelTransform,
|
||||
// new MeshRenderer(app, torus, uvRainbow(app), camera, {
|
||||
// drawMode: app.gl.TRIANGLE_FAN,
|
||||
// })
|
||||
// );
|
||||
|
||||
app.start();
|
||||
// // new Renderable(
|
||||
// // app,
|
||||
// // new Transform([1, 0, 0]),
|
||||
// // new MeshRenderer(app, plane, uvRainbow(app))
|
||||
// // );
|
||||
|
||||
// app.start();
|
||||
|
|
|
@ -4,13 +4,27 @@ import { Renderable } from "../renderer/renderable";
|
|||
import { Transform } from "../renderer/transform";
|
||||
import torus from "../meshes/torus";
|
||||
import { errorShader } from "../common-shaders/error";
|
||||
import plane from "../meshes/plane";
|
||||
import { uvRainbow } from "../common-shaders/uv-rainbow";
|
||||
import uvsphere from "../meshes/uvsphere";
|
||||
import { quat } from "gl-matrix";
|
||||
import trianglething from "../meshes/trianglething";
|
||||
import teapot from "../meshes/teapot";
|
||||
|
||||
const app = new WebGLApp({ fov: 45 });
|
||||
|
||||
const camera = new Transform([0, -2, -6]);
|
||||
|
||||
new Renderable(
|
||||
app,
|
||||
new Transform(),
|
||||
new MeshRenderer(app, torus, errorShader(app))
|
||||
new MeshRenderer(app, trianglething, uvRainbow(app), camera).configure({})
|
||||
);
|
||||
|
||||
// new Renderable(
|
||||
// app,
|
||||
// new Transform(),
|
||||
// new MeshRenderer(app, torus, uvRainbow(app), camera).configure({})
|
||||
// );
|
||||
|
||||
app.start();
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#version 300 es
|
||||
precision highp float;
|
||||
|
||||
uniform float uTime;
|
||||
uniform float uSinTime;
|
||||
uniform float uCosTime;
|
||||
|
||||
varying highp vec2 vTextureCoord;
|
||||
in vec2 vTextureCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
vec3 rgb2hsv(vec3 c) {
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
|
@ -30,6 +32,6 @@ void main() {
|
|||
hsv.z = 1.0;
|
||||
vec3 rgb = hsv2rgb(hsv);
|
||||
|
||||
gl_FragColor = vec4(rgb, 1.0);
|
||||
gl_FragColor = clamp(gl_FragColor, 0.0, 1.0);
|
||||
fragColor = vec4(rgb, 1.0);
|
||||
fragColor = clamp(fragColor, 0.0, 1.0);
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
attribute vec4 aVertexPosition;
|
||||
attribute vec2 aTextureCoord;
|
||||
#version 300 es
|
||||
layout(location = 0) in vec4 aVertexPosition;
|
||||
layout(location = 1) in vec2 aTextureCoord;
|
||||
|
||||
uniform mat4 uModelViewMatrix;
|
||||
uniform mat4 uProjectionMatrix;
|
||||
|
||||
varying highp vec2 vTextureCoord;
|
||||
out vec2 vTextureCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
|
||||
|
|
18
src/meshes/plane.ply
Normal file
18
src/meshes/plane.ply
Normal file
|
@ -0,0 +1,18 @@
|
|||
ply
|
||||
format ascii 1.0
|
||||
comment Created in Blender version 3.6.4
|
||||
element vertex 4
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
property float s
|
||||
property float t
|
||||
element face 2
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
1 -1 0 1 0
|
||||
-1 1 0 0 1
|
||||
-1 -1 0 0 0
|
||||
1 1 0 1 1
|
||||
3 0 1 2
|
||||
3 0 3 1
|
|
@ -1,20 +1,28 @@
|
|||
|
||||
import { Mesh } from "../renderer/mesh";
|
||||
|
||||
// prettier-ignore
|
||||
const mesh = new Float32Array([
|
||||
// f4 position, f4 color, f2 uv
|
||||
-1, -1, 0, 1, 1, 1, 1, 1, 0, 0,
|
||||
1, -1, 0, 1, 1, 1, 1, 1, 1, 0,
|
||||
-1, 1, 0, 1, 1, 1, 1, 1, 0, 1,
|
||||
1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
|
||||
]);
|
||||
const positions = new Float32Array([1,-1,0,-1,1,0,-1,-1,0,1,1,0]);
|
||||
|
||||
// prettier-ignore
|
||||
const colors = null;
|
||||
|
||||
// prettier-ignore
|
||||
const uvs = new Float32Array([1,0,0,1,0,0,1,1]);
|
||||
|
||||
|
||||
// prettier-ignore
|
||||
const normals = null;
|
||||
|
||||
// prettier-ignore
|
||||
const faces = new Uint32Array([0,1,2,0,3,1]);
|
||||
|
||||
export default new Mesh({
|
||||
mesh,
|
||||
positionSize: 4,
|
||||
colorSize: 4,
|
||||
uvSize: 2,
|
||||
vertexCount: 4,
|
||||
stride: 10,
|
||||
name: "plane",
|
||||
colors,
|
||||
faces,
|
||||
name: "src/meshes/plane.ply",
|
||||
normals,
|
||||
positions,
|
||||
uvs,
|
||||
vertexCount: 4
|
||||
});
|
||||
|
|
2028
src/meshes/teapot.ply
Normal file
2028
src/meshes/teapot.ply
Normal file
File diff suppressed because it is too large
Load diff
28
src/meshes/teapot.ts
Normal file
28
src/meshes/teapot.ts
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
76
src/meshes/trianglething.ply
Normal file
76
src/meshes/trianglething.ply
Normal file
|
@ -0,0 +1,76 @@
|
|||
ply
|
||||
format ascii 1.0
|
||||
comment Created in Blender version 3.6.4
|
||||
element vertex 31
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
property float nx
|
||||
property float ny
|
||||
property float nz
|
||||
property uchar red
|
||||
property uchar green
|
||||
property uchar blue
|
||||
property uchar alpha
|
||||
property float s
|
||||
property float t
|
||||
element face 26
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
0 2.609 0 0 -1 8.3803394e-07 0 1 255 255 0.00013659838 0.8180941
|
||||
-0.368004 2.9959495 0.50652 -0.5257306 -0.44721383 0.723607 0 1 255 255 0.15755458 0.7272099
|
||||
-0.595448 2.9959495 -0.19346951 -0.8506533 -0.44721213 -0.2763879 0 1 255 255 0.1575546 0.9089782
|
||||
0 2.609 0 0 -1 8.3803394e-07 0 1 255 255 0.00013659043 0.6363257
|
||||
0.368004 2.9959495 0.50652 0.5257306 -0.4472139 0.723607 0 1 255 255 0.15755458 0.54544157
|
||||
0 2.609 0 0 -1 8.3803394e-07 0 1 255 255 0.0001365666 0.09102075
|
||||
-0.595448 2.9959495 -0.19346951 -0.8506533 -0.44721213 -0.2763879 0 1 255 255 0.15755455 0.00013656964
|
||||
0 2.9959495 -0.6260975 0 -0.44721153 -0.89442825 0 1 255 255 0.15755457 0.18190491
|
||||
0 2.609 0 0 -1 8.3803394e-07 0 1 255 255 0.00013657454 0.2727891
|
||||
0.595448 2.9959495 -0.19346951 0.8506533 -0.4472122 -0.27638793 0 1 255 255 0.15755457 0.36367324
|
||||
0 2.609 0 0 -1 8.3803394e-07 0 1 255 255 0.00013658249 0.45455742
|
||||
0 3.6220505 0.6260975 0 0.44721153 0.89442825 0 1 255 255 0.31497157 0.6363257
|
||||
-0.595448 3.6220505 0.19346951 -0.8506533 0.44721216 0.27638793 0 1 255 255 0.31497157 0.8180941
|
||||
-0.368004 3.6220505 -0.50652 -0.5257306 0.4472139 -0.72360694 0 1 255 255 0.31497154 0.09102073
|
||||
0.368004 3.6220505 -0.50652 0.5257306 0.4472139 -0.72360694 0 1 255 255 0.31497154 0.27278906
|
||||
0.595448 3.6220505 0.19346951 0.85065323 0.4472122 0.2763879 0 1 255 255 0.31497154 0.45455742
|
||||
-0.368004 3.6220505 -0.50652 -0.5257306 0.4472139 -0.72360694 0 1 255 255 0.31497157 0.9998634
|
||||
0 4.0090003 0 0 1 -8.165459e-07 0 1 255 255 0.47238955 0.72720987
|
||||
0 4.0090003 0 0 1 -8.165459e-07 0 1 255 255 0.47238958 0.9089782
|
||||
0 4.0090003 0 0 1 -8.165459e-07 0 1 255 255 0.47238955 0.1819049
|
||||
0 4.0090003 0 0 1 -8.165459e-07 0 1 255 255 0.47238955 0.36367324
|
||||
0 4.0090003 0 0 1 -8.165459e-07 0 1 255 255 0.47238955 0.54544157
|
||||
1 0 0 0.8999471 -0.43599886 2.4163015e-07 0 1 255 255 0.8119813 0.33945516
|
||||
0 2.5 0 -5.150958e-08 1 0 0 1 255 255 0.642322 0.16979587
|
||||
-4.3711392e-08 0 1 -3.0203772e-08 -0.4359989 0.8999472 0 1 255 255 0.8119813 0.00013659486
|
||||
-1 0 -8.7422784e-08 -0.8999471 -0.4359989 -2.4291313e-07 0 1 255 255 0.47266275 0.00013660162
|
||||
-4.3711392e-08 0 1 -3.0203772e-08 -0.4359989 0.8999472 0 1 255 255 0.81198126 0.6790469
|
||||
1.19248815e-08 0 -1 0 -0.43599886 -0.8999471 0 1 255 255 0.47266275 0.33972836
|
||||
1 0 0 0.8999471 -0.43599886 2.4163015e-07 0 1 255 255 0.47266272 0.6790469
|
||||
1.19248815e-08 0 -1 0 -0.43599886 -0.8999471 0 1 255 255 0.47266275 0.33945513
|
||||
-1 0 -8.7422784e-08 -0.8999471 -0.4359989 -2.4291313e-07 0 1 255 255 0.81198126 0.3397284
|
||||
3 0 1 2
|
||||
3 1 3 4
|
||||
3 5 6 7
|
||||
3 8 7 9
|
||||
3 10 9 4
|
||||
3 1 4 11
|
||||
3 2 1 12
|
||||
3 7 6 13
|
||||
3 9 7 14
|
||||
3 4 9 15
|
||||
3 1 11 12
|
||||
3 2 12 16
|
||||
3 7 13 14
|
||||
3 9 14 15
|
||||
3 4 15 11
|
||||
3 12 11 17
|
||||
3 16 12 18
|
||||
3 14 13 19
|
||||
3 15 14 20
|
||||
3 11 15 21
|
||||
3 22 23 24
|
||||
3 24 23 25
|
||||
3 26 27 28
|
||||
3 25 23 29
|
||||
3 29 23 22
|
||||
3 26 30 27
|
28
src/meshes/trianglething.ts
Normal file
28
src/meshes/trianglething.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
import { Mesh } from "../renderer/mesh";
|
||||
|
||||
// prettier-ignore
|
||||
const positions = new Float32Array([0,2.609,0,-0.368004,2.9959495,0.50652,-0.595448,2.9959495,-0.19346951,0,2.609,0,0.368004,2.9959495,0.50652,0,2.609,0,-0.595448,2.9959495,-0.19346951,0,2.9959495,-0.6260975,0,2.609,0,0.595448,2.9959495,-0.19346951,0,2.609,0,0,3.6220505,0.6260975,-0.595448,3.6220505,0.19346951,-0.368004,3.6220505,-0.50652,0.368004,3.6220505,-0.50652,0.595448,3.6220505,0.19346951,-0.368004,3.6220505,-0.50652,0,4.0090003,0,0,4.0090003,0,0,4.0090003,0,0,4.0090003,0,0,4.0090003,0,1,0,0,0,2.5,0,-4.3711392e-8,0,1,-1,0,-8.7422784e-8,-4.3711392e-8,0,1,1.19248815e-8,0,-1,1,0,0,1.19248815e-8,0,-1,-1,0,-8.7422784e-8]);
|
||||
|
||||
// prettier-ignore
|
||||
const colors = new Uint8Array([0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255,0,1,255,255]);
|
||||
|
||||
// prettier-ignore
|
||||
const uvs = new Float32Array([0.00013659838,0.8180941,0.15755458,0.7272099,0.1575546,0.9089782,0.00013659043,0.6363257,0.15755458,0.54544157,0.0001365666,0.09102075,0.15755455,0.00013656964,0.15755457,0.18190491,0.00013657454,0.2727891,0.15755457,0.36367324,0.00013658249,0.45455742,0.31497157,0.6363257,0.31497157,0.8180941,0.31497154,0.09102073,0.31497154,0.27278906,0.31497154,0.45455742,0.31497157,0.9998634,0.47238955,0.72720987,0.47238958,0.9089782,0.47238955,0.1819049,0.47238955,0.36367324,0.47238955,0.54544157,0.8119813,0.33945516,0.642322,0.16979587,0.8119813,0.00013659486,0.47266275,0.00013660162,0.81198126,0.6790469,0.47266275,0.33972836,0.47266272,0.6790469,0.47266275,0.33945513,0.81198126,0.3397284]);
|
||||
|
||||
|
||||
// prettier-ignore
|
||||
const normals = new Float32Array([0,-1,8.3803394e-7,-0.5257306,-0.44721383,0.723607,-0.8506533,-0.44721213,-0.2763879,0,-1,8.3803394e-7,0.5257306,-0.4472139,0.723607,0,-1,8.3803394e-7,-0.8506533,-0.44721213,-0.2763879,0,-0.44721153,-0.89442825,0,-1,8.3803394e-7,0.8506533,-0.4472122,-0.27638793,0,-1,8.3803394e-7,0,0.44721153,0.89442825,-0.8506533,0.44721216,0.27638793,-0.5257306,0.4472139,-0.72360694,0.5257306,0.4472139,-0.72360694,0.85065323,0.4472122,0.2763879,-0.5257306,0.4472139,-0.72360694,0,1,-8.165459e-7,0,1,-8.165459e-7,0,1,-8.165459e-7,0,1,-8.165459e-7,0,1,-8.165459e-7,0.8999471,-0.43599886,2.4163015e-7,-5.150958e-8,1,0,-3.0203772e-8,-0.4359989,0.8999472,-0.8999471,-0.4359989,-2.4291313e-7,-3.0203772e-8,-0.4359989,0.8999472,0,-0.43599886,-0.8999471,0.8999471,-0.43599886,2.4163015e-7,0,-0.43599886,-0.8999471,-0.8999471,-0.4359989,-2.4291313e-7]);
|
||||
|
||||
// prettier-ignore
|
||||
const faces = new Uint32Array([0,1,2,1,3,4,5,6,7,8,7,9,10,9,4,1,4,11,2,1,12,7,6,13,9,7,14,4,9,15,1,11,12,2,12,16,7,13,14,9,14,15,4,15,11,12,11,17,16,12,18,14,13,19,15,14,20,11,15,21,22,23,24,24,23,25,26,27,28,25,23,29,29,23,22,26,30,27]);
|
||||
|
||||
export default new Mesh({
|
||||
colors,
|
||||
faces,
|
||||
name: "src/meshes/trianglething.ply",
|
||||
normals,
|
||||
positions,
|
||||
uvs,
|
||||
vertexCount: 31
|
||||
});
|
14234
src/meshes/uvsphere.ply
Normal file
14234
src/meshes/uvsphere.ply
Normal file
File diff suppressed because it is too large
Load diff
28
src/meshes/uvsphere.ts
Normal file
28
src/meshes/uvsphere.ts
Normal file
File diff suppressed because one or more lines are too long
|
@ -5,10 +5,12 @@ export abstract class Behavior {
|
|||
onBeforeUpdate?(...args: any[]): void;
|
||||
onUpdate?(...args: any[]): void;
|
||||
onAfterUpdate?(...args: any[]): void;
|
||||
onDraw?(...args: any[]): void;
|
||||
constructor(public app: WebGLApp) {
|
||||
this.onStart && app.onStart(this.onStart.bind(this));
|
||||
this.onUpdate && app.onUpdate(this.onUpdate.bind(this));
|
||||
this.onAfterUpdate && app.onAfterUpdate(this.onAfterUpdate.bind(this));
|
||||
this.onBeforeUpdate && app.onBeforeUpdate(this.onBeforeUpdate.bind(this));
|
||||
this.onDraw && app.onDraw(this.onDraw.bind(this));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,22 @@ import { Mesh } from "./mesh";
|
|||
import { Shader } from "./shader";
|
||||
import { WebGLApp } from "./webgl";
|
||||
import { Transform } from "./transform";
|
||||
import { errorShader } from "../common-shaders/error";
|
||||
|
||||
export type MeshRendererConfig = {
|
||||
drawMode?: number;
|
||||
cullMode?: number;
|
||||
};
|
||||
|
||||
export class MeshRenderer extends Behavior {
|
||||
private modelMatrix = mat4.create();
|
||||
private projectionMatrix = mat4.create();
|
||||
private _meshBuffer?: WebGLBuffer;
|
||||
private buffers: {
|
||||
position?: WebGLBuffer;
|
||||
uv?: WebGLBuffer;
|
||||
normal?: WebGLBuffer;
|
||||
color?: WebGLBuffer;
|
||||
faces?: WebGLBuffer;
|
||||
} = {};
|
||||
|
||||
constructor(
|
||||
public app: WebGLApp,
|
||||
|
@ -25,106 +31,130 @@ export class MeshRenderer extends Behavior {
|
|||
super(app);
|
||||
}
|
||||
|
||||
get meshBuffer() {
|
||||
if (this._meshBuffer) {
|
||||
return this._meshBuffer;
|
||||
}
|
||||
|
||||
throw new Error("mesh buffer not ready");
|
||||
configure(config: MeshRendererConfig) {
|
||||
this.config = config;
|
||||
return this;
|
||||
}
|
||||
|
||||
initializeMeshBuffer() {
|
||||
makeBuffer(data: TypedArray, target: number = 34962) {
|
||||
const gl = this.app.gl;
|
||||
const buffer = gl.createBuffer();
|
||||
if (!buffer) {
|
||||
throw new Error("failed to create mesh buffer");
|
||||
throw new Error("failed to create a buffer");
|
||||
}
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, this.mesh.config.mesh, gl.STATIC_DRAW);
|
||||
|
||||
this._meshBuffer = buffer;
|
||||
gl.bindBuffer(target, buffer);
|
||||
gl.bufferData(target, data, gl.STATIC_DRAW);
|
||||
gl.bindBuffer(target, null);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
initializeAttributes() {
|
||||
const gl = this.app.gl;
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.meshBuffer);
|
||||
initializeBuffers() {
|
||||
this.buffers.faces = this.makeBuffer(
|
||||
this.mesh.config.faces,
|
||||
this.app.gl.ELEMENT_ARRAY_BUFFER
|
||||
);
|
||||
|
||||
const positionLocation = this.shader.attrib("aVertexPosition");
|
||||
if (positionLocation !== -1) {
|
||||
this.buffers.position = this.makeBuffer(this.mesh.config.positions);
|
||||
this.bindAttrib(this.buffers.position, 0, 3, this.app.gl.FLOAT);
|
||||
|
||||
if (this.mesh.config.normals) {
|
||||
this.buffers.normal = this.makeBuffer(this.mesh.config.normals);
|
||||
this.bindAttrib(
|
||||
this.buffers.normal,
|
||||
"aVertexNormals",
|
||||
3,
|
||||
this.app.gl.FLOAT,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if (this.mesh.config.colors) {
|
||||
this.buffers.color = this.makeBuffer(this.mesh.config.colors);
|
||||
this.bindAttrib(
|
||||
this.buffers.color,
|
||||
"aVertexColors",
|
||||
4,
|
||||
this.app.gl.UNSIGNED_BYTE
|
||||
);
|
||||
}
|
||||
|
||||
if (this.mesh.config.uvs) {
|
||||
this.buffers.uv = this.makeBuffer(this.mesh.config.uvs);
|
||||
this.bindAttrib(this.buffers.uv, 1, 2, this.app.gl.FLOAT);
|
||||
}
|
||||
}
|
||||
|
||||
bindAttrib(
|
||||
buffer: WebGLBuffer,
|
||||
attribute: string | number,
|
||||
elements: number,
|
||||
glType: number,
|
||||
normalized: boolean = false
|
||||
) {
|
||||
const gl = this.app.gl;
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||
|
||||
const attributePosition = Number.isSafeInteger(attribute)
|
||||
? (attribute as number)
|
||||
: this.shader.attrib(attribute as string);
|
||||
if (attributePosition !== -1) {
|
||||
gl.vertexAttribPointer(
|
||||
positionLocation,
|
||||
this.mesh.config.positionSize,
|
||||
gl.FLOAT,
|
||||
false,
|
||||
4 * this.mesh.config.stride,
|
||||
attributePosition,
|
||||
elements,
|
||||
glType,
|
||||
normalized,
|
||||
0,
|
||||
0
|
||||
);
|
||||
gl.enableVertexAttribArray(positionLocation);
|
||||
this.shader.bindAttrib(positionLocation, "aVertexPosition");
|
||||
gl.enableVertexAttribArray(attributePosition);
|
||||
}
|
||||
|
||||
if (this.mesh.config.colorSize !== 0) {
|
||||
const colorLocation = this.shader.attrib("aVertexColor");
|
||||
if (colorLocation !== -1) {
|
||||
gl.vertexAttribPointer(
|
||||
colorLocation,
|
||||
this.mesh.config.colorSize,
|
||||
gl.FLOAT,
|
||||
false,
|
||||
4 * this.mesh.config.stride,
|
||||
4 * this.mesh.config.positionSize
|
||||
);
|
||||
gl.enableVertexAttribArray(colorLocation);
|
||||
this.shader.bindAttrib(colorLocation, "aVertexColor");
|
||||
}
|
||||
}
|
||||
|
||||
const uvLocation = this.shader.attrib("aTextureCoord");
|
||||
if (uvLocation !== -1) {
|
||||
gl.vertexAttribPointer(
|
||||
uvLocation,
|
||||
this.mesh.config.uvSize,
|
||||
gl.FLOAT,
|
||||
false,
|
||||
4 * this.mesh.config.stride,
|
||||
4 * (this.mesh.config.positionSize + this.mesh.config.colorSize)
|
||||
);
|
||||
gl.enableVertexAttribArray(uvLocation);
|
||||
this.shader.bindAttrib(uvLocation, "aTextureCoord");
|
||||
}
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
}
|
||||
|
||||
onStart() {
|
||||
mat4.perspective(
|
||||
this.projectionMatrix,
|
||||
this.app.config.fov || 45,
|
||||
this.app.canvas.width / this.app.canvas.height,
|
||||
this.app.aspect,
|
||||
this.app.config.zNear || 0.1,
|
||||
this.app.config.zFar || 100
|
||||
);
|
||||
|
||||
this.shader.compile();
|
||||
this.initializeMeshBuffer();
|
||||
this.initializeAttributes();
|
||||
this.initializeBuffers();
|
||||
this.shader.link();
|
||||
}
|
||||
|
||||
onRenderableUpdate(time: number, transform: Transform) {
|
||||
const gl = this.app.gl;
|
||||
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffers.faces || null);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers.position || null);
|
||||
|
||||
this.shader.use();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.meshBuffer);
|
||||
|
||||
this.shader.setupUniforms(
|
||||
time,
|
||||
this.projectionMatrix,
|
||||
transform,
|
||||
this.camera
|
||||
);
|
||||
gl.drawArrays(
|
||||
this.config.drawMode ?? gl.TRIANGLE_STRIP,
|
||||
0,
|
||||
this.mesh.config.vertexCount
|
||||
|
||||
gl.drawElements(
|
||||
this.config.drawMode ?? gl.TRIANGLES,
|
||||
this.mesh.config.faces.length,
|
||||
gl.UNSIGNED_INT,
|
||||
0
|
||||
);
|
||||
|
||||
// gl.drawArrays(
|
||||
// 0,
|
||||
// this.mesh.config.vertexCount
|
||||
// );
|
||||
|
||||
const err = gl.getError();
|
||||
if (err !== 0) {
|
||||
console.log({ err });
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
export type MeshConfig = {
|
||||
mesh: Float32Array;
|
||||
positionSize: number;
|
||||
colorSize: number;
|
||||
uvSize: number;
|
||||
vertexCount: number;
|
||||
stride: number;
|
||||
colors: Uint8Array | null;
|
||||
faces: Uint32Array;
|
||||
name: string;
|
||||
normals: Float32Array | null;
|
||||
positions: Float32Array;
|
||||
uvs: Float32Array | null;
|
||||
vertexCount: number;
|
||||
};
|
||||
|
||||
export class Mesh {
|
||||
|
|
|
@ -12,7 +12,7 @@ export class Renderable extends Behavior {
|
|||
super(app);
|
||||
}
|
||||
|
||||
onUpdate(time: number) {
|
||||
onDraw(time: number) {
|
||||
this.renderer.onRenderableUpdate(time, this.transform);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,6 @@ export class Shader {
|
|||
const gl = this.gl;
|
||||
this.attach(gl.FRAGMENT_SHADER, this.fragmentCode);
|
||||
this.attach(gl.VERTEX_SHADER, this.vertexCode);
|
||||
this.link();
|
||||
}
|
||||
|
||||
link() {
|
||||
|
@ -100,6 +99,9 @@ export class Shader {
|
|||
model: Transform,
|
||||
view: Transform
|
||||
) {
|
||||
const viewMatrix = view.toMat4();
|
||||
mat4.invert(viewMatrix, viewMatrix);
|
||||
|
||||
const { gl } = this._app as WebGLApp;
|
||||
gl.useProgram(this._program as WebGLProgram);
|
||||
gl.uniformMatrix4fv(this.uniform("uProjectionMatrix"), false, projection);
|
||||
|
|
|
@ -7,12 +7,19 @@ export class Transform {
|
|||
public scale = vec3.fromValues(1, 1, 1)
|
||||
) {}
|
||||
|
||||
rotateEuler(x: number, y: number, z: number) {
|
||||
quat.fromEuler(this.rotation, x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
toMat4() {
|
||||
return mat4.fromRotationTranslationScale(
|
||||
mat4.create(),
|
||||
const mat = mat4.create();
|
||||
mat4.fromRotationTranslationScale(
|
||||
mat,
|
||||
this.rotation,
|
||||
this.position,
|
||||
this.scale
|
||||
);
|
||||
return mat;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@ export class WebGLApp {
|
|||
onAfterUpdate: RenderHandle[];
|
||||
onUpdate: RenderHandle[];
|
||||
onStart: RenderHandle[];
|
||||
onDraw: RenderHandle[];
|
||||
} = {
|
||||
onBeforeUpdate: [],
|
||||
onAfterUpdate: [],
|
||||
onUpdate: [],
|
||||
onStart: [],
|
||||
onDraw: [],
|
||||
};
|
||||
|
||||
constructor(public config: WebGPUAppConfig = {}) {
|
||||
|
@ -36,7 +38,10 @@ export class WebGLApp {
|
|||
if (!context) {
|
||||
throw new Error("Canvas was unable to get a webgl2 context");
|
||||
}
|
||||
this.gl = context;
|
||||
const gl = (this.gl = context);
|
||||
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||
|
||||
// this.gl.getExtension("OES_element_index_uint"); // default
|
||||
|
||||
if (location.search.includes("telemetry")) {
|
||||
this.telemetry = new Telemetry(this);
|
||||
|
@ -53,6 +58,10 @@ export class WebGLApp {
|
|||
}
|
||||
}
|
||||
|
||||
get aspect() {
|
||||
return this.canvas.clientWidth / this.canvas.clientHeight;
|
||||
}
|
||||
|
||||
clear() {
|
||||
const gl = this.gl;
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black, fully opaque
|
||||
|
@ -78,16 +87,16 @@ export class WebGLApp {
|
|||
this.registry.onStart.push(handle);
|
||||
}
|
||||
|
||||
doUpdate(time: number) {
|
||||
// this.jobsToSubmitThisFrame = [];
|
||||
onDraw(handle: RenderHandle) {
|
||||
this.registry.onDraw.push(handle);
|
||||
}
|
||||
|
||||
doUpdate(time: number) {
|
||||
this.registry.onBeforeUpdate.forEach((handle) => handle(time, this));
|
||||
this.registry.onUpdate.forEach((handle) => handle(time, this));
|
||||
this.registry.onAfterUpdate.forEach((handle) => handle(time, this));
|
||||
|
||||
// if (this.jobsToSubmitThisFrame.length !== 0) {
|
||||
// this.device.queue.submit(this.jobsToSubmitThisFrame);
|
||||
// }
|
||||
this.registry.onDraw.forEach((handle) => handle(time, this));
|
||||
}
|
||||
|
||||
doStart(time: number = 0) {
|
||||
|
@ -96,15 +105,11 @@ export class WebGLApp {
|
|||
}
|
||||
|
||||
async oneShot(time: number = 0) {
|
||||
// await this.awaitRendererReady();
|
||||
|
||||
this.doStart(time);
|
||||
this.doUpdate(time);
|
||||
}
|
||||
|
||||
async start() {
|
||||
// await this.awaitRendererReady();
|
||||
|
||||
this.doStart();
|
||||
|
||||
const run = (time: number) => {
|
||||
|
@ -113,8 +118,4 @@ export class WebGLApp {
|
|||
};
|
||||
requestAnimationFrame(run);
|
||||
}
|
||||
|
||||
// commit(commandEncoder: GPUCommandBuffer) {
|
||||
// this.jobsToSubmitThisFrame.push(commandEncoder);
|
||||
// }
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue