diff --git a/src/main.ts b/src/main.ts index 274412e..3bc574b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,12 @@ import { showError } from "./debug"; 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 triangle from "./shapes/triangle.json"; + function render() { const canvas = document.querySelector("#canvas"); if (!canvas) { @@ -11,6 +17,20 @@ function render() { if (!gl) { throw new Error("This browser does not support WebGL"); } + + const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource); + const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource); + const program = loadProgram(gl, vertexShader, fragmentShader); + + const vertexPositionAttribLocation = gl.getAttribLocation(program, "vertexPosition"); + if (vertexPositionAttribLocation < 0) { + throw new Error("Failed to get attrib location for vertexPosition"); + } + + const verts = new Float32Array(triangle.vertices); + const buffer = loadBuffer(gl, verts); + + drawVertex(gl, program, vertexPositionAttribLocation, buffer, gl.TRIANGLES, verts.length); } try { diff --git a/src/shaders.ts b/src/shaderUtils.ts similarity index 51% rename from src/shaders.ts rename to src/shaderUtils.ts index 47ba477..c073ea0 100644 --- a/src/shaders.ts +++ b/src/shaderUtils.ts @@ -11,6 +11,8 @@ export function loadShader(gl: WebGLRenderingContext, type: GLenum, source: stri const compileError = gl.getShaderInfoLog(shader); throw new Error("Error when compiling shader: " + compileError); } + + return shader; } @@ -28,4 +30,40 @@ export function loadProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader const linkError = gl.getProgramInfoLog(program); throw new Error("Error when linking program: " + linkError); } + + return program; +} + + +export function drawVertex(gl: WebGLRenderingContext, program: WebGLProgram, 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.useProgram(program); + 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: WebGLRenderingContext, vertices: Float32Array) { + const buffer = gl.createBuffer(); + if (!buffer) { + throw new Error("WebGL fails to create buffer"); + } + + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); + + return buffer; } \ No newline at end of file diff --git a/src/shaders/basic.frag b/src/shaders/basic.frag new file mode 100644 index 0000000..73f137d --- /dev/null +++ b/src/shaders/basic.frag @@ -0,0 +1,5 @@ +precision mediump float; + +void main() { + gl_FragColor = vec4(0.22745, 0.35294, 0.25098, 1.0); +} \ No newline at end of file diff --git a/src/shaders/basic.vert b/src/shaders/basic.vert new file mode 100644 index 0000000..695fa40 --- /dev/null +++ b/src/shaders/basic.vert @@ -0,0 +1,6 @@ +precision mediump float; +attribute vec2 vertexPosition; + +void main() { + gl_Position = vec4(vertexPosition, 0.0, 1.0); +} \ No newline at end of file diff --git a/src/shapes/triangle.json b/src/shapes/triangle.json new file mode 100644 index 0000000..e24a600 --- /dev/null +++ b/src/shapes/triangle.json @@ -0,0 +1,8 @@ +{ + "name": "triangle", + "vertices": [ + 0.0, -0.5, + 0.3, 0.5, + -0.3, 0.5 + ] +} \ No newline at end of file