Added support for Textures
|
@ -0,0 +1,3 @@
|
|||
For a description of the contents of this pack, usage rights, and other useful details, go here:
|
||||
|
||||
http://blog.spiralgraphics.biz/2011/02/nine-cartoon-backdrops.html
|
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 105 KiB |
After Width: | Height: | Size: 132 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 137 KiB |
After Width: | Height: | Size: 82 KiB |
|
@ -1,4 +1,5 @@
|
|||
import { Vec2 } from "./common.js";
|
||||
import { Texture } from "./graphics.js";
|
||||
function drawTriangle(gfx, positions, color) {
|
||||
const a_position = gfx.getAttribute("a_position");
|
||||
const a_color = gfx.getAttribute("a_color");
|
||||
|
@ -35,7 +36,6 @@ function drawTriangleExts(gfx, position, exts, color) {
|
|||
}
|
||||
function drawRectangle(gfx, position, exts, color) {
|
||||
const a_position = gfx.getAttribute("a_position");
|
||||
const a_color = gfx.getAttribute("a_color");
|
||||
const points = [
|
||||
position.x, position.y,
|
||||
position.x + exts.x, position.y,
|
||||
|
@ -44,17 +44,35 @@ function drawRectangle(gfx, position, exts, color) {
|
|||
position.x + exts.x, position.y,
|
||||
position.x, position.y + exts.y,
|
||||
];
|
||||
const colors = [
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
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);
|
||||
if (color instanceof Texture) {
|
||||
const a_tex_position = gfx.getAttribute("a_tex_position");
|
||||
const uv = [
|
||||
0.0, 0.0,
|
||||
-1.0, 0.0,
|
||||
0.0, -1.0,
|
||||
-1.0, -1.0,
|
||||
-1.0, 0.0,
|
||||
0.0, -1.0,
|
||||
];
|
||||
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);
|
||||
gfx.ctx.drawArrays(gfx.ctx.TRIANGLES, 0, 6);
|
||||
}
|
||||
else {
|
||||
const a_color = gfx.getAttribute("a_color");
|
||||
const colors = [
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
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);
|
||||
}
|
||||
}
|
||||
function drawCircle(gfx, position, radius, color) {
|
||||
const points = new Array();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Vec2, Color } from "./common.js"
|
||||
import { Graphics } from "./graphics.js";
|
||||
import { Graphics, Texture } from "./graphics.js";
|
||||
|
||||
function drawTriangle(gfx: Graphics, positions: [Vec2, Vec2, Vec2], color: Color) {
|
||||
const a_position = gfx.getAttribute("a_position");
|
||||
|
@ -43,9 +43,8 @@ function drawTriangleExts(gfx: Graphics, position: Vec2, exts: Vec2, color: Colo
|
|||
gfx.ctx.drawArrays(gfx.ctx.TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
function drawRectangle(gfx: Graphics, position: Vec2, exts: Vec2, color: Color) {
|
||||
function drawRectangle(gfx: Graphics, position: Vec2, exts: Vec2, color: Color | Texture) {
|
||||
const a_position = gfx.getAttribute("a_position");
|
||||
const a_color = gfx.getAttribute("a_color");
|
||||
|
||||
const points: Array<number> = [
|
||||
position.x, position.y,
|
||||
|
@ -57,18 +56,38 @@ function drawRectangle(gfx: Graphics, position: Vec2, exts: Vec2, color: Color)
|
|||
position.x, position.y + exts.y,
|
||||
]
|
||||
|
||||
const colors: Array<number[]> = [
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
];
|
||||
if (color instanceof Texture) {
|
||||
const a_tex_position = gfx.getAttribute("a_tex_position");
|
||||
|
||||
const uv: Array<number> = [
|
||||
0.0, 0.0,
|
||||
-1.0, 0.0,
|
||||
0.0, -1.0,
|
||||
-1.0, -1.0,
|
||||
-1.0, 0.0,
|
||||
0.0, -1.0,
|
||||
];
|
||||
|
||||
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);
|
||||
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);
|
||||
gfx.ctx.drawArrays(gfx.ctx.TRIANGLES, 0, 6);
|
||||
} else {
|
||||
const a_color = gfx.getAttribute("a_color");
|
||||
|
||||
const colors: Array<number[]> = [
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -107,4 +107,30 @@ class Attribute {
|
|||
ctx.vertexAttribPointer(this.loc, this.size, this.type, this.normalized, this.stride, this.offset);
|
||||
}
|
||||
}
|
||||
export { fullscreenCanvas, Graphics, Attribute };
|
||||
class Texture {
|
||||
tex;
|
||||
constructor(tex) {
|
||||
this.tex = tex;
|
||||
}
|
||||
static async load(ctx, path) {
|
||||
let image = await loadTexture(path);
|
||||
let tex = ctx.createTexture();
|
||||
ctx.bindTexture(ctx.TEXTURE_2D, tex);
|
||||
ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image);
|
||||
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR);
|
||||
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR_MIPMAP_NEAREST);
|
||||
ctx.generateMipmap(ctx.TEXTURE_2D);
|
||||
ctx.bindTexture(ctx.TEXTURE_2D, null);
|
||||
return new Texture(tex);
|
||||
}
|
||||
}
|
||||
async function loadTexture(path) {
|
||||
return new Promise(resolve => {
|
||||
const img = new Image();
|
||||
img.addEventListener("load", () => {
|
||||
resolve(img);
|
||||
});
|
||||
img.src = path;
|
||||
});
|
||||
}
|
||||
export { Texture, fullscreenCanvas, Graphics, Attribute };
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { Vec2 } from "./common.js"
|
||||
|
||||
function fullscreenCanvas(gfx: Graphics, id: string) {
|
||||
const canvas = document.getElementById(id) as HTMLCanvasElement;
|
||||
canvas.width = window.innerWidth;
|
||||
|
@ -145,4 +143,36 @@ class Attribute {
|
|||
}
|
||||
}
|
||||
|
||||
export { fullscreenCanvas, Graphics, Attribute }
|
||||
class Texture {
|
||||
tex: WebGLTexture | null;
|
||||
|
||||
constructor(tex: WebGLTexture) {
|
||||
this.tex = tex;
|
||||
}
|
||||
|
||||
static async load(ctx: WebGL2RenderingContext, path: string): Promise<Texture> {
|
||||
let image = await loadTexture(path);
|
||||
|
||||
let tex = ctx.createTexture();
|
||||
ctx.bindTexture(ctx.TEXTURE_2D, tex);
|
||||
ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image);
|
||||
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR);
|
||||
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR_MIPMAP_NEAREST);
|
||||
ctx.generateMipmap(ctx.TEXTURE_2D);
|
||||
ctx.bindTexture(ctx.TEXTURE_2D, null);
|
||||
|
||||
return new Texture(tex);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadTexture(path: string): Promise<HTMLImageElement> {
|
||||
return new Promise(resolve => {
|
||||
const img = new Image();
|
||||
img.addEventListener("load", () => {
|
||||
resolve(img);
|
||||
})
|
||||
img.src = path;
|
||||
});
|
||||
}
|
||||
|
||||
export { Texture, fullscreenCanvas, Graphics, Attribute }
|
||||
|
|
|
@ -1,32 +1,35 @@
|
|||
import { initializeContext, Vec2, Mat4 } from "./common.js";
|
||||
import { Graphics, fullscreenCanvas } from "./graphics.js";
|
||||
import { Graphics, fullscreenCanvas, Texture } from "./graphics.js";
|
||||
import * as drawing from "./draw.js";
|
||||
import * as wasm from "./wasm.js";
|
||||
const vertexShader = `#version 300 es
|
||||
|
||||
in vec2 a_position;
|
||||
in vec4 a_color;
|
||||
out vec4 color;
|
||||
in vec2 a_tex_position;
|
||||
out vec2 v_tex_position;
|
||||
uniform mat4 u_matrix;
|
||||
|
||||
void main() {
|
||||
vec4 transformed = u_matrix * vec4(a_position.xy, 0.0, 1.0);
|
||||
|
||||
gl_Position = transformed;
|
||||
color = a_color;
|
||||
v_tex_position = a_tex_position;
|
||||
}
|
||||
`;
|
||||
const fragmentShader = `#version 300 es
|
||||
|
||||
precision highp float;
|
||||
in vec4 color;
|
||||
|
||||
in vec2 v_tex_position;
|
||||
out vec4 outColor;
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
void main() {
|
||||
outColor = color;
|
||||
outColor = texture(u_texture, v_tex_position);
|
||||
}
|
||||
`;
|
||||
function draw(gfx, angle) {
|
||||
function draw(gfx, angle, tex) {
|
||||
gfx.clear(0, 0, 0, 0);
|
||||
let left = 0;
|
||||
let right = gfx.ctx.canvas.width;
|
||||
|
@ -39,7 +42,7 @@ function draw(gfx, angle) {
|
|||
m = m.mult(Mat4.rotation_y(angle));
|
||||
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 - 50, gfx.ctx.canvas.height / 2 - 50), new Vec2(100, 100), [1, 0, 0, 1]);
|
||||
drawing.drawRectangle(gfx, new Vec2(gfx.ctx.canvas.width / 2 - 200, gfx.ctx.canvas.height / 2 - 200), new Vec2(400, 400), tex);
|
||||
}
|
||||
(async () => {
|
||||
const canvasId = "game";
|
||||
|
@ -50,16 +53,19 @@ function draw(gfx, angle) {
|
|||
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");
|
||||
let city = await Texture.load(ctx, "../../assets/genetica/rt/City Night.jpg");
|
||||
let angle = 0;
|
||||
let prevTimestamp = 0;
|
||||
const frame = (timestamp) => {
|
||||
const deltaTime = (timestamp - prevTimestamp) / 1000;
|
||||
prevTimestamp = timestamp;
|
||||
fullscreenCanvas(gfx, "game");
|
||||
draw(gfx, angle);
|
||||
draw(gfx, angle, city);
|
||||
angle += Math.PI * deltaTime * 0.5;
|
||||
window.requestAnimationFrame(frame);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { initializeContext, Vec2, Mat4, Vec4 } from "./common.js";
|
||||
import { Graphics, fullscreenCanvas } from "./graphics.js";
|
||||
import { Graphics, fullscreenCanvas, Texture } from "./graphics.js";
|
||||
import * as drawing from "./draw.js";
|
||||
import * as wasm from "./wasm.js";
|
||||
|
||||
|
@ -7,15 +7,15 @@ const vertexShader =
|
|||
`#version 300 es
|
||||
|
||||
in vec2 a_position;
|
||||
in vec4 a_color;
|
||||
out vec4 color;
|
||||
in vec2 a_tex_position;
|
||||
out vec2 v_tex_position;
|
||||
uniform mat4 u_matrix;
|
||||
|
||||
void main() {
|
||||
vec4 transformed = u_matrix * vec4(a_position.xy, 0.0, 1.0);
|
||||
|
||||
gl_Position = transformed;
|
||||
color = a_color;
|
||||
v_tex_position = a_tex_position;
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -23,17 +23,20 @@ const fragmentShader =
|
|||
`#version 300 es
|
||||
|
||||
precision highp float;
|
||||
in vec4 color;
|
||||
|
||||
in vec2 v_tex_position;
|
||||
out vec4 outColor;
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
void main() {
|
||||
outColor = color;
|
||||
outColor = texture(u_texture, v_tex_position);
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
|
||||
function draw(gfx: Graphics, angle: number) {
|
||||
function draw(gfx: Graphics, angle: number, tex: Texture) {
|
||||
gfx.clear(0, 0, 0, 0);
|
||||
|
||||
let left = 0;
|
||||
|
@ -56,9 +59,9 @@ function draw(gfx: Graphics, angle: number) {
|
|||
|
||||
drawing.drawRectangle(
|
||||
gfx,
|
||||
new Vec2(gfx.ctx.canvas.width / 2 - 50, gfx.ctx.canvas.height / 2 - 50),
|
||||
new Vec2(100, 100),
|
||||
[1, 0, 0, 1]);
|
||||
new Vec2(gfx.ctx.canvas.width / 2 - 200, gfx.ctx.canvas.height / 2 - 200),
|
||||
new Vec2(400, 400),
|
||||
tex);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
|
@ -72,11 +75,16 @@ function draw(gfx: Graphics, angle: number) {
|
|||
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");
|
||||
|
||||
let city = await Texture.load(ctx, "../../assets/genetica/rt/City Night.jpg");
|
||||
|
||||
let angle = 0;
|
||||
let prevTimestamp = 0;
|
||||
const frame = (timestamp: number) => {
|
||||
|
@ -84,7 +92,7 @@ function draw(gfx: Graphics, angle: number) {
|
|||
prevTimestamp = timestamp;
|
||||
|
||||
fullscreenCanvas(gfx, "game");
|
||||
draw(gfx, angle);
|
||||
draw(gfx, angle, city);
|
||||
angle += Math.PI * deltaTime * 0.5;
|
||||
|
||||
window.requestAnimationFrame(frame);
|
||||
|
|