From ab532a26089c6e2ecf761b45913c31d0b8118fd4 Mon Sep 17 00:00:00 2001 From: Maciej Samborski Date: Tue, 24 Dec 2024 21:12:41 +0100 Subject: [PATCH] Improved switching between textures and colors --- src/js/draw.js | 13 ++++--------- src/js/draw.ts | 13 ++++--------- src/js/graphics.js | 10 +++++++++- src/js/graphics.ts | 13 +++++++++++-- src/js/script.js | 24 ++++++++++++++++++++---- src/js/script.ts | 31 ++++++++++++++++++++++++++----- 6 files changed, 74 insertions(+), 30 deletions(-) diff --git a/src/js/draw.js b/src/js/draw.js index 926e8b7..52c0f2b 100644 --- a/src/js/draw.js +++ b/src/js/draw.js @@ -56,19 +56,14 @@ function drawRectangle(gfx, position, exts, color) { ]; a_position.data(gfx.ctx, points, gfx.ctx.STATIC_DRAW); a_tex_position.data(gfx.ctx, uv, gfx.ctx.STATIC_DRAW); - gfx.ctx.bindTexture(gfx.ctx.TEXTURE_2D, color.tex); + color.bind(gfx); gfx.ctx.drawArrays(gfx.ctx.TRIANGLES, 0, 6); + color.unbind(gfx); } else { const a_color = gfx.getAttribute("a_color"); - const colors = [ - color, - color, - color, - color, - color, - color, - ]; + const colors = new Array(6); + colors.fill(color); a_position.data(gfx.ctx, points, gfx.ctx.STATIC_DRAW); a_color.data(gfx.ctx, colors.flat(), gfx.ctx.STATIC_DRAW); gfx.ctx.drawArrays(gfx.ctx.TRIANGLES, 0, 6); diff --git a/src/js/draw.ts b/src/js/draw.ts index 685e151..2570725 100644 --- a/src/js/draw.ts +++ b/src/js/draw.ts @@ -70,19 +70,14 @@ function drawRectangle(gfx: Graphics, position: Vec2, exts: Vec2, color: Color | a_position.data(gfx.ctx, points, gfx.ctx.STATIC_DRAW); a_tex_position.data(gfx.ctx, uv, gfx.ctx.STATIC_DRAW); - gfx.ctx.bindTexture(gfx.ctx.TEXTURE_2D, color.tex); + color.bind(gfx); gfx.ctx.drawArrays(gfx.ctx.TRIANGLES, 0, 6); + color.unbind(gfx); } else { const a_color = gfx.getAttribute("a_color"); - const colors: Array = [ - color, - color, - color, - color, - color, - color, - ]; + const colors: Array = new Array(6); + colors.fill(color); a_position.data(gfx.ctx, points, gfx.ctx.STATIC_DRAW); a_color.data(gfx.ctx, colors.flat(), gfx.ctx.STATIC_DRAW); diff --git a/src/js/graphics.js b/src/js/graphics.js index b411e8d..64d9a0b 100644 --- a/src/js/graphics.js +++ b/src/js/graphics.js @@ -92,7 +92,6 @@ class Attribute { constructor(ctx, program, name) { this.loc = ctx.getAttribLocation(program, name); this.buffer = ctx.createBuffer(); - ctx.enableVertexAttribArray(this.loc); } format(size, type, normalized, stride, offset) { this.size = size; @@ -102,6 +101,7 @@ class Attribute { this.offset = offset; } data(ctx, data, usage) { + ctx.enableVertexAttribArray(this.loc); ctx.bindBuffer(ctx.ARRAY_BUFFER, this.buffer); ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(data), usage); ctx.vertexAttribPointer(this.loc, this.size, this.type, this.normalized, this.stride, this.offset); @@ -123,6 +123,14 @@ class Texture { ctx.bindTexture(ctx.TEXTURE_2D, null); return new Texture(tex); } + bind(gfx) { + gfx.ctx.uniform1i(gfx.getUniform("u_isTex"), 1); + gfx.ctx.bindTexture(gfx.ctx.TEXTURE_2D, this.tex); + } + unbind(gfx) { + gfx.ctx.bindTexture(gfx.ctx.TEXTURE_2D, null); + gfx.ctx.uniform1i(gfx.getUniform("u_isTex"), 0); + } } async function loadTexture(path) { return new Promise(resolve => { diff --git a/src/js/graphics.ts b/src/js/graphics.ts index 59f8375..4214bdd 100644 --- a/src/js/graphics.ts +++ b/src/js/graphics.ts @@ -118,8 +118,6 @@ class Attribute { constructor(ctx: WebGL2RenderingContext, program: WebGLProgram, name: string) { this.loc = ctx.getAttribLocation(program, name); this.buffer = ctx.createBuffer(); - - ctx.enableVertexAttribArray(this.loc); } format( @@ -137,6 +135,7 @@ class Attribute { } data(ctx: WebGL2RenderingContext, data: Array, usage: GLenum) { + ctx.enableVertexAttribArray(this.loc); ctx.bindBuffer(ctx.ARRAY_BUFFER, this.buffer); ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(data), usage); ctx.vertexAttribPointer(this.loc, this.size, this.type, this.normalized, this.stride, this.offset); @@ -163,6 +162,16 @@ class Texture { return new Texture(tex); } + + bind(gfx: Graphics) { + gfx.ctx.uniform1i(gfx.getUniform("u_isTex"), 1); + gfx.ctx.bindTexture(gfx.ctx.TEXTURE_2D, this.tex); + } + + unbind(gfx: Graphics) { + gfx.ctx.bindTexture(gfx.ctx.TEXTURE_2D, null); + gfx.ctx.uniform1i(gfx.getUniform("u_isTex"), 0); + } } async function loadTexture(path: string): Promise { diff --git a/src/js/script.js b/src/js/script.js index 3dadfb5..2fe64eb 100644 --- a/src/js/script.js +++ b/src/js/script.js @@ -6,14 +6,22 @@ const vertexShader = `#version 300 es in vec2 a_position; in vec2 a_tex_position; + in vec4 a_color; out vec2 v_tex_position; + out vec4 v_color; uniform mat4 u_matrix; + uniform bool u_isTex; void main() { vec4 transformed = u_matrix * vec4(a_position.xy, 0.0, 1.0); gl_Position = transformed; - v_tex_position = a_tex_position; + + if (u_isTex) { + v_tex_position = a_tex_position; + } else { + v_color = a_color; + } } `; const fragmentShader = `#version 300 es @@ -21,12 +29,18 @@ const fragmentShader = `#version 300 es precision highp float; in vec2 v_tex_position; + in vec4 v_color; out vec4 outColor; + uniform bool u_isTex; uniform sampler2D u_texture; void main() { - outColor = texture(u_texture, v_tex_position); + if (u_isTex) { + outColor = texture(u_texture, v_tex_position); + } else { + outColor = v_color; + } } `; function draw(gfx, angle, tex) { @@ -43,6 +57,7 @@ function draw(gfx, angle, tex) { m = m.mult(Mat4.rotation_z(angle)); gfx.ctx.uniformMatrix4fv(gfx.getUniform("u_matrix"), false, m.splat()); drawing.drawRectangle(gfx, new Vec2(gfx.ctx.canvas.width / 2 - 200, gfx.ctx.canvas.height / 2 - 200), new Vec2(400, 400), tex); + drawing.drawRectangle(gfx, new Vec2(100, 100), new Vec2(100, 100), [Math.sin(angle), Math.cos(angle), -Math.sin(angle), 1]); } (async () => { const canvasId = "game"; @@ -53,11 +68,12 @@ function draw(gfx, angle, tex) { fullscreenCanvas(gfx, canvasId); const a_position = gfx.createAttribute("a_position"); a_position.format(2, gfx.ctx.FLOAT, false, 0, 0); - //const a_color = gfx.createAttribute("a_color"); - //a_color.format(4, gfx.ctx.FLOAT, false, 0, 0); + const a_color = gfx.createAttribute("a_color"); + a_color.format(4, gfx.ctx.FLOAT, false, 0, 0); const a_tex_position = gfx.createAttribute("a_tex_position"); a_tex_position.format(2, gfx.ctx.FLOAT, false, 0, 0); gfx.createUniform("u_matrix"); + gfx.createUniform("u_isTex"); let city = await Texture.load(ctx, "../../assets/genetica/rt/City Night.jpg"); let angle = 0; let prevTimestamp = 0; diff --git a/src/js/script.ts b/src/js/script.ts index 5e1a546..20143a0 100644 --- a/src/js/script.ts +++ b/src/js/script.ts @@ -1,4 +1,4 @@ -import { initializeContext, Vec2, Mat4, Vec4 } from "./common.js"; +import { initializeContext, Vec2, Mat4 } from "./common.js"; import { Graphics, fullscreenCanvas, Texture } from "./graphics.js"; import * as drawing from "./draw.js"; import * as wasm from "./wasm.js"; @@ -8,14 +8,22 @@ const vertexShader = in vec2 a_position; in vec2 a_tex_position; + in vec4 a_color; out vec2 v_tex_position; + out vec4 v_color; uniform mat4 u_matrix; + uniform bool u_isTex; void main() { vec4 transformed = u_matrix * vec4(a_position.xy, 0.0, 1.0); gl_Position = transformed; - v_tex_position = a_tex_position; + + if (u_isTex) { + v_tex_position = a_tex_position; + } else { + v_color = a_color; + } } `; @@ -25,12 +33,18 @@ const fragmentShader = precision highp float; in vec2 v_tex_position; + in vec4 v_color; out vec4 outColor; + uniform bool u_isTex; uniform sampler2D u_texture; void main() { - outColor = texture(u_texture, v_tex_position); + if (u_isTex) { + outColor = texture(u_texture, v_tex_position); + } else { + outColor = v_color; + } } `; @@ -62,6 +76,12 @@ function draw(gfx: Graphics, angle: number, tex: Texture) { new Vec2(gfx.ctx.canvas.width / 2 - 200, gfx.ctx.canvas.height / 2 - 200), new Vec2(400, 400), tex); + + drawing.drawRectangle( + gfx, + new Vec2(100, 100), + new Vec2(100, 100), + [Math.sin(angle), Math.cos(angle), -Math.sin(angle), 1]); } (async () => { @@ -75,13 +95,14 @@ function draw(gfx: Graphics, angle: number, tex: Texture) { const a_position = gfx.createAttribute("a_position"); a_position.format(2, gfx.ctx.FLOAT, false, 0, 0); - //const a_color = gfx.createAttribute("a_color"); - //a_color.format(4, gfx.ctx.FLOAT, false, 0, 0); + const a_color = gfx.createAttribute("a_color"); + a_color.format(4, gfx.ctx.FLOAT, false, 0, 0); const a_tex_position = gfx.createAttribute("a_tex_position"); a_tex_position.format(2, gfx.ctx.FLOAT, false, 0, 0); gfx.createUniform("u_matrix"); + gfx.createUniform("u_isTex"); let city = await Texture.load(ctx, "../../assets/genetica/rt/City Night.jpg");