From a38639d099d324a4c91c4f6b2b260705650b75e0 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 12 Sep 2018 20:05:39 -0400 Subject: [PATCH] Eliminates the concept of an iCoordinate. Real-life precision appears not to support the idea of sub-sample pixel storage. --- Components/6560/6560.hpp | 2 +- Components/9918/9918.cpp | 2 +- Machines/AmstradCPC/AmstradCPC.cpp | 2 +- Machines/AppleII/Video.cpp | 2 +- Machines/Atari2600/TIA.cpp | 4 +-- Machines/Electron/Video.cpp | 4 +-- Machines/Oric/Video.cpp | 4 +-- Machines/ZX8081/Video.cpp | 2 +- Outputs/CRT/CRT.hpp | 18 +---------- Outputs/CRT/Internals/CRTOpenGL.cpp | 8 ----- Outputs/CRT/Internals/CRTOpenGL.hpp | 3 -- .../Internals/Shaders/IntermediateShader.cpp | 30 +++++++------------ .../Internals/Shaders/IntermediateShader.hpp | 5 ---- 13 files changed, 21 insertions(+), 65 deletions(-) diff --git a/Components/6560/6560.hpp b/Components/6560/6560.hpp index 169690c00..23bb6e4d1 100644 --- a/Components/6560/6560.hpp +++ b/Components/6560/6560.hpp @@ -69,7 +69,7 @@ template class MOS6560 { speaker_(audio_generator_) { crt_->set_svideo_sampling_function( - "vec2 svideo_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" + "vec2 svideo_sample(usampler2D texID, vec2 coordinate, float phase, float amplitude)" "{" "vec2 yc = texture(texID, coordinate).rg / vec2(255.0);" diff --git a/Components/9918/9918.cpp b/Components/9918/9918.cpp index c16f3735f..c64bbac72 100644 --- a/Components/9918/9918.cpp +++ b/Components/9918/9918.cpp @@ -92,7 +92,7 @@ TMS9918::TMS9918(Personality p) { // Unimaginatively, this class just passes RGB through to the shader. Investigation is needed // into whether there's a more natural form. crt_->set_rgb_sampling_function( - "vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)" + "vec3 rgb_sample(usampler2D sampler, vec2 coordinate)" "{" "return texture(sampler, coordinate).rgb / vec3(255.0);" "}"); diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index 92d146720..a6a8a20f9 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -327,7 +327,7 @@ class CRTCBusHandler { void setup_output(float aspect_ratio) { crt_.reset(new Outputs::CRT::CRT(1024, 16, Outputs::CRT::DisplayType::PAL50, 1)); crt_->set_rgb_sampling_function( - "vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)" + "vec3 rgb_sample(usampler2D sampler, vec2 coordinate)" "{" "uint sample = texture(texID, coordinate).r;" "return vec3(float((sample >> 4) & 3u), float((sample >> 2) & 3u), float(sample & 3u)) / 2.0;" diff --git a/Machines/AppleII/Video.cpp b/Machines/AppleII/Video.cpp index 11051188d..c65117f9f 100644 --- a/Machines/AppleII/Video.cpp +++ b/Machines/AppleII/Video.cpp @@ -18,7 +18,7 @@ VideoBase::VideoBase(bool is_iie, std::function &&target) : // Set a composite sampling function that assumes one byte per pixel input, and // accepts any non-zero value as being fully on, zero being fully off. crt_->set_composite_sampling_function( - "float composite_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate, float phase, float amplitude)" + "float composite_sample(usampler2D sampler, vec2 coordinate, float phase, float amplitude)" "{" "return clamp(texture(sampler, coordinate).r, 0.0, 1.0);" "}"); diff --git a/Machines/Atari2600/TIA.cpp b/Machines/Atari2600/TIA.cpp index af37c49f9..2d540e97a 100644 --- a/Machines/Atari2600/TIA.cpp +++ b/Machines/Atari2600/TIA.cpp @@ -124,7 +124,7 @@ void TIA::set_output_mode(Atari2600::TIA::OutputMode output_mode) { if(output_mode == OutputMode::NTSC) { crt_->set_svideo_sampling_function( - "vec2 svideo_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" + "vec2 svideo_sample(usampler2D texID, vec2 coordinate, float phase, float amplitude)" "{" "uint c = texture(texID, coordinate).r;" "uint y = c & 14u;" @@ -136,7 +136,7 @@ void TIA::set_output_mode(Atari2600::TIA::OutputMode output_mode) { display_type = Outputs::CRT::DisplayType::NTSC60; } else { crt_->set_svideo_sampling_function( - "vec2 svideo_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" + "vec2 svideo_sample(usampler2D texID, vec2 coordinate, float phase, float amplitude)" "{" "uint c = texture(texID, coordinate).r;" "uint y = c & 14u;" diff --git a/Machines/Electron/Video.cpp b/Machines/Electron/Video.cpp index 2d7b316af..88ac6073e 100644 --- a/Machines/Electron/Video.cpp +++ b/Machines/Electron/Video.cpp @@ -52,13 +52,11 @@ VideoOutput::VideoOutput(uint8_t *memory) : ram_(memory) { crt_.reset(new Outputs::CRT::CRT(crt_cycles_per_line, 8, Outputs::CRT::DisplayType::PAL50, 1)); crt_->set_rgb_sampling_function( - "vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)" + "vec3 rgb_sample(usampler2D sampler, vec2 coordinate)" "{" "uint texValue = texture(sampler, coordinate).r;" - "texValue >>= 4 - (int(icoordinate.x) & 4);" "return vec3( uvec3(texValue) & uvec3(4u, 2u, 1u));" "}"); - crt_->set_integer_coordinate_multiplier(8.0f); std::unique_ptr bookender(new FourBPPBookender); crt_->set_bookender(std::move(bookender)); // TODO: as implied below, I've introduced a clock's latency into the graphics pipeline somehow. Investigate. diff --git a/Machines/Oric/Video.cpp b/Machines/Oric/Video.cpp index 9022e14a5..e28d7cfe0 100644 --- a/Machines/Oric/Video.cpp +++ b/Machines/Oric/Video.cpp @@ -25,13 +25,13 @@ VideoOutput::VideoOutput(uint8_t *memory) : v_sync_start_position_(PAL50VSyncStartPosition), v_sync_end_position_(PAL50VSyncEndPosition), counter_period_(PAL50Period) { crt_->set_rgb_sampling_function( - "vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)" + "vec3 rgb_sample(usampler2D sampler, vec2 coordinate)" "{" "uint texValue = texture(sampler, coordinate).r;" "return vec3( uvec3(texValue) & uvec3(4u, 2u, 1u));" "}"); crt_->set_composite_sampling_function( - "float composite_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate, float phase, float amplitude)" + "float composite_sample(usampler2D sampler, vec2 coordinate, float phase, float amplitude)" "{" "uint texValue = uint(dot(texture(sampler, coordinate).rg, uvec2(1, 256)));" "uint iPhase = uint((phase + 3.141592654 + 0.39269908175) * 2.0 / 3.141592654) & 3u;" diff --git a/Machines/ZX8081/Video.cpp b/Machines/ZX8081/Video.cpp index 95e691301..ce2fcbc55 100644 --- a/Machines/ZX8081/Video.cpp +++ b/Machines/ZX8081/Video.cpp @@ -26,7 +26,7 @@ Video::Video() : // Set a composite sampling function that assumes two-level input; either a byte is 0, which is black, // or it is non-zero, which is white. crt_->set_composite_sampling_function( - "float composite_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate, float phase, float amplitude)" + "float composite_sample(usampler2D sampler, vec2 coordinate, float phase, float amplitude)" "{" "return texture(sampler, coordinate).r;" "}"); diff --git a/Outputs/CRT/CRT.hpp b/Outputs/CRT/CRT.hpp index c27fa86e5..a89bfa0d2 100644 --- a/Outputs/CRT/CRT.hpp +++ b/Outputs/CRT/CRT.hpp @@ -280,7 +280,7 @@ class CRT { /*! Sets a function that will map from whatever data the machine provided to a composite signal. @param shader A GLSL fragment including a function with the signature - `float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)` + `float composite_sample(usampler2D texID, vec2 coordinate, float phase, float amplitude)` that evaluates to the composite signal level as a function of a source buffer, sampling location, colour carrier phase and amplitude. */ @@ -290,22 +290,6 @@ class CRT { }); } - /*! - Sets a multiplier applied to iCoordinate values prior to their passing to the various sampling functions. - This multiplier is applied outside of the interpolation loop, making for a more precise interpolation - than if it were applied within the sampling function. - - Idiomatically, this is likely to be the number of output pixels packed into each input sample where - packing is in use. - - The default value is 1.0. - */ - inline void set_integer_coordinate_multiplier(float multiplier) { - enqueue_openGL_function([=] { - openGL_output_builder_.set_integer_coordinate_multiplier(multiplier); - }); - } - enum CompositeSourceType { /// The composite function provides continuous output. Continuous, diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index 2342ccb99..d4739b544 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -524,12 +524,4 @@ void OpenGLOutputBuilder::set_timing_uniforms() { if(rgb_input_shader_program_) { rgb_input_shader_program_->set_width_scalers(1.0f, 1.0f); } - set_integer_coordinate_multiplier(integer_coordinate_multiplier_); -} - -void OpenGLOutputBuilder::set_integer_coordinate_multiplier(float multiplier) { - integer_coordinate_multiplier_ = multiplier; - if(composite_input_shader_program_) composite_input_shader_program_->set_integer_coordinate_multiplier(multiplier); - if(svideo_input_shader_program_) svideo_input_shader_program_->set_integer_coordinate_multiplier(multiplier); - if(rgb_input_shader_program_) rgb_input_shader_program_->set_integer_coordinate_multiplier(multiplier); } diff --git a/Outputs/CRT/Internals/CRTOpenGL.hpp b/Outputs/CRT/Internals/CRTOpenGL.hpp index c50ac4560..5d9359b64 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.hpp +++ b/Outputs/CRT/Internals/CRTOpenGL.hpp @@ -105,8 +105,6 @@ class OpenGLOutputBuilder { float get_composite_output_width() const; void set_output_shader_width(); - float integer_coordinate_multiplier_ = 1.0f; - // Maintain a couple of rectangles for masking off the extreme edge of the display; // this is a bit of a cheat: there's some tolerance in when a sync pulse will be // generated. So it might be slightly later than expected. Which might cause a scan @@ -174,7 +172,6 @@ class OpenGLOutputBuilder { void set_rgb_sampling_function(const std::string &); void set_video_signal(VideoSignal); void set_timing(unsigned int input_frequency, unsigned int cycles_per_line, unsigned int height_of_display, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider); - void set_integer_coordinate_multiplier(float multiplier); }; } diff --git a/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp b/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp index ab886f269..2442e671e 100644 --- a/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp +++ b/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp @@ -46,11 +46,9 @@ std::unique_ptr IntermediateShader::make_shader(const std::s "uniform float inputVerticalOffset;" "uniform float outputVerticalOffset;" "uniform float textureHeightDivisor;" - "uniform float iCoordinateMultiplier;" "out vec3 phaseAndAmplitudeVarying;" "out vec2 inputPositionsVarying[11];" - "out vec2 iInputPositionVarying;" "out vec2 delayLinePositionVarying;" "void main(void)" @@ -75,9 +73,8 @@ std::unique_ptr IntermediateShader::make_shader(const std::s "vec2 extendedInputPosition = " << (input_is_inputPosition ? "inputPosition" : "outputPosition") << " + extensionVector;" "vec2 extendedOutputPosition = outputPosition + extensionVector;" - // keep iInputPositionVarying in whole source pixels, scale mappedInputPosition to the ordinary normalised range + // scale mappedInputPosition to the ordinary normalised range "vec2 textureSize = vec2(textureSize(texID, 0));" - "iInputPositionVarying = extendedInputPosition * iCoordinateMultiplier;" "vec2 mappedInputPosition = extendedInputPosition / textureSize;" // setup input positions spaced as per the supplied offsets; these are for filtering where required @@ -120,7 +117,6 @@ std::unique_ptr IntermediateShader::make_composite_source_sh "#version 150\n" "in vec2 inputPositionsVarying[11];" - "in vec2 iInputPositionVarying;" "in vec3 phaseAndAmplitudeVarying;" "out vec4 fragColour;" @@ -132,18 +128,18 @@ std::unique_ptr IntermediateShader::make_composite_source_sh if(!svideo_shader.empty()) { fragment_shader << svideo_shader << - "float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" + "float composite_sample(usampler2D texID, vec2 coordinate, float phase, float amplitude)" "{" - "vec2 svideoColour = svideo_sample(texID, coordinate, iCoordinate, phase, amplitude);" + "vec2 svideoColour = svideo_sample(texID, coordinate, phase, amplitude);" "return mix(svideoColour.x, svideoColour.y, abs(amplitude));" "}"; } else { fragment_shader << rgb_shader << "uniform mat3 rgbToLumaChroma;" - "float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" + "float composite_sample(usampler2D texID, vec2 coordinate, float phase, float amplitude)" "{" - "vec3 rgbColour = clamp(rgb_sample(texID, coordinate, iCoordinate), vec3(0.0), vec3(1.0));" + "vec3 rgbColour = clamp(rgb_sample(texID, coordinate), vec3(0.0), vec3(1.0));" "vec3 lumaChromaColour = rgbToLumaChroma * rgbColour;" "vec2 quadrature = vec2(cos(phase), sin(phase)) * vec2(abs(amplitude), amplitude);" "return dot(lumaChromaColour, vec3(1.0 - abs(amplitude), quadrature));" @@ -154,7 +150,7 @@ std::unique_ptr IntermediateShader::make_composite_source_sh fragment_shader << "void main(void)" "{" - "fragColour = vec4(composite_sample(texID, inputPositionsVarying[5], iInputPositionVarying, phaseAndAmplitudeVarying.x, phaseAndAmplitudeVarying.y));" + "fragColour = vec4(composite_sample(texID, inputPositionsVarying[5], phaseAndAmplitudeVarying.x, phaseAndAmplitudeVarying.y));" "}"; return make_shader(fragment_shader.str(), true, true); @@ -166,7 +162,6 @@ std::unique_ptr IntermediateShader::make_svideo_source_shade "#version 150\n" "in vec2 inputPositionsVarying[11];" - "in vec2 iInputPositionVarying;" "in vec3 phaseAndAmplitudeVarying;" "out vec3 fragColour;" @@ -178,9 +173,9 @@ std::unique_ptr IntermediateShader::make_svideo_source_shade fragment_shader << rgb_shader << "uniform mat3 rgbToLumaChroma;" - "vec2 svideo_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" + "vec2 svideo_sample(usampler2D texID, vec2 coordinate, float phase, float amplitude)" "{" - "vec3 rgbColour = clamp(rgb_sample(texID, coordinate, iCoordinate), vec3(0.0), vec3(1.0));" + "vec3 rgbColour = clamp(rgb_sample(texID, coordinate), vec3(0.0), vec3(1.0));" "vec3 lumaChromaColour = rgbToLumaChroma * rgbColour;" "vec2 quadrature = vec2(cos(phase), sin(phase)) * vec2(1.0, sign(amplitude));" "return vec2(lumaChromaColour.x, 0.5 + dot(quadrature, lumaChromaColour.yz) * 0.5);" @@ -190,7 +185,7 @@ std::unique_ptr IntermediateShader::make_svideo_source_shade fragment_shader << "void main(void)" "{" - "vec2 sample = svideo_sample(texID, inputPositionsVarying[5], iInputPositionVarying, phaseAndAmplitudeVarying.x, phaseAndAmplitudeVarying.y);" + "vec2 sample = svideo_sample(texID, inputPositionsVarying[5], phaseAndAmplitudeVarying.x, phaseAndAmplitudeVarying.y);" "vec2 quadrature = vec2(cos(phaseAndAmplitudeVarying.x), sin(phaseAndAmplitudeVarying.x)) * vec2(1.0, sign(phaseAndAmplitudeVarying.y)) * 0.5 * phaseAndAmplitudeVarying.z;" "fragColour = vec3(sample.x, vec2(0.5) + (sample.y * quadrature));" "}"; @@ -204,7 +199,6 @@ std::unique_ptr IntermediateShader::make_rgb_source_shader(c "#version 150\n" "in vec2 inputPositionsVarying[11];" - "in vec2 iInputPositionVarying;" "in vec3 phaseAndAmplitudeVarying;" "out vec3 fragColour;" @@ -215,7 +209,7 @@ std::unique_ptr IntermediateShader::make_rgb_source_shader(c "void main(void)" "{" - "fragColour = rgb_sample(texID, inputPositionsVarying[5], iInputPositionVarying);" + "fragColour = rgb_sample(texID, inputPositionsVarying[5]);" "}"; return make_shader(fragment_shader.str(), true, true); @@ -439,7 +433,3 @@ void IntermediateShader::set_is_double_height(bool is_double_height, float input set_uniform("inputVerticalOffset", input_offset); set_uniform("outputVerticalOffset", output_offset); } - -void IntermediateShader::set_integer_coordinate_multiplier(float multiplier) { - set_uniform("iCoordinateMultiplier", multiplier); -} diff --git a/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp b/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp index ff8316893..d8c5e9699 100644 --- a/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp +++ b/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp @@ -135,11 +135,6 @@ public: */ void set_is_double_height(bool is_double_height, float input_offset = 0.0f, float output_offset = 0.0f); - /*! - Sets the multiplier applied in the vertex shader to iCoordinates. - */ - void set_integer_coordinate_multiplier(float); - private: static std::unique_ptr make_shader(const std::string &fragment_shader, bool use_usampler, bool input_is_inputPosition); };