I have two files: lib/lib.odin and main.odin.
lib.odin has the following relevant code:
GameState :: struct {
vbo: u32,
vao: u32,
ebo: u32,
verts: []f32,
}
g: ^GameState
@(export)
game_init :: proc() {
g = new(GameState)
g.verts = []f32 {
0.0, 0.3, 1.0, 0.0, 0.0,
-0.3, -0.3, 0.0, 1.0, 0.0,
0.3, -0.3, 0.0, 0.0, 1.0,
}
gl.GenBuffers(1, &g.vbo)
// extra lines excluded
}
@(export)
game_init_window :: proc() {
if !glfw.Init() do return
glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 4)
glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 6)
glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
when ODIN_DEBUG {
glfw.WindowHint(glfw.OPENGL_DEBUG_CONTEXT, gl.TRUE)
}
window = glfw.CreateWindow(WIN_WIDTH, WIN_HEIGHT, "OdinLearnOpenGL", nil, nil)
// win error check
glfw.MakeContextCurrent(window)
gl.load_up_to(4, 6, glfw.gl_set_proc_address)
}
lib/lib.odin is compiled with the following build command:
odin build lib -build-mode:dll -debug -out:build/debug.dll -source-code-locations:normal -subsystem:console
In main.odin, I have the following, which is mostly copied from Karl Zylinski's hot reload template:
GameAPI :: struct {
lib: dynlib.Library,
init_window: proc(),
destroy_window: proc(),
init: proc(),
update: proc(),
get_state: proc() -> rawptr,
set_state: proc(mem: rawptr),
should_run: proc() -> b32
}
main :: proc() {
// some setup code for the tracking allocator and calling the GameAPI::init_window and init functions...
for game_api.should_run() {
game_api.update()
if game_api.force_reload() {
new_game_api := load_game_api(game_api_version)
append(&old_game_apis, game_api)
game_memory := game_api.get_state()
game_api = new_game_api
game_api.set_state(game_memory)
}
}
}