1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-04 18:29:40 +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));
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;
}
@ -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)
{
bind();
glUniform2i(outputTextureSizeUniform, (GLint)output_width, (GLint)output_height);
set_uniform("outputTextureSize", (GLint)output_width, (GLint)output_height);
}
void IntermediateShader::set_source_texture_unit(GLenum unit)
{
bind();
glUniform1i(texIDUniform, (GLint)(unit - GL_TEXTURE0));
set_uniform("texID", (GLint)(unit - GL_TEXTURE0));
}
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
// 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
// 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.
// Perform a linear search for the highest number of taps we can use with 11 samples.
float weights[12];
float offsets[5];
GLfloat weights[12];
GLfloat offsets[5];
unsigned int taps = 21;
while(1)
{
@ -458,26 +445,23 @@ void IntermediateShader::set_filter_coefficients(float sampling_rate, float cuto
taps -= 2;
}
glUniform4fv(weightsUniform, 3, weights);
glUniform1fv(offsetsUniform, 5, offsets);
set_uniform("weights", 4, 3, weights);
set_uniform("offsets", 1, 5, offsets);
}
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);
}
void IntermediateShader::set_phase_cycles_per_sample(float phase_cycles_per_sample, bool extend_runs_to_full_cycle)
{
bind();
glUniform1f(phaseCyclesPerTickUniform, phase_cycles_per_sample);
glUniform1f(extensionUniform, extend_runs_to_full_cycle ? ceilf(1.0f / phase_cycles_per_sample) : 0.0f);
set_uniform("phaseCyclesPerTick", (GLfloat)phase_cycles_per_sample);
set_uniform("extension", extend_runs_to_full_cycle ? ceilf(1.0f / phase_cycles_per_sample) : 0.0f);
}
void IntermediateShader::set_colour_conversion_matrices(float *fromRGB, float *toRGB)
{
bind();
glUniformMatrix3fv(lumaChromaToRGBUniform, 1, GL_FALSE, toRGB);
glUniformMatrix3fv(rgbToLumaChromaUniform, 1, GL_FALSE, fromRGB);
set_uniform_matrix("lumaChromaToRGB", 3, false, toRGB);
set_uniform_matrix("rgbToLumaChroma", 3, false, fromRGB);
}

View File

@ -88,15 +88,6 @@ public:
private:
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(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;
}
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 bonusWidth = (outputAspectRatioMultiplier - 1.0f) * visible_area.size.width;
visible_area.origin.x -= bonusWidth * 0.5f * visible_area.size.width;
visible_area.size.width *= outputAspectRatioMultiplier;
glUniform2f(boundsOriginUniform, (GLfloat)visible_area.origin.x, (GLfloat)visible_area.origin.y);
glUniform2f(boundsSizeUniform, (GLfloat)visible_area.size.width, (GLfloat)visible_area.size.height);
set_uniform("boundsOrigin", (GLfloat)visible_area.origin.x, (GLfloat)visible_area.origin.y);
set_uniform("boundsSize", (GLfloat)visible_area.size.width, (GLfloat)visible_area.size.height);
}
void OutputShader::set_source_texture_unit(GLenum unit)
{
bind();
glUniform1i(texIDUniform, (GLint)(unit - GL_TEXTURE0));
set_uniform("texID", (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)
{
bind();
float scan_angle = atan2f(1.0f / (float)height_of_display, 1.0f);
float scan_normal[] = { -sinf(scan_angle), cosf(scan_angle)};
float multiplier = (float)cycles_per_line / ((float)height_of_display * (float)horizontal_scan_period);
GLfloat scan_angle = atan2f(1.0f / (float)height_of_display, 1.0f);
GLfloat scan_normal[] = { -sinf(scan_angle), cosf(scan_angle)};
GLfloat multiplier = (float)cycles_per_line / ((float)height_of_display * (float)horizontal_scan_period);
scan_normal[0] *= multiplier;
scan_normal[1] *= multiplier;
glUniform2f(scanNormalUniform, scan_normal[0], scan_normal[1]);
glUniform2f(positionConversionUniform, horizontal_scan_period, vertical_scan_period / (unsigned int)vertical_period_divider);
set_uniform("scanNormal", scan_normal[0], scan_normal[1]);
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.
*/
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);
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);
/*!
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:
GLuint compile_shader(const char *source, GLenum type);
GLuint _shader_program;
GLint location_for_bound_uniform(const GLchar *name);
};
}