Explorar el Código

Circle drawing, line rendering, win32 mouse position things etc

Karl Zylinski hace 6 meses
padre
commit
97d92b799f
Se han modificado 5 ficheros con 174 adiciones y 19 borrados
  1. 126 0
      examples/box2d/karl2d_box2d.odin
  2. 0 5
      examples/minimal/minimal.odin
  3. 30 13
      karl2d.odin
  4. 5 0
      window_interface.odin
  5. 13 1
      window_win32.odin

+ 126 - 0
examples/box2d/karl2d_box2d.odin

@@ -0,0 +1,126 @@
+package karl2d_box2d_example
+
+import b2 "vendor:box2d"
+import k2 "../.."
+import "core:math"
+import "core:time"
+import "core:log"
+
+create_box :: proc(world_id: b2.WorldId, pos: b2.Vec2) -> b2.BodyId{
+	body_def := b2.DefaultBodyDef()
+	body_def.type = .dynamicBody
+	body_def.position = pos
+	body_id := b2.CreateBody(world_id, body_def)
+
+	shape_def := b2.DefaultShapeDef()
+	shape_def.density = 1
+	shape_def.material.friction = 0.3
+
+	box := b2.MakeBox(20, 20)
+	box_def := b2.DefaultShapeDef()
+	_ = b2.CreatePolygonShape(body_id, box_def, box)
+
+	return body_id
+}
+
+main :: proc() {
+	context.logger = log.create_console_logger()
+	k2.init(1280, 720, "Karl2D + Box2D example")
+
+	b2.SetLengthUnitsPerMeter(40)
+	world_def := b2.DefaultWorldDef()
+	world_def.gravity = b2.Vec2{0, -900}
+	world_id := b2.CreateWorld(world_def)
+	defer b2.DestroyWorld(world_id)
+
+	ground := k2.Rect {
+		0, 600,
+		1280, 120,
+	}
+
+	ground_body_def := b2.DefaultBodyDef()
+	ground_body_def.position = b2.Vec2{ground.x, -ground.y-ground.h}
+	ground_body_id := b2.CreateBody(world_id, ground_body_def)
+
+	ground_box := b2.MakeBox(ground.w, ground.h)
+	ground_shape_def := b2.DefaultShapeDef()
+	_ = b2.CreatePolygonShape(ground_body_id, ground_shape_def, ground_box)
+
+	bodies: [dynamic]b2.BodyId
+
+	px: f32 = 400
+	py: f32 = -400
+
+	num_per_row := 10
+	num_in_row := 0
+
+	for _ in 0..<50 {
+		b := create_box(world_id, {px, py})
+		append(&bodies, b)
+		num_in_row += 1
+
+		if num_in_row == num_per_row {
+			py += 30
+			px = 200
+			num_per_row -= 1
+			num_in_row = 0
+		}
+
+		px += 30
+	}
+
+	body_def := b2.DefaultBodyDef()
+	body_def.type = .dynamicBody
+	body_def.position = b2.Vec2{0, 4}
+	body_id := b2.CreateBody(world_id, body_def)
+
+	shape_def := b2.DefaultShapeDef()
+	shape_def.density = 1000
+	shape_def.material.friction = 0.3
+
+	circle: b2.Circle
+	circle.radius = 40
+	_ = b2.CreateCircleShape(body_id, shape_def, circle)
+
+	time_step: f32 = 1.0 / 60
+	sub_steps: i32 = 4
+
+	prev_time := time.now()
+
+	time_acc: f32
+
+	for !k2.shutdown_wanted() {
+		cur_time := time.now()
+		dt := f32(time.duration_seconds(time.diff(prev_time, cur_time)))
+		prev_time = cur_time
+
+		time_acc += dt
+		k2.process_events()
+		k2.clear(k2.BLACK)
+
+		k2.draw_rect(ground, k2.RED)
+		mouse_pos := k2.get_mouse_position()
+
+		b2.Body_SetTransform(body_id, {mouse_pos.x, -mouse_pos.y}, {})
+
+		for time_acc >= time_step {
+			b2.World_Step(world_id, time_step, sub_steps)
+			time_acc -= time_step
+		}
+
+		for b in bodies {
+			position := b2.Body_GetPosition(b)
+			r := b2.Body_GetRotation(b)
+			a := math.atan2(r.s, r.c)
+			// Y position is flipped because raylib has Y down and box2d has Y up.
+			k2.draw_rect_ex({position.x, -position.y, 40, 40}, {20, 20}, a*(180/3.14), k2.YELLOW)
+		}
+
+		k2.draw_circle(mouse_pos, 40, k2.MAGENTA)
+		k2.present()
+
+		free_all(context.temp_allocator)
+	}
+
+	k2.shutdown()
+}

+ 0 - 5
examples/minimal/minimal.odin

@@ -2,21 +2,16 @@ package karl2d_minimal_example
 
 import k2 "../.."
 import "core:log"
