1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-27 01:29:31 +00:00

Causes the s-video path correctly to function.

This commit is contained in:
Thomas Harte 2018-03-30 18:24:18 -04:00
parent 163a61dd63
commit 912791d3d4
5 changed files with 35 additions and 11 deletions

View File

@ -65,6 +65,9 @@ template <class T> 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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -124,12 +124,12 @@ std::unique_ptr<IntermediateShader> 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> 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> 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> 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> 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));"
"}";

View File

@ -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<IntermediateShader> 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<IntermediateShader> 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<IntermediateShader> 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<IntermediateShader> 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<IntermediateShader> 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<IntermediateShader> make_rgb_filter_shader();