Improved switching between textures and colors

This commit is contained in:
Maciej Samborski 2024-12-24 21:12:41 +01:00
parent 2c81bc0684
commit ab532a2608
6 changed files with 74 additions and 30 deletions

View File

@ -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);

View File

@ -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<number[]> = [
color,
color,
color,
color,
color,
color,
];
const colors: Array<number[]> = 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);

View File

@ -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 => {

View File

@ -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<number>, 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<HTMLImageElement> {

View File

@ -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;

View File

@ -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");