From 912791d3d48b494330c72487a146c34bc9ebcede Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 30 Mar 2018 18:24:18 -0400 Subject: [PATCH] Causes the s-video path correctly to function. --- Components/6560/6560.hpp | 3 +++ Machines/Atari2600/TIA.cpp | 2 ++ Outputs/CRT/Internals/CRTOpenGL.cpp | 12 +++++++++++- .../Internals/Shaders/IntermediateShader.cpp | 17 +++++++---------- .../Internals/Shaders/IntermediateShader.hpp | 12 ++++++++++++ 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/Components/6560/6560.hpp b/Components/6560/6560.hpp index 395047d9a..4f47f89e0 100644 --- a/Components/6560/6560.hpp +++ b/Components/6560/6560.hpp @@ -65,6 +65,9 @@ template class MOS6560 { "return vec2(yc.x, chroma);" "}"); + // default to s-video output + crt_->set_video_signal(Outputs::CRT::VideoSignal::SVideo); + // default to NTSC set_output_mode(OutputMode::NTSC); } diff --git a/Machines/Atari2600/TIA.cpp b/Machines/Atari2600/TIA.cpp index f1f8b1437..c26580a98 100644 --- a/Machines/Atari2600/TIA.cpp +++ b/Machines/Atari2600/TIA.cpp @@ -149,6 +149,8 @@ void TIA::set_output_mode(Atari2600::TIA::OutputMode output_mode) { "}"); display_type = Outputs::CRT::DisplayType::PAL50; } + crt_->set_video_signal(Outputs::CRT::VideoSignal::Composite); + // line number of cycles in a line of video is one less than twice the number of clock cycles per line; the Atari // outputs 228 colour cycles of material per line when an NTSC line 227.5. Since all clock numbers will be doubled // later, cycles_per_line * 2 - 1 is therefore the real length of an NTSC line, even though we're going to supply diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index ae266bd02..67feeda9e 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -159,7 +159,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out // for s-video, there are two steps — it's like composite but skips separation const RenderStage svideo_render_stages[] = { - {composite_input_shader_program_.get(), separated_texture_.get(), {0.0, 0.5, 0.5}}, + {svideo_input_shader_program_.get(), separated_texture_.get(), {0.0, 0.5, 0.5}}, {composite_chrominance_filter_shader_program_.get(), filtered_texture_.get(), {0.0, 0.0, 0.0}}, {nullptr, nullptr} }; @@ -364,6 +364,11 @@ void OpenGLOutputBuilder::prepare_source_vertex_array() { Shader::get_input_name(Shader::Input::PhaseTimeAndAmplitude), 3, GL_UNSIGNED_BYTE, GL_FALSE, SourceVertexSize, (void *)SourceVertexOffsetOfPhaseTimeAndAmplitude, 1); + + svideo_input_shader_program_->enable_vertex_attribute_with_pointer( + Shader::get_input_name(Shader::Input::InputStart), + 2, GL_UNSIGNED_SHORT, GL_FALSE, SourceVertexSize, + (void *)SourceVertexOffsetOfInputStart, 1); } } @@ -444,6 +449,7 @@ void OpenGLOutputBuilder::set_colour_space_uniforms() { if(composite_input_shader_program_) composite_input_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB); if(composite_separation_filter_program_) composite_separation_filter_program_->set_colour_conversion_matrices(fromRGB, toRGB); if(composite_chrominance_filter_shader_program_) composite_chrominance_filter_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB); + if(svideo_input_shader_program_) svideo_input_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB); } void OpenGLOutputBuilder::set_gamma() { @@ -496,6 +502,10 @@ void OpenGLOutputBuilder::set_timing_uniforms() { composite_input_shader_program_->set_width_scalers(1.0f, output_width); composite_input_shader_program_->set_extension(0.0f); } + if(svideo_input_shader_program_) { + svideo_input_shader_program_->set_width_scalers(1.0f, output_width); + svideo_input_shader_program_->set_extension(0.0f); + } if(rgb_input_shader_program_) { rgb_input_shader_program_->set_width_scalers(1.0f, 1.0f); } diff --git a/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp b/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp index 8bb35bbe2..9741ee2f0 100644 --- a/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp +++ b/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp @@ -124,12 +124,12 @@ std::unique_ptr IntermediateShader::make_composite_source_sh "out vec4 fragColour;" - "uniform usampler2D texID;"; + "uniform usampler2D texID;" + << composite_shader; - if(!composite_shader.size()) { - std::ostringstream derived_composite_sample; + if(composite_shader.empty()) { if(!svideo_shader.empty()) { - derived_composite_sample << + fragment_shader << svideo_shader << "float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" "{" @@ -137,7 +137,7 @@ std::unique_ptr IntermediateShader::make_composite_source_sh "return mix(svideoColour.x, svideoColour.y, amplitude);" "}"; } else { - derived_composite_sample << + fragment_shader << rgb_shader << "uniform mat3 rgbToLumaChroma;" "float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" @@ -148,9 +148,6 @@ std::unique_ptr IntermediateShader::make_composite_source_sh "return dot(lumaChromaColour, vec3(1.0 - amplitude, quadrature));" "}"; } - fragment_shader << derived_composite_sample.str(); - } else { - fragment_shader << composite_shader; } fragment_shader << @@ -185,7 +182,7 @@ std::unique_ptr IntermediateShader::make_svideo_source_shade "vec3 rgbColour = clamp(rgb_sample(texID, coordinate, iCoordinate), vec3(0.0), vec3(1.0));" "vec3 lumaChromaColour = rgbToLumaChroma * rgbColour;" "vec2 quadrature = vec2(cos(phase), -sin(phase));" - "return vec2(lumaChromaColour, quadrature);" + "return vec2(lumaChromaColour.x, 0.5 + dot(quadrature, lumaChromaColour.yz) * 0.5);" "}"; } @@ -193,7 +190,7 @@ std::unique_ptr IntermediateShader::make_svideo_source_shade "void main(void)" "{" "vec2 sample = svideo_sample(texID, inputPositionsVarying[5], iInputPositionVarying, phaseAndAmplitudeVarying.x);" - "vec2 quadrature = vec2(cos(phaseAndAmplitudeVarying.x), -sin(phaseAndAmplitudeVarying.x));" + "vec2 quadrature = vec2(cos(phaseAndAmplitudeVarying.x), -sin(phaseAndAmplitudeVarying.x)) * 0.5 * phaseAndAmplitudeVarying.z;" "fragColour = vec3(sample.x, vec2(0.5) + (sample.y * quadrature));" "}"; diff --git a/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp b/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp index 5458cfe99..fb7775436 100644 --- a/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp +++ b/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp @@ -46,6 +46,8 @@ public: converting them to single-channel composite values using @c composite_shader if non-empty or a reference composite conversion of @c svideo_shader (first preference) or @c rgb_shader (second preference) otherwise. + + [input format] => one-channel composite. */ static std::unique_ptr make_composite_source_shader(const std::string &composite_shader, const std::string &svideo_shader, const std::string &rgb_shader); @@ -53,28 +55,38 @@ public: Constructs and returns an intermediate shader that will take runs from the inputPositions, converting them to two-channel svideo values using @c svideo_shader if non-empty or a reference svideo conversion of @c rgb_shader otherwise. + + [input format] => three-channel Y, noisy (m, n). */ static std::unique_ptr make_svideo_source_shader(const std::string &svideo_shader, const std::string &rgb_shader); /*! Constructs and returns an intermediate shader that will take runs from the inputPositions, converting them to RGB values using @c rgb_shader. + + [input format] => three-channel RGB. */ static std::unique_ptr make_rgb_source_shader(const std::string &rgb_shader); /*! Constructs and returns an intermediate shader that will read composite samples from the R channel, filter then to obtain luminance, stored to R, and to separate out unfiltered chrominance, store to G and B. + + one-channel composite => three-channel Y, noisy (m, n). */ static std::unique_ptr make_chroma_luma_separation_shader(); /*! Constructs and returns an intermediate shader that will pass R through unchanged while filtering G and B. + + three-channel Y, noisy (m, n) => three-channel RGB. */ static std::unique_ptr make_chroma_filter_shader(); /*! Constructs and returns an intermediate shader that will filter R, G and B. + + three-channel RGB => frequency-limited three-channel RGB. */ static std::unique_ptr make_rgb_filter_shader();