diff --git a/src/geometry/Shape2D.ts b/src/geometry/Shape2D.ts index 8c860d0..18c124b 100644 --- a/src/geometry/Shape2D.ts +++ b/src/geometry/Shape2D.ts @@ -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, ) {} } \ No newline at end of file diff --git a/src/geometry/Triangle.ts b/src/geometry/Triangle.ts deleted file mode 100644 index 687a7e8..0000000 --- a/src/geometry/Triangle.ts +++ /dev/null @@ -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])); - } -} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 6388add..229de28 100644 --- a/src/main.ts +++ b/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("#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 { diff --git a/src/shaderUtils.ts b/src/shaderUtils.ts index 6e18d8c..c95b791 100644 --- a/src/shaderUtils.ts +++ b/src/shaderUtils.ts @@ -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) { diff --git a/src/shaders/basic.frag b/src/shaders/basic.frag index d21c455..c5cbba4 100644 --- a/src/shaders/basic.frag +++ b/src/shaders/basic.frag @@ -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); } \ No newline at end of file diff --git a/src/shaders/basic.vert b/src/shaders/basic.vert index f34c338..5f63269 100644 --- a/src/shaders/basic.vert +++ b/src/shaders/basic.vert @@ -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); } \ No newline at end of file diff --git a/src/vaoUtils.ts b/src/vaoUtils.ts new file mode 100644 index 0000000..2187814 --- /dev/null +++ b/src/vaoUtils.ts @@ -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; +} \ No newline at end of file diff --git a/src/verts/triangle.json b/src/verts/triangle.json new file mode 100644 index 0000000..38e6875 --- /dev/null +++ b/src/verts/triangle.json @@ -0,0 +1,3 @@ +{ + "vertices": [0.0, -1, 0.6, 1, -0.6, 1] +} \ No newline at end of file