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 {
|
export default class Shape2D {
|
||||||
constructor(
|
constructor(
|
||||||
public position: Vector2D,
|
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 vsSource from "./shaders/basic.vert?raw";
|
||||||
import fsSource from "./shaders/basic.frag?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 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() {
|
function render() {
|
||||||
const canvas = document.querySelector<HTMLCanvasElement>("#canvas");
|
const canvas = document.querySelector<HTMLCanvasElement>("#canvas");
|
||||||
@ -23,7 +24,6 @@ function render() {
|
|||||||
|
|
||||||
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
|
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
|
||||||
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
|
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
|
||||||
|
|
||||||
const program = loadProgram(gl, vertexShader, fragmentShader);
|
const program = loadProgram(gl, vertexShader, fragmentShader);
|
||||||
gl.useProgram(program);
|
gl.useProgram(program);
|
||||||
|
|
||||||
@ -32,17 +32,44 @@ function render() {
|
|||||||
throw new Error("Failed to get attrib location for vertexPosition");
|
throw new Error("Failed to get attrib location for vertexPosition");
|
||||||
}
|
}
|
||||||
|
|
||||||
const verts = new Float32Array(triangle.vertices);
|
const triangleVerts = new Float32Array(triangle.vertices);
|
||||||
const buffer = loadBuffer(gl, verts);
|
const triangleBuffer = loadBuffer(gl, triangleVerts);
|
||||||
|
const triangleVao = createBasicVao(gl, triangleBuffer, vertexPositionAttribLocation);
|
||||||
|
|
||||||
const fragmentColor = gl.getUniformLocation(program, "uColor");
|
const shapes: Shape2D[] = [
|
||||||
if (!fragmentColor) {
|
new Shape2D(new Vector2D(300, 300), 200, [0.22745, 0.35294, 0.25098], 3, triangleVao),
|
||||||
throw new Error("Uniform uColor not found");
|
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 {
|
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) {
|
export function loadBuffer(gl: WebGL2RenderingContext, vertices: Float32Array) {
|
||||||
const buffer = gl.createBuffer();
|
const buffer = gl.createBuffer();
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
#version 300 es
|
#version 300 es
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
uniform vec4 uColor;
|
uniform vec3 uColor;
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
fragColor = uColor;
|
fragColor = vec4(uColor, 1.0);
|
||||||
}
|
}
|
||||||
@ -1,8 +1,15 @@
|
|||||||
#version 300 es
|
#version 300 es
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
|
uniform vec2 uCanvasSize;
|
||||||
|
uniform vec2 uLocation;
|
||||||
|
uniform float uScale;
|
||||||
|
|
||||||
in vec2 vertexPosition;
|
in vec2 vertexPosition;
|
||||||
|
|
||||||
void main() {
|
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