mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-11 04:28:58 +00:00
Eliminated use of zero-alpha runs to clear new lines in the intermediate buffer in favour of a scissored glClear. It's just an easier way to scale the current approach to three intermediate buffers.
This commit is contained in:
parent
e2da77fb8b
commit
8232ed765e
@ -106,7 +106,6 @@ Flywheel::SyncEvent CRT::get_next_horizontal_sync_event(bool hsync_is_requested,
|
|||||||
#define source_output_position_y(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfOutputPosition + 2])
|
#define source_output_position_y(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfOutputPosition + 2])
|
||||||
#define source_phase(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAmplitudeAndAlpha + 0]
|
#define source_phase(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAmplitudeAndAlpha + 0]
|
||||||
#define source_amplitude(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAmplitudeAndAlpha + 1]
|
#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])
|
#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)
|
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,7 +164,6 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
|
|||||||
source_phase(0) = source_phase(1) = _colour_burst_phase;
|
source_phase(0) = source_phase(1) = _colour_burst_phase;
|
||||||
source_amplitude(0) = source_amplitude(1) = _colour_burst_amplitude;
|
source_amplitude(0) = source_amplitude(1) = _colour_burst_amplitude;
|
||||||
source_phase_time(0) = source_phase_time(1) = _colour_burst_time;
|
source_phase_time(0) = source_phase_time(1) = _colour_burst_time;
|
||||||
source_alpha(0) = source_alpha(1) = 255;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,14 +242,6 @@ 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::StartRetrace)
|
if(next_run_length == time_until_horizontal_sync_event && next_horizontal_sync_event == Flywheel::SyncEvent::StartRetrace)
|
||||||
{
|
{
|
||||||
_openGL_output_builder->increment_composite_output_y();
|
_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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,12 +206,59 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
// decide how much to draw
|
// decide how much to draw
|
||||||
if(_drawn_source_buffer_data_pointer != _source_buffer_data_pointer)
|
if(_drawn_source_buffer_data_pointer != _source_buffer_data_pointer)
|
||||||
{
|
{
|
||||||
|
// determine how many lines are newly reclaimed; they'll need to be cleared
|
||||||
|
uint16_t clearing_zones[4];
|
||||||
|
int number_of_clearing_zones = 0;
|
||||||
|
|
||||||
|
if(_composite_src_output_y != _cleared_composite_output_y)
|
||||||
|
{
|
||||||
|
uint16_t lines_to_clear = _composite_src_output_y - _cleared_composite_output_y;
|
||||||
|
if(lines_to_clear > IntermediateBufferHeight)
|
||||||
|
{
|
||||||
|
number_of_clearing_zones = 1;
|
||||||
|
clearing_zones[0] = 0;
|
||||||
|
clearing_zones[1] = IntermediateBufferHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clearing_zones[0] = (_cleared_composite_output_y+1)%IntermediateBufferHeight;
|
||||||
|
if(clearing_zones[0]+lines_to_clear < IntermediateBufferHeight)
|
||||||
|
{
|
||||||
|
clearing_zones[1] = lines_to_clear;
|
||||||
|
number_of_clearing_zones = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clearing_zones[1] = IntermediateBufferHeight - clearing_zones[0];
|
||||||
|
clearing_zones[2] = 0;
|
||||||
|
clearing_zones[3] = lines_to_clear - clearing_zones[1];
|
||||||
|
number_of_clearing_zones = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_composite_src_output_y %= IntermediateBufferHeight;
|
||||||
|
_cleared_composite_output_y = _composite_src_output_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all drawing will be from the source vertex array and without blending
|
||||||
|
glBindVertexArray(source_vertex_array);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
// switch to the initial texture
|
||||||
|
compositeTexture->bind_framebuffer();
|
||||||
composite_input_shader_program->bind();
|
composite_input_shader_program->bind();
|
||||||
|
|
||||||
compositeTexture->bind_framebuffer();
|
// clear as desired
|
||||||
glBindVertexArray(source_vertex_array);
|
if(number_of_clearing_zones)
|
||||||
|
{
|
||||||
glDisable(GL_BLEND);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
for(int c = 0; c < number_of_clearing_zones; c++)
|
||||||
|
{
|
||||||
|
glScissor(0, clearing_zones[c*2], IntermediateBufferWidth, clearing_zones[c*2 + 1]);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
size_t new_data_size = _source_buffer_data_pointer - _drawn_source_buffer_data_pointer;
|
size_t new_data_size = _source_buffer_data_pointer - _drawn_source_buffer_data_pointer;
|
||||||
size_t new_data_start = _drawn_source_buffer_data_pointer;
|
size_t new_data_start = _drawn_source_buffer_data_pointer;
|
||||||
@ -231,6 +278,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
glDrawArrays(GL_LINES, 0, (GLsizei)((new_data_size - first_data_length) / SourceVertexSize));
|
glDrawArrays(GL_LINES, 0, (GLsizei)((new_data_size - first_data_length) / SourceVertexSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// switch back to screen output
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
|
||||||
glViewport(0, 0, (GLsizei)output_width, (GLsizei)output_height);
|
glViewport(0, 0, (GLsizei)output_width, (GLsizei)output_height);
|
||||||
}
|
}
|
||||||
@ -358,7 +406,6 @@ char *OpenGLOutputBuilder::get_input_vertex_shader()
|
|||||||
"out vec2 inputPositionVarying;"
|
"out vec2 inputPositionVarying;"
|
||||||
"out vec2 iInputPositionVarying;"
|
"out vec2 iInputPositionVarying;"
|
||||||
"out float phaseVarying;"
|
"out float phaseVarying;"
|
||||||
"out float alphaVarying;"
|
|
||||||
|
|
||||||
"void main(void)"
|
"void main(void)"
|
||||||
"{"
|
"{"
|
||||||
@ -367,7 +414,6 @@ char *OpenGLOutputBuilder::get_input_vertex_shader()
|
|||||||
"inputPositionVarying = (inputPosition + vec2(0.0, 0.5)) / vec2(textureSize);"
|
"inputPositionVarying = (inputPosition + vec2(0.0, 0.5)) / vec2(textureSize);"
|
||||||
|
|
||||||
"phaseVarying = (phaseCyclesPerTick * phaseTime + phaseAmplitudeAndAlpha.x) * 2.0 * 3.141592654;"
|
"phaseVarying = (phaseCyclesPerTick * phaseTime + phaseAmplitudeAndAlpha.x) * 2.0 * 3.141592654;"
|
||||||
"alphaVarying = phaseAmplitudeAndAlpha.z;"
|
|
||||||
|
|
||||||
"vec2 eyePosition = 2.0*(outputPosition / outputTextureSize) - vec2(1.0) + vec2(0.5)/textureSize;"
|
"vec2 eyePosition = 2.0*(outputPosition / outputTextureSize) - vec2(1.0) + vec2(0.5)/textureSize;"
|
||||||
"gl_Position = vec4(eyePosition, 0.0, 1.0);"
|
"gl_Position = vec4(eyePosition, 0.0, 1.0);"
|
||||||
@ -390,7 +436,6 @@ char *OpenGLOutputBuilder::get_input_fragment_shader()
|
|||||||
"in vec2 inputPositionVarying;"
|
"in vec2 inputPositionVarying;"
|
||||||
"in vec2 iInputPositionVarying;"
|
"in vec2 iInputPositionVarying;"
|
||||||
"in float phaseVarying;"
|
"in float phaseVarying;"
|
||||||
"in float alphaVarying;"
|
|
||||||
|
|
||||||
"out vec4 fragColour;"
|
"out vec4 fragColour;"
|
||||||
|
|
||||||
@ -400,7 +445,7 @@ char *OpenGLOutputBuilder::get_input_fragment_shader()
|
|||||||
|
|
||||||
"void main(void)"
|
"void main(void)"
|
||||||
"{"
|
"{"
|
||||||
"fragColour = vec4(rgb_sample(texID, inputPositionVarying, iInputPositionVarying) * alphaVarying, 1.0);" // composite
|
"fragColour = vec4(rgb_sample(texID, inputPositionVarying, iInputPositionVarying), 1.0);"
|
||||||
"}"
|
"}"
|
||||||
, composite_shader);
|
, composite_shader);
|
||||||
return result;
|
return result;
|
||||||
|
@ -60,7 +60,7 @@ class OpenGLOutputBuilder {
|
|||||||
std::shared_ptr<std::mutex> _output_mutex;
|
std::shared_ptr<std::mutex> _output_mutex;
|
||||||
|
|
||||||
// transient buffers indicating composite data not yet decoded
|
// transient buffers indicating composite data not yet decoded
|
||||||
uint16_t _composite_src_output_y;
|
uint16_t _composite_src_output_y, _cleared_composite_output_y;
|
||||||
|
|
||||||
char *get_output_vertex_shader(const char *header);
|
char *get_output_vertex_shader(const char *header);
|
||||||
char *get_rgb_output_vertex_shader();
|
char *get_rgb_output_vertex_shader();
|
||||||
@ -150,12 +150,12 @@ class OpenGLOutputBuilder {
|
|||||||
|
|
||||||
inline uint16_t get_composite_output_y()
|
inline uint16_t get_composite_output_y()
|
||||||
{
|
{
|
||||||
return _composite_src_output_y;
|
return _composite_src_output_y % IntermediateBufferHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void increment_composite_output_y()
|
inline void increment_composite_output_y()
|
||||||
{
|
{
|
||||||
_composite_src_output_y = (_composite_src_output_y + 1) % IntermediateBufferHeight;
|
_composite_src_output_y++;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void increment_field()
|
inline void increment_field()
|
||||||
|
Loading…
Reference in New Issue
Block a user