From 3088c6c26f410f5c2b843db4136eb300669ec7b1 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Wed, 21 Apr 2021 01:33:01 +0300 Subject: [PATCH] win_opengl: (WIP)UI for options. Add comments to help find conditionals that put opengl in dev_branch. --- src/86box.c | 3 ++ src/include/86box/86box.h | 3 ++ src/include/86box/language.h | 3 +- src/include/86box/resource.h | 11 ++++++ src/include/86box/win_opengl_glslp.h | 2 +- src/win/86Box.rc | 19 +++++++++- src/win/win.c | 17 +++++---- src/win/win_opengl.c | 57 +++++++++++++++------------- src/win/win_opengl_glslp.c | 4 +- src/win/win_ui.c | 19 +++++++++- 10 files changed, 97 insertions(+), 41 deletions(-) diff --git a/src/86box.c b/src/86box.c index 6fb7541a7..8e220a76b 100644 --- a/src/86box.c +++ b/src/86box.c @@ -129,6 +129,9 @@ int video_fullscreen_scale = 0; /* (C) video */ int video_fullscreen_first = 0; /* (C) video */ int enable_overscan = 0; /* (C) video */ int force_43 = 0; /* (C) video */ +int video_vsync = 0; /* (C) video */ +int video_frametime = -1; /* (C) video */ +char video_shader[512] = { '\0' }; /* (C) video */ int serial_enabled[SERIAL_MAX] = {0,0}; /* (C) enable serial ports */ int bugger_enabled = 0; /* (C) enable ISAbugger */ int postcard_enabled = 0; /* (C) enable POST card */ diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 1429c698c..b16b8100b 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -90,7 +90,10 @@ extern int vid_cga_contrast, /* (C) video */ video_fullscreen_scale, /* (C) video */ enable_overscan, /* (C) video */ force_43, /* (C) video */ + video_vsync, /* (C) video */ + video_frametime, /* (C) video */ gfxcard; /* (C) graphics/video card */ +extern char video_shader[512]; /* (C) video */ extern int serial_enabled[], /* (C) enable serial ports */ bugger_enabled, /* (C) enable ISAbugger */ postcard_enabled, /* (C) enable POST card */ diff --git a/src/include/86box/language.h b/src/include/86box/language.h index 006bc2312..4f7e05f6e 100644 --- a/src/include/86box/language.h +++ b/src/include/86box/language.h @@ -116,6 +116,7 @@ #define IDS_2140 2140 // "CD-ROM images (*.ISO;*.CU.." #define IDS_2141 2141 // "%hs Device Configuration" #define IDS_2142 2142 // "Monitor in sleep mode" +#define IDS_2143 2143 // "OpenGL Shaders (*.GLSL)..." #define IDS_4096 4096 // "Hard disk (%s)" #define IDS_4097 4097 // "%01i:%01i" @@ -223,7 +224,7 @@ #define IDS_LANG_ENUS IDS_7168 -#define STR_NUM_2048 95 +#define STR_NUM_2048 96 #define STR_NUM_3072 11 #define STR_NUM_4096 39 #define STR_NUM_4352 6 diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index d2901b40f..a3b2a0f93 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -341,6 +341,17 @@ #define IDM_DISCORD 40090 #endif +#ifdef DEV_BRANCH /* feature-opengl */ +#define IDM_VID_GL_FPS_BLITTER 40100 +#define IDM_VID_GL_FPS_25 40101 +#define IDM_VID_GL_FPS_30 40102 +#define IDM_VID_GL_FPS_50 40103 +#define IDM_VID_GL_FPS_60 40104 +#define IDM_VID_GL_FPS_75 40105 +#define IDM_VID_GL_VSYNC 40106 +#define IDM_VID_GL_SHADER 40107 +#endif + #define IDM_LOG_BREAKPOINT 51201 #define IDM_DUMP_VRAM 51202 // should be an Action diff --git a/src/include/86box/win_opengl_glslp.h b/src/include/86box/win_opengl_glslp.h index 1a9e5a9ca..dcc098635 100644 --- a/src/include/86box/win_opengl_glslp.h +++ b/src/include/86box/win_opengl_glslp.h @@ -17,7 +17,7 @@ #include -GLuint load_custom_shaders(); +GLuint load_custom_shaders(const char* path); GLuint load_default_shaders(); #endif /*!WIN_OPENGL_GLSLP_H*/ \ No newline at end of file diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 382c7e48a..007207b90 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -66,13 +66,29 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL -#ifdef DEV_BRANCH +#ifdef DEV_BRANCH /* feature-opengl */ MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE #endif #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif END +#ifdef DEV_BRANCH /* feature-opengl */ + POPUP "Renderer o&ptions" + BEGIN + POPUP "Target &framerate" + BEGIN + MENUITEM "&Sync with video", IDM_VID_GL_FPS_BLITTER + MENUITEM "&25 fps", IDM_VID_GL_FPS_25 + MENUITEM "&30 fps", IDM_VID_GL_FPS_30 + MENUITEM "&50 fps", IDM_VID_GL_FPS_50 + MENUITEM "&60 fps", IDM_VID_GL_FPS_60 + MENUITEM "&75 fps", IDM_VID_GL_FPS_75 + END + MENUITEM "&VSync", IDM_VID_GL_VSYNC + MENUITEM "&Select shader...", IDM_VID_GL_SHADER + END +#endif MENUITEM SEPARATOR MENUITEM "Specify dimensions", IDM_VID_SPECIFY_DIM MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 @@ -1080,6 +1096,7 @@ BEGIN IDS_2140 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" IDS_2141 "%hs Device Configuration" IDS_2142 "Monitor in sleep mode" + IDS_2143 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0" END STRINGTABLE DISCARDABLE diff --git a/src/win/win.c b/src/win/win.c index 52cc1fe14..22e0e9237 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -99,17 +99,18 @@ static const struct { int (*pause)(void); void (*enable)(int enable); void (*set_fs)(int fs); + void (*reload)(void); } vid_apis[RENDERERS_NUM] = { - { "SDL_Software", 1, (int(*)(void*))sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs }, - { "SDL_Hardware", 1, (int(*)(void*))sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs }, - { "SDL_OpenGL", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs } -#ifdef DEV_BRANCH - ,{ "OpenGL_Core", 1, (int(*)(void*))opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs} + { "SDL_Software", 1, (int(*)(void*))sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL }, + { "SDL_Hardware", 1, (int(*)(void*))sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL }, + { "SDL_OpenGL", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL } +#ifdef DEV_BRANCH /* feature-opengl */ + ,{ "OpenGL_Core", 1, (int(*)(void*))opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, NULL} #else - ,{ "OpenGL_Core", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs } /* fall back to SDL_OpenGL */ + ,{ "OpenGL_Core", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL } /* fall back to SDL_OpenGL */ #endif #ifdef USE_VNC - ,{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL, NULL } + ,{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL, NULL } #endif }; @@ -928,7 +929,7 @@ plat_vidapi_name(int api) case 2: name = "sdl_opengl"; break; -#ifdef DEV_BRANCH +#ifdef DEV_BRANCH /* feature-opengl */ case 3: name = "opengl_core"; break; diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index 59f3e005e..c9775e462 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -41,6 +41,7 @@ #include #include +#include #include <86box/86box.h> #include <86box/plat.h> @@ -52,13 +53,6 @@ static const int INIT_WIDTH = 640; static const int INIT_HEIGHT = 400; -/* Option; Target framerate: Sync with emulation / 25 fps / 30 fps / 50 fps / 60 fps / 75 fps */ -static const int SYNC_WITH_BLITTER = 1; -static const int TARGET_FRAMETIME = 13; - -/* Option; Vsync: Off / On */ -static const int VSYNC = 0; - /** * @brief A dedicated OpenGL thread. * OpenGL context's don't handle multiple threads well. @@ -89,9 +83,10 @@ static union { HANDLE closing; HANDLE resize; + HANDLE reload; HANDLE blit_waiting; }; - HANDLE asArray[3]; + HANDLE asArray[4]; } sync_objects = { 0 }; /** @@ -115,6 +110,16 @@ static volatile struct int width, height, fullscreen, scaling_mode; } resize_info = { 0 }; +/** + * @brief Renderer options +*/ +static volatile struct +{ + int vsync; /* Vertical sync; 0 = off, 1 = on */ + int frametime; /* Frametime in ms, or -1 to sync with blitter */ + char shaderfile[512]; /* Shader file path. Match the length of openfilestring in win_dialog.c */ +} options = { 0 }; + /** * @brief Identifiers to OpenGL objects and uniforms. */ @@ -133,15 +138,6 @@ typedef struct GLint frame_count; } gl_identifiers; -/** - * @brief Userdata to pass onto windows message hook -*/ -typedef struct -{ - HWND window; - int* fullscreen; -} winmessage_data; - /** * @brief Set or unset OpenGL context window as a child window. * @@ -269,7 +265,7 @@ static gl_identifiers initialize_glcontext() glClearColor(0.f, 0.f, 0.f, 1.f); - gl.shader_progID = load_custom_shaders(); + gl.shader_progID = load_custom_shaders(options.shaderfile); if (gl.shader_progID == 0) gl.shader_progID = load_default_shaders(); @@ -362,7 +358,7 @@ static void opengl_main(void* param) window = SDL_CreateWindow("86Box OpenGL Renderer", 0, 0, resize_info.width, resize_info.height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS); - SDL_GL_SetSwapInterval(VSYNC); + SDL_GL_SetSwapInterval(options.vsync); /* Keep track of certain parameters, only changed in this thread to avoid race conditions */ int fullscreen = resize_info.fullscreen, video_width = INIT_WIDTH, video_height = INIT_HEIGHT; @@ -374,9 +370,6 @@ static void opengl_main(void* param) if (wmi.subsystem == SDL_SYSWM_WINDOWS) window_hwnd = wmi.info.win.window; - /* Pass window handle and full screen mode to windows message hook */ - winmessage_data msg_data = (winmessage_data){ window_hwnd, &fullscreen }; - if (!fullscreen) set_parent_binding(1); else @@ -391,23 +384,23 @@ static void opengl_main(void* param) if (gl.frame_count != -1) glUniform1i(gl.frame_count, 0); - uint32_t last_swap = -TARGET_FRAMETIME; + uint32_t last_swap = -options.frametime; /* Render loop */ int closing = 0; while (!closing) { - if (SYNC_WITH_BLITTER) + if (options.frametime < 0) render_and_swap(gl); DWORD wait_result = WAIT_TIMEOUT; do { - if (!SYNC_WITH_BLITTER) + if (options.frametime >= 0) { uint32_t ticks = plat_get_ticks(); - if (ticks - last_swap > TARGET_FRAMETIME) + if (ticks - last_swap >= options.frametime) { render_and_swap(gl); last_swap = ticks; @@ -591,6 +584,10 @@ int opengl_init(HWND hwnd) resize_info.fullscreen = video_fullscreen & 1; resize_info.scaling_mode = video_fullscreen_scale; + options.vsync = video_vsync; + options.frametime = -1; + strcpy_s(options.shaderfile, sizeof(options.shaderfile), "shaders/shader.glsl"); + thread = thread_create(opengl_main, (void*)NULL); atexit(opengl_close); @@ -652,4 +649,12 @@ void opengl_resize(int w, int h) resize_info.scaling_mode = video_fullscreen_scale; SetEvent(sync_objects.resize); +} + +void opengl_reload(void) +{ + if (thread == NULL) + return; + + SetEvent(sync_objects.reload); } \ No newline at end of file diff --git a/src/win/win_opengl_glslp.c b/src/win/win_opengl_glslp.c index 0b7e54c77..0a0d7f004 100644 --- a/src/win/win_opengl_glslp.c +++ b/src/win/win_opengl_glslp.c @@ -107,13 +107,13 @@ static char* read_file_to_string(const char* path) * @brief Compile custom shaders into a program. * @return Shader program identifier. */ -GLuint load_custom_shaders() +GLuint load_custom_shaders(const char* path) { GLint status = GL_FALSE; int info_log_length; /* TODO: get path from config */ - char* shader = read_file_to_string("shaders/shader.glsl"); + char* shader = read_file_to_string(path); if (shader != NULL) { diff --git a/src/win/win_ui.c b/src/win/win_ui.c index ce05d4a57..6a3584886 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -223,7 +223,7 @@ ResetAllMenus(void) CheckMenuItem(menuMain, IDM_VID_SDL_SW, MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_SDL_HW, MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_SDL_OPENGL, MF_UNCHECKED); -#ifdef DEV_BRANCH +#ifdef DEV_BRANCH /* feature-opengl */ CheckMenuItem(menuMain, IDM_VID_OPENGL_CORE, MF_UNCHECKED); #endif #ifdef USE_VNC @@ -672,7 +672,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_VID_SDL_SW: case IDM_VID_SDL_HW: case IDM_VID_SDL_OPENGL: -#ifdef DEV_BRANCH +#ifdef DEV_BRANCH /* feature-opengl */ case IDM_VID_OPENGL_CORE: #endif #ifdef USE_VNC @@ -684,6 +684,21 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) config_save(); break; +#ifdef DEV_BRANCH /* feature-opengl */ + case IDM_VID_GL_VSYNC: + video_vsync = !video_vsync; + CheckMenuItem(hmenu, IDM_VID_GL_VSYNC, video_vsync ? MF_CHECKED : MF_UNCHECKED); + //plat_reload_config + config_save(); + break; + case IDM_VID_GL_SHADER: + win_notify_dlg_open(); + if (file_dlg_st(hwnd, IDS_2143, video_shader, NULL, 0) == 0) + strcpy_s(video_shader, sizeof(video_shader), openfilestring); + win_notify_dlg_closed(); + break; +#endif + case IDM_VID_FULLSCREEN: plat_setfullscreen(1); config_save();