236 lines
8.5 KiB
Odin
236 lines
8.5 KiB
Odin
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)
|
|
|
|
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..<Y_SEGMENTS {
|
|
for x in 0..<X_SEGMENTS {
|
|
i0 := u32(y * (X_SEGMENTS + 1) + x)
|
|
i1 := u32((y + 1) * (X_SEGMENTS + 1) + x)
|
|
i2 := u32((y + 1) * (X_SEGMENTS + 1) + x + 1)
|
|
i3 := u32(y * (X_SEGMENTS + 1) + x + 1)
|
|
|
|
append(&indices, i0)
|
|
append(&indices, i3)
|
|
append(&indices, i1)
|
|
|
|
append(&indices, i1)
|
|
append(&indices, i3)
|
|
append(&indices, i2)
|
|
}
|
|
}
|
|
|
|
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 = vertices[:],
|
|
indices = indices[:],
|
|
)
|
|
|
|
return m, ok
|
|
}
|
|
}
|
|
|
|
return {}, false
|
|
} |