From a1318e6117e95e92cb2c5af7eafb9052b22427e3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 21:51:48 -0700 Subject: [PATCH] sketch out first bit of linux-backend of opengl-backend --- build.sh | 3 +- project.4coder | 8 +- src/render/opengl/linux/render_opengl_linux.c | 110 ++++++++++++++++++ src/render/opengl/linux/render_opengl_linux.h | 25 ++++ src/render/opengl/render_opengl.c | 22 +++- src/render/opengl/render_opengl.h | 2 + src/render/opengl/win32/render_opengl_win32.c | 8 +- src/scratch/ryan_scratch.c | 46 ++++++-- 8 files changed, 205 insertions(+), 19 deletions(-) create mode 100644 src/render/opengl/linux/render_opengl_linux.c create mode 100644 src/render/opengl/linux/render_opengl_linux.h diff --git a/build.sh b/build.sh index 03bde82c..ae301d3f 100644 --- a/build.sh +++ b/build.sh @@ -33,6 +33,7 @@ gcc_out="-o" # --- Per-Build Settings ------------------------------------------------------ link_dll="-fPIC" link_os_gfx="-lX11 -lXext" +link_render="-lGL" # --- Choose Compile/Link Lines ----------------------------------------------- if [ -v gcc ]; then compile_debug="$gcc_debug"; fi @@ -68,7 +69,7 @@ if [ -v rdi_from_pdb ]; then didbuild=1 && $compile ../src/rdi_from_pdb if [ -v rdi_from_dwarf ]; then didbuild=1 && $compile ../src/rdi_from_dwarf/rdi_from_dwarf.c $compile_link $out rdi_from_dwarf; fi if [ -v rdi_dump ]; then didbuild=1 && $compile ../src/rdi_dump/rdi_dump_main.c $compile_link $out rdi_dump; fi if [ -v rdi_breakpad_from_pdb ]; then didbuild=1 && $compile ../src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c $compile_link $out rdi_breakpad_from_pdb; fi -if [ -v ryan_scratch ]; then didbuild=1 && $compile ../src/scratch/ryan_scratch.c $compile_link $link_os_gfx $out ryan_scratch; fi +if [ -v ryan_scratch ]; then didbuild=1 && $compile ../src/scratch/ryan_scratch.c $compile_link $link_os_gfx $link_render $out ryan_scratch; fi cd .. # --- Warn On No Builds ------------------------------------------------------- diff --git a/project.4coder b/project.4coder index 6b22acea..dd21c25b 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: [raddbg] - .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [textperf] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, @@ -54,9 +54,13 @@ commands = //- rjf: [tester] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + //- rjf: [ryan_scratch] + .f1 = { .win = "raddbg_stable --ipc kill_all && wsl ./build.sh ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + //- rjf: running target - .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "wsl /mnt/c/devel/raddebugger/build/ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: local target builds .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/render/opengl/linux/render_opengl_linux.c b/src/render/opengl/linux/render_opengl_linux.c new file mode 100644 index 00000000..0214b97a --- /dev/null +++ b/src/render/opengl/linux/render_opengl_linux.c @@ -0,0 +1,110 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal VoidProc * +r_ogl_os_load_procedure(char *name) +{ + VoidProc *result = (VoidProc *)glXGetProcAddressARB((U8 *)name); + return result; +} + +internal void +r_ogl_os_init(CmdLine *cmdln) +{ + //- rjf: require GLX 1.3+ + int glx_version_major = 0; + int glx_version_minor = 0; + if(!glXQueryVersion(os_lnx_gfx_state->display, &glx_version_major, &glx_version_minor) || + (glx_version_major == 1 && glx_version_minor < 3) || + glx_version_major < 1) + { + Temp scratch = scratch_begin(0, 0); + String8 message = push_str8f(scratch.arena, "Unsupported GLX version (%i.%i, need at least 1.3)", glx_version_major, glx_version_minor); + os_graphical_message(1, str8_lit("Fatal Error"), message); + os_abort(1); + scratch_end(scratch); + } + + //- rjf: get frame buffer configs + local_persist int framebuffer_config_options[] = + { + GLX_X_RENDERABLE, 1, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, + GLX_DEPTH_SIZE, 24, + GLX_STENCIL_SIZE, 8, + GLX_DOUBLEBUFFER, 1, + None + }; + int framebuffer_configs_count = 0; + GLXFBConfig *framebuffer_configs = glXChooseFBConfig(os_lnx_gfx_state->display, DefaultScreen(os_lnx_gfx_state->display), framebuffer_config_options, &framebuffer_configs_count); + if(framebuffer_configs == 0) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Could not find a suitable framebuffer configuration.")); + os_abort(1); + } + GLXFBConfig framebuffer_config = framebuffer_configs[0]; + XFree(framebuffer_configs); + + //- rjf: get visual info; create color map + XVisualInfo *visual_info = glXGetVisualFromFBConfig(os_lnx_gfx_state->display, framebuffer_config); + Colormap cmap = XCreateColormap(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), visual_info->visual, AllocNone); + + //- rjf: construct set-window-attributes + XSetWindowAttributes set_window_attributes = {0}; + set_window_attributes.background_pixmap = None; + set_window_attributes.border_pixel = 0; + set_window_attributes.event_mask = StructureNotifyMask; + + //- rjf: construct context + { + B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); +#if BUILD_DEBUG + debug_mode = 1; +#endif + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((U8 *)"glXCreateContextAttribsARB"); + int context_options[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 3, + GLX_CONTEXT_FLAGS_ARB, !!debug_mode*GLX_CONTEXT_DEBUG_BIT_ARB, + None + }; + r_ogl_lnx_ctx = glXCreateContextAttribsARB(os_lnx_gfx_state->display, framebuffer_config, 0, 1, context_options); + } + + glXMakeCurrent(os_lnx_gfx_state->display, None, r_ogl_lnx_ctx); +} + +internal R_Handle +r_ogl_os_window_equip(OS_Handle window) +{ + R_Handle result = {0}; + return result; +} + +internal void +r_ogl_os_window_unequip(OS_Handle os, R_Handle r) +{ + +} + +internal void +r_ogl_os_select_window(OS_Handle os, R_Handle r) +{ + OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; + glXMakeCurrent(os_lnx_gfx_state->display, w->window, r_ogl_lnx_ctx); +} + +internal void +r_ogl_os_window_swap(OS_Handle os, R_Handle r) +{ + OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; + glXSwapBuffers(os_lnx_gfx_state->display, w->window); +} diff --git a/src/render/opengl/linux/render_opengl_linux.h b/src/render/opengl/linux/render_opengl_linux.h new file mode 100644 index 00000000..f70f40a5 --- /dev/null +++ b/src/render/opengl/linux/render_opengl_linux.h @@ -0,0 +1,25 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RENDER_OPENGL_LINUX_H +#define RENDER_OPENGL_LINUX_H + +#define glTexImage3D glTexImage3D__static +#define glTexSubImage3D glTexSubImage3D__static +#define glActiveTexture glActiveTexture__static +#include +#include +#undef glTexImage3D +#undef glTexSubImage3D +#undef glActiveTexture + +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + +global GLXContext r_ogl_lnx_ctx = 0; + +#endif // RENDER_OPENGL_LINUX_H diff --git a/src/render/opengl/render_opengl.c b/src/render/opengl/render_opengl.c index cfbec7de..60266ce0 100644 --- a/src/render/opengl/render_opengl.c +++ b/src/render/opengl/render_opengl.c @@ -6,6 +6,8 @@ #if OS_WINDOWS # include "render/opengl/win32/render_opengl_win32.c" +#elif OS_LINUX +# include "render/opengl/linux/render_opengl_linux.c" #else # error OS portion of OpenGL rendering backend not defined. #endif @@ -67,6 +69,7 @@ internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { raddbg_log("[OpenGL] %.*s\n", (int)length, message); + fprintf(stderr, "[OpenGL] %.*s\n", (int)length, message); } //////////////////////////////// @@ -103,7 +106,7 @@ r_init(CmdLine *cmdln) { stages[idx].out = glCreateShader(stages[idx].type); GLint src_size = stages[idx].src->size; - glShaderSource(stages[idx].out, 1, &stages[idx].src->str, &src_size); + glShaderSource(stages[idx].out, 1, (char **)&stages[idx].src->str, &src_size); glCompileShader(stages[idx].out); GLint info_log_length = 0; GLint status = 0; @@ -113,7 +116,7 @@ r_init(CmdLine *cmdln) { stages[idx].errors.str = push_array(r_ogl_state->arena, U8, info_log_length+1); stages[idx].errors.size = info_log_length; - glGetShaderInfoLog(stages[idx].out, info_log_length, 0, stages[idx].errors.str); + glGetShaderInfoLog(stages[idx].out, info_log_length, 0, (char *)stages[idx].errors.str); } raddbg_pin(text(stages[idx].errors.str)); } @@ -129,14 +132,14 @@ r_init(CmdLine *cmdln) R_OGL_AttributeArray inputs = r_ogl_shader_kind_input_attributes_table[k]; for EachIndex(idx, inputs.count) { - glBindAttribLocation(program, inputs.v[idx].index, inputs.v[idx].name.str); + glBindAttribLocation(program, inputs.v[idx].index, (char *)inputs.v[idx].name.str); } // rjf: bind outputs R_OGL_AttributeArray outputs = r_ogl_shader_kind_output_attributes_table[k]; for EachIndex(idx, outputs.count) { - glBindFragDataLocation(program, outputs.v[idx].index, outputs.v[idx].name.str); + glBindFragDataLocation(program, outputs.v[idx].index, (char *)outputs.v[idx].name.str); } // rjf: link / validate / store @@ -158,8 +161,15 @@ r_init(CmdLine *cmdln) glEnable(GL_FRAMEBUFFER_SRGB); //- rjf: set up debug callback - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(r_ogl_debug_message_callback, 0); + B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); +#if BUILD_DEBUG + debug_mode = 1; +#endif + if(debug_mode) + { + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(r_ogl_debug_message_callback, 0); + } } //- rjf: window setup/teardown diff --git a/src/render/opengl/render_opengl.h b/src/render/opengl/render_opengl.h index 39ee5b5d..8f020c5e 100644 --- a/src/render/opengl/render_opengl.h +++ b/src/render/opengl/render_opengl.h @@ -9,6 +9,8 @@ #if OS_WINDOWS # include "render/opengl/win32/render_opengl_win32.h" +#elif OS_LINUX +# include "render/opengl/linux/render_opengl_linux.h" #else # error OS portion of OpenGL rendering backend not defined. #endif diff --git a/src/render/opengl/win32/render_opengl_win32.c b/src/render/opengl/win32/render_opengl_win32.c index 7b40d711..7e08edb0 100644 --- a/src/render/opengl/win32/render_opengl_win32.c +++ b/src/render/opengl/win32/render_opengl_win32.c @@ -78,11 +78,15 @@ r_ogl_os_init(CmdLine *cmdline) HGLRC real_ctx = 0; if(pf) { - const int context_attribs[] = + B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); +#if BUILD_DEBUG + debug_mode = 1; +#endif + int context_attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3, - WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, !!debug_mode*WGL_CONTEXT_DEBUG_BIT_ARB, 0 }; real_ctx = wglCreateContextAttribsARB(dc, bootstrap_ctx, context_attribs); diff --git a/src/scratch/ryan_scratch.c b/src/scratch/ryan_scratch.c index 8f1a564b..aa195640 100644 --- a/src/scratch/ryan_scratch.c +++ b/src/scratch/ryan_scratch.c @@ -10,19 +10,21 @@ //////////////////////////////// //~ rjf: Includes -//- rjf: [lib] -#include "lib_rdi_format/rdi_format.h" -#include "lib_rdi_format/rdi_format.c" -#include "third_party/rad_lzb_simple/rad_lzb_simple.h" -#include "third_party/rad_lzb_simple/rad_lzb_simple.c" - //- rjf: [h] #include "base/base_inc.h" #include "os/os_inc.h" +#include "render/render_inc.h" //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" +#include "render/render_inc.c" + +//////////////////////////////// +//~ rjf: Globals + +global OS_Handle window_os = {0}; +global R_Handle window_r = {0}; //////////////////////////////// //~ rjf: Entry Points @@ -32,6 +34,8 @@ frame(void) { B32 quit = 0; Temp scratch = scratch_begin(0, 0); + + //- rjf: events test OS_EventList events = os_get_events(scratch.arena, 0); for(OS_Event *ev = events.first; ev != 0; ev = ev->next) { @@ -55,6 +59,31 @@ frame(void) break; } } + + //- rjf: drawing test + r_begin_frame(); + r_window_begin_frame(window_os, window_r); + { + R_PassList passes = {0}; + R_Pass *pass = r_pass_from_kind(scratch.arena, &passes, R_PassKind_UI); + R_PassParams_UI *pass_ui = pass->params_ui; + R_BatchGroup2DNode group = {0}; + pass_ui->rects.first = pass_ui->rects.last = &group; + pass_ui->rects.count = 1; + group.batches = r_batch_list_make(sizeof(R_Rect2DInst)); + group.params.xform = mat_3x3f32(1.f); + group.params.clip = os_client_rect_from_window(window_os); + R_Rect2DInst *inst = r_batch_list_push_inst(scratch.arena, &group.batches, 256); + MemoryZeroStruct(inst); + inst->dst = r2f32p(30, 30, 100 ,100); + inst->src = r2f32p(0, 0, 1, 1); + inst->colors[Corner_00] = inst->colors[Corner_01] = inst->colors[Corner_10] = inst->colors[Corner_11] = v4f32(1, 0, 0, 1); + inst->corner_radii[Corner_00] = inst->corner_radii[Corner_01] = inst->corner_radii[Corner_10] = inst->corner_radii[Corner_11] = 8.f; + r_window_submit(window_os, window_r, &passes); + } + r_window_end_frame(window_os, window_r); + r_end_frame(); + scratch_end(scratch); return quit; } @@ -62,7 +91,8 @@ frame(void) internal void entry_point(CmdLine *cmdline) { - OS_Handle window = os_window_open(r2f32p(0, 0, 1280, 720), OS_WindowFlag_UseDefaultPosition, str8_lit("Window")); - os_window_first_paint(window); + window_os = os_window_open(r2f32p(0, 0, 1280, 720), OS_WindowFlag_UseDefaultPosition, str8_lit("Window")); + os_window_first_paint(window_os); + window_r = r_window_equip(window_os); for(;!update();); }