Initial commit
This commit is contained in:
234
examples/main.odin
Normal file
234
examples/main.odin
Normal file
@ -0,0 +1,234 @@
|
||||
package main
|
||||
|
||||
import "../renderer"
|
||||
import "core:c"
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import clay "library:clay"
|
||||
import sdl "vendor:sdl3"
|
||||
|
||||
WINDOW_WIDTH :: 1024
|
||||
WINDOW_HEIGHT :: 728
|
||||
WINDOW_FLAGS :: sdl.WindowFlags{.RESIZABLE, .HIGH_PIXEL_DENSITY}
|
||||
|
||||
window: ^sdl.Window
|
||||
device: ^sdl.GPUDevice
|
||||
debug_enabled := false
|
||||
|
||||
body_text := clay.TextElementConfig {
|
||||
fontId = renderer.JETBRAINS_MONO_REGULAR,
|
||||
fontSize = 44,
|
||||
textColor = { 1.0, 1.0, 1.0, 1.0 },
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
defer destroy()
|
||||
|
||||
when ODIN_DEBUG == true {
|
||||
context.logger = log.create_console_logger(lowest = .Debug)
|
||||
|
||||
//----- Tracking allocator ----------------------------------
|
||||
// Temp
|
||||
track_temp: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track_temp, context.temp_allocator)
|
||||
context.temp_allocator = mem.tracking_allocator(&track_temp)
|
||||
// Default
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
// Log a warning about any memory that was not freed by the end of the program.
|
||||
// This could be fine for some global state or it could be a memory leak.
|
||||
defer {
|
||||
// Temp allocator
|
||||
if len(track_temp.allocation_map) > 0 {
|
||||
fmt.eprintf(
|
||||
"=== %v allocations not freed - temp allocator: ===\n",
|
||||
len(track_temp.allocation_map),
|
||||
)
|
||||
for _, entry in track_temp.allocation_map {
|
||||
fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location)
|
||||
}
|
||||
}
|
||||
if len(track_temp.bad_free_array) > 0 {
|
||||
fmt.eprintf(
|
||||
"=== %v incorrect frees - temp allocator: ===\n",
|
||||
len(track_temp.bad_free_array),
|
||||
)
|
||||
for entry in track_temp.bad_free_array {
|
||||
fmt.eprintf("- %p @ %v\n", entry.memory, entry.location)
|
||||
}
|
||||
}
|
||||
mem.tracking_allocator_destroy(&track_temp)
|
||||
// Default allocator
|
||||
if len(track.allocation_map) > 0 {
|
||||
fmt.eprintf(
|
||||
"=== %v allocations not freed - main allocator: ===\n",
|
||||
len(track.allocation_map),
|
||||
)
|
||||
for _, entry in track.allocation_map {
|
||||
fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location)
|
||||
}
|
||||
}
|
||||
if len(track.bad_free_array) > 0 {
|
||||
fmt.eprintf(
|
||||
"=== %v incorrect frees - main allocator: ===\n",
|
||||
len(track.bad_free_array),
|
||||
)
|
||||
for entry in track.bad_free_array {
|
||||
fmt.eprintf("- %p @ %v\n", entry.memory, entry.location)
|
||||
}
|
||||
}
|
||||
mem.tracking_allocator_destroy(&track)
|
||||
}
|
||||
}
|
||||
|
||||
if !sdl.Init(sdl.InitFlags{.VIDEO}) {
|
||||
log.error("Failed to initialize SDL:", sdl.GetError())
|
||||
}
|
||||
|
||||
window = sdl.CreateWindow("System Controller", WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_FLAGS)
|
||||
|
||||
if window == nil {
|
||||
log.error("Failed to create window:", sdl.GetError())
|
||||
os.exit(1)
|
||||
}
|
||||
|
||||
device = sdl.CreateGPUDevice(renderer.SHADER_TYPE, true, nil)
|
||||
if device == nil {
|
||||
log.error("Failed to create GPU device:", sdl.GetError())
|
||||
os.exit(1)
|
||||
}
|
||||
driver := sdl.GetGPUDeviceDriver(device)
|
||||
log.info("Created GPU device:", driver)
|
||||
|
||||
if !sdl.ClaimWindowForGPUDevice(device, window) {
|
||||
log.error("Failed to claim GPU device for window:", sdl.GetError())
|
||||
os.exit(1)
|
||||
}
|
||||
|
||||
renderer.init(device, window, WINDOW_WIDTH, WINDOW_HEIGHT, context)
|
||||
|
||||
// debug
|
||||
FPS_REFRESH_INTERVAL :: 1000.0 // 1 second
|
||||
fps_time := sdl.GetTicks()
|
||||
frame_count: int
|
||||
fps: f32
|
||||
|
||||
last_frame_time := sdl.GetTicks()
|
||||
|
||||
program: for {
|
||||
defer free_all(context.temp_allocator)
|
||||
|
||||
// Update debug FPS
|
||||
frame_time := sdl.GetTicks()
|
||||
when ODIN_DEBUG == true {
|
||||
frame_count += 1
|
||||
if frame_time - fps_time >= FPS_REFRESH_INTERVAL {
|
||||
new_fps := f32(frame_count)
|
||||
if new_fps != fps {
|
||||
log.info("FPS:", new_fps)
|
||||
}
|
||||
fps = new_fps
|
||||
frame_count = 0
|
||||
fps_time = frame_time
|
||||
}
|
||||
}
|
||||
|
||||
cmd_buffer := sdl.AcquireGPUCommandBuffer(device)
|
||||
if cmd_buffer == nil {
|
||||
log.error("Failed to acquire command buffer")
|
||||
os.exit(1)
|
||||
}
|
||||
|
||||
if update(cmd_buffer, frame_time - last_frame_time) {
|
||||
log.debug("User command to quit")
|
||||
break program
|
||||
}
|
||||
|
||||
draw(cmd_buffer)
|
||||
|
||||
last_frame_time = frame_time
|
||||
}
|
||||
}
|
||||
|
||||
destroy :: proc() {
|
||||
renderer.destroy(device)
|
||||
sdl.ReleaseWindowFromGPUDevice(device, window)
|
||||
sdl.DestroyWindow(window)
|
||||
sdl.DestroyGPUDevice(device)
|
||||
}
|
||||
|
||||
update :: proc(cmd_buffer: ^sdl.GPUCommandBuffer, delta_time: u64) -> bool {
|
||||
frame_time := f32(delta_time) / 1000.0
|
||||
input := input()
|
||||
|
||||
render_cmds: clay.ClayArray(clay.RenderCommand) = layout()
|
||||
|
||||
renderer.prepare(device, window, cmd_buffer, &render_cmds, input.mouse_delta, frame_time)
|
||||
|
||||
return input.should_quit
|
||||
}
|
||||
|
||||
Input :: struct {
|
||||
mouse_delta: [2]f32,
|
||||
should_quit: bool,
|
||||
}
|
||||
|
||||
input :: proc() -> Input {
|
||||
result := Input{}
|
||||
|
||||
event: sdl.Event
|
||||
for sdl.PollEvent(&event) == true {
|
||||
#partial switch event.type {
|
||||
case .KEY_DOWN:
|
||||
switch event.key.key {
|
||||
case sdl.K_ESCAPE:
|
||||
result.should_quit = true
|
||||
case sdl.K_D:
|
||||
if .LSHIFT in event.key.mod {
|
||||
debug_enabled = !debug_enabled
|
||||
clay.SetDebugModeEnabled(debug_enabled)
|
||||
}
|
||||
}
|
||||
case .QUIT:
|
||||
result.should_quit = true
|
||||
case .MOUSE_WHEEL:
|
||||
result.mouse_delta[0] = event.wheel.x
|
||||
result.mouse_delta[1] = event.wheel.y
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
draw :: proc(cmd_buffer: ^sdl.GPUCommandBuffer) {
|
||||
renderer.draw(device, window, cmd_buffer)
|
||||
submit_ok := sdl.SubmitGPUCommandBuffer(cmd_buffer)
|
||||
if !submit_ok {
|
||||
log.debug("Failed to submit command buffer:", sdl.GetError())
|
||||
}
|
||||
}
|
||||
|
||||
layout :: proc() -> clay.ClayArray(clay.RenderCommand) {
|
||||
clay.BeginLayout()
|
||||
|
||||
if clay.UI()(
|
||||
{
|
||||
id = clay.ID("OuterContainer"),
|
||||
layout = {
|
||||
layoutDirection = .TopToBottom,
|
||||
sizing = {clay.SizingGrow({}), clay.SizingGrow({})},
|
||||
childAlignment = {x = .Center, y = .Center},
|
||||
childGap = 16,
|
||||
},
|
||||
backgroundColor = {0.2, 0.2, 0.2, 1.0},
|
||||
},
|
||||
) {
|
||||
clay.Text("3D SCENE", &body_text)
|
||||
}
|
||||
|
||||
return clay.EndLayout()
|
||||
}
|
||||
|
Reference in New Issue
Block a user