gutter_runner/game/ui/raylib.odin

159 lines
4.0 KiB
Odin

// Raylib renderer for microui
package ui
import "core:log"
import "core:strings"
import rl "libs:raylib"
import "libs:raylib/rlgl"
import gl "vendor:OpenGL"
_ :: log
default_atlas_texture: rl.Texture2D
rl_init :: proc() {
rl.UnloadTexture(default_atlas_texture)
default_atlas_texture = {}
image := rl.Image{
data = &default_atlas_alpha,
width = DEFAULT_ATLAS_WIDTH,
height = DEFAULT_ATLAS_HEIGHT,
mipmaps = 1,
format = .UNCOMPRESSED_GRAYSCALE,
}
default_atlas_texture = rl.LoadTextureFromImage(image)
rl.SetTextureFilter(default_atlas_texture, .POINT)
gl.BindTexture(gl.TEXTURE_2D, default_atlas_texture.id)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_SWIZZLE_A, gl.RED)
gl.BindTexture(gl.TEXTURE_2D, 0)
}
to_rl_color :: proc(c: Color) -> rl.Color {
return rl.Color{c.r, c.g, c.b, c.a}
}
to_rl_rect :: proc(r: Rect) -> rl.Rectangle {
return rl.Rectangle{x = f32(r.x), y = f32(r.y), width = f32(r.w), height = f32(r.h)}
}
rl_measure_text_2d :: #force_inline proc(font: Font, font_size: i32, text: string) -> rl.Vector2 {
font := (cast(^rl.Font)font)
size := rl.MeasureTextEx(
font^ if font != nil else rl.GetFontDefault(),
strings.clone_to_cstring(text, context.temp_allocator),
f32(font_size),
f32(font_size / (font.baseSize if font != nil else 10)),
)
return size
}
rl_measure_text_width :: proc(font: Font, font_size: i32, text: string) -> i32 {
return i32(rl_measure_text_2d(font, font_size, text).x)
}
rl_measure_text_height :: proc(font: Font, font_size: i32) -> i32 {
return i32(rl_measure_text_2d(font, font_size, "A").y)
}
rl_draw :: proc(ctx: ^Context) {
tmp_cmd: ^Command
for cmd in next_command_iterator(ctx, &tmp_cmd) {
switch c in cmd {
case ^Command_Clip:
if c.rect == unclipped_rect {
rl.EndScissorMode()
} else {
rl.BeginScissorMode(c.rect.x, c.rect.y, c.rect.w, c.rect.h)
}
case ^Command_Text:
font := cast(^rl.Font)c.font
rl.DrawTextEx(
font^ if font != nil else rl.GetFontDefault(),
strings.clone_to_cstring(c.str, context.temp_allocator),
rl.Vector2{f32(c.pos.x), f32(c.pos.y)},
f32(c.font_size),
f32(c.font_size / (font.baseSize if font != nil else 10)),
to_rl_color(c.color),
)
case ^Command_Rect:
rl.DrawRectangle(c.rect.x, c.rect.y, c.rect.w, c.rect.h, to_rl_color(c.color))
case ^Command_Line:
segments := get_line_segments(ctx, c.first_segment, c.num_segments)
rl.DrawLineStrip(&segments[0], i32(len(segments)), to_rl_color(c.color))
case ^Command_Jump:
case ^Command_Icon:
src_rect := default_atlas[int(c.id)]
x := f32(c.rect.x + (c.rect.w - src_rect.w) / 2)
y := f32(c.rect.y + (c.rect.h - src_rect.h) / 2)
rl.DrawTextureRec(
default_atlas_texture,
to_rl_rect(src_rect),
{x, y},
to_rl_color(c.color),
)
}
}
rlgl.DrawRenderBatchActive()
rlgl.DisableScissorTest()
}
RL_MOUSE_BUTTON_MAPPING :: [Mouse]rl.MouseButton {
.LEFT = .LEFT,
.RIGHT = .RIGHT,
.MIDDLE = .MIDDLE,
}
RL_KEY_MAPPING :: [Key]rl.KeyboardKey {
.SHIFT = .LEFT_SHIFT,
.CTRL = .LEFT_CONTROL,
.ALT = .LEFT_ALT,
.BACKSPACE = .BACKSPACE,
.DELETE = .DELETE,
.RETURN = .ENTER,
.LEFT = .LEFT,
.RIGHT = .RIGHT,
.HOME = .HOME,
.END = .END,
.A = .A,
.X = .X,
.C = .C,
.V = .V,
}
rl_update_inputs :: proc(ctx: ^Context) {
ctx.mouse_pos.x = rl.GetMouseX()
ctx.mouse_pos.y = rl.GetMouseY()
for rl_btn, ui_btn in RL_MOUSE_BUTTON_MAPPING {
if rl.IsMouseButtonPressed(rl_btn) {
input_mouse_down(ctx, ctx.mouse_pos.x, ctx.mouse_pos.y, ui_btn)
}
if rl.IsMouseButtonReleased(rl_btn) {
input_mouse_up(ctx, ctx.mouse_pos.x, ctx.mouse_pos.y, ui_btn)
}
}
wheel_move := rl.GetMouseWheelMoveV() * -50
input_scroll(ctx, i32(wheel_move.x), i32(wheel_move.y))
for rl_key, ui_key in RL_KEY_MAPPING {
if rl.IsKeyPressed(rl_key) {
input_key_down(ctx, ui_key)
}
if rl.IsKeyReleased(rl_key) {
input_key_up(ctx, ui_key)
}
}
for char := rl.GetCharPressed(); char != 0; char = rl.GetCharPressed() {
strings.write_rune(&ctx.text_input, char)
}
}