1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-27 00:30:26 +00:00

Reduced precision of input phase, but I'm not necessarily persuaded by it as a move. However it's clear that something is off in that whole area. But if phase is locked by output position, do I need to retain this level of complexity? Also ensured that intermediate buffers prior to the final are sampled using the nearest sampling mode, also to reduce precision errors.

This commit is contained in:
Thomas Harte 2017-01-10 22:08:07 -05:00
parent eeb646868b
commit 4c3669f210
5 changed files with 26 additions and 93 deletions

View File

@ -147,7 +147,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, bool hsync_requested, bo
{ {
// output_y and texture locations will be written later; we won't necessarily know what it is outside of the locked region // output_y and texture locations will be written later; we won't necessarily know what it is outside of the locked region
source_output_position_x1() = (uint16_t)horizontal_flywheel_->get_current_output_position(); source_output_position_x1() = (uint16_t)horizontal_flywheel_->get_current_output_position();
source_phase() = colour_burst_phase_; source_phase() = 31 + colour_burst_phase_ & ~63; // phase is rounded to the nearest 1/4 of a cycle
source_amplitude() = colour_burst_amplitude_; source_amplitude() = colour_burst_amplitude_;
source_phase_time() = (uint8_t)colour_burst_time_; // assumption: burst was within the first 1/16 of the line source_phase_time() = (uint8_t)colour_burst_time_; // assumption: burst was within the first 1/16 of the line
} }

View File

