add basic edge shading

This commit is contained in:
catangent 2024-12-23 18:45:07 +00:00
parent c600c82e8f
commit c19a19166b
5 changed files with 73 additions and 182 deletions

View file

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

View file

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