Use VAOs to simplify rendering logic
This commit is contained in:
parent
ecfe53f705
commit
0e281bcbbc
@ -3,6 +3,9 @@ import Vector2D from "./Vector2D";
|
||||
export default class Shape2D {
|
||||
constructor(
|
||||
public position: Vector2D,
|
||||
public vertices: Float32Array,
|
||||
public scale: number,
|
||||
public color: [number, number, number],
|
||||
public verticesCount: number,
|
||||
public vao: WebGLVertexArrayObject,
|
||||
) {}
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
import Shape2D from "./Shape2D";
|
||||
import Vector2D from "./Vector2D";
|
||||
|
||||
export default class Triangle extends Shape2D {
|
||||
constructor(
|
||||
public position: Vector2D,
|
||||
) {
|
||||
super(position, new Float32Array([0.0, -0.5, 0.3, 0.5, -0.3, 0.5]));
|
||||
}
|
||||
}
|
||||
49
src/main.ts
49
src/main.ts
@ -3,12 +3,13 @@ import "./style.css";
|
||||
|
||||
import vsSource from "./shaders/basic.vert?raw";
|
||||
import fsSource from "./shaders/basic.frag?raw";
|
||||
import { drawVertex, loadBuffer, loadProgram, loadShader } from "./shaderUtils";
|
||||
import { loadBuffer, loadProgram, loadShader } from "./shaderUtils";
|
||||
|
||||
import Triangle from "./geometry/Triangle";
|
||||
import Vector2D from "./geometry/Vector2D";
|
||||
import { createBasicVao } from "./vaoUtils";
|
||||
import Shape2D from "./geometry/Shape2D";
|
||||
|
||||
const triangle = new Triangle(new Vector2D(0, 0));
|
||||
import triangle from "./verts/triangle.json";
|
||||
|
||||
function render() {
|
||||
const canvas = document.querySelector<HTMLCanvasElement>("#canvas");
|
||||
@ -23,7 +24,6 @@ function render() {
|
||||
|
||||
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
|
||||
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
|
||||
|
||||
const program = loadProgram(gl, vertexShader, fragmentShader);
|
||||
gl.useProgram(program);
|
||||
|
||||
@ -32,17 +32,44 @@ function render() {
|
||||
throw new Error("Failed to get attrib location for vertexPosition");
|
||||
}
|
||||
|
||||
const verts = new Float32Array(triangle.vertices);
|
||||
const buffer = loadBuffer(gl, verts);
|
||||
const triangleVerts = new Float32Array(triangle.vertices);
|
||||
const triangleBuffer = loadBuffer(gl, triangleVerts);
|
||||
const triangleVao = createBasicVao(gl, triangleBuffer, vertexPositionAttribLocation);
|
||||
|
||||
const fragmentColor = gl.getUniformLocation(program, "uColor");
|
||||
if (!fragmentColor) {
|
||||
throw new Error("Uniform uColor not found");
|
||||
const shapes: Shape2D[] = [
|
||||
new Shape2D(new Vector2D(300, 300), 200, [0.22745, 0.35294, 0.25098], 3, triangleVao),
|
||||
new Shape2D(new Vector2D(800, 300), 100, [0.22745, 0.35294, 0.25098], 3, triangleVao),
|
||||
]
|
||||
|
||||
const fragmentColorUniform = gl.getUniformLocation(program, "uColor");
|
||||
const canvasSizeUniform = gl.getUniformLocation(program, "uCanvasSize");
|
||||
const shapeLocationUniform = gl.getUniformLocation(program, "uLocation");
|
||||
const shapeScaleUniform = gl.getUniformLocation(program, "uScale");
|
||||
if (!(fragmentColorUniform && canvasSizeUniform && shapeLocationUniform && shapeScaleUniform)) {
|
||||
throw new Error(`Some uniform not found:
|
||||
${fragmentColorUniform ? "" : "uColor"};
|
||||
${canvasSizeUniform ? "" : "uCanvasSize"};
|
||||
${shapeLocationUniform ? "" : "uLocation"};
|
||||
${shapeScaleUniform ? "" : "uScale"};
|
||||
`);
|
||||
}
|
||||
|
||||
gl.uniform4f(fragmentColor, 0.22745, 0.35294, 0.25098, 1.0);
|
||||
canvas.width = canvas.clientWidth;
|
||||
canvas.height = canvas.clientHeight;
|
||||
gl.clearColor(0.1, 0.1, 0.1, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
gl.uniform2f(canvasSizeUniform, canvas.width, canvas.height);
|
||||
|
||||
shapes.forEach((shape) => {
|
||||
gl.uniform3f(fragmentColorUniform, shape.color[0], shape.color[1], shape.color[2]);
|
||||
gl.uniform2f(shapeLocationUniform, shape.position.x, shape.position.y);
|
||||
gl.uniform1f(shapeScaleUniform, shape.scale);
|
||||
|
||||
gl.bindVertexArray(shape.vao);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, shape.verticesCount);
|
||||
})
|
||||
|
||||
drawVertex(gl, vertexPositionAttribLocation, buffer, gl.TRIANGLES, verts.length);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@ -35,26 +35,6 @@ export function loadProgram(gl: WebGL2RenderingContext, vertexShader: WebGLShade
|
||||
}
|
||||
|
||||
|
||||
export function drawVertex(gl: WebGL2RenderingContext, vertexAttribArrayLocation: GLuint, buffer: WebGLBuffer, mode: GLenum, length: number) {
|
||||
gl.clearColor(0.1, 0.1, 0.1, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
gl.enableVertexAttribArray(vertexAttribArrayLocation);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||
|
||||
gl.vertexAttribPointer(
|
||||
vertexAttribArrayLocation,
|
||||
2,
|
||||
gl.FLOAT,
|
||||
false,
|
||||
2 * Float32Array.BYTES_PER_ELEMENT,
|
||||
0,
|
||||
);
|
||||
|
||||
gl.drawArrays(mode, 0, length / 2);
|
||||
}
|
||||
|
||||
|
||||
export function loadBuffer(gl: WebGL2RenderingContext, vertices: Float32Array) {
|
||||
const buffer = gl.createBuffer();
|
||||
if (!buffer) {
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
#version 300 es
|
||||
precision mediump float;
|
||||
|
||||
uniform vec4 uColor;
|
||||
uniform vec3 uColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = uColor;
|
||||
fragColor = vec4(uColor, 1.0);
|
||||
}
|
||||
@ -1,8 +1,15 @@
|
||||
#version 300 es
|
||||
precision mediump float;
|
||||
|
||||
uniform vec2 uCanvasSize;
|
||||
uniform vec2 uLocation;
|
||||
uniform float uScale;
|
||||
|
||||
in vec2 vertexPosition;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(vertexPosition, 0.0, 1.0);
|
||||
vec2 finalVertexPosition = vertexPosition * uScale + uLocation;
|
||||
vec2 clipPosition = (finalVertexPosition / uCanvasSize) * 2.0 - 1.0;
|
||||
|
||||
gl_Position = vec4(clipPosition, 0.0, 1.0);
|
||||
}
|
||||
15
src/vaoUtils.ts
Normal file
15
src/vaoUtils.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export function createBasicVao(gl: WebGL2RenderingContext, buffer: WebGLBuffer, attrib: number) {
|
||||
const vao = gl.createVertexArray();
|
||||
if (!vao) {
|
||||
throw new Error("Failed to create VAO");
|
||||
}
|
||||
|
||||
gl.bindVertexArray(vao);
|
||||
gl.enableVertexAttribArray(attrib);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||
gl.vertexAttribPointer(attrib, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.bindVertexArray(null);
|
||||
|
||||
return vao;
|
||||
}
|
||||
3
src/verts/triangle.json
Normal file
3
src/verts/triangle.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"vertices": [0.0, -1, 0.6, 1, -0.6, 1]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user