@ -69,9 +69,9 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
// } // }
// else // else
{ {
composite_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, composite_texture_unit)); composite_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, composite_texture_unit, GL_NEAREST));
separated_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, separated_texture_unit)); separated_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, separated_texture_unit, GL_NEAREST));
filtered_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, filtered_texture_unit)); filtered_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, filtered_texture_unit, GL_LINEAR));
} }
} }
@ -117,7 +117,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
// make sure there's a target to draw to // make sure there's a target to draw to
if(!framebuffer_ || framebuffer_->get_height() != output_height || framebuffer_->get_width() != output_width) if(!framebuffer_ || framebuffer_->get_height() != output_height || framebuffer_->get_width() != output_width)
{ {
std::unique_ptr<OpenGL::TextureTarget> new_framebuffer(new OpenGL::TextureTarget((GLsizei)output_width, (GLsizei)output_height, pixel_accumulation_texture_unit)); std::unique_ptr<OpenGL::TextureTarget> new_framebuffer(new OpenGL::TextureTarget((GLsizei)output_width, (GLsizei)output_height, pixel_accumulation_texture_unit, GL_LINEAR));
if(framebuffer_) if(framebuffer_)
{ {
new_framebuffer->bind_framebuffer(); new_framebuffer->bind_framebuffer();
@ -346,6 +346,7 @@ void OpenGLOutputBuilder::prepare_output_shader()
{ {
output_shader_program_ = OpenGL::OutputShader::make_shader("", "texture(texID, srcCoordinatesVarying).rgb", false); output_shader_program_ = OpenGL::OutputShader::make_shader("", "texture(texID, srcCoordinatesVarying).rgb", false);
output_shader_program_->set_source_texture_unit(work_texture_ ? work_texture_unit : filtered_texture_unit); output_shader_program_->set_source_texture_unit(work_texture_ ? work_texture_unit : filtered_texture_unit);
// output_shader_program_->set_source_texture_unit(composite_texture_unit);
output_shader_program_->set_origin_is_double_height(!!work_texture_); output_shader_program_->set_origin_is_double_height(!!work_texture_);
} }

View File

@ -75,7 +75,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *
// keep iInputPositionVarying in whole source pixels, scale mappedInputPosition to the ordinary normalised range // keep iInputPositionVarying in whole source pixels, scale mappedInputPosition to the ordinary normalised range
"vec2 textureSize = vec2(textureSize(texID, 0));" "vec2 textureSize = vec2(textureSize(texID, 0));"
"iInputPositionVarying = extendedInputPosition;" "iInputPositionVarying = extendedInputPosition;"
"vec2 mappedInputPosition = (extendedInputPosition + vec2(0.0, 0.5)) / textureSize;" "vec2 mappedInputPosition = (extendedInputPosition) / textureSize;" // + vec2(0.0, 0.5)
// setup input positions spaced as per the supplied offsets; these are for filtering where required // setup input positions spaced as per the supplied offsets; these are for filtering where required
"inputPositionsVarying[0] = mappedInputPosition - (vec2(5.0, 0.0) / textureSize);" "inputPositionsVarying[0] = mappedInputPosition - (vec2(5.0, 0.0) / textureSize);"
@ -93,7 +93,8 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *
// setup phaseAndAmplitudeVarying.x as colour burst subcarrier phase, in radians; // setup phaseAndAmplitudeVarying.x as colour burst subcarrier phase, in radians;
// setup phaseAndAmplitudeVarying.x as colour burst amplitude // setup phaseAndAmplitudeVarying.x as colour burst amplitude
"phaseAndAmplitudeVarying.x = (((extendedOutputPosition.x - phaseTimeAndAmplitude.y) / 4.0) + (phaseTimeAndAmplitude.x / 255.0)) * 2.0 * 3.141592654;" "phaseAndAmplitudeVarying.x = (extendedOutputPosition.x - phaseTimeAndAmplitude.y*widthScalers[1]) / 4.0 + phaseTimeAndAmplitude.x / 255.0;"
"phaseAndAmplitudeVarying.x *= 2.0 * 3.141592654;"
"phaseAndAmplitudeVarying.y = 0.33;" // TODO: reinstate connection with (phaseTimeAndAmplitude.y/256.0) "phaseAndAmplitudeVarying.y = 0.33;" // TODO: reinstate connection with (phaseTimeAndAmplitude.y/256.0)
// determine output position by scaling the output position according to the texture size // determine output position by scaling the output position according to the texture size
@ -187,7 +188,6 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_luma_separat
"in vec2 phaseAndAmplitudeVarying;" "in vec2 phaseAndAmplitudeVarying;"
"in vec2 inputPositionsVarying[11];" "in vec2 inputPositionsVarying[11];"
"uniform vec4 weights[3];"
"out vec3 fragColour;" "out vec3 fragColour;"
@ -195,54 +195,16 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_luma_separat
"void main(void)" "void main(void)"
"{" "{"
// grab 11 samples "vec4 samples = vec4("
"vec3 samples[] = vec3[](" "texture(texID, inputPositionsVarying[3]).r,"
"vec3(" "texture(texID, inputPositionsVarying[4]).r,"
"texture(texID, inputPositionsVarying[0]).r," "texture(texID, inputPositionsVarying[5]).r,"
"texture(texID, inputPositionsVarying[2]).r," "texture(texID, inputPositionsVarying[6]).r"
"texture(texID, inputPositionsVarying[3]).r"
"),"
"vec3("
"texture(texID, inputPositionsVarying[4]).r,"
"texture(texID, inputPositionsVarying[5]).r,"
"texture(texID, inputPositionsVarying[6]).r"
"),"
"vec3("
"texture(texID, inputPositionsVarying[7]).r,"
"texture(texID, inputPositionsVarying[8]).r,"
"texture(texID, inputPositionsVarying[10]).r"
")"
");" ");"
"float luminance = dot(samples, vec4(0.25));"
"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], fixedWeights[0]),"
"dot(samples[1], fixedWeights[1]),"
"dot(samples[2], fixedWeights[2])"
"), vec3(1.0));"
// define chroma to be whatever was here, minus luma // define chroma to be whatever was here, minus luma
"float chrominance = 0.5 * (samples[1].y - luminance) / phaseAndAmplitudeVarying.y;" "float chrominance = 0.5 * (samples.z - luminance) / phaseAndAmplitudeVarying.y;"
"luminance /= (1.0 - phaseAndAmplitudeVarying.y);" "luminance /= (1.0 - phaseAndAmplitudeVarying.y);"
// split choma colours here, as the most direct place, writing out // split choma colours here, as the most direct place, writing out
@ -268,48 +230,18 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_filter_shade
"void main(void)" "void main(void)"
"{" "{"
"vec3 samples[] = vec3[](" "vec3 samples[] = vec3[]("
"texture(texID, inputPositionsVarying[0]).rgb," "texture(texID, inputPositionsVarying[3]).rgb,"
"texture(texID, inputPositionsVarying[2]).rgb,"
"texture(texID, inputPositionsVarying[4]).rgb," "texture(texID, inputPositionsVarying[4]).rgb,"
"texture(texID, inputPositionsVarying[5]).rgb," "texture(texID, inputPositionsVarying[5]).rgb,"
"texture(texID, inputPositionsVarying[6]).rgb," "texture(texID, inputPositionsVarying[6]).rgb"
"texture(texID, inputPositionsVarying[8]).rgb,"
"texture(texID, inputPositionsVarying[10]).rgb"
");" ");"
"vec4 fixedWeights[2] = vec4[](" "vec4 chromaChannel1 = vec4(samples[0].g, samples[1].g, samples[2].g, samples[3].g);"
"vec4(" "vec4 chromaChannel2 = vec4(samples[0].b, samples[1].b, samples[2].b, samples[3].b);"
"0.001298,"
"-0.038576,"
"0.287031,"
"0.500000"
"),"
"vec4("
"0.287031,"
"-0.038576,"
"0.001298,"
"0.0"
")"
");"
"vec4 chromaChannel1[] = vec4[](" "vec3 lumaChromaColour = vec3(samples[2].r,"
"vec4(samples[0].g, samples[1].g, samples[2].g, samples[3].g)," "dot(chromaChannel1, vec4(0.25)),"
"vec4(samples[4].g, samples[5].g, samples[6].g, 0.0)" "dot(chromaChannel2, vec4(0.25))"
");"
"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, 0.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);" "vec3 lumaChromaColourInRange = (lumaChromaColour - vec3(0.0, 0.5, 0.5)) * vec3(1.0, 2.0, 2.0);"

View File

@ -12,7 +12,7 @@
using namespace OpenGL; using namespace OpenGL;
TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit) : TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit, GLint mag_filter) :
_width(width), _width(width),
_height(height), _height(height),
_pixel_shader(nullptr), _pixel_shader(nullptr),
@ -33,7 +33,7 @@ TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit)
uint8_t *blank_buffer = (uint8_t *)calloc((size_t)(_expanded_width * _expanded_height), 4); uint8_t *blank_buffer = (uint8_t *)calloc((size_t)(_expanded_width * _expanded_height), 4);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)_expanded_width, (GLsizei)_expanded_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, blank_buffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)_expanded_width, (GLsizei)_expanded_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, blank_buffer);
free(blank_buffer); free(blank_buffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0);

View File

@ -30,7 +30,7 @@ class TextureTarget {
@param height The height of target to create. @param height The height of target to create.
@param texture_unit A texture unit on which to bind the texture. @param texture_unit A texture unit on which to bind the texture.
*/ */
TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit); TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit, GLint mag_filter);
~TextureTarget(); ~TextureTarget();
/*! /*!