mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-23 20:29:42 +00:00
Definitively eliminated the additional y filtering step; if I'm going to work to ensure always four samples per colour cycle, I can put the channel separation coefficients directly into their shaders, cutting down on samples.
This commit is contained in:
parent
5740015f56
commit
0487b8c178
@ -18,10 +18,9 @@ using namespace Outputs::CRT;
|
||||
namespace {
|
||||
static const GLenum composite_texture_unit = GL_TEXTURE0;
|
||||
static const GLenum separated_texture_unit = GL_TEXTURE1;
|
||||
static const GLenum filtered_y_texture_unit = GL_TEXTURE2;
|
||||
static const GLenum filtered_texture_unit = GL_TEXTURE3;
|
||||
static const GLenum source_data_texture_unit = GL_TEXTURE4;
|
||||
static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE5;
|
||||
static const GLenum filtered_texture_unit = GL_TEXTURE2;
|
||||
static const GLenum source_data_texture_unit = GL_TEXTURE3;
|
||||
static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE4;
|
||||
}
|
||||
|
||||
OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
|
||||
@ -36,7 +35,6 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
|
||||
array_builder(SourceVertexBufferDataSize, OutputVertexBufferDataSize),
|
||||
composite_texture_(IntermediateBufferWidth, IntermediateBufferHeight, composite_texture_unit),
|
||||
separated_texture_(IntermediateBufferWidth, IntermediateBufferHeight, separated_texture_unit),
|
||||
filtered_y_texture_(IntermediateBufferWidth, IntermediateBufferHeight, filtered_y_texture_unit),
|
||||
filtered_texture_(IntermediateBufferWidth, IntermediateBufferHeight, filtered_texture_unit)
|
||||
{
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_CONSTANT_COLOR);
|
||||
@ -132,9 +130,9 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
||||
RenderStage composite_render_stages[] =
|
||||
{
|
||||
{&composite_texture_, composite_input_shader_program_.get(), {0.0, 0.0, 0.0}},
|
||||
// {&separated_texture_, composite_separation_filter_program_.get(), {0.0, 0.5, 0.5}},
|
||||
{&separated_texture_, composite_separation_filter_program_.get(), {0.0, 0.5, 0.5}},
|
||||
// {&filtered_y_texture_, composite_y_filter_shader_program_.get(), {0.0, 0.5, 0.5}},
|
||||
// {&filtered_texture_, composite_chrominance_filter_shader_program_.get(), {0.0, 0.0, 0.0}},
|
||||
{&filtered_texture_, composite_chrominance_filter_shader_program_.get(), {0.0, 0.0, 0.0}},
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
@ -211,7 +209,6 @@ void OpenGLOutputBuilder::reset_all_OpenGL_state()
|
||||
{
|
||||
composite_input_shader_program_ = nullptr;
|
||||
composite_separation_filter_program_ = nullptr;
|
||||
composite_y_filter_shader_program_ = nullptr;
|
||||
composite_chrominance_filter_shader_program_ = nullptr;
|
||||
rgb_input_shader_program_ = nullptr;
|
||||
rgb_filter_shader_program_ = nullptr;
|
||||
@ -255,12 +252,12 @@ void OpenGLOutputBuilder::prepare_composite_input_shaders()
|
||||
composite_separation_filter_program_->set_source_texture_unit(composite_texture_unit);
|
||||
composite_separation_filter_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight);
|
||||
|
||||
composite_y_filter_shader_program_ = OpenGL::IntermediateShader::make_luma_filter_shader();
|
||||
composite_y_filter_shader_program_->set_source_texture_unit(separated_texture_unit);
|
||||
composite_y_filter_shader_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight);
|
||||
// composite_y_filter_shader_program_ = OpenGL::IntermediateShader::make_luma_filter_shader();
|
||||
// composite_y_filter_shader_program_->set_source_texture_unit(separated_texture_unit);
|
||||
// composite_y_filter_shader_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight);
|
||||
|
||||
composite_chrominance_filter_shader_program_ = OpenGL::IntermediateShader::make_chroma_filter_shader();
|
||||
composite_chrominance_filter_shader_program_->set_source_texture_unit(filtered_y_texture_unit);
|
||||
composite_chrominance_filter_shader_program_->set_source_texture_unit(separated_texture_unit);
|
||||
composite_chrominance_filter_shader_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight);
|
||||
}
|
||||
|
||||
@ -295,7 +292,7 @@ void OpenGLOutputBuilder::prepare_source_vertex_array()
|
||||
void OpenGLOutputBuilder::prepare_output_shader()
|
||||
{
|
||||
output_shader_program_ = OpenGL::OutputShader::make_shader("", "texture(texID, srcCoordinatesVarying).rgb", false);
|
||||
output_shader_program_->set_source_texture_unit(composite_texture_unit);//filtered_texture_unit);
|
||||
output_shader_program_->set_source_texture_unit(filtered_texture_unit);
|
||||
}
|
||||
|
||||
void OpenGLOutputBuilder::prepare_output_vertex_array()
|
||||
@ -362,6 +359,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);
|
||||
}
|
||||
|
||||
@ -374,7 +372,6 @@ void OpenGLOutputBuilder::set_timing_uniforms()
|
||||
OpenGL::IntermediateShader *intermediate_shaders[] = {
|
||||
composite_input_shader_program_.get(),
|
||||
composite_separation_filter_program_.get(),
|
||||
composite_y_filter_shader_program_.get(),
|
||||
composite_chrominance_filter_shader_program_.get()
|
||||
};
|
||||
bool extends = false;
|
||||
@ -390,15 +387,9 @@ void OpenGLOutputBuilder::set_timing_uniforms()
|
||||
composite_separation_filter_program_->set_width_scalers(output_width, output_width);
|
||||
composite_separation_filter_program_->set_separation_frequency(sample_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(sample_cycles_per_line, colour_subcarrier_frequency);
|
||||
}
|
||||
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(sample_cycles_per_line, colour_subcarrier_frequency);
|
||||
}
|
||||
if(rgb_filter_shader_program_)
|
||||
{
|
||||
|
@ -66,12 +66,11 @@ class OpenGLOutputBuilder {
|
||||
GLsizei composite_src_output_y_;
|
||||
|
||||
std::unique_ptr<OpenGL::OutputShader> output_shader_program_;
|
||||
std::unique_ptr<OpenGL::IntermediateShader> composite_input_shader_program_, composite_separation_filter_program_, composite_y_filter_shader_program_, composite_chrominance_filter_shader_program_;
|
||||
std::unique_ptr<OpenGL::IntermediateShader> composite_input_shader_program_, composite_separation_filter_program_, composite_chrominance_filter_shader_program_;
|
||||
std::unique_ptr<OpenGL::IntermediateShader> rgb_input_shader_program_, rgb_filter_shader_program_;
|
||||
|
||||
OpenGL::TextureTarget composite_texture_; // receives raw composite levels
|
||||
OpenGL::TextureTarget separated_texture_; // receives unfiltered Y in the R channel plus unfiltered but demodulated chrominance in G and B
|
||||
OpenGL::TextureTarget filtered_y_texture_; // receives filtered Y in the R channel plus unfiltered chrominance in G and B
|
||||
OpenGL::TextureTarget separated_texture_; // receives filtered Y in the R channel plus unfiltered but demodulated chrominance in G and B
|
||||
OpenGL::TextureTarget filtered_texture_; // receives filtered YIQ or YUV
|
||||
|
||||
std::unique_ptr<OpenGL::TextureTarget> framebuffer_; // the current pixel output
|
||||
|
@ -194,35 +194,51 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_luma_separat
|
||||
"void main(void)"
|
||||
"{"
|
||||
// grab 11 samples
|
||||
"vec4 samples[3] = vec4[]("
|
||||
"vec4("
|
||||
"vec3 samples[] = vec3[]("
|
||||
"vec3("
|
||||
"texture(texID, inputPositionsVarying[0]).r,"
|
||||
"texture(texID, inputPositionsVarying[1]).r,"
|
||||
"texture(texID, inputPositionsVarying[2]).r,"
|
||||
"texture(texID, inputPositionsVarying[3]).r"
|
||||
"),"
|
||||
"vec4("
|
||||
"vec3("
|
||||
"texture(texID, inputPositionsVarying[4]).r,"
|
||||
"texture(texID, inputPositionsVarying[5]).r,"
|
||||
"texture(texID, inputPositionsVarying[6]).r,"
|
||||
"texture(texID, inputPositionsVarying[7]).r"
|
||||
"texture(texID, inputPositionsVarying[6]).r"
|
||||
"),"
|
||||
"vec4("
|
||||
"vec3("
|
||||
"texture(texID, inputPositionsVarying[7]).r,"
|
||||
"texture(texID, inputPositionsVarying[8]).r,"
|
||||
"texture(texID, inputPositionsVarying[9]).r,"
|
||||
"texture(texID, inputPositionsVarying[10]).r,"
|
||||
"0.0"
|
||||
"texture(texID, inputPositionsVarying[10]).r"
|
||||
")"
|
||||
");"
|
||||
|
||||
"vec3 fixedWeights[] = vec3[]("
|
||||
"vec3("
|
||||
"-0.000918,"
|
||||
"0.027278,"
|
||||
"0.103969"
|
||||
"),"
|
||||
"vec3("
|
||||
"0.202962,"
|
||||
"0.250000,"
|
||||
"0.202962"
|
||||
"),"
|
||||
"vec3("
|
||||
"0.103969,"
|
||||
"0.027278,"
|
||||
"-0.000918"
|
||||
")"
|
||||
");"
|
||||
|
||||
// apply the low-pass filter to separate luma
|
||||
"float luminance = "
|
||||
"dot(vec3("
|
||||
"dot(samples[0], weights[0]),"
|
||||
"dot(samples[1], weights[1]),"
|
||||
"dot(samples[2], weights[2])"
|
||||
"dot(samples[0], fixedWeights[0]),"
|
||||
"dot(samples[1], fixedWeights[1]),"
|
||||
"dot(samples[2], fixedWeights[2])"
|
||||
"), vec3(1.0));"
|
||||
|
||||
|
||||
// define chroma to be whatever was here, minus luma
|
||||
"float chrominance = 0.5 * (samples[1].y - luminance) / phaseAndAmplitudeVarying.y;"
|
||||
"luminance /= (1.0 - phaseAndAmplitudeVarying.y);"
|
||||
@ -251,40 +267,47 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_filter_shade
|
||||
"{"
|
||||
"vec3 samples[] = vec3[]("
|
||||
"texture(texID, inputPositionsVarying[0]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[1]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[2]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[3]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[4]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[5]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[6]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[7]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[8]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[9]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[10]).rgb"
|
||||
");"
|
||||
|
||||
"vec4 fixedWeights[2] = vec4[]("
|
||||
"vec4("
|
||||
"0.001298,"
|
||||
"-0.038576,"
|
||||
"0.287031,"
|
||||
"0.500000"
|
||||
"),"
|
||||
"vec4("
|
||||
"0.287031,"
|
||||
"-0.038576,"
|
||||
"0.001298,"
|
||||
"0.0"
|
||||
")"
|
||||
");"
|
||||
|
||||
"vec4 chromaChannel1[] = vec4[]("
|
||||
"vec4(samples[0].g, samples[1].g, samples[2].g, samples[3].g),"
|
||||
"vec4(samples[4].g, samples[5].g, samples[6].g, samples[7].g),"
|
||||
"vec4(samples[8].g, samples[9].g, samples[10].g, 0.0)"
|
||||
"vec4(samples[4].g, samples[5].g, samples[6].g, 0.0)"
|
||||
");"
|
||||
"vec4 chromaChannel2[] = vec4[]("
|
||||
"vec4(samples[0].b, samples[1].b, samples[2].b, samples[3].b),"
|
||||
"vec4(samples[4].b, samples[5].b, samples[6].b, samples[7].b),"
|
||||
"vec4(samples[8].b, samples[9].b, samples[10].b, 0.0)"
|
||||
"vec4(samples[4].b, samples[5].b, samples[6].b, 0.0)"
|
||||
");"
|
||||
|
||||
"vec3 lumaChromaColour = vec3(samples[5].r,"
|
||||
"dot(vec3("
|
||||
"dot(chromaChannel1[0], weights[0]),"
|
||||
"dot(chromaChannel1[1], weights[1]),"
|
||||
"dot(chromaChannel1[2], weights[2])"
|
||||
"), vec3(1.0)),"
|
||||
"dot(vec3("
|
||||
"dot(chromaChannel2[0], weights[0]),"
|
||||
"dot(chromaChannel2[1], weights[1]),"
|
||||
"dot(chromaChannel2[2], weights[2])"
|
||||
"), vec3(1.0))"
|
||||
"vec3 lumaChromaColour = vec3(samples[3].r,"
|
||||
"dot(vec2("
|
||||
"dot(chromaChannel1[0], fixedWeights[0]),"
|
||||
"dot(chromaChannel1[1], fixedWeights[1])"
|
||||
"), vec2(1.0)),"
|
||||
"dot(vec2("
|
||||
"dot(chromaChannel2[0], fixedWeights[0]),"
|
||||
"dot(chromaChannel2[1], fixedWeights[1])"
|
||||
"), vec2(1.0))"
|
||||
");"
|
||||
|
||||
"vec3 lumaChromaColourInRange = (lumaChromaColour - vec3(0.0, 0.5, 0.5)) * vec3(1.0, 2.0, 2.0);"
|
||||
@ -292,53 +315,6 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_filter_shade
|
||||
"}", false, false);
|
||||
}
|
||||
|
||||
std::unique_ptr<IntermediateShader> IntermediateShader::make_luma_filter_shader()
|
||||
{
|
||||
return make_shader(
|
||||
"#version 150\n"
|
||||
|
||||
"in vec2 inputPositionsVarying[11];"
|
||||
"uniform vec4 weights[3];"
|
||||
|
||||
"out vec3 fragColour;"
|
||||
|
||||
"uniform sampler2D texID;"
|
||||
"uniform mat3 lumaChromaToRGB;"
|
||||
|
||||
"void main(void)"
|
||||
"{"
|
||||
"vec3 samples[] = vec3[]("
|
||||
"texture(texID, inputPositionsVarying[0]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[1]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[2]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[3]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[4]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[5]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[6]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[7]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[8]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[9]).rgb,"
|
||||
"texture(texID, inputPositionsVarying[10]).rgb"
|
||||
");"
|
||||
|
||||
"vec4 luminance[] = vec4[]("
|
||||
"vec4(samples[0].r, samples[1].r, samples[2].r, samples[3].r),"
|
||||
"vec4(samples[4].r, samples[5].r, samples[6].r, samples[7].r),"
|
||||
"vec4(samples[8].r, samples[9].r, samples[10].r, 0.0)"
|
||||
");"
|
||||
|
||||
"fragColour = vec3("
|
||||
"dot(vec3("
|
||||
"dot(luminance[0], weights[0]),"
|
||||
"dot(luminance[1], weights[1]),"
|
||||
"dot(luminance[2], weights[2])"
|
||||
"), vec3(1.0)),"
|
||||
"samples[5].gb"
|
||||
");"
|
||||
// "fragColour = texture(texID, inputPositionsVarying[5]).rgb;"//lumaChromaToRGB * lumaChromaColourInRange;"
|
||||
"}", false, false);
|
||||
}
|
||||
|
||||
std::unique_ptr<IntermediateShader> IntermediateShader::make_rgb_filter_shader()
|
||||
{
|
||||
return make_shader(
|
||||
|
@ -44,11 +44,6 @@ public:
|
||||
*/
|
||||
static std::unique_ptr<IntermediateShader> make_chroma_filter_shader();
|
||||
|
||||
/*!
|
||||
Constructs and returns an intermediate shader that will filter R while passing through G and B unchanged.
|
||||
*/
|
||||
static std::unique_ptr<IntermediateShader> make_luma_filter_shader();
|
||||
|
||||
/*!
|
||||
Constructs and returns an intermediate shader that will filter R, G and B.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user