annoying work on font rendering
This commit is contained in:
parent
b0045107cb
commit
cf01001cc1
@ -6,16 +6,29 @@ Arb_Tri :: struct {
|
||||
|
||||
Arb_Draw_Command_Type :: enum {
|
||||
INVALID;
|
||||
DRAW_TEXT;
|
||||
FLUSH_TRI;
|
||||
SET_TEXTURE;
|
||||
PREPARE_TEXT;
|
||||
FONT_BOUNDARY;
|
||||
QUAD_OCCLUDER;
|
||||
REMOVE_TEXTURE;
|
||||
}
|
||||
|
||||
Arb_Draw_Command :: struct {
|
||||
type : Arb_Draw_Command_Type = .INVALID;
|
||||
|
||||
// for triangles
|
||||
tri_offset : int = 0;
|
||||
tri_count : int = 0;
|
||||
texture : *Ui_Texture;
|
||||
|
||||
// for text
|
||||
font : *Ui_Font;
|
||||
text : string;
|
||||
text_color : Vector4;
|
||||
x,y : s64;
|
||||
|
||||
}
|
||||
|
||||
Arb_Tri_State :: struct {
|
||||
@ -89,8 +102,16 @@ arb_tri_flush :: () {
|
||||
flush_arb_commands();
|
||||
}
|
||||
|
||||
debug_arb_flush : bool : true;
|
||||
is_in_pass : bool = false;
|
||||
|
||||
layer : s32 = 0;
|
||||
|
||||
flush_arb_commands :: () {
|
||||
layer = 0;
|
||||
if debug_arb_flush then print(" --- !BEGIN FLUSH! ---- \n");
|
||||
for arbTriState.command_list {
|
||||
if debug_arb_flush then print("[command] %\n", it.type);
|
||||
if it.type == {
|
||||
case .SET_TEXTURE;
|
||||
gPipelines.arbtri.bind.images[0] = it.texture.tex;
|
||||
@ -98,9 +119,61 @@ flush_arb_commands :: () {
|
||||
case .REMOVE_TEXTURE;
|
||||
gCurrentTexture = null;
|
||||
case .FLUSH_TRI;
|
||||
if !is_in_pass {
|
||||
sg_begin_pass(*(sg_pass.{ action = state.pass_action, swapchain = cast,force(sg_swapchain) sglue_swapchain() }));
|
||||
is_in_pass = true;
|
||||
}
|
||||
sg_apply_pipeline(gPipelines.arbtri.pipeline);
|
||||
sg_apply_bindings(*gPipelines.arbtri.bind);
|
||||
sg_draw(xx (it.tri_offset * 3), xx (it.tri_count * 3), 1);
|
||||
case .PREPARE_TEXT;
|
||||
if is_in_pass {
|
||||
sg_end_pass();
|
||||
is_in_pass = false;
|
||||
}
|
||||
font := it.font;
|
||||
text := it.text;
|
||||
if text.count < 1 then continue;
|
||||
print("prep at size: %\n", font.character_height);
|
||||
fonsSetFont(state.fons, state.font_default.fons_font);
|
||||
fonsSetSize(state.fons, xx font.character_height);
|
||||
w := fonsTextBounds(state.fons, 0.0, 0.0, text.data, text.data + text.count, null);
|
||||
gPreppedText = text;
|
||||
gPreppedTextWidth = cast(s32) w;
|
||||
|
||||
array_reset(*font.temporary_glyphs);
|
||||
array_reset(*font.temporary_glyphs_byte_offsets);
|
||||
|
||||
for 0..(text.count-1) {
|
||||
glyph : Ui_Font_Glyph;
|
||||
|
||||
glyph.advance = cast(u32) fonsTextBounds(state.fons, 0.0, 0.0, text.data + it, text.data + it + 1, null);
|
||||
|
||||
array_add(*font.temporary_glyphs, glyph);
|
||||
array_add(*font.temporary_glyphs_byte_offsets, cast(u32) it);
|
||||
}
|
||||
case .DRAW_TEXT;
|
||||
if gPreppedText.count < 1 then continue;
|
||||
text_color := it.text_color;
|
||||
x := it.x;
|
||||
y := it.y;
|
||||
font := it.font;
|
||||
|
||||
color := sfons_rgba(xx (255.0 * text_color.x), xx (255.0 * text_color.y), xx (255.0 * text_color.z), xx (255.0 * text_color.w));
|
||||
fonsSetColor(state.fons, color);
|
||||
result := cast(*u8) temporary_alloc(gPreppedText.count + 1); // Add 1 for the zero.
|
||||
memcpy(result, gPreppedText.data, gPreppedText.count);
|
||||
result[gPreppedText.count] = 0;
|
||||
sgl_layer(layer);
|
||||
fonsDrawText(state.fons, xx x, xx y, result, null);
|
||||
sg_begin_pass(*(sg_pass.{ action = state.pass_action, swapchain = cast,force(sg_swapchain) sglue_swapchain() }));
|
||||
sfons_flush(state.fons);
|
||||
sgl_draw_layer(layer);
|
||||
sg_end_pass();
|
||||
layer += 1;
|
||||
}
|
||||
}
|
||||
if is_in_pass {
|
||||
sg_end_pass();
|
||||
}
|
||||
}
|
||||
|
||||
72
src/editor/console.jai
Normal file
72
src/editor/console.jai
Normal file
@ -0,0 +1,72 @@
|
||||
Console_State :: enum {
|
||||
CLOSED;
|
||||
OPEN_HALF;
|
||||
OPEN_FULL;
|
||||
}
|
||||
|
||||
console_state : Console_State = .CLOSED;
|
||||
|
||||
console_h : float = 0.0;
|
||||
console_move_speed : float = 400.0;
|
||||
|
||||
get_console_h_target_from_state :: (state: Console_State) -> float {
|
||||
if state == {
|
||||
case .OPEN_HALF;
|
||||
return 45 * vh;
|
||||
case .OPEN_FULL;
|
||||
return 95 * vh;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
tick_console :: () {
|
||||
if input_button_states[Key_Code.F1] & .START {
|
||||
if console_state != .CLOSED {
|
||||
if input_button_states[Key_Code.SHIFT] & .DOWN {
|
||||
if console_state == .OPEN_FULL {
|
||||
console_state = .OPEN_HALF;
|
||||
} else {
|
||||
console_state = .OPEN_FULL;
|
||||
}
|
||||
} else {
|
||||
console_state = .CLOSED;
|
||||
}
|
||||
} else {
|
||||
if input_button_states[Key_Code.SHIFT] & .DOWN {
|
||||
console_state = .OPEN_FULL;
|
||||
} else {
|
||||
console_state = .OPEN_HALF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t := get_console_h_target_from_state(console_state);
|
||||
if console_h < t {
|
||||
console_h += cast(float) (console_move_speed * vh * delta_time);
|
||||
if console_h > t {
|
||||
console_h = t;
|
||||
}
|
||||
}
|
||||
if console_h > t {
|
||||
console_h -= cast(float) (console_move_speed * vh * delta_time);
|
||||
if console_h < t {
|
||||
console_h = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console_input : string = "HELLO??";
|
||||
|
||||
draw_console :: (theme: *GR.Overall_Theme) {
|
||||
if console_h < 1 then return;
|
||||
r := GR.get_rect(0, 0, 100*vw, console_h);
|
||||
draw_rectangle(r, theme.text_input_theme.button_theme.surface_color);
|
||||
r.w = 102*vw;
|
||||
r.x -= 1*vw;
|
||||
r.y = r.h - ui_h(5, 4);
|
||||
r.h = ui_h(5, 4);
|
||||
GR.label(r, "HELLO?!! wTF=", *theme.label_theme);
|
||||
// a, new, state := GR.text_input(r, console_input, *theme.text_input_theme);
|
||||
|
||||
// if !state.active then GR.activate(state);
|
||||
}
|
||||
18
src/editor/editor.jai
Normal file
18
src/editor/editor.jai
Normal file
@ -0,0 +1,18 @@
|
||||
#load "console.jai";
|
||||
|
||||
draw_editor_ui :: (theme: *GR.Overall_Theme) {
|
||||
r := GR.get_rect(0,0,0,0);
|
||||
r.x = 0; r.w = 100*vw;
|
||||
r.y = 0; r.h = ui_h(5, 0);
|
||||
draw_bg_rectangle(r, theme);
|
||||
r.w = 15*vw;
|
||||
GR.label(r, "Trueno!", *t_label_left(theme));
|
||||
r = GR.get_rect(0, ui_h(5,0), ui_w(20, 20), ui_h(95, 0));
|
||||
draw_bg_rectangle(r, theme);
|
||||
|
||||
draw_console(theme);
|
||||
}
|
||||
|
||||
tick_editor_ui :: () {
|
||||
tick_console();
|
||||
}
|
||||
28
src/main.jai
28
src/main.jai
@ -1,6 +1,10 @@
|
||||
#import "Basic";
|
||||
#import "Math";
|
||||
#import "Input";
|
||||
stbi :: #import "stb_image";
|
||||
|
||||
#load "ui/ui.jai";
|
||||
#load "editor/editor.jai";
|
||||
#load "pipelines.jai";
|
||||
#load "time.jai";
|
||||
#load "arbtri.jai";
|
||||
@ -8,11 +12,11 @@
|
||||
#load "load.jai";
|
||||
#load "./shaders/jai/shader_triangle.jai";
|
||||
|
||||
#import "Input";
|
||||
|
||||
stbi :: #import "stb_image";
|
||||
last_frame_time : float64;
|
||||
delta\ _time : float64;
|
||||
|
||||
state: struct {
|
||||
pass_action_clear : sg_pass_action;
|
||||
pass_action : sg_pass_action;
|
||||
dpi_scale : float;
|
||||
fons : *FONScontext;
|
||||
@ -27,8 +31,8 @@ Window_Info :: struct {
|
||||
|
||||
get_window_info :: () -> Window_Info {
|
||||
return Window_Info.{
|
||||
1200,
|
||||
1200,
|
||||
1920,
|
||||
1080,
|
||||
"trueno!"
|
||||
};
|
||||
}
|
||||
@ -63,7 +67,8 @@ init :: () {
|
||||
state.font_default.fons_font = FONS_INVALID;
|
||||
create_pipelines();
|
||||
|
||||
state.pass_action.colors[0] = .{ load_action = .CLEAR, clear_value = .{ r = 0.5, g = 0.5, b = 0.9, a = 1 } };
|
||||
state.pass_action_clear.colors[0] = .{ load_action = .CLEAR, clear_value = .{ r = 0.5, g = 0.5, b = 0.9, a = 1 } };
|
||||
state.pass_action.colors[0] = .{ load_action = .LOAD };
|
||||
init_font_loads();
|
||||
}
|
||||
|
||||
@ -73,6 +78,9 @@ init_after_mandatory_loads :: () {
|
||||
|
||||
frame :: () {
|
||||
|
||||
delta_time = get_time() - last_frame_time;
|
||||
last_frame_time = get_time();
|
||||
|
||||
sfetch_dowork();
|
||||
|
||||
if mandatory_loads_done() && !init_after_mandatory_done {
|
||||
@ -81,6 +89,7 @@ frame :: () {
|
||||
}
|
||||
|
||||
if !mandatory_loads_done() then return;
|
||||
fonsClearState(state.fons);
|
||||
|
||||
dpis := state.dpi_scale;
|
||||
|
||||
@ -94,12 +103,11 @@ frame :: () {
|
||||
sgl_ortho(0.0, sapp_widthf(), sapp_heightf(), 0.0, -1.0, +1.0);
|
||||
|
||||
tick_ui();
|
||||
sg_begin_pass(*(sg_pass.{ action = state.pass_action, swapchain = cast,force(sg_swapchain) sglue_swapchain() }));
|
||||
render_ui();
|
||||
sfons_flush(state.fons);
|
||||
is_in_pass = true;
|
||||
sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, swapchain = cast,force(sg_swapchain) sglue_swapchain() }));
|
||||
arb_tri_flush();
|
||||
sgl_draw();
|
||||
sg_end_pass();
|
||||
// sg_end_pass();
|
||||
sg_commit();
|
||||
|
||||
input_per_frame_event_and_flag_update();
|
||||
|
||||
5
src/ui/component_themes.jai
Normal file
5
src/ui/component_themes.jai
Normal file
@ -0,0 +1,5 @@
|
||||
t_label_left :: (theme: *GR.Overall_Theme) -> GR.Label_Theme {
|
||||
t := theme.label_theme;
|
||||
t.alignment = GR.Text_Alignment.Left;
|
||||
return t;
|
||||
}
|
||||
@ -1,6 +1,37 @@
|
||||
GR :: #import "GetRect_LeftHanded"()(Type_Indicator = Ui_Type_Indicator);
|
||||
Input :: #import "Input";
|
||||
|
||||
#load "component_themes.jai";
|
||||
|
||||
// vw is 1/100 of view width
|
||||
vw : float;
|
||||
// vh is 1/100 of view height
|
||||
vh : float;
|
||||
|
||||
// These are for making minimum widths and heights.
|
||||
// nvh is 1/100 of 1080;
|
||||
nvh : float : 1080 / 100;
|
||||
// nvw is 1/100 of 1920;
|
||||
nvw : float : 1920 / 100;
|
||||
|
||||
ui_w :: (normal_w : int, min_w: int) -> float {
|
||||
min_width := min_w * nvw;
|
||||
normal_width := normal_w * vw;
|
||||
|
||||
if min_width > normal_width then return min_width;
|
||||
|
||||
return normal_width;
|
||||
}
|
||||
|
||||
ui_h :: (normal_h : int, min_h: int) -> float {
|
||||
min_height := min_h * nvh;
|
||||
normal_height := normal_h * vh;
|
||||
|
||||
if min_height > normal_height then return min_height;
|
||||
|
||||
return normal_height;
|
||||
}
|
||||
|
||||
default_texture : *Ui_Texture = null;
|
||||
|
||||
Ui_Font_Glyph :: struct {
|
||||
@ -105,6 +136,7 @@ set_shader_for_color :: (enable_blend := false) {
|
||||
type = .REMOVE_TEXTURE
|
||||
});
|
||||
add_uvs = false;
|
||||
immediate_flush();
|
||||
}
|
||||
|
||||
|
||||
@ -114,12 +146,20 @@ set_shader_for_images :: (texture: *Ui_Texture) {
|
||||
texture = texture
|
||||
});
|
||||
add_uvs = true;
|
||||
immediate_flush();
|
||||
}
|
||||
|
||||
gPreppedText: string;
|
||||
gPreppedTextWidth : s32;
|
||||
|
||||
prepare_text :: (font: *Ui_Type_Indicator.Font, text: string, effects: Ui_Type_Indicator.Font_Effects = 0) -> s64 {
|
||||
if text.count < 1 then return 0;
|
||||
|
||||
arb_tri_command_add(.{
|
||||
type = .PREPARE_TEXT,
|
||||
font = font,
|
||||
text = text
|
||||
});
|
||||
fonsSetFont(state.fons, state.font_default.fons_font);
|
||||
fonsSetSize(state.fons, xx font.character_height);
|
||||
w := fonsTextBounds(state.fons, 0.0, 0.0, text.data, text.data + text.count, null);
|
||||
@ -141,12 +181,13 @@ prepare_text :: (font: *Ui_Type_Indicator.Font, text: string, effects: Ui_Type_I
|
||||
return cast(s64) w;
|
||||
}
|
||||
draw_prepared_text :: (font: *Ui_Type_Indicator.Font, x: s64, y: s64, text_color: Vector4, effects: Ui_Type_Indicator.Font_Effects = 0) {
|
||||
color := sfons_rgba(xx (255.0 * text_color.x), xx (255.0 * text_color.y), xx (255.0 * text_color.z), xx (255.0 * text_color.w));
|
||||
fonsSetColor(state.fons, color);
|
||||
result := cast(*u8) temporary_alloc(gPreppedText.count + 1); // Add 1 for the zero.
|
||||
memcpy(result, gPreppedText.data, gPreppedText.count);
|
||||
result[gPreppedText.count] = 0;
|
||||
fonsDrawText(state.fons, xx x, xx y, result, null);
|
||||
arb_tri_command_add(.{
|
||||
type = .DRAW_TEXT,
|
||||
text_color = text_color,
|
||||
font = font,
|
||||
x = x,
|
||||
y = y
|
||||
});
|
||||
}
|
||||
get_mouse_pointer_position :: (window: Ui_Type_Indicator.Window_Type, right_handed: bool) -> (x: int, y: int, success: bool) {
|
||||
return xx input_mouse_x, xx input_mouse_y, true;
|
||||
@ -232,8 +273,12 @@ tick_ui :: () {
|
||||
for ui_events {
|
||||
GR.getrect_handle_event(it);
|
||||
}
|
||||
vw = (cast(float) w)/100.0;
|
||||
vh = (cast(float) h)/100.0;
|
||||
array_reset_keeping_memory(*ui_events);
|
||||
GR.ui_per_frame_update(1, xx w, xx h, get_time());
|
||||
|
||||
tick_editor_ui();
|
||||
}
|
||||
|
||||
checkboxTest : bool = false;
|
||||
@ -247,29 +292,26 @@ idk : bool;
|
||||
|
||||
test_color : Vector3 = .{1.0, 0.0, 1.0};
|
||||
|
||||
draw_bg_rectangle :: (r: GR.Rect, theme: GR.Overall_Theme) {
|
||||
draw_rectangle(r, theme.background_color);
|
||||
}
|
||||
|
||||
draw_rectangle :: (r: GR.Rect, color: Vector4) {
|
||||
set_shader_for_color();
|
||||
immediate_quad(.{r.x, r.y}, .{r.x + r.w, r.y}, .{r.x + r.w, r.y + r.h}, .{r.x, r.y + r.h}, color);
|
||||
immediate_flush();
|
||||
}
|
||||
|
||||
font_boundary :: () {
|
||||
arb_tri_command_add(.{type = .FONT_BOUNDARY});
|
||||
}
|
||||
|
||||
render_ui :: () {
|
||||
proc := GR.default_theme_procs[0];
|
||||
my_theme := proc();
|
||||
GR.set_default_theme(my_theme);
|
||||
|
||||
r := GR.get_rect(10, 10, 400, 30);
|
||||
pressed := GR.button(r, "GetRect render lfg!!", *my_theme.button_theme);
|
||||
if pressed {
|
||||
}
|
||||
|
||||
r.y += 50;
|
||||
|
||||
GR.text_input(r, "TTT", *my_theme.text_input_theme);
|
||||
|
||||
r.y += 150;
|
||||
if GR.base_checkbox(r, "CHECK!!!", idk, null) {
|
||||
idk = !idk;
|
||||
}
|
||||
|
||||
r.y += 150;
|
||||
r.h = 500;
|
||||
|
||||
GR.color_picker(r, *test_color);
|
||||
draw_editor_ui(*my_theme);
|
||||
r := GR.get_rect(100, 100, 200, 50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user