implement image atlasing and tiling

This commit is contained in:
catAngent 2024-09-19 21:33:32 +01:00
parent 5c7f996eb6
commit e560c0de6b
7 changed files with 95 additions and 33 deletions

BIN
resources/images/tiles.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

BIN
resources/images/tiles.png~ Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,16 @@
#version 330 core
uniform sampler2D diffuseMap;
uniform vec2 textureTiling;
in vec2 fragTexCoord;
in vec2 fragTexCoord2;
in vec4 fragColor;
out vec4 outColor;
void main()
{
vec2 texCoord = (floor(fragTexCoord*textureTiling) + fract(fragTexCoord2)) / textureTiling;
outColor = texture(diffuseMap, texCoord);
}

View file

@ -0,0 +1,19 @@
#version 330
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec2 vertexTexCoord2;
in vec4 vertexColor;
out vec2 fragTexCoord;
out vec2 fragTexCoord2;
out vec4 fragColor;
uniform mat4 mvp;
void main() {
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
fragTexCoord2 = vertexTexCoord2;
gl_Position = mvp*vec4(vertexPosition, 1.0);
}

View file

@ -4,8 +4,10 @@ const raylib = rh.raylib;
const v3 = rh.v3;
const chunks = @import("world/chunk.zig");
const TILE_TEXTURE_RESOLUTION = 16;
const benchmark_chunk_meshing = false;
const debug = false;
const debug = true;
pub fn drawCameraPosition(camera: raylib.Camera3D, x: i32, y: i32) !void {
var buf: [256:0]u8 = undefined;
@ -51,32 +53,35 @@ pub fn main() !void {
.projection = raylib.CAMERA_PERSPECTIVE,
};
const checked = raylib.GenImageChecked(2, 2, 1, 1, raylib.BLUE, raylib.GREEN);
const texture = raylib.LoadTextureFromImage(checked);
const tiles = raylib.LoadImage("resources/images/tiles.png");
const texture = raylib.LoadTextureFromImage(tiles);
const tile_rows = @divExact(@as(u32, @intCast(tiles.height)), TILE_TEXTURE_RESOLUTION);
const tile_columns = @divExact(@as(u32, @intCast(tiles.width)), TILE_TEXTURE_RESOLUTION);
defer raylib.UnloadTexture(texture);
raylib.UnloadImage(checked);
raylib.UnloadImage(tiles);
const shader = raylib.LoadShader("resources/shaders/tiling.vs", "resources/shaders/tiling.fs");
defer raylib.UnloadShader(shader);
raylib.SetShaderValue(shader, raylib.GetShaderLocation(shader, "textureTiling"), &.{ @as(f32, @floatFromInt(tile_columns)), @as(f32, @floatFromInt(tile_rows)) }, raylib.SHADER_UNIFORM_VEC2);
var chunk = try chunks.Chunk.init(a7r);
defer chunk.deinit();
for (0..32) |raw_x| for (0..32) |raw_z| {
for (0..32) |raw_x| for (0..32) |raw_y| for (0..32) |raw_z| {
const x: u5 = @intCast(raw_x);
const y: u5 = @intCast(raw_y);
const z: u5 = @intCast(raw_z);
chunk.setTile(x, 0, z, 1);
chunk.setTile(x, 31, z, 1);
const xt: i32 = @as(i32, @intCast(x)) - 16;
const yt: i32 = @as(i32, @intCast(y)) - 16;
const zt: i32 = @as(i32, @intCast(z)) - 16;
if (xt * xt + yt * yt + zt * zt < 15 * 15) chunk.setTile(x, y, z, 1);
};
for (0..32) |raw_a| {
const a: u5 = @intCast(raw_a);
chunk.setTile(a, a, a, 1);
chunk.setTile(a, 31 - a, a, 1);
chunk.setTile(31 - a, a, a, 1);
chunk.setTile(31 - a, 31 - a, a, 1);
}
if (benchmark_chunk_meshing) {
var tmp: u64 = 0;
for (0..500) |_| {
const start = try std.time.Instant.now();
const model = raylib.LoadModelFromMesh(try chunk.createMesh());
const model = raylib.LoadModelFromMesh(try chunk.createMesh(tile_rows, tile_columns));
defer raylib.UnloadModel(model);
const end = try std.time.Instant.now();
tmp += end.since(start);
@ -86,10 +91,10 @@ pub fn main() !void {
});
}
const model = raylib.LoadModelFromMesh(try chunk.createMesh());
const model = raylib.LoadModelFromMesh(try chunk.createMesh(tile_rows, tile_columns));
defer raylib.UnloadModel(model);
model.materials[0].maps[raylib.MATERIAL_MAP_DIFFUSE].texture = texture;
model.materials[0].shader = shader;
while (!raylib.WindowShouldClose()) {
raylib.ClearBackground(raylib.BLACK);
@ -122,6 +127,8 @@ pub fn main() !void {
{
raylib.BeginMode3D(camera);
defer raylib.EndMode3D();
raylib.BeginShaderMode(shader);
defer raylib.EndShaderMode();
raylib.DrawModel(model, model_position, 0.5, raylib.WHITE);
}

View file

@ -54,7 +54,7 @@ pub const Chunk = struct {
}
}
pub fn createMesh(chunk: Chunk) !raylib.Mesh {
pub fn createMesh(chunk: Chunk, tile_rows: u32, tile_columns: u32) !raylib.Mesh {
var raw_quads = try std.ArrayList(RawQuad).initCapacity(chunk.a7r, 4096);
defer raw_quads.deinit();
@ -78,14 +78,13 @@ pub const Chunk = struct {
const surface = tile_surfaces[y][z];
if (surface == 0) continue;
var y2 = y + 1;
var z2 = z + 1;
while (y2 <= 31 and tile_surfaces[y2][z] == surface) : (y2 += 1) {
tile_surfaces[y2][z] = 0;
}
var z2 = z + 1;
zloop: while (z2 <= 31) : (z2 += 1) {
for (y..y2) |ytmp| if (tile_surfaces[ytmp][z2] != surface) break :zloop;
for (y..y2) |ytmp| tile_surfaces[ytmp][z2] = 0;
tile_surfaces[y][z2] = 0;
}
y2 -= 1;
z2 -= 1;
@ -118,50 +117,71 @@ pub const Chunk = struct {
const vertices: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 3)));
const texcoords: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 2)));
const texcoords2: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 2)));
const normals: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 3)));
for (raw_quads.items, 0..) |raw_quad, i| {
if (raw_quad.tile <= 0) continue;
const tile = @as(u32, @intCast(raw_quad.tile));
for (0..6) |j| {
normals[18 * i + 3 * j + 0] = raw_quad.normal.x;
normals[18 * i + 3 * j + 1] = raw_quad.normal.y;
normals[18 * i + 3 * j + 2] = raw_quad.normal.z;
}
const left_uv = @as(f32, @floatFromInt(tile % tile_columns)) / @as(f32, @floatFromInt(tile_columns));
const right_uv = @as(f32, @floatFromInt(tile % tile_columns + 1)) / @as(f32, @floatFromInt(tile_columns));
const top_uv = @as(f32, @floatFromInt(tile / tile_columns)) / @as(f32, @floatFromInt(tile_rows));
const bottom_uv = @as(f32, @floatFromInt(tile / tile_columns + 1)) / @as(f32, @floatFromInt(tile_rows));
vertices[18 * i + 0] = raw_quad.top_left.x;
vertices[18 * i + 1] = raw_quad.top_left.y;
vertices[18 * i + 2] = raw_quad.top_left.z;
texcoords[12 * i + 0] = 0.0;
texcoords[12 * i + 1] = 0.0;
texcoords[12 * i + 0] = left_uv;
texcoords[12 * i + 1] = top_uv;
texcoords2[12 * i + 0] = 0.0;
texcoords2[12 * i + 1] = 0.0;
vertices[18 * i + 3] = raw_quad.top_right.x;
vertices[18 * i + 4] = raw_quad.top_right.y;
vertices[18 * i + 5] = raw_quad.top_right.z;
texcoords[12 * i + 2] = raw_quad.width;
texcoords[12 * i + 3] = 0.0;
texcoords[12 * i + 2] = right_uv;
texcoords[12 * i + 3] = top_uv;
texcoords2[12 * i + 2] = raw_quad.width;
texcoords2[12 * i + 3] = 0.0;
vertices[18 * i + 6] = raw_quad.bottom_left.x;
vertices[18 * i + 7] = raw_quad.bottom_left.y;
vertices[18 * i + 8] = raw_quad.bottom_left.z;
texcoords[12 * i + 4] = 0.0;
texcoords[12 * i + 5] = raw_quad.height;
texcoords[12 * i + 4] = left_uv;
texcoords[12 * i + 5] = bottom_uv;
texcoords2[12 * i + 4] = 0.0;
texcoords2[12 * i + 5] = raw_quad.height;
vertices[18 * i + 9] = raw_quad.bottom_right.x;
vertices[18 * i + 10] = raw_quad.bottom_right.y;
vertices[18 * i + 11] = raw_quad.bottom_right.z;
texcoords[12 * i + 6] = raw_quad.width;
texcoords[12 * i + 7] = raw_quad.height;
texcoords[12 * i + 6] = right_uv;
texcoords[12 * i + 7] = bottom_uv;
texcoords2[12 * i + 6] = raw_quad.width;
texcoords2[12 * i + 7] = raw_quad.height;
vertices[18 * i + 12] = raw_quad.bottom_left.x;
vertices[18 * i + 13] = raw_quad.bottom_left.y;
vertices[18 * i + 14] = raw_quad.bottom_left.z;
texcoords[12 * i + 8] = 0.0;
texcoords[12 * i + 9] = raw_quad.height;
texcoords[12 * i + 8] = left_uv;
texcoords[12 * i + 9] = bottom_uv;
texcoords2[12 * i + 8] = 0.0;
texcoords2[12 * i + 9] = raw_quad.height;
vertices[18 * i + 15] = raw_quad.top_right.x;
vertices[18 * i + 16] = raw_quad.top_right.y;
vertices[18 * i + 17] = raw_quad.top_right.z;
texcoords[12 * i + 10] = raw_quad.width;
texcoords[12 * i + 11] = 0.0;
texcoords[12 * i + 10] = right_uv;
texcoords[12 * i + 11] = top_uv;
texcoords2[12 * i + 10] = raw_quad.width;
texcoords2[12 * i + 11] = 0.0;
}
var mesh = raylib.Mesh{
@ -170,7 +190,7 @@ pub const Chunk = struct {
.vertices = vertices,
.texcoords = texcoords,
.texcoords2 = null,
.texcoords2 = texcoords2,
.normals = normals,
.tangents = null,
.colors = null,