1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-07 23:29:06 +00:00

Switched pervasively to using the named slot uniform setters on Shader.

This commit is contained in:
Thomas Harte 2016-05-13 22:08:32 -04:00
parent f487062c62
commit 30f335fa35
6 changed files with 160 additions and 57 deletions

View File

@ -89,15 +89,6 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *
std::unique_ptr<IntermediateShader> shader = std::unique_ptr<IntermediateShader>(new IntermediateShader(vertex_shader, fragment_shader, bindings)); std::unique_ptr<IntermediateShader> shader = std::unique_ptr<IntermediateShader>(new IntermediateShader(vertex_shader, fragment_shader, bindings));
free(vertex_shader); free(vertex_shader);
shader->texIDUniform = shader->get_uniform_location("texID");
shader->outputTextureSizeUniform = shader->get_uniform_location("outputTextureSize");
shader->phaseCyclesPerTickUniform = shader->get_uniform_location("phaseCyclesPerTick");
shader->extensionUniform = shader->get_uniform_location("extension");
shader->weightsUniform = shader->get_uniform_location("weights");
shader->rgbToLumaChromaUniform = shader->get_uniform_location("rgbToLumaChroma");
shader->lumaChromaToRGBUniform = shader->get_uniform_location("lumaChromaToRGB");
shader->offsetsUniform = shader->get_uniform_location("offsets");
return shader; return shader;
} }
@ -395,28 +386,24 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_rgb_filter_shader()
void IntermediateShader::set_output_size(unsigned int output_width, unsigned int output_height) void IntermediateShader::set_output_size(unsigned int output_width, unsigned int output_height)
{ {
bind(); set_uniform("outputTextureSize", (GLint)output_width, (GLint)output_height);
glUniform2i(outputTextureSizeUniform, (GLint)output_width, (GLint)output_height);
} }
void IntermediateShader::set_source_texture_unit(GLenum unit) void IntermediateShader::set_source_texture_unit(GLenum unit)
{ {
bind(); set_uniform("texID", (GLint)(unit - GL_TEXTURE0));
glUniform1i(texIDUniform, (GLint)(unit - GL_TEXTURE0));
} }
void IntermediateShader::set_filter_coefficients(float sampling_rate, float cutoff_frequency) void IntermediateShader::set_filter_coefficients(float sampling_rate, float cutoff_frequency)
{ {
bind();
// The process below: the source texture will have bilinear filtering enabled; so by // The process below: the source texture will have bilinear filtering enabled; so by
// sampling at non-integral offsets from the centre the shader can get a weighted sum // sampling at non-integral offsets from the centre the shader can get a weighted sum
// of two source pixels, then scale that once, to do two taps per sample. However // of two source pixels, then scale that once, to do two taps per sample. However
// that works only if the two coefficients being joined have the same sign. So the // that works only if the two coefficients being joined have the same sign. So the
// number of usable taps is between 11 and 21 depending on the values that come out. // number of usable taps is between 11 and 21 depending on the values that come out.
// Perform a linear search for the highest number of taps we can use with 11 samples. // Perform a linear search for the highest number of taps we can use with 11 samples.
float weights[12]; GLfloat weights[12];
float offsets[5]; GLfloat offsets[5];
unsigned int taps = 21; unsigned int taps = 21;
while(1) while(1)
{ {
@ -458,26 +445,23 @@ void IntermediateShader::set_filter_coefficients(float sampling_rate, float cuto
taps -= 2; taps -= 2;
} }
glUniform4fv(weightsUniform, 3, weights); set_uniform("weights", 4, 3, weights);
glUniform1fv(offsetsUniform, 5, offsets); set_uniform("offsets", 1, 5, offsets);
} }
void IntermediateShader::set_separation_frequency(float sampling_rate, float colour_burst_frequency) void IntermediateShader::set_separation_frequency(float sampling_rate, float colour_burst_frequency)
{ {
// TODO: apply separately-formed filters for luminance and chrominance
set_filter_coefficients(sampling_rate, colour_burst_frequency); set_filter_coefficients(sampling_rate, colour_burst_frequency);
} }
void IntermediateShader::set_phase_cycles_per_sample(float phase_cycles_per_sample, bool extend_runs_to_full_cycle) void IntermediateShader::set_phase_cycles_per_sample(float phase_cycles_per_sample, bool extend_runs_to_full_cycle)
{ {
bind(); set_uniform("phaseCyclesPerTick", (GLfloat)phase_cycles_per_sample);
glUniform1f(phaseCyclesPerTickUniform, phase_cycles_per_sample); set_uniform("extension", extend_runs_to_full_cycle ? ceilf(1.0f / phase_cycles_per_sample) : 0.0f);
glUniform1f(extensionUniform, extend_runs_to_full_cycle ? ceilf(1.0f / phase_cycles_per_sample) : 0.0f);
} }
void IntermediateShader::set_colour_conversion_matrices(float *fromRGB, float *toRGB) void IntermediateShader::set_colour_conversion_matrices(float *fromRGB, float *toRGB)
{ {
bind(); set_uniform_matrix("lumaChromaToRGB", 3, false, toRGB);
glUniformMatrix3fv(lumaChromaToRGBUniform, 1, GL_FALSE, toRGB); set_uniform_matrix("rgbToLumaChroma", 3, false, fromRGB);
glUniformMatrix3fv(rgbToLumaChromaUniform, 1, GL_FALSE, fromRGB);
} }

View File

@ -88,15 +88,6 @@ public:
private: private:
static std::unique_ptr<IntermediateShader> make_shader(const char *fragment_shader, bool use_usampler, bool input_is_inputPosition); static std::unique_ptr<IntermediateShader> make_shader(const char *fragment_shader, bool use_usampler, bool input_is_inputPosition);
GLint texIDUniform;
GLint outputTextureSizeUniform;
GLint weightsUniform;
GLint phaseCyclesPerTickUniform;
GLint extensionUniform;
GLint rgbToLumaChromaUniform;
GLint lumaChromaToRGBUniform;
GLint offsetsUniform;
}; };
} }

