1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Added the option for both intermediate and output shaders to use only a portion of the input/output texture; made an attempt to pick an appropriate proportion in order to align signal sampling with the colour subcarrier.

This commit is contained in:
Thomas Harte 2017-01-03 22:16:52 -05:00
parent f2b8b26bc4
commit 7d60df9075
6 changed files with 64 additions and 10 deletions

View File

@ -381,11 +381,40 @@ void OpenGLOutputBuilder::set_timing_uniforms()
extends = true;
}
if(output_shader_program_) output_shader_program_->set_timing(height_of_display_, cycles_per_line_, horizontal_scan_period_, vertical_scan_period_, vertical_period_divider_);
float colour_subcarrier_frequency = (float)colour_cycle_numerator_ / (float)colour_cycle_denominator_;
if(composite_separation_filter_program_) composite_separation_filter_program_->set_separation_frequency(cycles_per_line_, colour_subcarrier_frequency);
if(composite_y_filter_shader_program_) composite_y_filter_shader_program_->set_filter_coefficients(cycles_per_line_, colour_subcarrier_frequency * 0.25f);
if(composite_chrominance_filter_shader_program_) composite_chrominance_filter_shader_program_->set_filter_coefficients(cycles_per_line_, colour_subcarrier_frequency * 0.5f);
if(rgb_filter_shader_program_) rgb_filter_shader_program_->set_filter_coefficients(cycles_per_line_, (float)input_frequency_ * 0.5f);
float output_width = ((float)colour_cycle_numerator_ * 4.0f) / (float)(colour_cycle_denominator_ * IntermediateBufferWidth);
if(composite_separation_filter_program_)
{
composite_separation_filter_program_->set_width_scalers(output_width, output_width);
composite_separation_filter_program_->set_separation_frequency(cycles_per_line_, colour_subcarrier_frequency);
}
if(composite_y_filter_shader_program_)
{
composite_y_filter_shader_program_->set_width_scalers(output_width, output_width);
composite_y_filter_shader_program_->set_filter_coefficients(cycles_per_line_, colour_subcarrier_frequency * 0.25f);
}
if(composite_chrominance_filter_shader_program_)
{
composite_chrominance_filter_shader_program_->set_width_scalers(output_width, output_width);
composite_chrominance_filter_shader_program_->set_filter_coefficients(cycles_per_line_, colour_subcarrier_frequency * 0.5f);
}
if(rgb_filter_shader_program_)
{
rgb_filter_shader_program_->set_width_scalers(output_width, output_width);
rgb_filter_shader_program_->set_filter_coefficients(cycles_per_line_, (float)input_frequency_ * 0.5f);
}
if(output_shader_program_)
{
output_shader_program_->set_input_width_scaler(output_width);
output_shader_program_->set_timing(height_of_display_, cycles_per_line_, horizontal_scan_period_, vertical_scan_period_, vertical_period_divider_);
}
if(composite_input_shader_program_)
{
composite_input_shader_program_->set_width_scalers(1.0f, output_width);
}
if(rgb_input_shader_program_)
{
rgb_input_shader_program_->set_width_scalers(1.0f, output_width);
}
}

View File

@ -45,6 +45,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *
"uniform float extension;"
"uniform %s texID;"
"uniform float offsets[5];"
"uniform vec2 widthScalers;"
"out vec2 phaseAndAmplitudeVarying;"
"out vec2 inputPositionsVarying[11];"
@ -59,8 +60,8 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *
// inputPosition.x is either inputStart.x or ends.x, depending on whether it is on the left or the right;
// outputPosition.x is either outputStart.x or ends.y;
// .ys are inputStart.y and outputStart.y respectively
"vec2 inputPosition = vec2(mix(inputStart.x, ends.x, extent), inputStart.y);"
"vec2 outputPosition = vec2(mix(outputStart.x, ends.y, extent), outputStart.y);"
"vec2 inputPosition = vec2(mix(inputStart.x, ends.x, extent)*widthScalers[0], inputStart.y);"
"vec2 outputPosition = vec2(mix(outputStart.x, ends.y, extent)*widthScalers[1], outputStart.y);"
// extension is the amount to extend both the input and output by to add a full colour cycle at each end
"vec2 extensionVector = vec2(extension, 0.0) * 2.0 * (extent - 0.5);"
@ -477,3 +478,8 @@ void IntermediateShader::set_colour_conversion_matrices(float *fromRGB, float *t
set_uniform_matrix("lumaChromaToRGB", 3, false, toRGB);
set_uniform_matrix("rgbToLumaChroma", 3, false, fromRGB);
}
void IntermediateShader::set_width_scalers(float input_scaler, float output_scaler)
{
set_uniform("widthScalers", input_scaler, output_scaler);
}

View File

@ -88,6 +88,12 @@ public:
*/
void set_colour_conversion_matrices(float *fromRGB, float *toRGB);
/*!
Sets the proportions of the input and output areas that should be considered the whole width 1.0 means use all available
space, 0.5 means use half, etc.
*/
void set_width_scalers(float input_scaler, float output_scaler);
private:
static std::unique_ptr<IntermediateShader> make_shader(const char *fragment_shader, bool use_usampler, bool input_is_inputPosition);
};

View File

@ -38,6 +38,7 @@ std::unique_ptr<OutputShader> OutputShader::make_shader(const char *fragment_met
"uniform vec2 positionConversion;"
"uniform vec2 scanNormal;"
"uniform %s texID;"
"uniform float inputScaler;"
"out float lateralVarying;"
"out vec2 srcCoordinatesVarying;"
@ -54,7 +55,7 @@ std::unique_ptr<OutputShader> OutputShader::make_shader(const char *fragment_met
"vec2 vSrcCoordinates = vec2(x, vertical.y);"
"ivec2 textureSize = textureSize(texID, 0);"
"iSrcCoordinatesVarying = vSrcCoordinates;"
"srcCoordinatesVarying = vec2(vSrcCoordinates.x / textureSize.x, (vSrcCoordinates.y + 0.5) / textureSize.y);"
"srcCoordinatesVarying = vec2(inputScaler * vSrcCoordinates.x / textureSize.x, (vSrcCoordinates.y + 0.5) / textureSize.y);"
"vec2 vPosition = vec2(x, vertical.x);"
"vec2 floatingPosition = (vPosition / positionConversion) + lateral * scanNormal;"
@ -117,3 +118,8 @@ void OutputShader::set_timing(unsigned int height_of_display, unsigned int cycle
set_uniform("scanNormal", scan_normal[0], scan_normal[1]);
set_uniform("positionConversion", (GLfloat)horizontal_scan_period, (GLfloat)vertical_scan_period / (GLfloat)vertical_period_divider);
}
void OutputShader::set_input_width_scaler(float input_scaler)
{
set_uniform("inputScaler", input_scaler);
}

View File

@ -58,6 +58,12 @@ public:
to occur upon the next `bind`.
*/
void set_timing(unsigned int height_of_display, unsigned int cycles_per_line, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider);
/*!
Sets the proportion of the input area that should be considered the whole width 1.0 means use all available
space, 0.5 means use half, etc.
*/
void set_input_width_scaler(float input_scaler);
};
}

View File

@ -156,7 +156,8 @@ void Shader::set_uniform(const std::string &name, GLint value1, GLint value2)
void Shader::set_uniform(const std::string &name, GLfloat value1, GLfloat value2)
{
enqueue_function([name, value1, value2, this] {
glUniform2f(location(), value1, value2);
GLint location = location();
glUniform2f(location, value1, value2);
});
}