From d01a198a08ee3d0ca1177b41a7b3a1a0b5949dbc Mon Sep 17 00:00:00 2001 From: lzzrhx Date: Tue, 11 Aug 2026 16:53:35 +0200 Subject: [PATCH] Added SDL2 example with custom colorbuffer and font rendering --- .github/workflows/check.yml | 1 + sdl2/colorbuffer_and_font_rendering/LICENSE | 13 + sdl2/colorbuffer_and_font_rendering/app.odin | 155 +++++++++++ sdl2/colorbuffer_and_font_rendering/draw.odin | 65 +++++ sdl2/colorbuffer_and_font_rendering/font.odin | 256 ++++++++++++++++++ sdl2/colorbuffer_and_font_rendering/main.odin | 49 ++++ 6 files changed, 539 insertions(+) create mode 100644 sdl2/colorbuffer_and_font_rendering/LICENSE create mode 100644 sdl2/colorbuffer_and_font_rendering/app.odin create mode 100644 sdl2/colorbuffer_and_font_rendering/draw.odin create mode 100644 sdl2/colorbuffer_and_font_rendering/font.odin create mode 100644 sdl2/colorbuffer_and_font_rendering/main.odin diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 5777e75..21f2f2a 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -132,6 +132,7 @@ jobs: odin check sdl2/chase_in_space $FLAGS odin check sdl2/hellope $FLAGS odin check sdl2/microui $FLAGS + odin check sdl2/colorbuffer_and_font_rendering $FLAGS odin check sdl3/microui $FLAGS diff --git a/sdl2/colorbuffer_and_font_rendering/LICENSE b/sdl2/colorbuffer_and_font_rendering/LICENSE new file mode 100644 index 0000000..00c4225 --- /dev/null +++ b/sdl2/colorbuffer_and_font_rendering/LICENSE @@ -0,0 +1,13 @@ +//////////////////////////////////////////////////////////////////////////////// +// LICENSE +//////////////////////////////////////////////////////////////////////////////// + + Although no font files are included in this example, the bits for the included + + font are based on "ToshibaSat 8x16" from the Oldschool PC Font Pack + + by VileR (https://int10h.org/oldschool-pc-fonts/), released under a + + Creative Commons Attribution-ShareAlike 4.0 International License. + + See https://int10h.org/oldschool-pc-fonts/readme/#legal_stuff for further details. diff --git a/sdl2/colorbuffer_and_font_rendering/app.odin b/sdl2/colorbuffer_and_font_rendering/app.odin new file mode 100644 index 0000000..1d38668 --- /dev/null +++ b/sdl2/colorbuffer_and_font_rendering/app.odin @@ -0,0 +1,155 @@ +package main +import "core:fmt" +import "core:log" +import "core:math" +import "core:math/rand" +import "vendor:sdl2" + +App :: struct { + running: bool, + window: ^sdl2.Window, + renderer: ^sdl2.Renderer, + render_texture: ^sdl2.Texture, + keystate: [^]u8, + ui_drawn_areas: ^[dynamic; UI_DRAWS_PER_FRAME_LIMIT]Rect, + ui_colorbuffer: ^Colorbuffer, + main_colorbuffer: ^Colorbuffer, + time: u32, + prev_time: u32, + dt: f64, + fps: int, + frame: u32, +} + +Colorbuffer :: struct { + buf: []u32, + texture: ^sdl2.Texture, + width: int, + height: int, +} + +Rect :: struct { + x: int, + y: int, + width: int, + height: int, +} + +init_sdl :: proc(app: ^App) -> bool { + if sdl_res := sdl2.Init(sdl2.INIT_VIDEO); sdl_res < 0 { + log.fatalf("sdl2.Init returned %v", sdl_res) + return false + } + // Create window + app.window = sdl2.CreateWindow(WINDOW_TITLE, sdl2.WINDOWPOS_CENTERED, sdl2.WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_FLAGS) + if app.window == nil { + log.fatal("sdl2.CreateWindow failed.") + return false + } + // Create renderer + app.renderer = sdl2.CreateRenderer(app.window, -1, RENDERER_FLAGS) + if app.renderer == nil { + log.fatal("sdl2.CreateRenderer failed.") + return false + } + // Create render texture + app.render_texture = sdl2.CreateTexture(app.renderer, .RGBA32, .TARGET, WINDOW_WIDTH, WINDOW_HEIGHT) + if app.render_texture == nil { + log.fatal("sdl2.CreateTexture failed.") + return false + } + // Create colorbuffer texture for UI rendering + app.ui_colorbuffer.texture = sdl2.CreateTexture(app.renderer, .RGBA32, .STREAMING, i32(app.ui_colorbuffer.width), i32(app.ui_colorbuffer.height)) + if app.ui_colorbuffer.texture == nil { + log.fatal("sdl2.CreateTexture failed.") + return false + } + // Create main colorbuffer texture + app.main_colorbuffer.texture = sdl2.CreateTexture(app.renderer, .RGBA32, .STREAMING, i32(app.main_colorbuffer.width), i32(app.main_colorbuffer.height)) + if app.main_colorbuffer.texture == nil { + log.fatal("sdl2.CreateTexture failed.") + return false + } + sdl2.SetTextureBlendMode(app.ui_colorbuffer.texture, .BLEND) + app.keystate = sdl2.GetKeyboardState(nil) + return true +} + +input :: proc(app: ^App) { + e: sdl2.Event + for sdl2.PollEvent(&e) { + #partial switch(e.type) { + case .QUIT: app.running = false + case .KEYDOWN: + #partial switch(e.key.keysym.sym) { + case .ESCAPE: app.running = false + } + } + } +} + +update :: proc(app: ^App) { + // Update timekeeping variables + app.time = sdl2.GetTicks() + app.dt = f64(app.time - app.prev_time) + if app.dt > 0.0 && app.frame % 60 == 0 { + app.fps = int(1000.0 / app.dt) + } + app.dt /= 1000.0 + app.prev_time = app.time + app.frame += 1 +} + +draw :: proc(app: ^App) { + // Draw Odin logo to the main colorbuffer + r_max: f32 = 0.8 + cos := math.cos_f32(math.PI / 6) + sin := math.sin_f32(math.PI / 6) + width := r_max * sin / 3 + for _ in 0 ..< 4 { + θ := math.PI * 2 * rand.float32() + r := rand.float32_range(r_max - width, r_max) + offset: f32 + if rand.float32() < 0.3 || ((θ < 5 * math.PI / 6) && (θ > 4 * math.PI / 6)) || ((θ > 9 * math.PI / 6) && (θ < 10 * math.PI / 6)) { + offset = width * rand.float32() - width * (rand.float32() > 0.5 ? 3 : 1) + θ = 10 * math.PI / 6 + r = rand.float32_range(-r_max, r_max) * math.sin(math.acos(abs(offset) / r_max)) + } + draw_pixel(app.main_colorbuffer, {int(RENDER_WIDTH * 0.5 * (1 + (r * math.cos(θ) + offset * cos) * (f32(RENDER_HEIGHT) / f32(RENDER_WIDTH)))), int(RENDER_HEIGHT * 0.5 * (1 + r * math.sin(θ) + offset * sin))}, rand.uint32()) + } + // Clear UI buffer + if len(app.ui_drawn_areas) > 0 { + for i in 0 ..< len(app.ui_drawn_areas) { + area := app.ui_drawn_areas[i] + for x in area.x ..< area.x + area.width { + for y in area.y ..< area.y + area.height { + app.ui_colorbuffer.buf[x + y * app.ui_colorbuffer.width] = 0x00_00_00_00 + } + } + } + clear(app.ui_drawn_areas) + } + // Draw UI + draw_ui({2, 0}, app.fps, app.fps >= 50 ? 0xFF_32_DC_32 : (app.fps >= 30 ? 0xFF_32_DC_DC : 0xFF_32_32_DC ), app.ui_colorbuffer, app.ui_drawn_areas) + draw_ui({2, RENDER_HEIGHT - 16 - 2}, fmt.tprintf("%vx%v", RENDER_WIDTH, RENDER_HEIGHT), 0xFF_FF_FF_FF, app.ui_colorbuffer, app.ui_drawn_areas) + // Update buffer textures + sdl2.UpdateTexture(app.ui_colorbuffer.texture, nil, raw_data(app.ui_colorbuffer.buf), i32(app.ui_colorbuffer.width) * 4) + sdl2.UpdateTexture(app.main_colorbuffer.texture, nil, raw_data(app.main_colorbuffer.buf), i32(app.main_colorbuffer.width) * 4) + // Render buffer textures + sdl2.SetRenderTarget(app.renderer, app.render_texture) + sdl2.SetRenderDrawColor(app.renderer, 0, 0, 0, 255) + sdl2.RenderClear(app.renderer) + sdl2.RenderCopy(app.renderer, app.main_colorbuffer.texture, nil, nil) + sdl2.RenderCopy(app.renderer, app.ui_colorbuffer.texture, nil, nil) + sdl2.SetRenderTarget(app.renderer, nil) + sdl2.RenderCopy(app.renderer, app.render_texture, nil, nil) + sdl2.RenderPresent(app.renderer) +} + +exit :: proc(app: ^App) { + free(app.ui_drawn_areas) + delete(app.ui_colorbuffer.buf) + delete(app.main_colorbuffer.buf) + sdl2.DestroyWindow(app.window) + sdl2.Quit() +} diff --git a/sdl2/colorbuffer_and_font_rendering/draw.odin b/sdl2/colorbuffer_and_font_rendering/draw.odin new file mode 100644 index 0000000..a7c6f1f --- /dev/null +++ b/sdl2/colorbuffer_and_font_rendering/draw.odin @@ -0,0 +1,65 @@ +package main +import "core:math" + +draw_pixel :: proc(colorbuffer: ^Colorbuffer, pos: [2]int, color: u32) { + if pos.x >= 0 && pos.x < colorbuffer.width && pos.y >= 0 && pos.y < colorbuffer.height { + colorbuffer.buf[int(pos.x + pos.y * colorbuffer.width)] = color + } +} + +draw_line :: proc(colorbuffer: ^Colorbuffer, pos: [2][2]int, color: u32) { + dx: f32 = f32(pos[1].x - pos[0].x) + dy: f32 = f32(pos[1].y - pos[0].y) + step := math.abs(dx) >= math.abs(dy) ? math.abs(dx) : math.abs(dy) + dx /= step + dy /= step + x: f32 = f32(pos[0].x) + y: f32 = f32(pos[0].y) + for _ in 0 ..= int(step) { + draw_pixel(colorbuffer, {int(math.round_f32(x)), int(math.round_f32(y))}, color) + x += dx + y += dy + } +} + +draw_u128 :: proc(colorbuffer: ^Colorbuffer, bits: u128, pos: [2]int, color: u32) { + for i in 0 ..< 8 { + for j in 0 ..< 16 { + bit := u128(0x80000000000000000000000000000000) >> u128(j+i*16) + if bits & bit == bit { + draw_pixel(colorbuffer, {pos.x + i, pos.y + j}, color) + } + } + } +} + +draw_ui :: proc { + draw_ui_int, + draw_ui_string, +} + +draw_ui_int :: proc(pos: [2]int, m: int, color: u32, ui_colorbuffer: ^Colorbuffer, ui_drawn_areas: ^[dynamic; UI_DRAWS_PER_FRAME_LIMIT]Rect) { + num_digits: int = 1 + for n := math.abs(m); n >= 10; n /= 10 { + num_digits += 1 + } + draw_ui_add_drawn_area(ui_drawn_areas, pos.x, pos.y, num_digits * (CHAR_WIDTH + CHAR_SPACING), CHAR_HEIGHT) + for i, n := num_digits, m; i > 0; i, n = i - 1, n / 10 { + draw_u128(ui_colorbuffer, font_char(n % 10), {pos.x + (i-1) * (CHAR_WIDTH + CHAR_SPACING), pos.y}, color) + } +} + +draw_ui_string :: proc(pos: [2]int, txt: string, color: u32, ui_colorbuffer: ^Colorbuffer, ui_drawn_areas: ^[dynamic; UI_DRAWS_PER_FRAME_LIMIT]Rect) { + draw_ui_add_drawn_area(ui_drawn_areas, pos.x, pos.y, len(txt) * (CHAR_WIDTH + CHAR_SPACING), CHAR_HEIGHT) + for c, i in txt { + if c != ' ' { + draw_u128(ui_colorbuffer, font_char(c), {pos.x + i * (CHAR_WIDTH + CHAR_SPACING), pos.y}, color) + } + } +} + +draw_ui_add_drawn_area :: proc(ui_drawn_areas: ^[dynamic; UI_DRAWS_PER_FRAME_LIMIT]Rect, x0, y0, width, height: int) { + if (len(ui_drawn_areas) < cap(ui_drawn_areas)) { + append(ui_drawn_areas, Rect{x0, y0, width, height}) + } +} diff --git a/sdl2/colorbuffer_and_font_rendering/font.odin b/sdl2/colorbuffer_and_font_rendering/font.odin new file mode 100644 index 0000000..a81be53 --- /dev/null +++ b/sdl2/colorbuffer_and_font_rendering/font.odin @@ -0,0 +1,256 @@ +package main + +font_char :: proc { + font_char_from_int, + font_char_from_rune, +} + +font_char_from_int :: proc(n: int) -> u128 { + switch n { + case 1: return CHAR_1 + case 2: return CHAR_2 + case 3: return CHAR_3 + case 4: return CHAR_4 + case 5: return CHAR_5 + case 6: return CHAR_6 + case 7: return CHAR_7 + case 8: return CHAR_8 + case 9: return CHAR_9 + } + return CHAR_0 +} + +font_char_from_rune :: proc(letter: rune) -> u128 { + switch letter { + case '0': return CHAR_0 + case '1': return CHAR_1 + case '2': return CHAR_2 + case '3': return CHAR_3 + case '4': return CHAR_4 + case '5': return CHAR_5 + case '6': return CHAR_6 + case '7': return CHAR_7 + case '8': return CHAR_8 + case '9': return CHAR_9 + case 'a': return CHAR_LC_A + case 'b': return CHAR_LC_B + case 'c': return CHAR_LC_C + case 'd': return CHAR_LC_D + case 'e': return CHAR_LC_E + case 'f': return CHAR_LC_F + case 'g': return CHAR_LC_G + case 'h': return CHAR_LC_H + case 'i': return CHAR_LC_I + case 'j': return CHAR_LC_J + case 'k': return CHAR_LC_K + case 'l': return CHAR_LC_L + case 'm': return CHAR_LC_M + case 'n': return CHAR_LC_N + case 'o': return CHAR_LC_O + case 'p': return CHAR_LC_P + case 'q': return CHAR_LC_Q + case 'r': return CHAR_LC_R + case 's': return CHAR_LC_S + case 't': return CHAR_LC_T + case 'u': return CHAR_LC_U + case 'v': return CHAR_LC_V + case 'w': return CHAR_LC_W + case 'x': return CHAR_LC_X + case 'y': return CHAR_LC_Y + case 'z': return CHAR_LC_Z + case 'A': return CHAR_A + case 'B': return CHAR_B + case 'C': return CHAR_C + case 'D': return CHAR_D + case 'E': return CHAR_E + case 'F': return CHAR_F + case 'G': return CHAR_G + case 'H': return CHAR_H + case 'I': return CHAR_I + case 'J': return CHAR_J + case 'K': return CHAR_K + case 'L': return CHAR_L + case 'M': return CHAR_M + case 'N': return CHAR_N + case 'O': return CHAR_O + case 'P': return CHAR_P + case 'Q': return CHAR_Q + case 'R': return CHAR_R + case 'S': return CHAR_S + case 'T': return CHAR_T + case 'U': return CHAR_U + case 'V': return CHAR_V + case 'W': return CHAR_W + case 'X': return CHAR_X + case 'Y': return CHAR_Y + case 'Z': return CHAR_Z + case '+': return CHAR_PLUS + case '\\': return CHAR_BACKSLASH + case '!': return CHAR_EXCLAMATION + case '"': return CHAR_QUOTATION + case '#': return CHAR_HASH + case '%': return CHAR_PERCENT + case '&': return CHAR_AMPERSAND + case '/': return CHAR_SLASH + case '(': return CHAR_L_PAR + case ')': return CHAR_R_PAR + case '=': return CHAR_EQ + case '?': return CHAR_QUESTION + case '`': return CHAR_BACKTICK + case '@': return CHAR_AT + case '$': return CHAR_DOLLAR + case '{': return CHAR_L_CURLY_BRACKET + case '[': return CHAR_L_BRACKET + case ']': return CHAR_R_BRACKET + case '}': return CHAR_R_CURLY_BRACKET + case '^': return CHAR_CARET + case '~': return CHAR_TILDE + case '*': return CHAR_ASTERISK + case '\'': return CHAR_APOSTROPHE + case ',': return CHAR_COMMA + case ';': return CHAR_SEMICOLON + case '.': return CHAR_DOT + case ':': return CHAR_COLON + case '-': return CHAR_MINUS + case '_': return CHAR_UNDERSCORE + case '<': return CHAR_LT + case '>': return CHAR_GT + case '☺': return CHAR_SMILE1 + case '☻': return CHAR_SMILE2 + case '♥': return CHAR_HEART + case '♦': return CHAR_DIAMONDS + case '♣': return CHAR_CLUBS + case '♠': return CHAR_SPADES + case '•': return CHAR_BULLET + case '♂': return CHAR_MALE + case '♀': return CHAR_FEMALE + case '♪': return CHAR_NOTE + case '♫': return CHAR_NOTE2 + case '►': return CHAR_RIGHT + case '◄': return CHAR_LEFT + case '↑': return CHAR_U_ARROW + case '↓': return CHAR_D_ARROW + case '→': return CHAR_R_ARROW + case '←': return CHAR_L_ARROW + case '▲': return CHAR_UP + case '▼': return CHAR_DOWN + } + return CHAR_QUESTION +} + +// 8x16 font (128 bits for each character) based on "ToshibaSat 8x16" from the Oldschool PC Font Pack by VileR (https://int10h.org/oldschool-pc-fonts/) +CHAR_WIDTH :: 8 +CHAR_HEIGHT :: 16 +CHAR_SPACING :: 1 +CHAR_0 :u128: 0b011111111100000011111111111000001000000000100000100011100010000010000000001000001111111111100000011111111100000000000000000000 +CHAR_1 :u128: 0b000000000000000000100000001000000110000000100000111111111110000011111111111000000000000000100000000000000010000000000000000000 +CHAR_2 :u128: 0b010000001110000011000001111000001000001100100000100001100010000010001100001000001111100000100000011100000010000000000000000000 +CHAR_3 :u128: 0b010000000100000011000000011000001000100000100000100010000010000010001000001000001111111111100000011101111100000000000000000000 +CHAR_4 :u128: 0b000001100000000000001110000000000001101000000000001100100000000001111111111000001111111111100000000000100000000000000000000000 +CHAR_5 :u128: 0b111110000100000011111000011000001000100000100000100010000010000010001000001000001000111111100000100001111100000000000000000000 +CHAR_6 :u128: 0b001111111100000001111111111000001100100000100000100010000010000010001000001000001000111111100000000001111100000000000000000000 +CHAR_7 :u128: 0b110000000000000011000000000000001000001111100000100001111110000010001100000000001111100000000000111100000000000000000000000000 +CHAR_8 :u128: 0b011101111100000011111111111000001000100000100000100010000010000010001000001000001111111111100000011101111100000000000000000000 +CHAR_9 :u128: 0b011110000000000011111100001000001000010000100000100001000010000010000100011000001111111111000000011111111000000000000000000000 +CHAR_A :u128: 0b001111111110000001111111111000001100001000000000100000100000000011000010000000000111111111100000001111111110000000000000000000 +CHAR_B :u128: 0b111111111110000011111111111000001000100000100000100010000010000010001000001000001111111111100000011101111100000000000000000000 +CHAR_C :u128: 0b011111111100000011111111111000001000000000100000100000000010000010000000001000001100000001100000010000000100000000000000000000 +CHAR_D :u128: 0b111111111110000011111111111000001000000000100000100000000010000011000000011000000111111111000000001111111000000000000000000000 +CHAR_E :u128: 0b111111111110000011111111111000001000100000100000100010000010000010001000001000001000100000100000100000000010000000000000000000 +CHAR_F :u128: 0b111111111110000011111111111000001000100000000000100010000000000010001000000000001000100000000000100000000000000000000000000000 +CHAR_G :u128: 0b011111111100000011111111111000001000000000100000100001000010000010000100001000001100011111100000010001111110000000000000000000 +CHAR_H :u128: 0b111111111110000011111111111000000000010000000000000001000000000000000100000000001111111111100000111111111110000000000000000000 +CHAR_I :u128: 0b100000000010000010000000001000001111111111100000111111111110000010000000001000001000000000100000000000000000000000000000000000 +CHAR_J :u128: 0b000000001100000000000000111000000000000000100000100000000010000011111111111000001111111111000000100000000000000000000000000000 +CHAR_K :u128: 0b111111111110000011111111111000000000111000000000000110110000000000110001100000001110000011100000110000000110000000000000000000 +CHAR_L :u128: 0b111111111110000011111111111000000000000000100000000000000010000000000000001000000000000000100000000000000010000000000000000000 +CHAR_M :u128: 0b111111111110000011111111111000000011000000000000000111100000000000110000000000001111111111100000111111111110000000000000000000 +CHAR_N :u128: 0b111111111110000011111111111000000011100000000000000011000000000000000111000000001111111111100000111111111110000000000000000000 +CHAR_O :u128: 0b011111111100000011111111111000001000000000100000100000000010000010000000001000001111111111100000011111111100000000000000000000 +CHAR_P :u128: 0b111111111110000011111111111000001000010000000000100001000000000010000100000000001111110000000000011110000000000000000000000000 +CHAR_Q :u128: 0b011111111100000011111111111000001000000010100000100000001100000010000000011000001111111110110000011111111101000000000000000000 +CHAR_R :u128: 0b111111111110000011111111111000001000010000000000100001100000000010000111100000001111110111100000011110000110000000000000000000 +CHAR_S :u128: 0b011000000100000011110000011000001001100000100000100011000010000010000110001000001100001111100000010000011100000000000000000000 +CHAR_T :u128: 0b100000000000000010000000000000001000000000000000111111111110000011111111111000001000000000000000100000000000000010000000000000 +CHAR_U :u128: 0b111111111100000011111111111000000000000000100000000000000010000000000000001000001111111111100000111111111100000000000000000000 +CHAR_V :u128: 0b111111110000000011111111100000000000000011000000000000000110000000000000110000001111111110000000111111110000000000000000000000 +CHAR_W :u128: 0b111111111000000011111111111000000000000011100000000011111000000000000000111000001111111111100000111111111000000000000000000000 +CHAR_X :u128: 0b111000001110000011110001111000000001111100000000000011100000000000011111000000001111000111100000111000001110000000000000000000 +CHAR_Y :u128: 0b111110000000000011111100000000000000011111100000000001111110000011111100000000001111100000000000000000000000000000000000000000 +CHAR_Z :u128: 0b100000011110000010000011111000001000011000100000100011000010000010011000001000001111000000100000111000000010000000000000000000 +CHAR_LC_A :u128: 0b000000011100000000010011111000000001001000100000000100100010000000010010001000000001111111100000000011111110000000000000000000 +CHAR_LC_B :u128: 0b111111111110000011111111111000000000100001000000000100000010000000010000001000000001111111100000000011111100000000000000000000 +CHAR_LC_C :u128: 0b000011111100000000011111111000000001000000100000000100000010000000010000001000000001100001100000000010000100000000000000000000 +CHAR_LC_D :u128: 0b000011111100000000011111111000000001000000100000000100000010000000001000010000001111111111100000111111111110000000000000000000 +CHAR_LC_E :u128: 0b000011111100000000011111111000000001001000100000000100100010000000010010001000000001111000100000000011100010000000000000000000 +CHAR_LC_F :u128: 0b000010000000000000001000000000000111111111100000111111111110000010001000000000001100100000000000010000000000000000000000000000 +CHAR_LC_G :u128: 0b000011111001000000011111110110000001000001001000000100000100100000001000100010000001111111111000000111111111000000000000000000 +CHAR_LC_H :u128: 0b111111111110000011111111111000000000100000000000000100000000000000010000000000000001111111100000000011111110000000000000000000 +CHAR_LC_I :u128: 0b000000000000000000000000000000000001000000100000100111111110000010011111111000000000000000100000000000000000000000000000000000 +CHAR_LC_J :u128: 0b000000000011000000000000001110000000000000001000000100000000100000010000000010001001111111111000100111111111000000000000000000 +CHAR_LC_K :u128: 0b111111111110000011111111111000000000001100000000000001111000000000001100110000000001100001100000000100000010000000000000000000 +CHAR_LC_L :u128: 0b000000000000000000000000000000001000000000100000111111111110000011111111111000000000000000100000000000000000000000000000000000 +CHAR_LC_M :u128: 0b000111111110000000011111111000000001100000000000000011111000000000011000000000000001111111100000000011111110000000000000000000 +CHAR_LC_N :u128: 0b000111111110000000011111111000000000100000000000000100000000000000010000000000000001111111100000000011111110000000000000000000 +CHAR_LC_O :u128: 0b000011111100000000011111111000000001000000100000000100000010000000010000001000000001111111100000000011111100000000000000000000 +CHAR_LC_P :u128: 0b000111111111100000011111111110000000100010000000000100000100000000010000010000000001111111000000000011111000000000000000000000 +CHAR_LC_Q :u128: 0b000011111000000000011111110000000001000001000000000100000100000000001000100000000001111111111000000111111111100000000000000000 +CHAR_LC_R :u128: 0b000111111110000000011111111000000000100000000000000100000000000000010000000000000001100000000000000010000000000000000000000000 +CHAR_LC_S :u128: 0b000011000100000000011110011000000001001000100000000100110010000000010001001000000001100111100000000010001100000000000000000000 +CHAR_LC_T :u128: 0b000100000000000000010000000000001111111111000000111111111110000000010000001000000001000001100000000100000100000000000000000000 +CHAR_LC_U :u128: 0b000111111100000000011111111000000000000000100000000000000010000000000000001000000001111111100000000111111100000000000000000000 +CHAR_LC_V :u128: 0b000111110000000000011111100000000000000011000000000000000110000000000000110000000001111110000000000111110000000000000000000000 +CHAR_LC_W :u128: 0b000111111100000000011111111000000000000001100000000001111100000000000000011000000001111111100000000111111100000000000000000000 +CHAR_LC_X :u128: 0b000110000110000000011100111000000000011110000000000000110000000000000111100000000001110011100000000110000110000000000000000000 +CHAR_LC_Y :u128: 0b000111111001000000011111110110000000000001001000000000000100100000000000100010000001111111111000000111111111000000000000000000 +CHAR_LC_Z :u128: 0b000100000110000000010000111000000001000110100000000100110010000000010110001000000001110000100000000110000010000000000000000000 +CHAR_PLUS :u128: 0b000000000000000000000100000000000000010000000000000111110000000000011111000000000000010000000000000001000000000000000000000000 +CHAR_BACKSLASH :u128: 0b110000000000000011110000000000000011110000000000000011100000000000000111100000000000000111100000000000000110000000000000000000 +CHAR_EXCLAMATION :u128: 0b000000000000000001111000000000001111111101100000111111110110000001111000000000000000000000000000000000000000000000000000000000 +CHAR_QUOTATION :u128: 0b111110000000000011111000000000000000000000000000000000000000000011111000000000001111100000000000000000000000000000000000000000 +CHAR_HASH :u128: 0b000100010000000011111111111000001111111111100000000100010000000011111111111000001111111111100000000100010000000000000000000000 +CHAR_PERCENT :u128: 0b110000000110000011000001111000000000011110000000000011100000000000111100000000001111000001100000110000000110000000000000000000 +CHAR_AMPERSAND :u128: 0b000000111100000001100111111000001111110000100000100111100110000011110011110000000110011111100000000001100110000000000000000000 +CHAR_SLASH :u128: 0b000000000110000000000001111000000000011110000000000011100000000000111100000000001111000000000000110000000000000000000000000000 +CHAR_L_PAR :u128: 0b000000000000000000111111100000000111111111000000110000000110000010000000001000000000000000000000000000000000000000000000000000 +CHAR_R_PAR :u128: 0b000000000000000010000000001000001100000001100000011111111100000000111111100000000000000000000000000000000000000000000000000000 +CHAR_EQ :u128: 0b000010100000000000001010000000000000101000000000000010100000000000001010000000000000101000000000000010100000000000000000000000 +CHAR_QUESTION :u128: 0b011000000000000011100000000000001000001101100000100001110110000010001100000000001111100000000000011100000000000000000000000000 +CHAR_BACKTICK :u128: 0b000000000000000000000000000000000000000000000000111000000000000011110000000000000001000000000000000000000000000000000000000000 +CHAR_AT :u128: 0b011111111100000011111111111000001000000000100000100011110010000010001111001000001111111100100000011111110010000000000000000000 +CHAR_DOLLAR :u128: 0b001110001000000001111100110000000100010001000001110001000111000111000100011100000110011111000000001000111000000000000000000000 +CHAR_L_CURLY_BRACKET :u128: 0b000001000000000000000100000000000111111111000000111110111110000010000000001000001000000000100000000000000000000000000000000000 +CHAR_L_BRACKET :u128: 0b000000000000000011111111111000001111111111100000100000000010000010000000001000000000000000000000000000000000000000000000000000 +CHAR_R_BRACKET :u128: 0b000000000000000010000000001000001000000000100000111111111110000011111111111000000000000000000000000000000000000000000000000000 +CHAR_R_CURLY_BRACKET :u128: 0b100000000010000010000000001000001111101111100000011111111100000000000100000000000000010000000000000000000000000000000000000000 +CHAR_CARET :u128: 0b000100000000000000110000000000000110000000000000110000000000000001100000000000000011000000000000000100000000000000000000000000 +CHAR_TILDE :u128: 0b001000000000000001100000000000000100000000000000011000000000000000100000000000000110000000000000010000000000000000000000000000 +CHAR_ASTERISK :u128: 0b000001000000000000010101000000000001111100000000000011100000000000011111000000000001010100000000000001000000000000000000000000 +CHAR_APOSTROPHE :u128: 0b000000000000000000000000000000000001000000000000111100000000000011100000000000000000000000000000000000000000000000000000000000 +CHAR_COMMA :u128: 0b000000000000000000000000000000000000000000010000000000000111000000000000011000000000000000000000000000000000000000000000000000 +CHAR_SEMICOLON :u128: 0b000000000000000000000000000000000000000000010000000001100111000000000110011000000000000000000000000000000000000000000000000000 +CHAR_DOT :u128: 0b000000000000000000000000000000000000000000000000000000000110000000000000011000000000000000000000000000000000000000000000000000 +CHAR_COLON :u128: 0b000000000000000000000000000000000000000000000000000001100110000000000110011000000000000000000000000000000000000000000000000000 +CHAR_MINUS :u128: 0b000001000000000000000100000000000000010000000000000001000000000000000100000000000000010000000000000001000000000000000000000000 +CHAR_UNDERSCORE :u128: 0b000000000000100000000000000010000000000000001000000000000000100000000000000010000000000000001000000000000000100000000000000010 +CHAR_LT :u128: 0b000001000000000000001110000000000001101100000000001100011000000001100000110000001100000001100000100000000010000000000000000000 +CHAR_GT :u128: 0b100000000010000011000000011000000110000011000000001100011000000000011011000000000000111000000000000001000000000000000000000000 +CHAR_SMILE1 :u128: 0b011111111100000010000000001000010001100100010001000000001001000100000000100100010001100100010000100000000010000001111111110000 +CHAR_SMILE2 :u128: 0b011111111100000011111111111000011110011011110001111111110111000111111111011100011110011011110000111111111110000001111111110000 +CHAR_HEART :u128: 0b001110000000000001111110000000000111111110000000001111111110000001111111100000000111111000000000001110000000000000000000000000 +CHAR_DIAMONDS :u128: 0b000001000000000000011111000000000111111111000001111111111111000001111111110000000001111100000000000001000000000000000000000000 +CHAR_CLUBS :u128: 0b000011110000000000001111000000000011011000100000011111111110000001111111111000000011011000100000000011110000000000001111000000 +CHAR_SPADES :u128: 0b000011100000000000011111000000000011111100100000011111101110000001111110111000000011111100100000000111110000000000001110000000 +CHAR_BULLET :u128: 0b000000000000000000000110000000000000111100000000000011110000000000000110000000000000000000000000000000000000000000000000000000 +CHAR_MALE :u128: 0b000000111000000000000111110000000000110001000000010111000100000001110111110000000111001110000000011110000000000000000000000000 +CHAR_FEMALE :u128: 0b001110010000000001111101000000000100011111000000010001111100000001111101000000000011100100000000000000000000000000000000000000 +CHAR_NOTE :u128: 0b000000000110000000000000111000000000000011100000111111111100000001110000000000000011100000000000000111000000000000000000000000 +CHAR_NOTE2 :u128: 0b000000000110000000000000111000011111111111000001100110000000000011001100000110000110011000111000001111111111000000000000000000 +CHAR_RIGHT :u128: 0b011111111100000000111111100000000001111100000000000011100000000000001110000000000000010000000000000001000000000000000000000000 +CHAR_LEFT :u128: 0b000001000000000000000100000000000000111000000000000011100000000000011111000000000011111110000000011111111100000000000000000000 +CHAR_U_ARROW :u128: 0b001000000000000001100000000000001111111111100000111111111110000001100000000000000010000000000000000000000000000000000000000000 +CHAR_D_ARROW :u128: 0b000000001000000000000000110000001111111111100000111111111110000000000000110000000000000010000000000000000000000000000000000000 +CHAR_R_ARROW :u128: 0b000001100000000000000110000000000000011000000000000101101000000000011111100000000000111100000000000001100000000000000000000000 +CHAR_L_ARROW :u128: 0b000001100000000000001111000000000001111110000000000101101000000000000110000000000000011000000000000001100000000000000000000000 +CHAR_UP :u128: 0b000000001100000000000011110000000000111111000000001111111100000000001111110000000000001111000000000000001100000000000000000000 +CHAR_DOWN :u128: 0b001100000000000000111100000000000011111100000000001111111100000000111111000000000011110000000000001100000000000000000000000000 diff --git a/sdl2/colorbuffer_and_font_rendering/main.odin b/sdl2/colorbuffer_and_font_rendering/main.odin new file mode 100644 index 0000000..bb82763 --- /dev/null +++ b/sdl2/colorbuffer_and_font_rendering/main.odin @@ -0,0 +1,49 @@ +package main +import "core:log" +import "core:mem" +import "vendor:sdl2" + +RENDERER_FLAGS :: sdl2.RendererFlags{.ACCELERATED, .PRESENTVSYNC, .TARGETTEXTURE} +WINDOW_TITLE :: "sdl2_colorbuffer_and_font_rendering" +WINDOW_FLAGS :: sdl2.WindowFlags{.SHOWN} +WINDOW_WIDTH :: 1280 +WINDOW_HEIGHT :: 720 +RENDER_WIDTH :: 1280 +RENDER_HEIGHT :: 720 +UI_DRAWS_PER_FRAME_LIMIT :: 100 + +main :: proc() { + // Tracking allocator and logger set up + context.logger = log.create_console_logger() + tracking_allocator: mem.Tracking_Allocator + mem.tracking_allocator_init(&tracking_allocator, context.allocator) + context.allocator = mem.tracking_allocator(&tracking_allocator) + defer { + for _, entry in tracking_allocator.allocation_map { + log.errorf("%v: Leaked %v bytes", entry.location, entry.size) + } + mem.tracking_allocator_destroy(&tracking_allocator) + } + + // Program initialization + app := App{ + running = true, + ui_colorbuffer = &Colorbuffer{ buf = new([RENDER_WIDTH * RENDER_HEIGHT]u32)[:], width = RENDER_WIDTH, height = RENDER_HEIGHT }, + ui_drawn_areas = new([dynamic; UI_DRAWS_PER_FRAME_LIMIT]Rect), + main_colorbuffer = &Colorbuffer{ buf = new([RENDER_WIDTH * RENDER_HEIGHT]u32)[:], width = RENDER_WIDTH, height = RENDER_HEIGHT }, + } + if !init_sdl(&app) { + log.panic("SDL initialization failed.") + } + + // Main loop + for app.running { + input(&app) + update(&app) + draw(&app) + free_all(context.temp_allocator) + } + + // Exit the program + exit(&app) +}