-import "core:time"
 
 main :: proc() {
 	context.logger = log.create_console_logger()
 	k2.init(1280, 720, "Karl2D Minimal Program")
 	k2.set_window_position(300, 100)
 
-	start_time := time.now()
-
 	for !k2.shutdown_wanted() {
-		t := f32(time.duration_seconds(time.since(start_time)))
 		k2.process_events()
 		k2.clear(k2.BLUE)
 		k2.present()
-
 		free_all(context.temp_allocator)
 	}
 

+ 30 - 13
karl2d.odin

@@ -99,6 +99,7 @@ present :: proc() {
 process_events :: proc() {
 	s.keys_went_up = {}
 	s.keys_went_down = {}
+	s.mouse_delta = {}
 
 	wi.process_events()
 
@@ -116,6 +117,11 @@ process_events :: proc() {
 		case Window_Event_Key_Went_Up:
 			s.keys_is_held[e.key] = false
 			s.keys_went_up[e.key] = true
+
+		case Window_Event_Mouse_Move:
+			prev_pos := s.mouse_position
+			s.mouse_position = e.position
+			s.mouse_delta = prev_pos - s.mouse_position
 		}
 	}
 
@@ -241,11 +247,6 @@ draw_rect_ex :: proc(r: Rect, origin: Vec2, rot: f32, c: Color) {
 		draw_current_batch()
 	}
 
-	r := r
-
-	r.x -= origin.x
-	r.y -= origin.y
-
 	s.batch_texture = s.shape_drawing_texture
 	tl, tr, bl, br: Vec2
 
@@ -333,8 +334,26 @@ draw_rect_outline :: proc(r: Rect, thickness: f32, color: Color) {
 	draw_rect(right, color)
 }
 
-draw_circle :: proc(center: Vec2, radius: f32, color: Color) {
-	panic("not implemented")
+draw_circle :: proc(center: Vec2, radius: f32, color: Color, segments := 16) {
+	if s.batch_texture != TEXTURE_NONE && s.batch_texture != s.shape_drawing_texture {
+		draw_current_batch()
+	}
+
+	s.batch_texture = s.shape_drawing_texture
+
+	prev := center + {radius, 0}
+	for s in 1..=segments {
+		sr := (f32(s)/f32(segments)) * 2*math.PI
+		rot := linalg.matrix2_rotate(sr)
+		p := center + rot * Vec2{radius, 0}
+			
+
+		_batch_vertex(prev, {0, 0}, color)
+		_batch_vertex(p, {1, 0}, color)
+		_batch_vertex(center, {1, 1}, color)
+
+		prev = p
+	}
 }
 
 draw_line :: proc(start: Vec2, end: Vec2, thickness: f32, color: Color) {
@@ -380,11 +399,6 @@ draw_texture_ex :: proc(tex: Texture, src: Rect, dst: Rect, origin: Vec2, rotati
 		draw_current_batch()
 	}
 
-	r := dst
-
-	r.x -= origin.x
-	r.y -= origin.y
-
 	s.batch_texture = tex.handle
 	tl, tr, bl, br: Vec2
 
@@ -535,7 +549,7 @@ get_mouse_wheel_delta :: proc() -> f32 {
 }
 
 get_mouse_position :: proc() -> Vec2 {
-	panic("not implemented")
+	return s.mouse_position
 }
 
 _batch_vertex :: proc(v: Vec2, uv: Vec2, color: Color) {
@@ -592,6 +606,9 @@ State :: struct {
 	
 	shutdown_wanted: bool,
 
+	mouse_position: Vec2,
+	mouse_delta: Vec2,
+
 	keys_went_down: #sparse [Keyboard_Key]bool,
 	keys_went_up: #sparse [Keyboard_Key]bool,
 	keys_is_held: #sparse [Keyboard_Key]bool,

+ 5 - 0
window_interface.odin

@@ -17,6 +17,7 @@ Window_Event :: union  {
 	Window_Event_Close_Wanted,
 	Window_Event_Key_Went_Down,
 	Window_Event_Key_Went_Up,
+	Window_Event_Mouse_Move,
 }
 
 Window_Event_Key_Went_Down :: struct {
@@ -28,3 +29,7 @@ Window_Event_Key_Went_Up :: struct {
 }
 
 Window_Event_Close_Wanted :: struct {}
+
+Window_Event_Mouse_Move :: struct {
+	position: Vec2,
+}

+ 13 - 1
window_win32.odin

@@ -110,7 +110,6 @@ win32_clear_events :: proc() {
 	runtime.clear(&s.events)
 }
 
-
 _win32_window_proc :: proc "stdcall" (hwnd: win32.HWND, msg: win32.UINT, wparam: win32.WPARAM, lparam: win32.LPARAM) -> win32.LRESULT {
 	context = s.custom_context
 	switch msg {
@@ -126,11 +125,24 @@ _win32_window_proc :: proc "stdcall" (hwnd: win32.HWND, msg: win32.UINT, wparam:
 			key = key,
 		})
 
+		return 0
+
 	case win32.WM_KEYUP:
 		key := WIN32_VK_MAP[wparam]
 		append(&s.events, Window_Event_Key_Went_Up {
 			key = key,
 		})
+
+		return 0
+
+	case win32.WM_MOUSEMOVE:
+		x := win32.GET_X_LPARAM(lparam)
+		y := win32.GET_Y_LPARAM(lparam)
+		append(&s.events, Window_Event_Mouse_Move {
+			position = {f32(x), f32(y)},
+		})
+
+		return 0
 	}
 
 	return win32.DefWindowProcW(hwnd, msg, wparam, lparam)