package renderer import "core:math" import "core:log" Mesh :: struct { amount_of_indices: u32, backend: Mesh_Backend, } Mesh_Handle :: distinct u32 Buffer_Handle :: distinct u32 Mesh_Layout :: struct { name: string, amount: u8, type_size: u32, } create_mesh :: proc { create_mesh_layout_vertices_indices, create_mesh_from_primitive, } create_mesh_layout_vertices_indices :: proc(renderer: ^Renderer, layout: []Mesh_Layout, vertices: []f32, indices: []u32) -> (Mesh, bool) { // TODO: SS - Should probably return a Mesh_Handle. mesh: Mesh if len(vertices) == 0 { return {}, false } if len(indices) == 0 { return {}, false } m: Mesh m.amount_of_indices = u32(len(indices)) when RENDER_BACKEND_OPENGL { opengl_mesh, ok := opengl_create_mesh(renderer, layout, vertices, indices) if !ok { return {}, false } m.backend = opengl_mesh } else { #assert(false) } return m, true } Primitive_Mesh_Type :: enum { Cube, Quad, Sphere, } create_mesh_from_primitive :: proc(renderer: ^Renderer, primitive_mesh_type: Primitive_Mesh_Type) -> (Mesh, bool) { switch primitive_mesh_type { case .Cube: { m, ok := create_mesh( renderer = renderer, layout = { { "position", 3, size_of(f32), }, { "normal", 3, size_of(f32), }, { "texture_coords", 2, size_of(f32), }, { "tangent", 3, size_of(f32), }, }, vertices = []f32{ // Positions // Normals // UV // Tangent // Back face -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, // Front face -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, // Left face -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, // Right face 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, -1.0, // Bottom face -0.5, -0.5, -0.5, 0.0,-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.5, -0.5, -0.5, 0.0,-1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.5, -0.5, 0.5, 0.0,-1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, -0.5, -0.5, 0.5, 0.0,-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, // Top face -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, }, indices = []u32 { // Back face 0, 3, 1, 1, 3, 2, // Front face 4, 5, 7, 5, 6, 7, // Left face 8, 9, 11, 9, 10, 11, // Right face 12, 13, 15, 13, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Top face 20, 22, 21, 20, 23, 22 } ) return m, ok } case .Quad: { m, ok := create_mesh( renderer = renderer, layout = { { "position", 3, size_of(f32), }, { "normal", 3, size_of(f32), }, { "texture_coords", 2, size_of(f32), }, { "tangent", 3, size_of(f32), }, }, vertices = []f32 { // Positions. // Normals // Texture Coordinates. // Tangent. 0.5, 0.5, 0.0, 0, 0, 0, 1.0, 1.0, 1, 0, 0, // Top right. 0.5, -0.5, 0.0, 0, 0, 0, 1.0, 0.0, 1, 0, 0, // Bottom right. -0.5, -0.5, 0.0, 0, 0, 0, 0.0, 0.0, 1, 0, 0, // Bottom left. -0.5, 0.5, 0.0, 0, 0, 0, 0.0, 1.0, 1, 0, 0, // Top left. }, indices = []u32 { 0, 1, 3, 1, 2, 3, } ) return m, ok } case .Sphere: { X_SEGMENTS :: 64 Y_SEGMENTS :: 32 vertices := make([dynamic]f32, 0) indices := make([dynamic]u32, 0) defer delete(vertices) defer delete(indices) for y in 0..=Y_SEGMENTS { y_segment := f32(y) / f32(Y_SEGMENTS) phi := y_segment * math.PI for x in 0..=X_SEGMENTS { x_segment := f32(x) / f32(X_SEGMENTS) theta := x_segment * math.TAU px := math.cos(theta) * math.sin(phi) py := math.cos(phi) pz := math.sin(theta) * math.sin(phi) // Position. append(&vertices, px * 0.5) append(&vertices, py * 0.5) append(&vertices, pz * 0.5) // Normal. append(&vertices, px) append(&vertices, py) append(&vertices, pz) // UV. append(&vertices, x_segment) append(&vertices, 1.0 - y_segment) // Tangent. tx := -math.sin(theta) ty := f32(0.0) tz := math.cos(theta) append(&vertices, tx) append(&vertices, ty) append(&vertices, tz) } } for y in 0..