177 lines
8.6 KiB
Zig
177 lines
8.6 KiB
Zig
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 UpdateMeshBuffer(mesh: ChunkMesh, index: i32, data: ?*const anyopaque, dataSize: i32, offset: i32) void {
|
|
raylib.rlUpdateVertexBuffer(mesh.vboId[index], data, dataSize, offset);
|
|
}
|
|
pub export fn UnloadMesh(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 DrawMesh(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);
|
|
}
|