View File

@ -86,45 +86,34 @@ std::unique_ptr<OutputShader> OutputShader::make_shader(const char *fragment_met
free(vertex_shader); free(vertex_shader);
free(fragment_shader); free(fragment_shader);
result->boundsSizeUniform = result->get_uniform_location("boundsSize");
result->boundsOriginUniform = result->get_uniform_location("boundsOrigin");
result->texIDUniform = result->get_uniform_location("texID");
result->scanNormalUniform = result->get_uniform_location("scanNormal");
result->positionConversionUniform = result->get_uniform_location("positionConversion");
return result; return result;
} }
void OutputShader::set_output_size(unsigned int output_width, unsigned int output_height, Outputs::CRT::Rect visible_area) void OutputShader::set_output_size(unsigned int output_width, unsigned int output_height, Outputs::CRT::Rect visible_area)
{ {
bind();
GLfloat outputAspectRatioMultiplier = ((float)output_width / (float)output_height) / (4.0f / 3.0f); GLfloat outputAspectRatioMultiplier = ((float)output_width / (float)output_height) / (4.0f / 3.0f);
GLfloat bonusWidth = (outputAspectRatioMultiplier - 1.0f) * visible_area.size.width; GLfloat bonusWidth = (outputAspectRatioMultiplier - 1.0f) * visible_area.size.width;
visible_area.origin.x -= bonusWidth * 0.5f * visible_area.size.width; visible_area.origin.x -= bonusWidth * 0.5f * visible_area.size.width;
visible_area.size.width *= outputAspectRatioMultiplier; visible_area.size.width *= outputAspectRatioMultiplier;
glUniform2f(boundsOriginUniform, (GLfloat)visible_area.origin.x, (GLfloat)visible_area.origin.y); set_uniform("boundsOrigin", (GLfloat)visible_area.origin.x, (GLfloat)visible_area.origin.y);
glUniform2f(boundsSizeUniform, (GLfloat)visible_area.size.width, (GLfloat)visible_area.size.height); set_uniform("boundsSize", (GLfloat)visible_area.size.width, (GLfloat)visible_area.size.height);
} }
void OutputShader::set_source_texture_unit(GLenum unit) void OutputShader::set_source_texture_unit(GLenum unit)
{ {
bind(); set_uniform("texID", (GLint)(unit - GL_TEXTURE0));
glUniform1i(texIDUniform, (GLint)(unit - GL_TEXTURE0));
} }
void OutputShader::set_timing(unsigned int height_of_display, unsigned int cycles_per_line, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider) void OutputShader::set_timing(unsigned int height_of_display, unsigned int cycles_per_line, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider)
{ {
bind(); GLfloat scan_angle = atan2f(1.0f / (float)height_of_display, 1.0f);
GLfloat scan_normal[] = { -sinf(scan_angle), cosf(scan_angle)};
float scan_angle = atan2f(1.0f / (float)height_of_display, 1.0f); GLfloat multiplier = (float)cycles_per_line / ((float)height_of_display * (float)horizontal_scan_period);
float scan_normal[] = { -sinf(scan_angle), cosf(scan_angle)};
float multiplier = (float)cycles_per_line / ((float)height_of_display * (float)horizontal_scan_period);
scan_normal[0] *= multiplier; scan_normal[0] *= multiplier;
scan_normal[1] *= multiplier; scan_normal[1] *= multiplier;
glUniform2f(scanNormalUniform, scan_normal[0], scan_normal[1]); set_uniform("scanNormal", scan_normal[0], scan_normal[1]);
glUniform2f(positionConversionUniform, horizontal_scan_period, vertical_scan_period / (unsigned int)vertical_period_divider); set_uniform("positionConversion", (GLfloat)horizontal_scan_period, (GLfloat)vertical_scan_period / (GLfloat)vertical_period_divider);
} }

