From a90ec561e7d05b7f798159b09fe0f4033aff476b Mon Sep 17 00:00:00 2001 From: Damian Tarnawski Date: Sat, 4 May 2024 22:35:38 +0200 Subject: [PATCH] Render some planets --- example/shapes.odin | 3 +- example/sol_system.odin | 125 +++++++++++++++++++++++++++++++++------- example/utils.odin | 2 +- 3 files changed, 108 insertions(+), 22 deletions(-) diff --git a/example/shapes.odin b/example/shapes.odin index 1e281e1..641e369 100644 --- a/example/shapes.odin +++ b/example/shapes.odin @@ -11,6 +11,7 @@ ORANGE :: RGBA{250, 150, 50, 255} PURPLE :: RGBA{160, 100, 200, 255} PURPLE_DARK :: RGBA{ 80, 30, 30, 255} BLACK :: RGBA{ 0, 0, 0, 255} +GRAY :: RGBA{ 80, 80, 80, 255} CUBE_TRIANGLES :: 6 * 2 @@ -138,7 +139,7 @@ get_pyramid_positions :: proc(pos: vec3 = 0, h: f32 = 1) -> [PYRAMID_VERTICES]ve } } -get_sphere_vertices :: proc (segments: int) -> int { +get_sphere_vertices :: #force_inline proc(segments: int) -> int { return 6 * segments * segments } diff --git a/example/sol_system.odin b/example/sol_system.odin index 2fca3f1..11c94bb 100644 --- a/example/sol_system.odin +++ b/example/sol_system.odin @@ -4,11 +4,14 @@ package example import glm "core:math/linalg/glsl" import gl "../wasm/webgl" +PLANETS_COUNT :: 1 + 1 + 4 // root + sun + planets +SPHERE_SEGMENTS :: 8 @private State_Sol_System :: struct { - objects : []Object, - rotation: [2]f32, + planets : [PLANETS_COUNT]Planet, + rotation : [2]f32, + shape_sphere: Shape, } Shape :: struct { @@ -19,13 +22,16 @@ Shape :: struct { colors : []u8vec4, } -Object :: struct { +Planet :: struct { using uniforms: Uniform_Values_Sol_System, - shape : Shape, - rotation : vec3, - rotation_speed: vec3, - translation : vec3, - scale : f32, + shape : ^Shape, + rotation : f32, + orbit_speed : f32, + orbit_distance: f32, + rotation_speed: f32, + size : f32, + parent_idx : int, + color : u8vec4, } @@ -35,32 +41,85 @@ setup_sol_system :: proc(s: ^State_Sol_System, program: gl.Program) { gl.Enable(gl.DEPTH_TEST) /* - Sphere + Sphere shape */ - sphere_segments :: 6 - sphere_vertices := get_sphere_vertices(sphere_segments) + sphere_vertices := get_sphere_vertices(SPHERE_SEGMENTS) - sphere_shape: Shape = { + s.shape_sphere = { positions = make([]vec3 , sphere_vertices), normals = make([]vec3 , sphere_vertices), colors = make([]u8vec4, sphere_vertices), vao = gl.CreateVertexArray(), } - get_sphere_base_triangle(sphere_shape.positions, sphere_shape.normals, 1, sphere_segments) - rand_colors_gray(sphere_shape.colors) + get_sphere_base_triangle(s.shape_sphere.positions, s.shape_sphere.normals, 1, SPHERE_SEGMENTS) + rand_colors_gray(s.shape_sphere.colors) - gl.BindVertexArray(sphere_shape.vao) - input_locations_sol_system(&sphere_shape, program) + gl.BindVertexArray(s.shape_sphere.vao) + input_locations_sol_system(&s.shape_sphere, program) - attribute(sphere_shape.a_position, gl.CreateBuffer(), sphere_shape.positions) - attribute(sphere_shape.a_color , gl.CreateBuffer(), sphere_shape.colors) + attribute(s.shape_sphere.a_position, gl.CreateBuffer(), s.shape_sphere.positions) + attribute(s.shape_sphere.a_color , gl.CreateBuffer(), s.shape_sphere.colors) /* - Objects + Planets */ - s.objects = make([]Object, 60) + + /* Sun */ + s.planets[1] = { + shape = &s.shape_sphere, + orbit_speed = 0, + orbit_distance = 0, + rotation_speed = 0.1, + size = 200, + parent_idx = 0, + color = YELLOW, + } + + /* Mercury */ + s.planets[2] = { + shape = &s.shape_sphere, + orbit_speed = 0.1, + orbit_distance = 100, + rotation_speed = 0.1, + size = 40, + parent_idx = 1, + color = GRAY, + } + + /* Venus */ + s.planets[3] = { + shape = &s.shape_sphere, + orbit_speed = 0.05, + orbit_distance = 200, + rotation_speed = 0.1, + size = 30, + parent_idx = 1, + color = ORANGE, + } + + /* Earth */ + s.planets[4] = { + shape = &s.shape_sphere, + orbit_speed = 0.03, + orbit_distance = 300, + rotation_speed = 0.1, + size = 80, + parent_idx = 1, + color = BLUE, + } + + /* Moon */ + s.planets[5] = { + shape = &s.shape_sphere, + orbit_speed = 0.1, + orbit_distance = 50, + rotation_speed = 0.1, + size = 20, + parent_idx = 4, + color = GRAY, + } /* Init rotation */ s.rotation = 1 @@ -84,4 +143,30 @@ frame_sol_system :: proc(s: ^State_Sol_System, delta: f32) { view_mat *= mat4_rotate_x(s.rotation.x) view_mat *= mat4_rotate_y(s.rotation.y) + + for &planet in s.planets { + planet.rotation += planet.rotation_speed * delta * 0.01 + planet.rotation = planet.rotation if planet.rotation < 360 else planet.rotation - 360 + + + if planet.shape != nil { + parent := s.planets[planet.parent_idx] + + planet.u_matrix = + view_mat * + mat4_rotate_y(parent.orbit_speed * delta) * + mat4_translate({parent.orbit_distance, 0, 0}) * + mat4_rotate_y(parent.rotation) * + mat4_rotate_y(planet.orbit_speed * delta) * + mat4_translate({planet.orbit_distance, 0, 0}) * + mat4_rotate_y(planet.rotation) * + mat4_scale(planet.size) + + planet.u_color_mult = u8vec4_to_vec4(planet.color) + + gl.BindVertexArray(planet.shape.vao) + uniforms_sol_system(planet.shape, planet) + gl.DrawArrays(gl.TRIANGLES, 0, len(planet.shape.positions)) + } + } } diff --git a/example/utils.odin b/example/utils.odin index fab286b..a8af9fc 100644 --- a/example/utils.odin +++ b/example/utils.odin @@ -392,7 +392,7 @@ rand_color :: proc(r: ^rand.Rand = nil) -> u8vec4 { return color } rand_color_gray :: proc(r: ^rand.Rand = nil) -> u8vec4 { - l := u8(rand.uint64(r)) / 2 + 128 + l := u8(rand.uint64(r)) / 4 + 256/2 return {l, l, l, 255} } rand_colors :: proc(colors: []u8vec4, r: ^rand.Rand = nil) {