From 70039d22f1269412c1ab5ae8e34efb21321bfca4 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 12 Nov 2017 19:29:22 -0500 Subject: [PATCH] Allows a CRT machine owner to set the target frame buffer for OpenGL output, breaking the assumption that it'll be zero. --- OSBindings/Mac/Clock Signal/Machine/CSMachine.mm | 1 + OSBindings/SDL/main.cpp | 5 +++++ Outputs/CRT/CRT.hpp | 7 +++++++ Outputs/CRT/Internals/CRTOpenGL.cpp | 6 +++++- Outputs/CRT/Internals/CRTOpenGL.hpp | 4 +++- 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm index d8131fad4..3c02d8449 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm @@ -170,6 +170,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg // Since OS X v10.6, Macs have had a gamma of 2.2. _machine->get_crt()->set_output_gamma(2.2f); + _machine->get_crt()->set_target_framebuffer(0); } - (void)drawViewForPixelSize:(CGSize)pixelSize onlyIfDirty:(BOOL)onlyIfDirty { diff --git a/OSBindings/SDL/main.cpp b/OSBindings/SDL/main.cpp index 359eab012..6762919d0 100644 --- a/OSBindings/SDL/main.cpp +++ b/OSBindings/SDL/main.cpp @@ -11,6 +11,7 @@ #include #include +#include #include "../../StaticAnalyser/StaticAnalyser.hpp" #include "../../Machines/Utility/MachineForTarget.hpp" @@ -175,6 +176,9 @@ int main(int argc, char *argv[]) { SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GL_MakeCurrent(window, gl_context); + GLint target_framebuffer = 0; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &target_framebuffer); + // For vanilla SDL purposes, assume system ROMs can be found in one of: // // /usr/local/share/CLK/[system]; or @@ -221,6 +225,7 @@ int main(int argc, char *argv[]) { // Setup output, assuming a CRT machine for now, and prepare a best-effort updater. machine->crt_machine()->setup_output(4.0 / 3.0); machine->crt_machine()->get_crt()->set_output_gamma(2.2f); + machine->crt_machine()->get_crt()->set_target_framebuffer(target_framebuffer); // For now, lie about audio output intentions. auto speaker = machine->crt_machine()->get_speaker(); diff --git a/Outputs/CRT/CRT.hpp b/Outputs/CRT/CRT.hpp index 7344a711e..374cfcb91 100644 --- a/Outputs/CRT/CRT.hpp +++ b/Outputs/CRT/CRT.hpp @@ -241,6 +241,13 @@ class CRT { openGL_output_builder_.draw_frame(output_width, output_height, only_if_dirty); } + /*! Sets the OpenGL framebuffer to which output is drawn. */ + inline void set_target_framebuffer(GLint framebuffer) { + enqueue_openGL_function( [framebuffer, this] { + openGL_output_builder_.set_target_framebuffer(framebuffer); + }); + } + /*! Sets the gamma exponent for the simulated screen. */ void set_input_gamma(float gamma); diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index 077adf612..7dc5024ca 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -75,6 +75,10 @@ bool OpenGLOutputBuilder::get_is_television_output() { return output_device_ == OutputDevice::Television || !rgb_input_shader_program_; } +void OpenGLOutputBuilder::set_target_framebuffer(GLint target_framebuffer) { + target_framebuffer_ = target_framebuffer; +} + void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty) { // lock down any other draw_frames draw_mutex_.lock(); @@ -219,7 +223,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out // copy framebuffer to the intended place glDisable(GL_BLEND); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, static_cast(target_framebuffer_)); glViewport(0, 0, (GLsizei)output_width, (GLsizei)output_height); glActiveTexture(pixel_accumulation_texture_unit); diff --git a/Outputs/CRT/Internals/CRTOpenGL.hpp b/Outputs/CRT/Internals/CRTOpenGL.hpp index 2255719ca..36deb7eb4 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.hpp +++ b/Outputs/CRT/Internals/CRTOpenGL.hpp @@ -50,6 +50,7 @@ class OpenGLOutputBuilder { // Other things the caller may have provided. std::string composite_shader_; std::string rgb_shader_; + GLint target_framebuffer_ = 0; // Methods used by the OpenGL code void prepare_output_shader(); @@ -145,7 +146,8 @@ class OpenGLOutputBuilder { if(!composite_output_buffer_is_full()) composite_src_output_y_++; } - + + void set_target_framebuffer(GLint target_framebuffer); void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty); void set_openGL_context_will_change(bool should_delete_resources); void set_composite_sampling_function(const std::string &shader);