View File

@ -56,9 +56,6 @@ public:
Binds this shader and configures its understanding of how to map from the source vertex stream to screen coordinates. Binds this shader and configures its understanding of how to map from the source vertex stream to screen coordinates.
*/ */
void set_timing(unsigned int height_of_display, unsigned int cycles_per_line, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider); void set_timing(unsigned int height_of_display, unsigned int cycles_per_line, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider);
private:
GLint boundsOriginUniform, boundsSizeUniform, texIDUniform, scanNormalUniform, positionConversionUniform;
}; };
} }

View File

@ -120,3 +120,119 @@ void Shader::enable_vertex_attribute_with_pointer(const char *name, GLint size,
glVertexAttribPointer((GLuint)location, size, type, normalised, stride, pointer); glVertexAttribPointer((GLuint)location, size, type, normalised, stride, pointer);
glVertexAttribDivisor((GLuint)location, divisor); glVertexAttribDivisor((GLuint)location, divisor);
} }
// The various set_uniforms...
GLint Shader::location_for_bound_uniform(const GLchar *name)
{
bind();
return glGetUniformLocation(_shader_program, name);
}
void Shader::set_uniform(const GLchar *name, GLint value)
{
glUniform1i(location_for_bound_uniform(name), value);
}
void Shader::set_uniform(const GLchar *name, GLint value1, GLint value2)
{
glUniform2i(location_for_bound_uniform(name), value1, value2);
}
void Shader::set_uniform(const GLchar *name, GLint value1, GLint value2, GLint value3)
{
glUniform3i(location_for_bound_uniform(name), value1, value2, value3);
}
void Shader::set_uniform(const GLchar *name, GLint value1, GLint value2, GLint value3, GLint value4)
{
glUniform4i(location_for_bound_uniform(name), value1, value2, value3, value4);
}
void Shader::set_uniform(const GLchar *name, GLint size, GLsizei count, const GLint *values)
{
switch(size)
{
case 1: glUniform1iv(location_for_bound_uniform(name), count, values); break;
case 2: glUniform2iv(location_for_bound_uniform(name), count, values); break;
case 3: glUniform3iv(location_for_bound_uniform(name), count, values); break;
case 4: glUniform4iv(location_for_bound_uniform(name), count, values); break;
}
}
void Shader::set_uniform(const GLchar *name, GLfloat value)
{
glUniform1f(location_for_bound_uniform(name), value);
}
void Shader::set_uniform(const GLchar *name, GLfloat value1, GLfloat value2)
{
glUniform2f(location_for_bound_uniform(name), value1, value2);
}
void Shader::set_uniform(const GLchar *name, GLfloat value1, GLfloat value2, GLfloat value3)
{
glUniform3f(location_for_bound_uniform(name), value1, value2, value3);
}
void Shader::set_uniform(const GLchar *name, GLfloat value1, GLfloat value2, GLfloat value3, GLfloat value4)
{
glUniform4f(location_for_bound_uniform(name), value1, value2, value3, value4);
}
void Shader::set_uniform(const GLchar *name, GLint size, GLsizei count, const GLfloat *values)
{
switch(size)
{
case 1: glUniform1fv(location_for_bound_uniform(name), count, values); break;
case 2: glUniform2fv(location_for_bound_uniform(name), count, values); break;
case 3: glUniform3fv(location_for_bound_uniform(name), count, values); break;
case 4: glUniform4fv(location_for_bound_uniform(name), count, values); break;
}
}
void Shader::set_uniform(const GLchar *name, GLuint value)
{
glUniform1ui(location_for_bound_uniform(name), value);
}
void Shader::set_uniform(const GLchar *name, GLuint value1, GLuint value2)
{
glUniform2ui(location_for_bound_uniform(name), value1, value2);
}
void Shader::set_uniform(const GLchar *name, GLuint value1, GLuint value2, GLuint value3)
{
glUniform3ui(location_for_bound_uniform(name), value1, value2, value3);
}
void Shader::set_uniform(const GLchar *name, GLuint value1, GLuint value2, GLuint value3, GLuint value4)
{
glUniform4ui(location_for_bound_uniform(name), value1, value2, value3, value4);
}
void Shader::set_uniform(const GLchar *name, GLint size, GLsizei count, const GLuint *values)
{
switch(size)
{
case 1: glUniform1uiv(location_for_bound_uniform(name), count, values); break;
case 2: glUniform2uiv(location_for_bound_uniform(name), count, values); break;
case 3: glUniform3uiv(location_for_bound_uniform(name), count, values); break;
case 4: glUniform4uiv(location_for_bound_uniform(name), count, values); break;
}
}
void Shader::set_uniform_matrix(const GLchar *name, GLint size, bool transpose, const GLfloat *values)
{
set_uniform_matrix(name, size, 1, transpose, values);
}
void Shader::set_uniform_matrix(const GLchar *name, GLint size, GLsizei count, bool transpose, const GLfloat *values)
{
GLboolean glTranspose = transpose ? GL_TRUE : GL_FALSE;
switch(size)
{
case 2: glUniformMatrix2fv(location_for_bound_uniform(name), count, glTranspose, values); break;
case 3: glUniformMatrix3fv(location_for_bound_uniform(name), count, glTranspose, values); break;
case 4: glUniformMatrix4fv(location_for_bound_uniform(name), count, glTranspose, values); break;
}
}

