From 4a76692826767de5d058041d8dd89852fae14eef Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 10 Nov 2017 19:58:47 -0500 Subject: [PATCH] Rendering improvements and partial cleanup --- 4coder_lib/4coder_mem.h | 4 +- 4ed.cpp | 14 +- 4ed_cursor_codes.h | 5 +- 4ed_render_fill.cpp | 77 +++---- 4ed_render_format.h | 43 ++-- 4ed_render_target.cpp | 113 +++++---- 4ed_render_target.h | 4 +- opengl/4ed_opengl_defines.h | 21 ++ opengl/4ed_opengl_funcs.h | 21 ++ .../4ed_opengl_render.cpp | 218 +++++++++--------- platform_all/4ed_shared_init_logic.cpp | 7 +- platform_linux/linux_4ed.cpp | 69 +++--- platform_mac/mac_4ed.cpp | 44 ++-- platform_mac/mac_4ed.m | 25 +- platform_mac/osx_objective_c_to_cpp_links.h | 6 + platform_win32/win32_4ed.cpp | 81 ++++--- platform_win32/win32_gl.h | 4 - 17 files changed, 402 insertions(+), 354 deletions(-) create mode 100644 opengl/4ed_opengl_defines.h create mode 100644 opengl/4ed_opengl_funcs.h rename 4ed_render_opengl.cpp => opengl/4ed_opengl_render.cpp (71%) diff --git a/4coder_lib/4coder_mem.h b/4coder_lib/4coder_mem.h index e029f8eb..a83a8e3c 100644 --- a/4coder_lib/4coder_mem.h +++ b/4coder_lib/4coder_mem.h @@ -92,10 +92,11 @@ partition_reduce(Partition *data, i32_4tech size){ } } -inline void +inline void* partition_align(Partition *data, u32_4tech boundary){ --boundary; data->pos = (data->pos + boundary) & (~boundary); + return(data->base + data->pos); } inline void* @@ -121,6 +122,7 @@ partition_sub_part(Partition *data, i32_4tech size){ #define push_struct(part, T) (T*)partition_allocate(part, sizeof(T)) #define push_array(part, T, size) (T*)partition_allocate(part, sizeof(T)*(size)) #define push_block(part, size) partition_allocate(part, size) +#define push_align(part, b) partition_align(part, b) inline Temp_Memory begin_temp_memory(Partition *data){ diff --git a/4ed.cpp b/4ed.cpp index b3decb21..cf113e44 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -2312,14 +2312,6 @@ App_Step_Sig(app_step){ { begin_render_section(target, system); - target->clip_top = -1; - i32_Rect target_rect = {0}; - target_rect.x0 = 0; - target_rect.y0 = 0; - target_rect.x1 = target->width; - target_rect.y1 = target->height; - draw_push_clip(target, target_rect); - Command_Data *command = cmd; USE_PANEL(active_panel); USE_VIEW(active_view); @@ -2338,8 +2330,6 @@ App_Step_Sig(app_step){ u32 back_color = style->main.back_color; draw_rectangle(target, full, back_color); - draw_push_clip(target, panel->inner); - b32 file_scroll = false; GUI_Scroll_Vars scroll_zero = {0}; GUI_Scroll_Vars *scroll_vars = &view->gui_scroll; @@ -2353,9 +2343,7 @@ App_Step_Sig(app_step){ } } - do_render_file_view(system, view, models, scroll_vars, active_view, panel->inner, active, target, &dead_input); - - draw_pop_clip(target); + do_render_file_view(system, view, models, scroll_vars, active_view, panel->inner, active, target, &dead_input); u32 margin_color; if (active){ diff --git a/4ed_cursor_codes.h b/4ed_cursor_codes.h index 7f9f2024..aac5f163 100644 --- a/4ed_cursor_codes.h +++ b/4ed_cursor_codes.h @@ -12,7 +12,8 @@ #if !defined(FRED_CURSOR_CODES_H) #define FRED_CURSOR_CODES_H -typedef enum Application_Mouse_Cursor{ +typedef i32 Application_Mouse_Cursor; +enum{ APP_MOUSE_CURSOR_DEFAULT, APP_MOUSE_CURSOR_ARROW, APP_MOUSE_CURSOR_IBEAM, @@ -20,7 +21,7 @@ typedef enum Application_Mouse_Cursor{ APP_MOUSE_CURSOR_UPDOWN, // never below this APP_MOUSE_CURSOR_COUNT -} Application_Mouse_Cursor; +}; #endif diff --git a/4ed_render_fill.cpp b/4ed_render_fill.cpp index 5c41dfcc..adc11871 100644 --- a/4ed_render_fill.cpp +++ b/4ed_render_fill.cpp @@ -22,13 +22,12 @@ draw_pop_clip(Render_Target *target){ inline void draw_change_clip(Render_Target *target, i32_Rect clip_box){ - render_pop_clip(target); - render_push_clip(target, clip_box); + render_change_clip(target, clip_box); } internal void begin_render_section(Render_Target *target, System_Functions *system){ - target->size = 0; + target->buffer.pos = 0; target->clip_top = -1; i32_Rect clip; @@ -44,31 +43,31 @@ end_render_section(Render_Target *target, System_Functions *system){ Assert(target->clip_top == 0); } -internal void -draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){ - Render_Piece_Combined piece; - piece.header.type = piece_type_rectangle; - piece.rectangle.rect = f32R(rect); - piece.rectangle.color = color; - render_push_piece(target, piece); -} +#define CmdHeader(t) cmd.header.size = sizeof(cmd), cmd.header.type = t internal void draw_rectangle(Render_Target *target, f32_Rect rect, u32 color){ - Render_Piece_Combined piece; - piece.header.type = piece_type_rectangle; - piece.rectangle.rect = rect; - piece.rectangle.color = color; - render_push_piece(target, piece); + Render_Command_Rectangle cmd = {0}; + CmdHeader(RenCom_Rectangle); + cmd.rect = rect; + cmd.color = color; + void *h = render_begin_push(target, &cmd, cmd.header.size); + render_end_push(target, h); +} + +internal void +draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){ + draw_rectangle(target, f32R(rect), color); } internal void draw_rectangle_outline(Render_Target *target, f32_Rect rect, u32 color){ - Render_Piece_Combined piece; - piece.header.type = piece_type_outline; - piece.rectangle.rect = rect; - piece.rectangle.color = color; - render_push_piece(target, piece); + Render_Command_Rectangle cmd = {0}; + CmdHeader(RenCom_Outline); + cmd.rect = rect; + cmd.color = color; + void *h = render_begin_push(target, &cmd, cmd.header.size); + render_end_push(target, h); } inline void @@ -90,25 +89,21 @@ draw_margin(Render_Target *target, i32_Rect outer, i32 width, u32 color){ draw_margin(target, outer, inner, color); } -internal void -draw_font_glyph(Render_Target *target, Font_ID font_id, i32 type, u32 codepoint, f32 x, f32 y, u32 color){ - Render_Piece_Combined piece; - piece.header.type = type; - piece.glyph.pos.x = x; - piece.glyph.pos.y = y; - piece.glyph.color = color; - piece.glyph.font_id = font_id; - piece.glyph.codepoint = codepoint; - render_push_piece(target, piece); -} - internal void draw_font_glyph(Render_Target *target, Font_ID font_id, u32 codepoint, f32 x, f32 y, u32 color){ - draw_font_glyph(target, font_id, piece_type_glyph, codepoint, x, y, color); + Render_Command_Glyph cmd; + CmdHeader(RenCom_Glyph); + cmd.pos.x = x; + cmd.pos.y = y; + cmd.color = color; + cmd.font_id = font_id; + cmd.codepoint = codepoint; + void *h = render_begin_push(target, &cmd, cmd.header.size); + render_end_push(target, h); } internal f32 -draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_id, i32 type, String str_, i32 x_, i32 y_, u32 color){ +draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_id, String str_, i32 x_, i32 y_, u32 color){ f32 x = 0; Render_Font *font = system->font.get_render_data_by_id(font_id); @@ -134,7 +129,7 @@ draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_i if (behavior.do_codepoint_advance){ u32 codepoint = step.value; if (color != 0){ - draw_font_glyph(target, font_id, type, codepoint, x, y, color); + draw_font_glyph(target, font_id, codepoint, x, y, color); } x += font_get_glyph_advance(system, font, codepoint); } @@ -147,7 +142,7 @@ draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_i f32 xx = x; for (u32 j = 0; j < 3; ++j){ - draw_font_glyph(target, font_id, type, cs[j], xx, y, color); + draw_font_glyph(target, font_id, cs[j], xx, y, color); xx += sub_advances[j]; } } @@ -162,27 +157,27 @@ draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_i internal f32 draw_string(System_Functions *system, Render_Target *target, Font_ID font_id, String str, i32 x, i32 y, u32 color){ - f32 w = draw_string_base(system, target, font_id, piece_type_glyph, str, x, y, color); + f32 w = draw_string_base(system, target, font_id, str, x, y, color); return(w); } internal f32 draw_string(System_Functions *system, Render_Target *target, Font_ID font_id, char *str, i32 x, i32 y, u32 color){ String string = make_string_slowly(str); - f32 w = draw_string_base(system, target, font_id, piece_type_glyph, string, x, y, color); + f32 w = draw_string_base(system, target, font_id, string, x, y, color); return(w); } internal f32 font_string_width(System_Functions *system, Render_Target *target, Font_ID font_id, String str){ - f32 w = draw_string_base(system, target, font_id, piece_type_glyph, str, 0, 0, 0); + f32 w = draw_string_base(system, target, font_id, str, 0, 0, 0); return(w); } internal f32 font_string_width(System_Functions *system, Render_Target *target, Font_ID font_id, char *str){ String string = make_string_slowly(str); - f32 w = draw_string_base(system, target, font_id, piece_type_glyph, string, 0, 0, 0); + f32 w = draw_string_base(system, target, font_id, string, 0, 0, 0); return(w); } diff --git a/4ed_render_format.h b/4ed_render_format.h index c0016401..ba00e712 100644 --- a/4ed_render_format.h +++ b/4ed_render_format.h @@ -9,56 +9,43 @@ // TOP -enum Render_Piece_Type{ - piece_type_rectangle, - piece_type_outline, - piece_type_glyph, - piece_type_change_clip +enum Render_Command_Type{ + RenCom_Rectangle, + RenCom_Outline, + RenCom_Glyph, + RenCom_ChangeClip }; -struct Render_Piece_Header{ +struct Render_Command_Header{ + i32 size; i32 type; }; -struct Render_Piece_Rectangle{ +struct Render_Command_Rectangle{ + Render_Command_Header header; f32_Rect rect; u32 color; }; -struct Render_Piece_Gradient{ +struct Render_Command_Gradient{ + Render_Command_Header header; f32_Rect rect; u32 left_color; u32 right_color; }; -struct Render_Piece_Glyph{ +struct Render_Command_Glyph{ + Render_Command_Header header; Vec2 pos; u32 color; Font_ID font_id; u32 codepoint; }; -struct Render_Piece_Glyph_Advance{ - Vec2 pos; - u32 color; - f32 advance; - Font_ID font_id; - u32 codepoint; -}; - -struct Render_Piece_Change_Clip{ +struct Render_Command_Change_Clip{ + Render_Command_Header header; i32_Rect box; }; -struct Render_Piece_Combined{ - Render_Piece_Header header; - union{ - Render_Piece_Rectangle rectangle; - Render_Piece_Gradient gradient; - Render_Piece_Glyph glyph; - Render_Piece_Glyph_Advance glyph_advance; - }; -}; - // BOTTOM diff --git a/4ed_render_target.cpp b/4ed_render_target.cpp index a9c98223..59d1131b 100644 --- a/4ed_render_target.cpp +++ b/4ed_render_target.cpp @@ -9,64 +9,86 @@ // TOP -#define Render_Push_Clip_Sig(n, t, c) void (n)(Render_Target *t, i32_Rect c) -#define Render_Pop_Clip_Sig(n, t) i32_Rect (n)(Render_Target *t) -#define Render_Push_Piece_Sig(n, t, p) void (n)(Render_Target *t, Render_Piece_Combined p) +#define Render_Begin_Push_Sig(n,t,p,s) void* (n)(Render_Target *t, void *p, i32 s) +#define Render_End_Push_Sig(n,t,h) void (n)(Render_Target *t, void *h) +#define Render_Change_Clip_Sig(n,t,c) void (n)(Render_Target *t, i32_Rect c) +#define Render_Push_Clip_Sig(n,t,c) void (n)(Render_Target *t, i32_Rect c) +#define Render_Pop_Clip_Sig(n,t) i32_Rect (n)(Render_Target *t) -inline void -draw_safe_push(Render_Target *t, i32 size, void *x){ - if (size + t->size <= t->max){ - memcpy(t->push_buffer + t->size, x, size); - t->size += size; +//////////////////////////////// + +internal +Render_Begin_Push_Sig(render_internal_begin_push, t, ptr, size){ + void *out = push_array(&t->buffer, u8, size); + if (out != 0){ + memcpy(out, ptr, size); } + + // TODO(allen): Application side logging. +#if 0 + else{ + LOG("Render command buffer out of memory!\n"); + } +#endif + return(out); } -#define PutStruct(s,x) draw_safe_push(t, sizeof(s), &x) - -internal -Render_Push_Piece_Sig(render_push_piece, t, piece){ - if (!t->clip_all){ - PutStruct(Render_Piece_Header, piece.header); - - switch (piece.header.type){ - case piece_type_rectangle: case piece_type_outline: - { - PutStruct(Render_Piece_Rectangle, piece.rectangle); - }break; - - case piece_type_glyph: - { - PutStruct(Render_Piece_Glyph, piece.glyph); - }break; - } - - Assert(t->size <= t->max); +internal +Render_End_Push_Sig(render_internal_end_push, t, h){ + if (h != 0){ + u8 *end_ptr = (u8*)push_align(&t->buffer, 8); + Render_Command_Header *header = (Render_Command_Header*)h; + header->size = (i32)(end_ptr - (u8*)h); } + // TODO(allen): else { LOG } } internal void -render_push_piece_clip(Render_Target *t, i32_Rect clip_box){ - if (!t->clip_all){ - // TODO(allen): optimize out if there are two clip box changes in a row - Render_Piece_Change_Clip clip = {0}; - Render_Piece_Header header = {0}; - - header.type = piece_type_change_clip; - clip.box = clip_box; - - PutStruct(Render_Piece_Header, header); - PutStruct(Render_Piece_Change_Clip, clip); +render_internal_push_clip(Render_Target *t, i32_Rect clip_box){ + t->clip_all = (clip_box.x0 >= clip_box.x1 || clip_box.y0 >= clip_box.y1); + if (t->clip_all){ + return; } + + // TODO(allen): If the previous command was also a push clip should + // undo that one and just do this one. (OPTIMIZATION). + Render_Command_Change_Clip cmd = {0}; + cmd.header.size = sizeof(cmd); + cmd.header.type = RenCom_ChangeClip; + cmd.box = clip_box; + void *h = render_internal_begin_push(t, &cmd, cmd.header.size); + render_internal_end_push(t, h); +} + +//////////////////////////////// + +internal +Render_Begin_Push_Sig(render_begin_push, t, ptr, size){ + void *out = 0; + if (!t->clip_all){ + out = render_internal_begin_push(t, ptr, size); + } + return(out); +} + +internal +Render_End_Push_Sig(render_end_push, t, h){ + render_internal_end_push(t, h); +} + +internal +Render_Change_Clip_Sig(render_change_clip, t, clip_box){ + Assert(t->clip_top > -1); + t->clip_boxes[t->clip_top] = clip_box; + render_internal_push_clip(t, clip_box); } internal Render_Push_Clip_Sig(render_push_clip, t, clip_box){ Assert(t->clip_top == -1 || fits_inside(clip_box, t->clip_boxes[t->clip_top])); - Assert(t->clip_top+1 < ArrayCount(t->clip_boxes)); + Assert(t->clip_top + 1 < ArrayCount(t->clip_boxes)); t->clip_boxes[++t->clip_top] = clip_box; - - t->clip_all = (clip_box.x0 >= clip_box.x1 || clip_box.y0 >= clip_box.y1); - render_push_piece_clip(t, clip_box); + render_internal_push_clip(t, clip_box); } internal @@ -75,10 +97,7 @@ Render_Pop_Clip_Sig(render_pop_clip, t){ i32_Rect result = t->clip_boxes[t->clip_top]; --t->clip_top; i32_Rect clip_box = t->clip_boxes[t->clip_top]; - - t->clip_all = (clip_box.x0 >= clip_box.x1 || clip_box.y0 >= clip_box.y1); - render_push_piece_clip(t, clip_box); - + render_internal_push_clip(t, clip_box); return(result); } diff --git a/4ed_render_target.h b/4ed_render_target.h index 56b800b2..b72825c5 100644 --- a/4ed_render_target.h +++ b/4ed_render_target.h @@ -22,9 +22,7 @@ struct Render_Target{ i32 bound_texture; u32 color; - // TODO(allen): change this to a Partition - char *push_buffer; - i32 size, max; + Partition buffer; }; #endif diff --git a/opengl/4ed_opengl_defines.h b/opengl/4ed_opengl_defines.h new file mode 100644 index 00000000..e90b9259 --- /dev/null +++ b/opengl/4ed_opengl_defines.h @@ -0,0 +1,21 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 10.11.2017 + * + * OpenGL defines for 4coder + * + */ + +// TOP + +#if !defined(FRED_OPENGL_DEFINES_H) +#define FRED_OPENGL_DEFINES_H + +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_OUTPUT 0x92E0 + +#endif + +// BOTTOM + diff --git a/opengl/4ed_opengl_funcs.h b/opengl/4ed_opengl_funcs.h new file mode 100644 index 00000000..7a3cec64 --- /dev/null +++ b/opengl/4ed_opengl_funcs.h @@ -0,0 +1,21 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 10.11.2017 + * + * OpenGL functions for 4coder + * + */ + +// TOP +/* Usage: +#define GL_FUNC(N,R,P) ~~~~ +#include "4ed_opengl_funcs.h" +*/ + +#undef GL_FUNC + +// BOTTOM + + + diff --git a/4ed_render_opengl.cpp b/opengl/4ed_opengl_render.cpp similarity index 71% rename from 4ed_render_opengl.cpp rename to opengl/4ed_opengl_render.cpp index 509d1715..cb92386f 100644 --- a/4ed_render_opengl.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -9,12 +9,13 @@ // TOP -#define ExtractStruct(s) ((s*)cursor); cursor += sizeof(s) +// TODO(allen): If we don't actually need this then burn down 4ed_opengl_funcs.h +// Declare function types and function pointers +//#define GL_FUNC(N,R,P) typedef R (N##_Function) P; N##_Function *P = 0; +//#include "4ed_opengl_funcs.h" +#include "4ed_opengl_defines.h" -inline void -private_draw_set_clip(Render_Target *t, i32_Rect clip_box){ - glScissor(clip_box.x0, t->height - clip_box.y1, clip_box.x1 - clip_box.x0, clip_box.y1 - clip_box.y0); -} +// OpenGL 2.1 implementation inline void private_draw_bind_texture(Render_Target *t, i32 texid){ @@ -33,106 +34,27 @@ private_draw_set_color(Render_Target *t, u32 color){ } } -inline void -private_draw_rectangle(Render_Target *t, f32_Rect rect, u32 color){ - private_draw_set_color(t, color); - private_draw_bind_texture(t, 0); - glBegin(GL_QUADS); - { - glVertex2f(rect.x0, rect.y0); - glVertex2f(rect.x0, rect.y1); - glVertex2f(rect.x1, rect.y1); - glVertex2f(rect.x1, rect.y0); - } - glEnd(); -} - -inline void -private_draw_rectangle_outline(Render_Target *t, f32_Rect rect, u32 color){ - f32_Rect r = get_inner_rect(rect, .5f); - private_draw_set_color(t, color); - private_draw_bind_texture(t, 0); - glBegin(GL_LINE_STRIP); - { - glVertex2f(r.x0, r.y0); - glVertex2f(r.x1, r.y0); - glVertex2f(r.x1, r.y1); - glVertex2f(r.x0, r.y1); - glVertex2f(r.x0, r.y0); - } - glEnd(); -} - -struct Render_Quad{ - f32 x0, y0, x1, y1; - f32 s0, t0, s1, t1; -}; - -inline Render_Quad -get_render_quad(Glyph_Bounds *b, i32 pw, i32 ph, float xpos, float ypos){ - Render_Quad q; - - float ipw = 1.0f / pw, iph = 1.0f / ph; - - q.x0 = xpos + b->xoff; - q.y0 = ypos + b->yoff; - q.x1 = xpos + b->xoff2; - q.y1 = ypos + b->yoff2; - - q.s0 = b->x0 * ipw; - q.t0 = b->y0 * iph; - q.s1 = b->x1 * ipw; - q.t1 = b->y1 * iph; - - return(q); -} - -inline void -private_draw_glyph(System_Functions *system, Render_Target *t, Render_Font *font, u32 codepoint, f32 x, f32 y, u32 color){ - Glyph_Data glyph = font_get_glyph(system, font, codepoint); - if (glyph.tex != 0){ - Render_Quad q = get_render_quad(&glyph.bounds, glyph.tex_width, glyph.tex_height, x, y); - - private_draw_set_color(t, color); - private_draw_bind_texture(t, glyph.tex); - glBegin(GL_QUADS); - { - glTexCoord2f(q.s0, q.t1); glVertex2f(q.x0, q.y1); - glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1); - glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0); - glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0); - } - glEnd(); - } -} - -internal void CALL_CONVENTION -opengl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam){ - // TODO(allen): Fill this in with my preferred thingy. -} - internal void interpret_render_buffer(System_Functions *system, Render_Target *t){ local_persist b32 first_opengl_call = true; if (first_opengl_call){ first_opengl_call = false; - // TODO(allen): Get logging working everywhere -#if 0 - //TODO(inso): glGetStringi is required in core profile if the GL version is >= 3.0 - char *Vendor = (char *)glGetString(GL_VENDOR); - char *Renderer = (char *)glGetString(GL_RENDERER); - char *Version = (char *)glGetString(GL_VERSION); + char *vendor = (char *)glGetString(GL_VENDOR); + char *renderer = (char *)glGetString(GL_RENDERER); + char *version = (char *)glGetString(GL_VERSION); - LOGF("GL_VENDOR: %s\n", Vendor); - LOGF("GL_RENDERER: %s\n", Renderer); - LOGF("GL_VERSION: %s\n", Version); -#endif + LOGF("GL_VENDOR: %s\n", vendor); + LOGF("GL_RENDERER: %s\n", renderer); + LOGF("GL_VERSION: %s\n", version); // TODO(allen): Get this up and running for dev mode again. #if (defined(BUILD_X64) && 0) || (defined(BUILD_X86) && 0) // NOTE(casey): This slows down GL but puts error messages to // the debug console immediately whenever you do something wrong + + void CALL_CONVENTION gl_dbg(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam); + glDebugMessageCallback_type *glDebugMessageCallback = (glDebugMessageCallback_type *)win32_load_gl_always("glDebugMessageCallback", module); glDebugMessageControl_type *glDebugMessageControl = @@ -152,39 +74,113 @@ interpret_render_buffer(System_Functions *system, Render_Target *t){ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - char *cursor = t->push_buffer; - char *cursor_end = cursor + t->size; + i32 width = t->width; + i32 height = t->height; - for (; cursor < cursor_end;){ - Render_Piece_Header *header = ExtractStruct(Render_Piece_Header); + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, height, 0, -1, 1); + glScissor(0, 0, width, height); + glClearColor(1.f, 0.f, 1.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, 0); + t->bound_texture = 0; + + glColor4f(0.f, 0.f, 0.f, 0.f); + t->color = 0; + + u8 *start = (u8*)t->buffer.base; + u8 *end = (u8*)t->buffer.base + t->buffer.pos; + Render_Command_Header *header = 0; + for (u8 *p = start; p < end; p += header->size){ + header = (Render_Command_Header*)p; i32 type = header->type; switch (type){ - case piece_type_rectangle: + case RenCom_Rectangle: { - Render_Piece_Rectangle *rectangle = ExtractStruct(Render_Piece_Rectangle); - private_draw_rectangle(t, rectangle->rect, rectangle->color); + Render_Command_Rectangle *rectangle = (Render_Command_Rectangle*)header; + f32_Rect r = rectangle->rect; + private_draw_set_color(t, rectangle->color); + private_draw_bind_texture(t, 0); + glBegin(GL_QUADS); + { + glVertex2f(r.x0, r.y0); + glVertex2f(r.x0, r.y1); + glVertex2f(r.x1, r.y1); + glVertex2f(r.x1, r.y0); + } + glEnd(); }break; - case piece_type_outline: + case RenCom_Outline: { - Render_Piece_Rectangle *rectangle = ExtractStruct(Render_Piece_Rectangle); - private_draw_rectangle_outline(t, rectangle->rect, rectangle->color); + Render_Command_Rectangle *rectangle = (Render_Command_Rectangle*)header; + f32_Rect r = get_inner_rect(rectangle->rect, .5f); + private_draw_set_color(t, rectangle->color); + private_draw_bind_texture(t, 0); + glBegin(GL_LINE_STRIP); + { + glVertex2f(r.x0, r.y0); + glVertex2f(r.x1, r.y0); + glVertex2f(r.x1, r.y1); + glVertex2f(r.x0, r.y1); + glVertex2f(r.x0, r.y0); + } + glEnd(); }break; - case piece_type_glyph: + case RenCom_Glyph: { - Render_Piece_Glyph *glyph = ExtractStruct(Render_Piece_Glyph); - + Render_Command_Glyph *glyph = (Render_Command_Glyph*)header; Render_Font *font = system->font.get_render_data_by_id(glyph->font_id); - Assert(font != 0); - private_draw_glyph(system, t, font, glyph->codepoint, glyph->pos.x, glyph->pos.y, glyph->color); + if (font == 0){ + break; + } + + Glyph_Data g = font_get_glyph(system, font, glyph->codepoint); + if (g.tex == 0){ + break; + } + + f32 x = glyph->pos.x; + f32 y = glyph->pos.y; + + f32_Rect xy = {0}; + xy.x0 = x + g.bounds.xoff; + xy.y0 = y + g.bounds.yoff; + xy.x1 = x + g.bounds.xoff2; + xy.y1 = y + g.bounds.yoff2; + + // TODO(allen): Why aren't these baked in??? + f32 unit_u = 1.f/g.tex_width; + f32 unit_v = 1.f/g.tex_height; + + f32_Rect uv = {0}; + uv.x0 = g.bounds.x0*unit_u; + uv.y0 = g.bounds.y0*unit_v; + uv.x1 = g.bounds.x1*unit_u; + uv.y1 = g.bounds.y1*unit_v; + + private_draw_set_color(t, glyph->color); + private_draw_bind_texture(t, g.tex); + glBegin(GL_QUADS); + { + glTexCoord2f(uv.x0, uv.y1); glVertex2f(xy.x0, xy.y1); + glTexCoord2f(uv.x1, uv.y1); glVertex2f(xy.x1, xy.y1); + glTexCoord2f(uv.x1, uv.y0); glVertex2f(xy.x1, xy.y0); + glTexCoord2f(uv.x0, uv.y0); glVertex2f(xy.x0, xy.y0); + } + glEnd(); }break; - case piece_type_change_clip: + case RenCom_ChangeClip: { - Render_Piece_Change_Clip *clip = ExtractStruct(Render_Piece_Change_Clip); - private_draw_set_clip(t, clip->box); + Render_Command_Change_Clip *clip = (Render_Command_Change_Clip*)header; + i32_Rect box = clip->box; + glScissor(box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0); }break; } } diff --git a/platform_all/4ed_shared_init_logic.cpp b/platform_all/4ed_shared_init_logic.cpp index ea951b1e..2d00786a 100644 --- a/platform_all/4ed_shared_init_logic.cpp +++ b/platform_all/4ed_shared_init_logic.cpp @@ -29,11 +29,12 @@ memory_init(){ memory_vars.user_memory = system_memory_allocate_extended(0, memory_vars.user_memory_size); memory_vars.debug_memory_size = MB(512); memory_vars.debug_memory = system_memory_allocate_extended(0, memory_vars.debug_memory_size); - target.max = MB(1); - target.push_buffer = (char*)system_memory_allocate(target.max); + + i32 render_memsize = MB(1); + target.buffer = make_part(system_memory_allocate(render_memsize), render_memsize); b32 alloc_success = true; - if (memory_vars.vars_memory == 0 || memory_vars.target_memory == 0 || memory_vars.user_memory == 0 || target.push_buffer == 0){ + if (memory_vars.vars_memory == 0 || memory_vars.target_memory == 0 || memory_vars.user_memory == 0 || target.buffer.base == 0){ alloc_success = false; } diff --git a/platform_linux/linux_4ed.cpp b/platform_linux/linux_4ed.cpp index 8afe449e..3bd6d67b 100644 --- a/platform_linux/linux_4ed.cpp +++ b/platform_linux/linux_4ed.cpp @@ -447,7 +447,7 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ #include "4ed_font_data.h" #include "4ed_system_shared.cpp" -#include "4ed_render_opengl.cpp" +#include "opengl/4ed_opengl_render.cpp" // // End of system funcs @@ -460,12 +460,6 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ internal void LinuxResizeTarget(i32 width, i32 height){ if (width > 0 && height > 0){ - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, height, 0, -1, 1); - glScissor(0, 0, width, height); - target.width = width; target.height = height; } @@ -1652,8 +1646,8 @@ main(int argc, char **argv){ system_schedule_step(); - linuxvars.keep_running = 1; - linuxvars.input.first_step = 1; + linuxvars.keep_running = true; + linuxvars.input.first_step = true; linuxvars.input.dt = (frame_useconds / 1000000.f); for (;;){ @@ -1675,13 +1669,13 @@ main(int argc, char **argv){ continue; } - b32 do_step = 0; + b32 do_step = false; - for(int i = 0; i < num_events; ++i){ + for (int i = 0; i < num_events; ++i){ int fd = events[i].data.u64 & UINT32_MAX; u64 type = events[i].data.u64 & ~fd; - switch(type){ + switch (type){ case LINUX_4ED_EVENT_X11: { LinuxHandleX11Events(); } break; @@ -1696,7 +1690,7 @@ main(int argc, char **argv){ do { ret = read(linuxvars.step_event_fd, &ev, 8); } while (ret != -1 || errno != EAGAIN); - do_step = 1; + do_step = true; } break; case LINUX_4ED_EVENT_STEP_TIMER: { @@ -1705,7 +1699,7 @@ main(int argc, char **argv){ do { ret = read(linuxvars.step_timer_fd, &count, 8); } while (ret != -1 || errno != EAGAIN); - do_step = 1; + do_step = true; } break; case LINUX_4ED_EVENT_CLI: { @@ -1717,14 +1711,11 @@ main(int argc, char **argv){ if (do_step){ linuxvars.last_step = system_now_time(); + // NOTE(allen): Frame Clipboard Input if (linuxvars.input.first_step || !linuxvars.has_xfixes){ XConvertSelection(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.atom_UTF8_STRING, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime); } - Application_Step_Result result = {}; - result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; - result.trying_to_kill = !linuxvars.keep_running; - if (linuxvars.new_clipboard){ linuxvars.input.clipboard = linuxvars.clipboard_contents; linuxvars.new_clipboard = 0; @@ -1732,29 +1723,26 @@ main(int argc, char **argv){ linuxvars.input.clipboard = null_string; } + // NOTE(allen): Initialize result So the Core Doesn't Have to Fill Things it Doesn't Care About + Application_Step_Result result = {0}; + result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; + result.trying_to_kill = !linuxvars.keep_running; + // HACK(allen): THIS SHIT IS FUCKED (happens on mac too) b32 keep_running = linuxvars.keep_running; + // NOTE(allen): Application Core Update app.step(&sysfunc, &target, &memory_vars, &linuxvars.input, &result); + // NOTE(allen): Finish the Loop if (result.perform_kill){ break; - } else if (!keep_running && !linuxvars.keep_running){ + } + else if (!keep_running && !linuxvars.keep_running){ linuxvars.keep_running = true; } - if (linuxvars.do_toggle){ - linux_toggle_fullscreen(); - linuxvars.do_toggle = false; - } - - if (result.animating){ - system_schedule_step(); - } - - interpret_render_buffer(&sysfunc, &target); - glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow); - + // NOTE(allen): Switch to New Cursor if (result.mouse_cursor_type != linuxvars.cursor && !linuxvars.input.mouse.l){ Cursor c = xcursors[result.mouse_cursor_type]; if (!linuxvars.hide_cursor){ @@ -1763,15 +1751,32 @@ main(int argc, char **argv){ linuxvars.cursor = result.mouse_cursor_type; } + // NOTE(allen): Render + interpret_render_buffer(&sysfunc, &target); + glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow); + + // NOTE(allen): Toggle Full Screen + if (linuxvars.do_toggle){ + linux_toggle_fullscreen(); + linuxvars.do_toggle = false; + } + + // NOTE(allen): Schedule Another Step if Needed + if (result.animating){ + system_schedule_step(); + } + flush_thread_group(BACKGROUND_THREADS); - linuxvars.input.first_step = 0; + // TODO(allen): CROSS REFERENCE WITH WIN32 "TIC898989" linuxvars.input.keys = null_key_input_data; linuxvars.input.mouse.press_l = 0; linuxvars.input.mouse.release_l = 0; linuxvars.input.mouse.press_r = 0; linuxvars.input.mouse.release_r = 0; linuxvars.input.mouse.wheel = 0; + + linuxvars.input.first_step = 0; } } diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index eb17ba58..2a05b4f9 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -312,7 +312,7 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ #include "4ed_font_data.h" #include "4ed_system_shared.cpp" -#include "4ed_render_opengl.cpp" +#include "opengl/4ed_opengl_render.cpp" //////////////////////////////// @@ -336,12 +336,6 @@ osx_resize(int width, int height){ osx_objc.width = width; osx_objc.height = height; - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, height, 0, -1, 1); - glScissor(0, 0, width, height); - target.width = width; target.height = height; @@ -490,15 +484,7 @@ osx_step(void){ result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; result.trying_to_kill = !osxvars.keep_running; - if (osx_objc.has_clipboard_item){ - //void *clipboard_data; - //umem clipboard_size, clipboard_max; - osxvars.input.clipboard = make_string(osx_objc.clipboard_data, (i32)osx_objc.clipboard_size); - } - else{ - osxvars.input.clipboard = null_string; - } - + // NOTE(allen): Prepare the Frame Input osxvars.input.dt = 1.f/60.f; if (osxvars.has_prev_time){ u64 time_u = system_now_time(); @@ -511,6 +497,7 @@ osx_step(void){ osxvars.prev_time_u = system_now_time(); } + // TODO(allen): CROSS REFERENCE WITH WINDOWS SPECIAL CODE "TIC898989" Application_Step_Input frame_input = osxvars.input; osxvars.input.first_step = false; osxvars.input.keys = null_key_input_data; @@ -520,14 +507,25 @@ osx_step(void){ osxvars.input.mouse.release_r = false; osxvars.input.mouse.wheel = 0; + // NOTE(allen): Frame Clipboard Input + if (osx_objc.has_clipboard_item){ + osxvars.input.clipboard = make_string(osx_objc.clipboard_data, (i32)osx_objc.clipboard_size); + } + else{ + osxvars.input.clipboard = null_string; + } + + // HACK(allen): Got this all messed up with respect to how everyone else (other OS layers) work osx_objc.do_toggle = false; osx_objc.full_screen = osx_is_fullscreen(); // HACK(allen): THIS SHIT IS FUCKED (happens on linux too) b32 keep_running = osxvars.keep_running; + // NOTE(allen): Application Core Update app.step(&sysfunc, &target, &memory_vars, &frame_input, &result); + // NOTE(allen): Finish the Loop if (result.perform_kill){ osx_close_app(); } @@ -535,14 +533,20 @@ osx_step(void){ osxvars.keep_running = true; } + // NOTE(allen): Switch to New Cursor + osx_show_cursor(0, result.mouse_cursor_type); + + // NOTE(allen): Render + osx_begin_render(); + interpret_render_buffer(&sysfunc, &target); + osx_end_render(); + + // NOTE(allen): Toggle Full Screen if (osx_objc.do_toggle){ osx_toggle_fullscreen(); } - osx_show_cursor(0, result.mouse_cursor_type); - - interpret_render_buffer(&sysfunc, &target); - + // NOTE(allen): Schedule Another Step if Needed if (result.animating || cli_count > 0){ osx_schedule_step(); } diff --git a/platform_mac/mac_4ed.m b/platform_mac/mac_4ed.m index d4afa75f..0ed862ad 100644 --- a/platform_mac/mac_4ed.m +++ b/platform_mac/mac_4ed.m @@ -186,11 +186,7 @@ static i32 did_update_for_clipboard = true; osx_objc.prev_clipboard_change_count = board.changeCount; } - CGLLockContext([[self openGLContext] CGLContextObj]); - [[self openGLContext] makeCurrentContext]; osx_step(); - [[self openGLContext] flushBuffer]; - CGLUnlockContext([[self openGLContext] CGLContextObj]); } } return kCVReturnSuccess; @@ -289,15 +285,6 @@ static i32 did_update_for_clipboard = true; } @end -#if 0 -static -DISPLINK_SIG(osx_display_link){ - My4coderView* view = (__bridge My4coderView*)context; - CVReturn result = [view getFrame]; - return result; -} -#endif - @implementation AppDelegate - (void)applicationDidFinishLaunching:(id)sender { @@ -643,6 +630,18 @@ osx_show_cursor(i32 show, i32 cursor_type){ My4coderView* view = 0; NSWindow* window = 0; +void +osx_begin_render(){ + CGLLockContext([[view openGLContext] CGLContextObj]); + [[view openGLContext] makeCurrentContext]; +} + +void +osx_end_render(){ + [[view openGLContext] flushBuffer]; + CGLUnlockContext([[view openGLContext] CGLContextObj]); +} + void osx_schedule_step(void){ [NSTimer scheduledTimerWithTimeInterval: 0.0 diff --git a/platform_mac/osx_objective_c_to_cpp_links.h b/platform_mac/osx_objective_c_to_cpp_links.h index 3c5c1274..364fa985 100644 --- a/platform_mac/osx_objective_c_to_cpp_links.h +++ b/platform_mac/osx_objective_c_to_cpp_links.h @@ -105,6 +105,12 @@ osx_get_file_change_event(char *buffer, i32 max, i32 *size); external void osx_show_cursor(i32 show_inc, i32 cursor_type); +void +osx_begin_render(); + +void +osx_end_render(); + external void osx_schedule_step(void); diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index e898e193..9bb197cc 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -488,7 +488,7 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ #include "4ed_font_data.h" #include "4ed_system_shared.cpp" -#include "4ed_render_opengl.cpp" +#include "opengl/4ed_opengl_render.cpp" // // Helpers @@ -533,12 +533,6 @@ Win32KeycodeInit(){ internal void Win32Resize(i32 width, i32 height){ if (width > 0 && height > 0){ - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, height, 0, -1, 1); - glScissor(0, 0, width, height); - target.width = width; target.height = height; } @@ -1186,9 +1180,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS MSG msg; for (;keep_running;){ // TODO(allen): Find a good way to wait on a pipe - // without interfering with the reading process - // Looks like we can ReadFile with a size of zero - // in an IOCP for this effect. + // without interfering with the reading process. + // NOTE(allen): Looks like we can ReadFile with a + // size of zero in an IOCP for this effect. if (!win32vars.first){ system_release_lock(FRAME_LOCK); @@ -1274,6 +1268,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS system_acquire_lock(FRAME_LOCK); } + // NOTE(allen): Mouse Out of Window Detection POINT mouse_point; if (GetCursorPos(&mouse_point) && ScreenToClient(win32vars.window_handle, &mouse_point)){ @@ -1293,40 +1288,28 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS } if (!is_hit){ - win32vars.input_chunk.trans.out_of_window = 1; + win32vars.input_chunk.trans.out_of_window = true; } win32vars.input_chunk.pers.mouse_x = mouse_point.x; win32vars.input_chunk.pers.mouse_y = mouse_point.y; } else{ - win32vars.input_chunk.trans.out_of_window = 1; + win32vars.input_chunk.trans.out_of_window = true; } + // NOTE(allen): Prepare the Frame Input + + // TODO(allen): CROSS REFERENCE WITH LINUX SPECIAL CODE "TIC898989" Win32_Input_Chunk input_chunk = win32vars.input_chunk; win32vars.input_chunk.trans = null_input_chunk_transient; input_chunk.pers.control_keys[MDFR_CAPS_INDEX] = GetKeyState(VK_CAPITAL) & 0x1; - win32vars.clipboard_contents = null_string; - if (win32vars.clipboard_sequence != 0){ - DWORD new_number = GetClipboardSequenceNumber(); - if (new_number != win32vars.clipboard_sequence){ - win32vars.clipboard_sequence = new_number; - if (win32vars.next_clipboard_is_self){ - win32vars.next_clipboard_is_self = 0; - } - else{ - win32_read_clipboard_contents(); - } - } - } - Application_Step_Input input = {0}; input.first_step = win32vars.first; - // NOTE(allen): The expected dt given the frame limit in seconds. input.dt = frame_useconds / 1000000.f; input.keys = input_chunk.trans.key_data; @@ -1343,33 +1326,47 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS input.mouse.wheel = input_chunk.trans.mouse_wheel; input.mouse.x = input_chunk.pers.mouse_x; + input.mouse.y = input_chunk.pers.mouse_y; + // NOTE(allen): Frame Clipboard Input + win32vars.clipboard_contents = null_string; + if (win32vars.clipboard_sequence != 0){ + DWORD new_number = GetClipboardSequenceNumber(); + if (new_number != win32vars.clipboard_sequence){ + win32vars.clipboard_sequence = new_number; + if (win32vars.next_clipboard_is_self){ + win32vars.next_clipboard_is_self = 0; + } + else{ + win32_read_clipboard_contents(); + } + } + } input.clipboard = win32vars.clipboard_contents; - - Application_Step_Result result = {(Application_Mouse_Cursor)0}; + // NOTE(allen): Initialize result So the Core Doesn't Have to Fill Things it Doesn't Care About + Application_Step_Result result = {0}; result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; result.lctrl_lalt_is_altgr = win32vars.lctrl_lalt_is_altgr; result.trying_to_kill = input_chunk.trans.trying_to_kill; - result.perform_kill = 0; + // TODO(allen): Not really appropriate to round trip this all the way to the OS layer, redo this system. + // NOTE(allen): Ask the Core About Exiting if We Have an Exit Signal if (win32vars.send_exit_signal){ result.trying_to_kill = true; win32vars.send_exit_signal = false; } + // NOTE(allen): Application Core Update app.step(&sysfunc, &target, &memory_vars, &input, &result); + // NOTE(allen): Finish the Loop if (result.perform_kill){ keep_running = false; } - if (win32vars.do_toggle){ - win32_toggle_fullscreen(); - win32vars.do_toggle = false; - } - + // NOTE(allen): Switch to New Cursor Win32SetCursorFromUpdate(result.mouse_cursor_type); if (win32vars.cursor_show != win32vars.prev_cursor_show){ win32vars.prev_cursor_show = win32vars.cursor_show; @@ -1393,19 +1390,28 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS // TODO(allen): MouseCursorShow_HideWhenStill } } + + // NOTE(allen): Update lctrl_lalt_is_altgr Status win32vars.lctrl_lalt_is_altgr = result.lctrl_lalt_is_altgr; + // NOTE(allen): Render HDC hdc = GetDC(win32vars.window_handle); interpret_render_buffer(&sysfunc, &target); SwapBuffers(hdc); ReleaseDC(win32vars.window_handle, hdc); - win32vars.first = 0; + // NOTE(allen): Toggle Full Screen + if (win32vars.do_toggle){ + win32_toggle_fullscreen(); + win32vars.do_toggle = false; + } + // NOTE(allen): Schedule Another Step if Needed if (result.animating){ system_schedule_step(); } + // NOTE(allen): Sleep a Bit to Cool Off :) flush_thread_group(BACKGROUND_THREADS); u64 timer_end = Win32HighResolutionTime(); @@ -1419,6 +1425,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS } system_acquire_lock(FRAME_LOCK); timer_start = Win32HighResolutionTime(); + + // TODO(allen): Only rely on version right inside input? + win32vars.first = 0; } return(0); diff --git a/platform_win32/win32_gl.h b/platform_win32/win32_gl.h index ebdf5a69..040a1832 100644 --- a/platform_win32/win32_gl.h +++ b/platform_win32/win32_gl.h @@ -70,9 +70,5 @@ #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -// TODO(allen): these don't belong here, but the organizational stuff is not fully in place yet. -#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -#define GL_DEBUG_OUTPUT 0x92E0 - // BOTTOM