diff --git a/resources/shaders/tiling.fs b/resources/shaders/tiling.fs index a8ab20b..f684a1c 100644 --- a/resources/shaders/tiling.fs +++ b/resources/shaders/tiling.fs @@ -6,6 +6,13 @@ uniform vec2 textureTiling; in vec2 fragTexCoord; in vec2 fragTexCoord2; in vec4 fragColor; +flat in int ambientOcclusionSide1; +flat in int ambientOcclusionSide2; +flat in int ambientOcclusionCorner1; +flat in int ambientOcclusionCorner2; +flat in int ambientOcclusionCorner3; +flat in int quadHeight; +flat in int quadWidth; out vec4 outColor; @@ -13,4 +20,10 @@ void main() { vec2 texCoord = (floor(fragTexCoord*textureTiling) + fract(fragTexCoord2)) / textureTiling; outColor = texture(diffuseMap, texCoord); + + ivec2 floorFragTexCoord2 = ivec2(fragTexCoord2); + if ((fragTexCoord2.x < 0.05 || fragTexCoord2.x > quadWidth-0.05) && (((ambientOcclusionSide1 >> floorFragTexCoord2.y) & 1) == 1)) outColor *= 0.5; + else if((fragTexCoord2.y < 0.05 || fragTexCoord2.y > quadHeight-0.05) && (((ambientOcclusionSide2 >> floorFragTexCoord2.y) & 1) == 1)) outColor *= 0.5; + + outColor.a = 1; } diff --git a/resources/shaders/tiling.vs b/resources/shaders/tiling.vs index d9a24bb..29676f5 100644 --- a/resources/shaders/tiling.vs +++ b/resources/shaders/tiling.vs @@ -2,13 +2,22 @@ in vec3 vertexPosition; in vec2 vertexTexCoord; -in vec2 vertexTexCoord2; +in vec2 vertexTexCoord2; in vec4 vertexColor; +in vec4 vertexTangent; // metadata1 out vec2 fragTexCoord; out vec2 fragTexCoord2; out vec4 fragColor; +flat out int ambientOcclusionSide1; +flat out int ambientOcclusionSide2; +flat out int ambientOcclusionCorner1; +flat out int ambientOcclusionCorner2; +flat out int ambientOcclusionCorner3; +flat out int quadHeight; +flat out int quadWidth; + uniform mat4 mvp; void main() { @@ -16,4 +25,15 @@ void main() { fragColor = vertexColor; fragTexCoord2 = vertexTexCoord2; gl_Position = mvp*vec4(vertexPosition, 1.0); + + // metadata 1 processing + ambientOcclusionSide1 = floatBitsToInt(vertexTangent.x); + ambientOcclusionSide2 = floatBitsToInt(vertexTangent.y); + int metadata1Z = floatBitsToInt(vertexTangent.z); + int metadata1W = floatBitsToInt(vertexTangent.w); + ambientOcclusionCorner1 = (metadata1Z & 0x1) >> 0; + ambientOcclusionCorner2 = (metadata1Z & 0x2) >> 1; + ambientOcclusionCorner3 = (metadata1Z & 0x4) >> 2; + quadHeight = (metadata1Z & 0x1f8) >> 3; + quadWidth = (metadata1Z & 0x7e00) >> 9; } diff --git a/src/rendering/chunk_mesh.zig b/src/rendering/chunk_mesh.zig deleted file mode 100644 index 1650a2a..0000000 --- a/src/rendering/chunk_mesh.zig +++ /dev/null @@ -1,177 +0,0 @@ -const std = @import("std"); -const raylib_helper = @import("../lib_helpers/raylib_helper.zig"); -const raylib = raylib_helper.raylib; - -const MAX_VBOS = 4; - -const VERTICES_VBO_ID = 0; -const TEXCOORDS_VBO_ID = 1; -const TEXCOORDS2_VBO_ID = 2; -const NORMALS_VBO_ID = 3; - -const ChunkMesh = packed struct { - vertexCount: i32, - triangleCount: i32, - - vertices: [*]f32, // vertex position, XYZ, 3 vars per vertex - texcoords: [*]f32, // vertex texture coorinates, UV, 2 vars per vertex - texcoords2: [*]f32, // vertex second texture coorinates, UV, 2 vars per vertex - normals: [*]f32, // vertex normals, XYZ, 3 vars per vertex - - vaoId: u32, - vboId: [*]u32, -}; - -pub fn UploadChunkMesh(mesh: ChunkMesh, dynamic: bool) void { - if (mesh.vaoId > 0) { - raylib.TraceLog(raylib.LOG_WARNING, "VAO: [ID %i] Trying to re-load an already loaded chunk mesh", mesh.vaoId); - return; - } - - mesh.vboId = @ptrCast(@alignCast(raylib.MemAlloc(@sizeOf(u32) * MAX_VBOS))); - mesh.vaoId = 0; - - mesh.vboId[VERTICES_VBO_ID] = 0; - mesh.vboId[TEXCOORDS_VBO_ID] = 0; - mesh.vboId[TEXCOORDS2_VBO_ID] = 0; - mesh.vboId[NORMALS_VBO_ID] = 0; - - mesh.vaoId = raylib.rlLoadVertexArray(); - raylib.rlEnableVertexArray(mesh.vaoId); - - mesh.vboId[VERTICES_VBO_ID] = raylib.rlLoadVertexBuffer(mesh.vertices, mesh.vertexCount * 3 * @sizeOf(f32), dynamic); - raylib.rlSetVertexAttribute(VERTICES_VBO_ID, 3, raylib.RL_FLOAT, false, 0, 0); - raylib.rlEnableVertexAttribute(VERTICES_VBO_ID); - - mesh.vboId[TEXCOORDS_VBO_ID] = raylib.rlLoadVertexBuffer(mesh.texcoords, mesh.vertexCount * 2 * @sizeOf(f32), dynamic); - raylib.rlSetVertexAttribute(TEXCOORDS_VBO_ID, 2, raylib.RL_FLOAT, false, 0, 0); - raylib.rlEnableVertexAttribute(TEXCOORDS_VBO_ID); - - mesh.vboId[TEXCOORDS2_VBO_ID] = raylib.rlLoadVertexBuffer(mesh.texcoords, mesh.vertexCount * 2 * @sizeOf(f32), dynamic); - raylib.rlSetVertexAttribute(TEXCOORDS2_VBO_ID, 2, raylib.RL_FLOAT, false, 0, 0); - raylib.rlEnableVertexAttribute(TEXCOORDS2_VBO_ID); - - mesh.vboId[NORMALS_VBO_ID] = raylib.rlLoadVertexBuffer(mesh.vertices, mesh.vertexCount * 3 * @sizeOf(f32), dynamic); - raylib.rlSetVertexAttribute(NORMALS_VBO_ID, 3, raylib.RL_FLOAT, false, 0, 0); - raylib.rlEnableVertexAttribute(NORMALS_VBO_ID); - - if (mesh.vaoId > 0) { - raylib.TraceLog(raylib.LOG_INFO, "VAO: [ID %i] Chunk mesh uploaded successfully to VRAM (GPU)", mesh.vaoId); - } else { - raylib.TraceLog(raylib.LOG_INFO, "VBO: Chunk mesh uploaded successfully to VRAM (GPU)"); - } - raylib.rlDisableVertexArray(); -} -pub fn UpdateChunkMeshBuffer(mesh: ChunkMesh, index: i32, data: ?*const anyopaque, dataSize: i32, offset: i32) void { - raylib.rlUpdateVertexBuffer(mesh.vboId[index], data, dataSize, offset); -} -pub fn UnloadChunkMesh(mesh: ChunkMesh) void { - raylib.rlUnloadVertexArray(mesh.vaoId); - if (mesh.vboId != null) { - for (0..MAX_VBOS) |i| { - raylib.rlUnloadVertexBuffer(mesh.vboId[i]); - } - } - raylib.MemFree(mesh.vboId); - - raylib.MemFree(mesh.vertices); - raylib.MemFree(mesh.texcoords); - raylib.MemFree(mesh.texcoords2); - raylib.MemFree(mesh.normals); -} -pub fn DrawChunkMesh(mesh: ChunkMesh, material: raylib.Material, transform: raylib.Matrix) void { - raylib.rlEnableShader(material.shader.id); - if (material.shader.locs[raylib.SHADER_LOC_COLOR_DIFFUSE] != -1) { - const values: [4]f32 = [4]f32{ - @as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_DIFFUSE].color.r)) / 255.0, - @as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_DIFFUSE].color.g)) / 255.0, - @as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_DIFFUSE].color.b)) / 255.0, - @as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_DIFFUSE].color.a)) / 255.0, - }; - raylib.rlSetUniform(material.shader.locs[raylib.SHADER_LOC_COLOR_DIFFUSE], values, raylib.SHADER_UNIFORM_VEC4, 1); - } - if (material.shader.locs[raylib.SHADER_LOC_COLOR_SPECULAR] != -1) { - const values: [4]f32 = [4]f32{ - @as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_SPECULAR].color.r)) / 255.0, - @as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_SPECULAR].color.g)) / 255.0, - @as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_SPECULAR].color.b)) / 255.0, - @as(u32, @floatFromInt(material.maps[raylib.MATERIAL_MAP_SPECULAR].color.a)) / 255.0, - }; - raylib.rlSetUniform(material.shader.locs[raylib.SHADER_LOC_COLOR_SPECULAR], values, raylib.SHADER_UNIFORM_VEC4, 1); - } - - var matModel: raylib.Matrix = raylib.MatrixIdentity(); - const matView: raylib.Matrix = raylib.rlGetMatrixModelview(); - var matModelView: raylib.Matrix = raylib.MatrixIdentity(); - const matProjection: raylib.Matrix = raylib.rlGetMatrixProjection(); - - if (material.shader.locs[raylib.SHADER_LOC_MATRIX_VIEW] != -1) raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_VIEW], matView); - if (material.shader.locs[raylib.SHADER_LOC_MATRIX_PROJECTION] != -1) raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_PROJECTION], matProjection); - - matModel = raylib.MatrixMultiply(transform, raylib.rlGetMatrixTransform()); - if (material.shader.locs[raylib.SHADER_LOC_MATRIX_MODEL] != -1) raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_MODEL], matModel); - - matModelView = raylib.MatrixMultiply(matModel, matView); - if (material.shader.locs[raylib.SHADER_LOC_MATRIX_NORMAL] != -1) raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_NORMAL], raylib.MatrixTranspose(raylib.MatrixInvert(matModel))); - - for (0..raylib.MAX_MATERIAL_MAPS) |i| { - if (material.maps[i].texture.id > 0) { - raylib.rlActiveTextureSlot(i); - if (i == raylib.MATERIAL_MAP_IRRADIANCE or i == raylib.MATERIAL_MAP_PREFILTER or i == raylib.MATERIAL_MAP_CUBEMAP) { - raylib.rlEnableTextureCubemap(material.maps[i].texture.id); - } else { - raylib.rlEnableTexture(material.maps[i].texture.id); - } - raylib.rlSetUniform(material.shader.locs[raylib.SHADER_LOC_MAP_DIFFUSE + i], &i, raylib.SHADER_UNIFORM_INT, 1); - } - } - - if (!raylib.rlEnableVertexArray(mesh.vaoId)) { - raylib.rlEnableVertexBuffer(mesh.vboId[0]); - raylib.rlSetVertexAttribute(material.shader.locs[VERTICES_VBO_ID], 3, raylib.RL_FLOAT, 0, 0, 0); - raylib.rlEnableVertexAttribute(material.shader.locs[VERTICES_VBO_ID]); - - raylib.rlEnableVertexBuffer(mesh.vboId[1]); - raylib.rlSetVertexAttribute(material.shader.locs[TEXCOORDS_VBO_ID], 2, raylib.RL_FLOAT, 0, 0, 0); - raylib.rlEnableVertexAttribute(material.shader.locs[TEXCOORDS_VBO_ID]); - - raylib.rlEnableVertexBuffer(mesh.vboId[2]); - raylib.rlSetVertexAttribute(material.shader.locs[TEXCOORDS2_VBO_ID], 2, raylib.RL_FLOAT, 0, 0, 0); - raylib.rlEnableVertexAttribute(material.shader.locs[TEXCOORDS2_VBO_ID]); - - raylib.rlEnableVertexBuffer(mesh.vboId[3]); - raylib.rlSetVertexAttribute(material.shader.locs[NORMALS_VBO_ID], 3, raylib.RL_FLOAT, 0, 0, 0); - raylib.rlEnableVertexAttribute(material.shader.locs[NORMALS_VBO_ID]); - } - var eyeCount = 1; - if (raylib.rlIsStereoRenderEnabled()) { - eyeCount = 2; - } - for (0..eyeCount) |eye| { - var matModelViewProjection: raylib.Matrix = raylib.MatrixIdentity(); - if (eyeCount == 1) { - matModelViewProjection = raylib.MatrixMultiply(matModelView, matProjection); - } else { - raylib.rlViewport(@divTrunc(eye * raylib.rlGetFramebufferWidth(), 2), 0, @divTrunc(raylib.rlGetFramebufferWidth(), 2), raylib.rlGetFramebufferHeight()); - matModelViewProjection = raylib.MatrixMultiply(raylib.MatrixMultiply(matModelView, raylib.rlGetMatrixViewOffsetStereo(eye)), raylib.rlGetMatrixProjectionStereo(eye)); - } - raylib.rlSetUniformMatrix(material.shader.locs[raylib.SHADER_LOC_MATRIX_MVP], matModelViewProjection); - raylib.rlDrawVertexArray(0, mesh.vertexCount); - } - for (0..raylib.MAX_MATERIAL_MAPS) |i| { - if (material.maps[i].texture.id > 0) { - raylib.rlActiveTextureSlot(i); - if (((i == raylib.MATERIAL_MAP_IRRADIANCE) or (i == raylib.MATERIAL_MAP_PREFILTER)) or (i == raylib.MATERIAL_MAP_CUBEMAP)) { - raylib.rlDisableTextureCubemap(); - } else { - raylib.rlDisableTexture(); - } - } - } - raylib.rlDisableVertexArray(); - raylib.rlDisableVertexBuffer(); - raylib.rlDisableVertexBufferElement(); - raylib.rlDisableShader(); - raylib.rlSetMatrixModelview(matView); - raylib.rlSetMatrixProjection(matProjection); -} diff --git a/src/world/chunk.zig b/src/world/chunk.zig index e826bb1..560b124 100644 --- a/src/world/chunk.zig +++ b/src/world/chunk.zig @@ -3,6 +3,7 @@ const raylib_helper = @import("../lib_helpers/raylib_helper.zig"); const raylib = raylib_helper.raylib; const v3 = raylib_helper.v3; const A7r = std.mem.Allocator; +const comptimePrint = std.fmt.comptimePrint; const RawQuad = struct { tile: u32, @@ -15,6 +16,24 @@ const RawQuad = struct { height: f32, }; +const Metadata1 = packed struct { + ambient_occlusion_1: u32, + ambient_occlusion_2: u32, + ambient_occlusion_corner1: bool, + ambient_occlusion_corner2: bool, + ambient_occlusion_corner3: bool, + quad_height: u6, + quad_width: u6, + unused: u17 = 0, + unused_2: u32 = 0, +}; + +comptime { + if (@bitSizeOf(Metadata1) != 128) { + @compileError(comptimePrint("Metadata 1 has wrong size. Expected 128 bits, found {}", .{@bitSizeOf(Metadata1)})); + } +} + pub const Chunk = struct { tiles: []u32, a7r: A7r, @@ -151,6 +170,7 @@ pub const Chunk = struct { 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))); + const metadata1_packed: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 4))); for (raw_quads.items, 0..) |raw_quad, i| { if (raw_quad.tile <= 0) continue; @@ -214,6 +234,22 @@ pub const Chunk = struct { texcoords[12 * i + 11] = bottom_uv; texcoords2[12 * i + 10] = 0.0; texcoords2[12 * i + 11] = raw_quad.height; + + for (0..6) |j| { + const metadata1 = Metadata1{ + .ambient_occlusion_1 = 0xffffffff, + .ambient_occlusion_2 = 0xffffffff, + .ambient_occlusion_corner1 = true, + .ambient_occlusion_corner2 = true, + .ambient_occlusion_corner3 = true, + .quad_height = @intFromFloat(raw_quad.height), + .quad_width = @intFromFloat(raw_quad.width), + }; + const metadata1_baked: [4]f32 = @bitCast(metadata1); + for (0..4) |k| { + metadata1_packed[24 * i + 4 * j + k] = @bitCast(@as(f32, metadata1_baked[k])); + } + } } var mesh = raylib.Mesh{ @@ -224,6 +260,7 @@ pub const Chunk = struct { .texcoords = texcoords, .texcoords2 = texcoords2, .normals = normals, + .tangents = metadata1_packed, .vaoId = 0, .vboId = null, diff --git a/todo.md b/todo.md index f57a97c..f9913d4 100644 --- a/todo.md +++ b/todo.md @@ -2,11 +2,9 @@ yoink implementation of mesh into meshes.zig so i could modify it to add ambient occlusion vars implement ambient occlusion either - via passing extra info to shader (can use 132 bits to indicate what tiles around the quad are obsuring light. need to pass as an extra variable) -implement animated textures by either - - making literally everything animated - - somehow passing extra info to shader +implement animations (smooth or minecraft like), random orientation/mirroring, metallicity (shine on edges) +implement second layer of textures on top of first one for more details limit vertical camera rotations -update libraries like raylib # future tasks implement chunk meshing cache to reduce delay on block placement