From 9ede284eb6d6d9b12b6bc2550ddb98c8b3746b45 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 17 Apr 2016 20:34:52 -0400 Subject: [PATCH] Added blanking source runs, ensuring the rolling buffer is appropriately cleared. --- Outputs/CRT/CRT.cpp | 14 ++++++++-- Outputs/CRT/Internals/CRTConstants.hpp | 2 +- Outputs/CRT/Internals/CRTOpenGL.cpp | 36 +++++++++++++++----------- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Outputs/CRT/CRT.cpp b/Outputs/CRT/CRT.cpp index 7e1199b7a..c78b4b3b6 100644 --- a/Outputs/CRT/CRT.cpp +++ b/Outputs/CRT/CRT.cpp @@ -105,8 +105,9 @@ Flywheel::SyncEvent CRT::get_next_horizontal_sync_event(bool hsync_is_requested, #define source_input_position_y(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfInputPosition + 2]) #define source_output_position_x(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfOutputPosition + 0]) #define source_output_position_y(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfOutputPosition + 2]) -#define source_phase(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAndAmplitude + 0] -#define source_amplitude(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAndAmplitude + 1] +#define source_phase(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAmplitudeAndAlpha + 0] +#define source_amplitude(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAmplitudeAndAlpha + 1] +#define source_alpha(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAmplitudeAndAlpha + 2] #define source_phase_time(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseTime]) void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divider, bool hsync_requested, bool vsync_requested, const bool vsync_charging, const Scan::Type type, uint16_t tex_x, uint16_t tex_y) @@ -165,6 +166,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi source_phase(0) = source_phase(1) = _colour_burst_phase; source_amplitude(0) = source_amplitude(1) = _colour_burst_amplitude; source_phase_time(0) = source_phase_time(1) = _colour_burst_time; + source_alpha(0) = source_alpha(1) = 255; } } @@ -243,6 +245,14 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi if(next_run_length == time_until_horizontal_sync_event && next_horizontal_sync_event == Flywheel::SyncEvent::EndRetrace) { _openGL_output_builder->increment_composite_output_y(); + + // store a run to clear the new line + next_run = _openGL_output_builder->get_next_source_run(); + source_output_position_x(0) = 0; + source_output_position_x(1) = IntermediateBufferWidth; + source_output_position_y(0) = source_output_position_y(1) = _openGL_output_builder->get_composite_output_y(); + source_alpha(0) = source_alpha(1) = 0; + _openGL_output_builder->complete_source_run(); } } diff --git a/Outputs/CRT/Internals/CRTConstants.hpp b/Outputs/CRT/Internals/CRTConstants.hpp index c42a7fbb9..27b45cb1a 100644 --- a/Outputs/CRT/Internals/CRTConstants.hpp +++ b/Outputs/CRT/Internals/CRTConstants.hpp @@ -29,7 +29,7 @@ const size_t OutputVertexSize = 16; // remapping occurs to ensure a continous stream of data for each scan, giving correct out-of-bounds behaviour const size_t SourceVertexOffsetOfInputPosition = 0; const size_t SourceVertexOffsetOfOutputPosition = 4; -const size_t SourceVertexOffsetOfPhaseAndAmplitude = 8; +const size_t SourceVertexOffsetOfPhaseAmplitudeAndAlpha = 8; const size_t SourceVertexOffsetOfPhaseTime = 12; const size_t SourceVertexSize = 16; diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index b6a60734c..6e11f5433 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -147,7 +147,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out prepare_composite_input_shader(); prepare_source_vertex_array(); - prepare_composite_output_shader(); +// prepare_composite_output_shader(); prepare_rgb_output_shader(); prepare_output_vertex_array(); @@ -201,7 +201,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out { composite_input_shader_program->bind(); - compositeTexture->bind_framebuffer(); +// compositeTexture->bind_framebuffer(); glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); glBindVertexArray(source_vertex_array); @@ -230,7 +230,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out } // transfer to screen - perform_output_stage(output_width, output_height, rgb_shader_program.get()); +// perform_output_stage(output_width, output_height, rgb_shader_program.get()); } else perform_output_stage(output_width, output_height, rgb_shader_program.get()); @@ -255,6 +255,7 @@ void OpenGLOutputBuilder::perform_output_stage(unsigned int output_width, unsign // update uniforms push_size_uniforms(output_width, output_height); + glViewport(0, 0, (GLsizei)output_width, (GLsizei)output_height); // Ensure we're back on the output framebuffer, drawing from the output array buffer glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); @@ -342,7 +343,7 @@ char *OpenGLOutputBuilder::get_input_vertex_shader() "in vec2 inputPosition;" "in vec2 outputPosition;" - "in vec2 phaseAndAmplitude;" + "in vec3 phaseAmplitudeAndAlpha;" "in float phaseTime;" "uniform float phaseCyclesPerTick;" @@ -351,15 +352,18 @@ char *OpenGLOutputBuilder::get_input_vertex_shader() "out vec2 inputPositionVarying;" "out float phaseVarying;" + "out float alphaVarying;" "void main(void)" "{" "ivec2 textureSize = textureSize(texID, 0);" "inputPositionVarying = vec2(inputPosition.x / textureSize.x, (inputPosition.y + 0.5) / textureSize.y);" + "phaseVarying = (phaseCyclesPerTick * phaseTime + phaseAmplitudeAndAlpha.x) * 2.0 * 3.141592654;" + "alphaVarying = phaseAmplitudeAndAlpha.z;" + "vec2 eyePosition = 2.0*(outputPosition / outputTextureSize) - vec2(1.0);" "gl_Position = vec4(eyePosition, 0.0, 1.0);" - "phaseVarying = (phaseCyclesPerTick * phaseTime + phaseAndAmplitude.x) * 2.0 * 3.141592654;" "}"); } @@ -377,6 +381,7 @@ char *OpenGLOutputBuilder::get_input_fragment_shader() "in vec2 inputPositionVarying;" "in float phaseVarying;" + "in float alphaVarying;" "out vec4 fragColour;" @@ -386,7 +391,7 @@ char *OpenGLOutputBuilder::get_input_fragment_shader() "void main(void)" "{" - "fragColour = vec4(rgb_sample(texID, inputPositionVarying, inputPositionVarying), 1.0);" // composite + "fragColour = vec4(rgb_sample(texID, inputPositionVarying, inputPositionVarying) * alphaVarying, 1.0);" // composite "}" , composite_shader); } @@ -537,24 +542,24 @@ void OpenGLOutputBuilder::prepare_source_vertex_array() { if(composite_input_shader_program) { - GLint inputPositionAttribute = composite_input_shader_program->get_attrib_location("inputPosition"); - GLint outputPositionAttribute = composite_input_shader_program->get_attrib_location("outputPosition"); - GLint phaseAndAmplitudeAttribute = composite_input_shader_program->get_attrib_location("phaseAndAmplitude"); - GLint phaseTimeAttribute = composite_input_shader_program->get_attrib_location("phaseTime"); + GLint inputPositionAttribute = composite_input_shader_program->get_attrib_location("inputPosition"); + GLint outputPositionAttribute = composite_input_shader_program->get_attrib_location("outputPosition"); + GLint phaseAmplitudeAndAlphaAttribute = composite_input_shader_program->get_attrib_location("phaseAmplitudeAndAlpha"); + GLint phaseTimeAttribute = composite_input_shader_program->get_attrib_location("phaseTime"); glBindVertexArray(source_vertex_array); glEnableVertexAttribArray((GLuint)inputPositionAttribute); glEnableVertexAttribArray((GLuint)outputPositionAttribute); - glEnableVertexAttribArray((GLuint)phaseAndAmplitudeAttribute); + glEnableVertexAttribArray((GLuint)phaseAmplitudeAndAlphaAttribute); glEnableVertexAttribArray((GLuint)phaseTimeAttribute); const GLsizei vertexStride = SourceVertexSize; glBindBuffer(GL_ARRAY_BUFFER, source_array_buffer); - glVertexAttribPointer((GLuint)inputPositionAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)SourceVertexOffsetOfInputPosition); - glVertexAttribPointer((GLuint)outputPositionAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)SourceVertexOffsetOfOutputPosition); - glVertexAttribPointer((GLuint)phaseAndAmplitudeAttribute, 2, GL_UNSIGNED_BYTE, GL_TRUE, vertexStride, (void *)SourceVertexOffsetOfPhaseAndAmplitude); - glVertexAttribPointer((GLuint)phaseTimeAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)SourceVertexOffsetOfPhaseTime); + glVertexAttribPointer((GLuint)inputPositionAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)SourceVertexOffsetOfInputPosition); + glVertexAttribPointer((GLuint)outputPositionAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)SourceVertexOffsetOfOutputPosition); + glVertexAttribPointer((GLuint)phaseAmplitudeAndAlphaAttribute, 3, GL_UNSIGNED_BYTE, GL_TRUE, vertexStride, (void *)SourceVertexOffsetOfPhaseAmplitudeAndAlpha); + glVertexAttribPointer((GLuint)phaseTimeAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)SourceVertexOffsetOfPhaseTime); } } @@ -643,6 +648,7 @@ void OpenGLOutputBuilder::prepare_rgb_output_shader() void OpenGLOutputBuilder::prepare_composite_output_shader() { +// rgb_shader_program = prepare_output_shader(get_composite_output_fragment_shader()); composite_output_shader_program = prepare_output_shader(get_composite_output_fragment_shader()); }