View File

@ -75,9 +75,35 @@ public:
*/ */
void enable_vertex_attribute_with_pointer(const char *name, GLint size, GLenum type, GLboolean normalised, GLsizei stride, const GLvoid *pointer, GLuint divisor); void enable_vertex_attribute_with_pointer(const char *name, GLint size, GLenum type, GLboolean normalised, GLsizei stride, const GLvoid *pointer, GLuint divisor);
/*!
All @c set_uniforms bind the current shader, look up the uniform by name and set the supplied value or values.
*/
void set_uniform(const GLchar *name, GLint value);
void set_uniform(const GLchar *name, GLint value1, GLint value2);
void set_uniform(const GLchar *name, GLint value1, GLint value2, GLint value3);
void set_uniform(const GLchar *name, GLint value1, GLint value2, GLint value3, GLint value4);
void set_uniform(const GLchar *name, GLint size, GLsizei count, const GLint *values);
void set_uniform(const GLchar *name, GLfloat value);
void set_uniform(const GLchar *name, GLfloat value1, GLfloat value2);
void set_uniform(const GLchar *name, GLfloat value1, GLfloat value2, GLfloat value3);
void set_uniform(const GLchar *name, GLfloat value1, GLfloat value2, GLfloat value3, GLfloat value4);
void set_uniform(const GLchar *name, GLint size, GLsizei count, const GLfloat *values);
void set_uniform(const GLchar *name, GLuint value);
void set_uniform(const GLchar *name, GLuint value1, GLuint value2);
void set_uniform(const GLchar *name, GLuint value1, GLuint value2, GLuint value3);
void set_uniform(const GLchar *name, GLuint value1, GLuint value2, GLuint value3, GLuint value4);
void set_uniform(const GLchar *name, GLint size, GLsizei count, const GLuint *values);
void set_uniform_matrix(const GLchar *name, GLint size, bool transpose, const GLfloat *values);
void set_uniform_matrix(const GLchar *name, GLint size, GLsizei count, bool transpose, const GLfloat *values);
private: private:
GLuint compile_shader(const char *source, GLenum type); GLuint compile_shader(const char *source, GLenum type);
GLuint _shader_program; GLuint _shader_program;
GLint location_for_bound_uniform(const GLchar *name);
}; };
} }