mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Started edging towards the necessary flexibility for the other two intermediate shaders.
This commit is contained in:
parent
4b9985626d
commit
23ce032ba1
@ -106,6 +106,7 @@ 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_phase(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAmplitudeAndOffset + 0]
|
||||
#define source_amplitude(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAmplitudeAndOffset + 1]
|
||||
#define source_offset(v) next_run[SourceVertexSize*v + SourceVertexOffsetOfPhaseAmplitudeAndOffset + 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)
|
||||
@ -164,6 +165,8 @@ 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_offset(0) = 0;
|
||||
source_offset(1) = 255;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,9 +381,10 @@ void OpenGLOutputBuilder::set_rgb_sampling_function(const char *shader)
|
||||
|
||||
#pragma mark - Input vertex shader (i.e. from source data to intermediate line layout)
|
||||
|
||||
char *OpenGLOutputBuilder::get_input_vertex_shader()
|
||||
char *OpenGLOutputBuilder::get_input_vertex_shader(const char *input_position)
|
||||
{
|
||||
return strdup(
|
||||
char *result;
|
||||
asprintf(&result,
|
||||
"#version 150\n"
|
||||
|
||||
"in vec2 inputPosition;"
|
||||
@ -394,6 +395,7 @@ char *OpenGLOutputBuilder::get_input_vertex_shader()
|
||||
"uniform float phaseCyclesPerTick;"
|
||||
"uniform usampler2D texID;"
|
||||
"uniform ivec2 outputTextureSize;"
|
||||
"uniform float extension;"
|
||||
|
||||
"out vec2 inputPositionVarying;"
|
||||
"out vec2 iInputPositionVarying;"
|
||||
@ -402,16 +404,21 @@ char *OpenGLOutputBuilder::get_input_vertex_shader()
|
||||
|
||||
"void main(void)"
|
||||
"{"
|
||||
"vec2 extensionVector = vec2(extension, 0.0) * 2.0 * (phaseAmplitudeAndOffset.z - 0.5);"
|
||||
"vec2 extendedInputPosition = %s + extensionVector;"
|
||||
"vec2 extendedOutputPosition = outputPosition + extensionVector;"
|
||||
|
||||
"ivec2 textureSize = textureSize(texID, 0);"
|
||||
"iInputPositionVarying = inputPosition;"
|
||||
"inputPositionVarying = (inputPosition + vec2(0.0, 0.5)) / vec2(textureSize);"
|
||||
"iInputPositionVarying = extendedInputPosition;"
|
||||
"inputPositionVarying = (extendedInputPosition + vec2(0.0, 0.5)) / vec2(textureSize);"
|
||||
|
||||
"phaseVarying = (phaseCyclesPerTick * (outputPosition.x - phaseTime) + phaseAmplitudeAndOffset.x) * 2.0 * 3.141592654;"
|
||||
"amplitudeVarying = phaseAmplitudeAndOffset.y;"
|
||||
|
||||
"vec2 eyePosition = 2.0*(outputPosition / outputTextureSize) - vec2(1.0) + vec2(0.5)/textureSize;"
|
||||
"vec2 eyePosition = 2.0*(extendedOutputPosition / outputTextureSize) - vec2(1.0) + vec2(0.5)/textureSize;"
|
||||
"gl_Position = vec4(eyePosition, 0.0, 1.0);"
|
||||
"}");
|
||||
"}", input_position);
|
||||
return result;
|
||||
}
|
||||
|
||||
char *OpenGLOutputBuilder::get_input_fragment_shader()
|
||||
@ -567,25 +574,44 @@ char *OpenGLOutputBuilder::get_output_fragment_shader(const char *sampling_funct
|
||||
|
||||
#pragma mark - Program compilation
|
||||
|
||||
void OpenGLOutputBuilder::prepare_composite_input_shader()
|
||||
std::unique_ptr<OpenGL::Shader> OpenGLOutputBuilder::prepare_intermediate_shader(const char *input_position, char *fragment_shader, GLenum texture_unit, bool extends)
|
||||
{
|
||||
char *vertex_shader = get_input_vertex_shader();
|
||||
char *fragment_shader = get_input_fragment_shader();
|
||||
std::unique_ptr<OpenGL::Shader> shader;
|
||||
char *vertex_shader = get_input_vertex_shader(input_position);
|
||||
if(vertex_shader && fragment_shader)
|
||||
{
|
||||
composite_input_shader_program = std::unique_ptr<OpenGL::Shader>(new OpenGL::Shader(vertex_shader, fragment_shader, nullptr));
|
||||
OpenGL::Shader::AttributeBinding bindings[] =
|
||||
{
|
||||
{"inputPosition", 0},
|
||||
{"outputPosition", 1},
|
||||
{"phaseAmplitudeAndOffset", 2},
|
||||
{"phaseTime", 3},
|
||||
{nullptr}
|
||||
};
|
||||
shader = std::unique_ptr<OpenGL::Shader>(new OpenGL::Shader(vertex_shader, fragment_shader, bindings));
|
||||
|
||||
GLint texIDUniform = composite_input_shader_program->get_uniform_location("texID");
|
||||
GLint phaseCyclesPerTickUniform = composite_input_shader_program->get_uniform_location("phaseCyclesPerTick");
|
||||
GLint outputTextureSizeUniform = composite_input_shader_program->get_uniform_location("outputTextureSize");
|
||||
GLint texIDUniform = shader->get_uniform_location("texID");
|
||||
GLint phaseCyclesPerTickUniform = shader->get_uniform_location("phaseCyclesPerTick");
|
||||
GLint outputTextureSizeUniform = shader->get_uniform_location("outputTextureSize");
|
||||
GLint extensionUniform = shader->get_uniform_location("extension");
|
||||
|
||||
composite_input_shader_program->bind();
|
||||
glUniform1i(texIDUniform, source_data_texture_unit - GL_TEXTURE0);
|
||||
glUniform1f(phaseCyclesPerTickUniform, (float)_colour_cycle_numerator / (float)(_colour_cycle_denominator * _cycles_per_line));
|
||||
shader->bind();
|
||||
glUniform1i(texIDUniform, (GLint)(texture_unit - GL_TEXTURE0));
|
||||
glUniform2i(outputTextureSizeUniform, IntermediateBufferWidth, IntermediateBufferHeight);
|
||||
|
||||
float phaseCyclesPerTick = (float)_colour_cycle_numerator / (float)(_colour_cycle_denominator * _cycles_per_line);
|
||||
glUniform1f(phaseCyclesPerTickUniform, phaseCyclesPerTick);
|
||||
glUniform1f(extensionUniform, extends ? ceilf(1.0f / phaseCyclesPerTick) : 0.0f);
|
||||
}
|
||||
free(vertex_shader);
|
||||
free(fragment_shader);
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void OpenGLOutputBuilder::prepare_composite_input_shader()
|
||||
{
|
||||
composite_input_shader_program = prepare_intermediate_shader("inputPosition", get_input_fragment_shader(), source_data_texture_unit, false);
|
||||
}
|
||||
|
||||
void OpenGLOutputBuilder::prepare_source_vertex_array()
|
||||
|
@ -48,7 +48,10 @@ class OpenGLOutputBuilder {
|
||||
void prepare_rgb_output_shader();
|
||||
void prepare_composite_output_shader();
|
||||
std::unique_ptr<OpenGL::Shader> prepare_output_shader(char *vertex_shader, char *fragment_shader, GLint source_texture_unit);
|
||||
|
||||
void prepare_composite_input_shader();
|
||||
std::unique_ptr<OpenGL::Shader> prepare_intermediate_shader(const char *input_position, char *fragment_shader, GLenum texture_unit, bool extends);
|
||||
|
||||
void prepare_output_vertex_array();
|
||||
void prepare_source_vertex_array();
|
||||
void push_size_uniforms(unsigned int output_width, unsigned int output_height);
|
||||
@ -70,7 +73,7 @@ class OpenGLOutputBuilder {
|
||||
char *get_rgb_output_fragment_shader();
|
||||
char *get_composite_output_fragment_shader();
|
||||
|
||||
char *get_input_vertex_shader();
|
||||
char *get_input_vertex_shader(const char *input_position);
|
||||
char *get_input_fragment_shader();
|
||||
|
||||
std::unique_ptr<OpenGL::Shader> rgb_shader_program;
|
||||
|
Loading…
x
Reference in New Issue
Block a user