Mesh chunks

This commit is contained in:
2026-03-13 09:30:41 -03:00
parent e890c561cd
commit 9db229dde4
6 changed files with 141 additions and 54 deletions
+39 -5
View File
@@ -9,13 +9,14 @@ const VERTS_PER_SPRITE = 6;
const FLOATS_PER_VERT = 9;
let program: WebGLProgram;
let buffer: WebGLBuffer;
let main_buffer: WebGLBuffer;
const vertex_data = new Float32Array(MAX_SPRITES * VERTS_PER_SPRITE * FLOATS_PER_VERT);
let vert_index = 0;
let pos_loc: GLint;
let uv_loc: GLint;
let color_loc: GLint;
let texture_loc: WebGLUniformLocation | null;
let mvp_loc: WebGLUniformLocation | null;
let col_diffuse_loc: WebGLUniformLocation | null;
@@ -75,8 +76,8 @@ export function init_window(canvas_element: HTMLCanvasElement) {
program = create_program(vertex_src, fragment_src);
buffer = gl.createBuffer()!;
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
main_buffer = gl.createBuffer()!;
gl.bindBuffer(gl.ARRAY_BUFFER, main_buffer);
const stride = FLOATS_PER_VERT * 4;
@@ -88,7 +89,7 @@ export function init_window(canvas_element: HTMLCanvasElement) {
gl.enableVertexAttribArray(uv_loc);
gl.vertexAttribPointer(uv_loc, 2, gl.FLOAT, false, stride, 12);
const color_loc = gl.getAttribLocation(program, "vertexColor");
color_loc = gl.getAttribLocation(program, "vertexColor");
gl.enableVertexAttribArray(color_loc);
gl.vertexAttribPointer(color_loc, 4, gl.FLOAT, false, stride, 20);
@@ -153,6 +154,9 @@ export function begin_mode_3d(new_camera: Camera) {
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.depthMask(true);
gl.enable(gl.POLYGON_OFFSET_FILL);
gl.polygonOffset(1, 1);
update_camera();
}
@@ -167,6 +171,8 @@ export function end_mode_3d() {
mode3d = false;
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
gl.depthMask(false);
gl.disable(gl.POLYGON_OFFSET_FILL);
}
export function clear_background(r: number, g: number, b: number, a = 1) {
@@ -179,7 +185,7 @@ export function flush_batch() {
return;
}
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bindBuffer(gl.ARRAY_BUFFER, main_buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertex_data.subarray(0, vert_index), gl.STREAM_DRAW);
if (mode3d) {
@@ -188,6 +194,11 @@ export function flush_batch() {
gl.uniformMatrix4fv(mvp_loc, false, ortho);
}
const stride = FLOATS_PER_VERT * 4;
gl.vertexAttribPointer(pos_loc, 3, gl.FLOAT, false, stride, 0);
gl.vertexAttribPointer(uv_loc, 2, gl.FLOAT, false, stride, 12);
gl.vertexAttribPointer(color_loc, 4, gl.FLOAT, false, stride, 20);
gl.uniform4f(col_diffuse_loc, 1, 1, 1, 1);
gl.activeTexture(gl.TEXTURE0);
@@ -199,6 +210,29 @@ export function flush_batch() {
vert_index = 0;
}
export function flush_buffer(buffer: WebGLBuffer, draw_count: number) {
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
if (mode3d) {
gl.uniformMatrix4fv(mvp_loc, false, mvp);
} else {
gl.uniformMatrix4fv(mvp_loc, false, ortho);
}
const stride = FLOATS_PER_VERT * 4;
gl.vertexAttribPointer(pos_loc, 3, gl.FLOAT, false, stride, 0);
gl.vertexAttribPointer(uv_loc, 2, gl.FLOAT, false, stride, 12);
gl.vertexAttribPointer(color_loc, 4, gl.FLOAT, false, stride, 20);
gl.uniform4f(col_diffuse_loc, 1, 1, 1, 1);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, current_texture);
gl.uniform1i(texture_loc, 0);
gl.drawArrays(gl.TRIANGLES, 0, draw_count);
}
export function resize_canvas() {
const width = self.innerWidth;
const height = self.innerHeight;
+61 -43
View File
@@ -1,7 +1,8 @@
import { flush_batch, get_current_texture, push_vertex, set_current_texture } from "./core.ts";
import { Texture } from "./types.ts";
export function push_cube(
export function push_cube_to_mesh(
vertices: number[],
vertex_count: number,
texture: Texture,
x: number,
y: number,
@@ -24,11 +25,6 @@ export function push_cube(
top = true,
bottom = true,
) {
if (get_current_texture() !== texture.tex) {
flush_batch();
set_current_texture(texture.tex);
}
const x2 = x + w;
const y2 = y + h;
const z2 = z + d;
@@ -38,63 +34,85 @@ export function push_cube(
const u1 = (sx + sw) / texture.width;
const v1 = (sy + sh) / texture.height;
let i = vertex_count;
const push = (px: number, py: number, pz: number, u: number, vv: number) => {
vertices[i++] = px;
vertices[i++] = py;
vertices[i++] = pz;
vertices[i++] = u;
vertices[i++] = vv;
vertices[i++] = r;
vertices[i++] = g;
vertices[i++] = b;
vertices[i++] = a;
};
// front (+z)
if (front) {
push_vertex(x, y, z2, u0, v0, r, g, b, a);
push_vertex(x2, y, z2, u1, v0, r, g, b, a);
push_vertex(x, y2, z2, u0, v1, r, g, b, a);
push_vertex(x2, y, z2, u1, v0, r, g, b, a);
push_vertex(x2, y2, z2, u1, v1, r, g, b, a);
push_vertex(x, y2, z2, u0, v1, r, g, b, a);
push(x, y, z2, u0, v1);
push(x2, y, z2, u1, v1);
push(x2, y2, z2, u1, v0);
push(x, y, z2, u0, v1);
push(x2, y2, z2, u1, v0);
push(x, y2, z2, u0, v0);
}
// back (-z)
if (back) {
push_vertex(x2, y, z, u0, v0, r, g, b, a);
push_vertex(x, y, z, u1, v0, r, g, b, a);
push_vertex(x2, y2, z, u0, v1, r, g, b, a);
push_vertex(x, y, z, u1, v0, r, g, b, a);
push_vertex(x, y2, z, u1, v1, r, g, b, a);
push_vertex(x2, y2, z, u0, v1, r, g, b, a);
push(x2, y, z, u0, v1);
push(x, y, z, u1, v1);
push(x, y2, z, u1, v0);
push(x2, y, z, u0, v1);
push(x, y2, z, u1, v0);
push(x2, y2, z, u0, v0);
}
// left (-x)
if (left) {
push_vertex(x, y, z, u0, v0, r, g, b, a);
push_vertex(x, y, z2, u1, v0, r, g, b, a);
push_vertex(x, y2, z, u0, v1, r, g, b, a);
push_vertex(x, y, z2, u1, v0, r, g, b, a);
push_vertex(x, y2, z2, u1, v1, r, g, b, a);
push_vertex(x, y2, z, u0, v1, r, g, b, a);
push(x, y, z, u0, v1);
push(x, y, z2, u1, v1);
push(x, y2, z2, u1, v0);
push(x, y, z, u0, v1);
push(x, y2, z2, u1, v0);
push(x, y2, z, u0, v0);
}
// right (+x)
if (right) {
push_vertex(x2, y, z2, u0, v0, r, g, b, a);
push_vertex(x2, y, z, u1, v0, r, g, b, a);
push_vertex(x2, y2, z2, u0, v1, r, g, b, a);
push_vertex(x2, y, z, u1, v0, r, g, b, a);
push_vertex(x2, y2, z, u1, v1, r, g, b, a);
push_vertex(x2, y2, z2, u0, v1, r, g, b, a);
push(x2, y, z2, u0, v1);
push(x2, y, z, u1, v1);
push(x2, y2, z, u1, v0);
push(x2, y, z2, u0, v1);
push(x2, y2, z, u1, v0);
push(x2, y2, z2, u0, v0);
}
// top (+y)
if (top) {
push_vertex(x, y2, z2, u0, v0, r, g, b, a);
push_vertex(x2, y2, z2, u1, v0, r, g, b, a);
push_vertex(x, y2, z, u0, v1, r, g, b, a);
push_vertex(x2, y2, z2, u1, v0, r, g, b, a);
push_vertex(x2, y2, z, u1, v1, r, g, b, a);
push_vertex(x, y2, z, u0, v1, r, g, b, a);
push(x, y2, z2, u0, v1);
push(x2, y2, z2, u1, v1);
push(x2, y2, z, u1, v0);
push(x, y2, z2, u0, v1);
push(x2, y2, z, u1, v0);
push(x, y2, z, u0, v0);
}
// bottom (-y)
if (bottom) {
push_vertex(x, y, z, u0, v0, r, g, b, a);
push_vertex(x2, y, z, u1, v0, r, g, b, a);
push_vertex(x, y, z2, u0, v1, r, g, b, a);
push_vertex(x2, y, z, u1, v0, r, g, b, a);
push_vertex(x2, y, z2, u1, v1, r, g, b, a);
push_vertex(x, y, z2, u0, v1, r, g, b, a);
push(x, y, z, u0, v1);
push(x2, y, z, u1, v1);
push(x2, y, z2, u1, v0);
push(x, y, z, u0, v1);
push(x2, y, z2, u1, v0);
push(x, y, z2, u0, v0);
}
return i;
}
+2
View File
@@ -21,6 +21,8 @@ export function load_texture(image: HTMLImageElement): Texture {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
return {
tex: texture,