win_opengl: Add sync options that would later be settable in UI.
This commit is contained in:
@@ -11,9 +11,10 @@
|
|||||||
* NOTE: This is very much still a work-in-progress.
|
* NOTE: This is very much still a work-in-progress.
|
||||||
* Expect missing functionality, hangs and bugs.
|
* Expect missing functionality, hangs and bugs.
|
||||||
*
|
*
|
||||||
* TODO: Loader for glsl files.
|
* TODO: More shader features
|
||||||
* libretro has a sizeable library that could
|
* - scaling
|
||||||
* be a good target for compatibility.
|
* - multipass
|
||||||
|
* - previous frames
|
||||||
* (UI) options
|
* (UI) options
|
||||||
* More error handling
|
* More error handling
|
||||||
* ...
|
* ...
|
||||||
@@ -54,6 +55,14 @@
|
|||||||
static const int INIT_WIDTH = 640;
|
static const int INIT_WIDTH = 640;
|
||||||
static const int INIT_HEIGHT = 400;
|
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_FRAMERATE = 75;
|
||||||
|
static const int TARGET_FRAMETIME = 1000 / TARGET_FRAMERATE;
|
||||||
|
|
||||||
|
/* Option; Vsync: Off / On */
|
||||||
|
static const int VSYNC = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A dedicated OpenGL thread.
|
* @brief A dedicated OpenGL thread.
|
||||||
* OpenGL context's don't handle multiple threads well.
|
* OpenGL context's don't handle multiple threads well.
|
||||||
@@ -419,7 +428,7 @@ static void winmessage_hook(void* userdata, void* hWnd, unsigned int message, Ui
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize OpenGL context
|
* @brief Initialize OpenGL context
|
||||||
* @return Object identifiers
|
* @return Identifiers
|
||||||
*/
|
*/
|
||||||
static gl_identifiers initialize_glcontext()
|
static gl_identifiers initialize_glcontext()
|
||||||
{
|
{
|
||||||
@@ -495,6 +504,10 @@ static gl_identifiers initialize_glcontext()
|
|||||||
glUniformMatrix4fv(mvp_matrix, 1, GL_FALSE, mvp);
|
glUniformMatrix4fv(mvp_matrix, 1, GL_FALSE, mvp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLint frame_direction = glGetUniformLocation(gl.shader_progID, "FrameDirection");
|
||||||
|
if (frame_direction != -1)
|
||||||
|
glUniform1i(frame_direction, 1); /* always forward */
|
||||||
|
|
||||||
gl.input_size = glGetUniformLocation(gl.shader_progID, "InputSize");
|
gl.input_size = glGetUniformLocation(gl.shader_progID, "InputSize");
|
||||||
gl.output_size = glGetUniformLocation(gl.shader_progID, "OutputSize");
|
gl.output_size = glGetUniformLocation(gl.shader_progID, "OutputSize");
|
||||||
gl.texture_size = glGetUniformLocation(gl.shader_progID, "TextureSize");
|
gl.texture_size = glGetUniformLocation(gl.shader_progID, "TextureSize");
|
||||||
@@ -505,14 +518,31 @@ static gl_identifiers initialize_glcontext()
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clean up OpenGL context
|
* @brief Clean up OpenGL context
|
||||||
* @param Object identifiers from initialize
|
* @param Identifiers from initialize
|
||||||
*/
|
*/
|
||||||
static void finalize_glcontext(gl_identifiers obj)
|
static void finalize_glcontext(gl_identifiers gl)
|
||||||
{
|
{
|
||||||
glDeleteProgram(obj.shader_progID);
|
glDeleteProgram(gl.shader_progID);
|
||||||
glDeleteTextures(1, &obj.textureID);
|
glDeleteTextures(1, &gl.textureID);
|
||||||
glDeleteBuffers(1, &obj.vertexBufferID);
|
glDeleteBuffers(1, &gl.vertexBufferID);
|
||||||
glDeleteVertexArrays(1, &obj.vertexArrayID);
|
glDeleteVertexArrays(1, &gl.vertexArrayID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Renders a frame and swaps the buffer
|
||||||
|
* @param gl Identifiers from initialize
|
||||||
|
*/
|
||||||
|
static void render_and_swap(gl_identifiers gl)
|
||||||
|
{
|
||||||
|
static int frame_counter = 0;
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
SDL_GL_SwapWindow(window);
|
||||||
|
|
||||||
|
if (gl.frame_count != -1)
|
||||||
|
glUniform1i(gl.frame_count, frame_counter = (frame_counter + 1) & 1023);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -527,6 +557,8 @@ static void opengl_main()
|
|||||||
|
|
||||||
window = SDL_CreateWindow("86Box OpenGL Renderer", 0, 0, resize_info.width, resize_info.height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
|
window = SDL_CreateWindow("86Box OpenGL Renderer", 0, 0, resize_info.width, resize_info.height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
|
||||||
|
|
||||||
|
SDL_GL_SetSwapInterval(VSYNC);
|
||||||
|
|
||||||
/* Keep track of certain parameters, only changed in this thread to avoid race conditions */
|
/* 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;
|
int fullscreen = resize_info.fullscreen, video_width = INIT_WIDTH, video_height = INIT_HEIGHT;
|
||||||
|
|
||||||
@@ -553,26 +585,32 @@ static void opengl_main()
|
|||||||
|
|
||||||
gl_identifiers gl = initialize_glcontext();
|
gl_identifiers gl = initialize_glcontext();
|
||||||
|
|
||||||
int frame_counter = 0;
|
|
||||||
|
|
||||||
if (gl.frame_count != -1)
|
if (gl.frame_count != -1)
|
||||||
glUniform1i(gl.frame_count, 0);
|
glUniform1i(gl.frame_count, 0);
|
||||||
|
|
||||||
|
uint32_t last_swap = -TARGET_FRAMETIME;
|
||||||
|
|
||||||
/* Render loop */
|
/* Render loop */
|
||||||
int closing = 0;
|
int closing = 0;
|
||||||
while (!closing)
|
while (!closing)
|
||||||
{
|
{
|
||||||
/* Now redrawing only after a blit. For some shaders to work properly redraw should be in sync with (emulated) display refresh rate. */
|
if (SYNC_WITH_BLITTER)
|
||||||
|
render_and_swap(gl);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
|
|
||||||
SDL_GL_SwapWindow(window);
|
|
||||||
|
|
||||||
DWORD wait_result = WAIT_TIMEOUT;
|
DWORD wait_result = WAIT_TIMEOUT;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
if (!SYNC_WITH_BLITTER)
|
||||||
|
{
|
||||||
|
uint32_t ticks = plat_get_ticks();
|
||||||
|
if (ticks - last_swap > TARGET_FRAMETIME)
|
||||||
|
{
|
||||||
|
render_and_swap(gl);
|
||||||
|
last_swap = ticks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
/* Handle SDL_Window events */
|
/* Handle SDL_Window events */
|
||||||
@@ -619,8 +657,6 @@ static void opengl_main()
|
|||||||
glUniform2f(gl.input_size, video_width, video_height);
|
glUniform2f(gl.input_size, video_width, video_height);
|
||||||
if (gl.texture_size != -1)
|
if (gl.texture_size != -1)
|
||||||
glUniform2f(gl.texture_size, video_width, video_height);
|
glUniform2f(gl.texture_size, video_width, video_height);
|
||||||
if (gl.frame_count != -1)
|
|
||||||
glUniform1i(gl.frame_count, frame_counter = (frame_counter + 1) & 1023);
|
|
||||||
}
|
}
|
||||||
else if (sync_event == sync_objects.resize)
|
else if (sync_event == sync_objects.resize)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user