Skip to content

Instantly share code, notes, and snippets.

@kdchambers
Last active October 26, 2021 17:46
Show Gist options
  • Save kdchambers/6168252f989649686d2c64c0076a9220 to your computer and use it in GitHub Desktop.
Save kdchambers/6168252f989649686d2c64c0076a9220 to your computer and use it in GitHub Desktop.
Update function for a simple modal-based test editor that uses Vulkan for the graphics API.
// SPDX-License-Identifier: GPL-3.0
// Copyright (c) 2021 Keith Chambers
// This program is free software: you can redistribute it and/or modify it under the terms
// of the GNU General Public License as published by the Free Software Foundation, version 3.
// NOTE: This gist is a snippet from https://github.com/kdchambers/zedikor/blob/main/src/core.zig
// The update function is used to check what changes have occurred due to user input and whether
// vertexes need to be updated and screen re-rendered.
fn update(allocator: *Allocator, app: *GraphicsContext) !void {
const vertices = @ptrCast([*]TextureVertex, @alignCast(16, &mapped_device_memory[vertices_range_index_begin]));
assert(screen_dimensions.width > 0);
assert(screen_dimensions.height > 0);
vertex_buffer_count = 0;
// Wrap our fixed-size buffer in allocator interface to be generic
var fixed_buffer_allocator = FixedBufferAllocator{
.allocator = .{
.allocFn = FixedBufferAllocator.alloc,
.resizeFn = FixedBufferAllocator.resize,
},
.buffer = @ptrCast([*]u8, &vertices[0]),
.capacity = @intCast(u32, vertices_range_count * @sizeOf(TextureVertex)),
.used = 0,
};
var face_allocator = &fixed_buffer_allocator.allocator;
const lines_to_render = blk: {
// Clamp lines_to_render to `lines_per_view`
const lines_available = text_buffer_line_count - @intCast(u16, editor_context.view_extent.line_top_index);
break :blk if (lines_available > lines_per_view) lines_per_view else lines_available;
};
const line_range = lineRange(text_buffer[0..text_buffer_length], @intCast(u16, editor_context.view_extent.line_top_index), @intCast(u16, lines_to_render));
assert(lines_to_render <= lines_per_view);
assert(line_range.len <= lines_per_view * 80);
const scale_factor = geometry.ScaleFactor2D{
.horizontal = (2.0 / @intToFloat(f32, screen_dimensions.width)),
.vertical = (2.0 / @intToFloat(f32, screen_dimensions.height)),
};
const is_saved_text = if (editor_context.is_synced_with_source) "saved" else "unsaved";
const mode_text = if (editor_mode == .input) "input" else "command";
const save_status_faces = try text.writeText(face_allocator, glyph_set, .{ .x = 0.5, .y = 0.975 }, scale_factor, is_saved_text);
const current_mode_faces = try text.writeText(face_allocator, glyph_set, .{ .x = 0.8, .y = 0.975 }, scale_factor, mode_text);
vertex_buffer_count += @intCast(u32, save_status_faces.len + current_mode_faces.len);
var command_input_face_count: usize = 0;
if (editor_mode == .command) {
const command_input_faces = try text.writeText(face_allocator, glyph_set, .{ .x = -0.95, .y = 0.975 }, scale_factor, command_text_buffer[0..command_text_buffer_len]);
command_input_face_count = command_input_faces.len;
}
const placement = geometry.Coordinates2D(.ndc_right){ .x = -0.98, .y = -0.9 };
const line_margin_digit_count: u32 = digitCount(editor_context.view_extent.line_top_index + lines_to_render);
assert(line_margin_digit_count > 0);
// Margin from line count to editor text area
const left_margin: f32 = 10.0 * scale_factor.horizontal;
// Generic x increment between characters
const base_x_increment = 10.0 * scale_factor.horizontal;
// TODO: Don't hardcode
const line_height = 18.0 * scale_factor.vertical;
const line_margin_vertices = try gui.generateLineMargin(TextureVertex, face_allocator, glyph_set, placement, scale_factor, @intCast(u16, editor_context.view_extent.line_top_index), lines_to_render, line_height);
vertex_buffer_count += @intCast(u16, line_margin_vertices.len);
// TODO: Don't hardcode
const cursor_placement: geometry.Coordinates2D(.ndc_right) = .{
.x = placement.x + (@intToFloat(f32, text_cursor.coordinates.x) * (scale_factor.horizontal * 10.0)) + left_margin + (@intToFloat(f32, line_margin_digit_count) * base_x_increment),
.y = placement.y + (@intToFloat(f32, text_cursor.coordinates.y - editor_context.view_extent.line_top_index) * (scale_factor.vertical * 18.0)),
};
const cursor_face = try text.writeText(face_allocator, glyph_set, cursor_placement, scale_factor, "|");
vertex_buffer_count += @intCast(u16, cursor_face.len);
const editor_placement: geometry.Coordinates2D(.ndc_right) = .{
.x = placement.x + left_margin + (@intToFloat(f32, line_margin_digit_count) * (10.0 * scale_factor.horizontal)),
.y = placement.y,
};
const text_editor_faces = try text.writeText(face_allocator, glyph_set, editor_placement, scale_factor, line_range);
vertex_buffer_count += @intCast(u16, text_editor_faces.len);
text_buffer_dirty = false;
is_render_requested = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment