Skip to content

Instantly share code, notes, and snippets.

@benoitjacquier
Created October 21, 2022 06:49
Show Gist options
  • Save benoitjacquier/c259c20c04bffb5fb49a60a2bb151355 to your computer and use it in GitHub Desktop.
Save benoitjacquier/c259c20c04bffb5fb49a60a2bb151355 to your computer and use it in GitHub Desktop.
package imgui_impl_raylib
import "core:mem"
import imgui "../..";
import rl "vendor:raylib"
@private
state: Raylib_State;
Raylib_State :: struct {
startup: bool,
time : f64,
atlas_tex: rl.Texture,
}
startup :: proc() {
assert(state.startup==false)
assert(state.atlas_tex.id==0)
state.time = 0
io := imgui.get_io()
io.backend_platform_name = "imgui_impl_raylib"
// Create default texture
pixels : ^u8
image := rl.Image{}
imgui.font_atlas_get_tex_data_as_rgba32(io.fonts, &pixels, &image.width, &image.height)
image.data = pixels
image.mipmaps = 1
image.format = .UNCOMPRESSED_R8G8B8A8
state.atlas_tex = rl.LoadTextureFromImage(image)
io.fonts.tex_id = imgui.Texture_ID(&state.atlas_tex.id)
state.startup = true
}
shutdown :: proc() {
assert(state.startup)
assert(state.atlas_tex.id!=0)
imgui.font_atlas_clear_tex_data(imgui.get_io().fonts)
rl.UnloadTexture(state.atlas_tex)
state.atlas_tex = rl.Texture2D{}
state.startup = false
}
new_frame :: proc() {
io := imgui.get_io()
// Update display size
io.display_size = imgui.Vec2{f32(rl.GetScreenWidth()), f32(rl.GetScreenHeight())}
// TODO: not sure whate to do about display_framebuffer_scale
// Time
current_time := rl.GetTime();
io.delta_time = state.time > 0.0 ? f32(current_time - state.time) : f32(1.0/ 60.0)
state.time = current_time;
// Keyboard
{
io.key_ctrl = rl.IsKeyDown(.RIGHT_CONTROL) || rl.IsKeyDown(.LEFT_CONTROL)
io.key_shift = rl.IsKeyDown(.RIGHT_SHIFT) || rl.IsKeyDown(.LEFT_SHIFT)
io.key_alt = rl.IsKeyDown(.RIGHT_ALT) || rl.IsKeyDown(.LEFT_ALT)
io.key_super = rl.IsKeyDown(.RIGHT_SUPER) || rl.IsKeyDown(.LEFT_SUPER)
io.keys_down[imgui.Key.Tab] = rl.IsKeyDown(.TAB)
io.keys_down[imgui.Key.LeftArrow] = rl.IsKeyDown(.LEFT)
io.keys_down[imgui.Key.RightArrow] = rl.IsKeyDown(.RIGHT)
io.keys_down[imgui.Key.UpArrow] = rl.IsKeyDown(.UP)
io.keys_down[imgui.Key.DownArrow] = rl.IsKeyDown(.DOWN)
io.keys_down[imgui.Key.PageUp] = rl.IsKeyDown(.PAGE_UP)
io.keys_down[imgui.Key.PageDown] = rl.IsKeyDown(.PAGE_DOWN)
io.keys_down[imgui.Key.Home] = rl.IsKeyDown(.HOME)
io.keys_down[imgui.Key.End] = rl.IsKeyDown(.END)
io.keys_down[imgui.Key.Insert] = rl.IsKeyDown(.INSERT)
io.keys_down[imgui.Key.Delete] = rl.IsKeyDown(.DELETE)
io.keys_down[imgui.Key.Backspace] = rl.IsKeyDown(.BACKSPACE)
io.keys_down[imgui.Key.Space] = rl.IsKeyDown(.SPACE)
io.keys_down[imgui.Key.Enter] = rl.IsKeyDown(.ENTER)
io.keys_down[imgui.Key.Escape] = rl.IsKeyDown(.SPACE)
io.keys_down[imgui.Key.KeyPadEnter] = rl.IsKeyDown(.KP_ENTER)
io.keys_down[imgui.Key.A] = rl.IsKeyDown(.A)
io.keys_down[imgui.Key.C] = rl.IsKeyDown(.C)
io.keys_down[imgui.Key.V] = rl.IsKeyDown(.V)
io.keys_down[imgui.Key.X] = rl.IsKeyDown(.X)
io.keys_down[imgui.Key.Y] = rl.IsKeyDown(.Y)
io.keys_down[imgui.Key.Z] = rl.IsKeyDown(.Z)
// text input
kp := rl.GetCharPressed()
for kp!=0 {
imgui.io_add_input_character(io, u32(kp))
kp = rl.GetCharPressed()
}
}
// Mouse
{
io.mouse_down[0] = rl.IsMouseButtonDown(.LEFT)
io.mouse_down[1] = rl.IsMouseButtonDown(.RIGHT)
io.mouse_down[2] = rl.IsMouseButtonDown(.MIDDLE)
if rl.IsWindowMinimized()==false {
io.mouse_pos = imgui.Vec2{f32(rl.GetMouseX()), f32(rl.GetMouseY())}
}
// show/hide
if io.config_flags & .NoMouseCursorChange != .NoMouseCursorChange {
desired_cursor := imgui.get_mouse_cursor();
if io.mouse_draw_cursor || desired_cursor == .None {
rl.HideCursor()
} else {
rl.ShowCursor()
}
}
if rl.GetMouseWheelMove() > 0 {
io.mouse_wheel += 1;
} else if rl.GetMouseWheelMove() < 0 {
io.mouse_wheel -= 1;
}
}
}
render :: proc(draw_data: ^imgui.Draw_Data) {
push_vert :: #force_inline proc(idx_vert: imgui.Draw_Vert) {
#no_bounds_check {
c := transmute([4]u8)idx_vert.col
rl.rlColor4ub(c[0], c[1], c[2], c[3])
rl.rlTexCoord2f(idx_vert.uv.x, idx_vert.uv.y)
rl.rlVertex2f(idx_vert.pos.x, idx_vert.pos.y)
}
}
rl.rlDisableBackfaceCulling()
rl.rlPushMatrix();
lists := mem.slice_ptr(draw_data.cmd_lists, int(draw_data.cmd_lists_count))
for list in lists {
cmds := mem.slice_ptr(list.cmd_buffer.data, int(list.cmd_buffer.size));
for cmd, idx in cmds {
if cmd.user_callback!=nil {
cmd.user_callback(list, &cmds[idx])
} else {
assert(cmd.elem_count%3==0)
idx_buffer := mem.slice_ptr(list.idx_buffer.data, int(list.idx_buffer.size))[cmd.idx_offset:]
vtx_buffer := mem.slice_ptr(list.vtx_buffer.data, int(list.vtx_buffer.size))[cmd.vtx_offset:]
pos := draw_data.display_pos;
rectX := (i32)(cmd.clip_rect.x - pos.x);
rectY := (i32)(cmd.clip_rect.y - pos.y);
rectW := (i32)(cmd.clip_rect.z - f32(rectX));
rectH := (i32)(cmd.clip_rect.w - f32(rectY));
rl.BeginScissorMode(rectX, rectY, rectW, rectH)
rl.rlBegin(rl.RL_TRIANGLES);
tex_ptr := transmute(^u32)cmd.texture_id
tex_id := tex_ptr^
rl.rlSetTexture(tex_id)
for i :u32=0; i< (cmd.elem_count-2); i+=3 {
#no_bounds_check {
push_vert(vtx_buffer[idx_buffer[i]])
push_vert(vtx_buffer[idx_buffer[i+2]])
push_vert(vtx_buffer[idx_buffer[i+1]])
}
}
rl.rlEnd();
}
}
}
rl.rlPopMatrix();
rl.EndScissorMode()
rl.rlEnableBackfaceCulling()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment