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

Made an attempt to queue uniform changes until the next call to bind. That's to allow usage from other threads.

This commit is contained in:
Thomas Harte 2016-05-14 18:06:55 -04:00
parent cca53598d3
commit 492dc7ccbf
2 changed files with 132 additions and 81 deletions

View File

@ -95,6 +95,7 @@ void Shader::bind()
glUseProgram(_shader_program);
bound_shader = this;
}
flush_functions();
}
void Shader::unbind()
@ -122,117 +123,162 @@ void Shader::enable_vertex_attribute_with_pointer(const char *name, GLint size,
}
// The various set_uniforms...
GLint Shader::location_for_bound_uniform(const GLchar *name)
#define location() glGetUniformLocation(_shader_program, name.c_str())
void Shader::set_uniform(const std::string &name, GLint value)
{
bind();
return glGetUniformLocation(_shader_program, name);
enqueue_function([name, value, this] {
glUniform1i(location(), value);
});
}
void Shader::set_uniform(const GLchar *name, GLint value)
void Shader::set_uniform(const std::string &name, GLuint value)
{
glUniform1i(location_for_bound_uniform(name), value);
enqueue_function([name, value, this] {
glUniform1ui(location(), value);
});
}
void Shader::set_uniform(const GLchar *name, GLint value1, GLint value2)
void Shader::set_uniform(const std::string &name, GLfloat value)
{
glUniform2i(location_for_bound_uniform(name), value1, value2);
enqueue_function([name, value, this] {
glUniform1f(location(), value);
});
}
void Shader::set_uniform(const GLchar *name, GLint value1, GLint value2, GLint value3)
void Shader::set_uniform(const std::string &name, GLint value1, GLint value2)
{
glUniform3i(location_for_bound_uniform(name), value1, value2, value3);
enqueue_function([name, value1, value2, this] {
glUniform2i(location(), value1, value2);
});
}
void Shader::set_uniform(const GLchar *name, GLint value1, GLint value2, GLint value3, GLint value4)
void Shader::set_uniform(const std::string &name, GLfloat value1, GLfloat value2)
{
glUniform4i(location_for_bound_uniform(name), value1, value2, value3, value4);
enqueue_function([name, value1, value2, this] {
glUniform2f(location(), value1, value2);
});
}
void Shader::set_uniform(const GLchar *name, GLint size, GLsizei count, const GLint *values)
void Shader::set_uniform(const std::string &name, GLuint value1, GLuint value2)
{
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;
}
enqueue_function([name, value1, value2, this] {
glUniform2ui(location(), value1, value2);
});
}
void Shader::set_uniform(const GLchar *name, GLfloat value)
void Shader::set_uniform(const std::string &name, GLint value1, GLint value2, GLint value3)
{
glUniform1f(location_for_bound_uniform(name), value);
enqueue_function([name, value1, value2, value3, this] {
glUniform3i(location(), value1, value2, value3);
});
}
void Shader::set_uniform(const GLchar *name, GLfloat value1, GLfloat value2)
void Shader::set_uniform(const std::string &name, GLfloat value1, GLfloat value2, GLfloat value3)
{
glUniform2f(location_for_bound_uniform(name), value1, value2);
enqueue_function([name, value1, value2, value3, this] {
glUniform3f(location(), value1, value2, value3);
});
}
void Shader::set_uniform(const GLchar *name, GLfloat value1, GLfloat value2, GLfloat value3)
void Shader::set_uniform(const std::string &name, GLuint value1, GLuint value2, GLuint value3)
{
glUniform3f(location_for_bound_uniform(name), value1, value2, value3);
enqueue_function([name, value1, value2, value3, this] {
glUniform3ui(location(), value1, value2, value3);
});
}
void Shader::set_uniform(const GLchar *name, GLfloat value1, GLfloat value2, GLfloat value3, GLfloat value4)
void Shader::set_uniform(const std::string &name, GLint value1, GLint value2, GLint value3, GLint value4)
{
glUniform4f(location_for_bound_uniform(name), value1, value2, value3, value4);
enqueue_function([name, value1, value2, value3, value4, this] {
glUniform4i(location(), value1, value2, value3, value4);
});
}
void Shader::set_uniform(const GLchar *name, GLint size, GLsizei count, const GLfloat *values)
void Shader::set_uniform(const std::string &name, GLfloat value1, GLfloat value2, GLfloat value3, GLfloat value4)
{
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;
}
enqueue_function([name, value1, value2, value3, value4, this] {
glUniform4f(location(), value1, value2, value3, value4);
});
}
void Shader::set_uniform(const GLchar *name, GLuint value)
void Shader::set_uniform(const std::string &name, GLuint value1, GLuint value2, GLuint value3, GLuint value4)
{
glUniform1ui(location_for_bound_uniform(name), value);
enqueue_function([name, value1, value2, value3, value4, this] {
glUniform4ui(location(), value1, value2, value3, value4);
});
}
void Shader::set_uniform(const GLchar *name, GLuint value1, GLuint value2)
void Shader::set_uniform(const std::string &name, GLint size, GLsizei count, const GLint *values)
{
glUniform2ui(location_for_bound_uniform(name), value1, value2);
enqueue_function([name, size, count, values, this] {
switch(size)
{
case 1: glUniform1iv(location(), count, values); break;
case 2: glUniform2iv(location(), count, values); break;
case 3: glUniform3iv(location(), count, values); break;
case 4: glUniform4iv(location(), count, values); break;
}
});
}
void Shader::set_uniform(const GLchar *name, GLuint value1, GLuint value2, GLuint value3)
void Shader::set_uniform(const std::string &name, GLint size, GLsizei count, const GLfloat *values)
{
glUniform3ui(location_for_bound_uniform(name), value1, value2, value3);
enqueue_function([name, size, count, values, this] {
switch(size)
{
case 1: glUniform1fv(location(), count, values); break;
case 2: glUniform2fv(location(), count, values); break;
case 3: glUniform3fv(location(), count, values); break;
case 4: glUniform4fv(location(), count, values); break;
}
});
}
void Shader::set_uniform(const GLchar *name, GLuint value1, GLuint value2, GLuint value3, GLuint value4)
void Shader::set_uniform(const std::string &name, GLint size, GLsizei count, const GLuint *values)
{
glUniform4ui(location_for_bound_uniform(name), value1, value2, value3, value4);
enqueue_function([name, size, count, values, this] {
switch(size)
{
case 1: glUniform1uiv(location(), count, values); break;
case 2: glUniform2uiv(location(), count, values); break;
case 3: glUniform3uiv(location(), count, values); break;
case 4: glUniform4uiv(location(), count, values); break;
}
});
}
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)
void Shader::set_uniform_matrix(const std::string &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)
void Shader::set_uniform_matrix(const std::string &name, GLint size, GLsizei count, bool transpose, const GLfloat *values)
{
enqueue_function([name, size, count, transpose, values, this] {
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;
}
switch(size)
{
case 2: glUniformMatrix2fv(location(), count, glTranspose, values); break;
case 3: glUniformMatrix3fv(location(), count, glTranspose, values); break;
case 4: glUniformMatrix4fv(location(), count, glTranspose, values); break;
}
});
}
void Shader::enqueue_function(std::function<void(void)> function)
{
_enqueued_functions.push_back(function);
}
void Shader::flush_functions()
{
for(std::function<void(void)> function : _enqueued_functions)
{
function();
}
_enqueued_functions.clear();
}

View File

@ -10,6 +10,9 @@
#define Shader_hpp
#include "OpenGL.hpp"
#include <string>
#include <functional>
#include <list>
namespace OpenGL {
@ -76,34 +79,36 @@ 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.
All @c set_uniforms queue up the requested uniform changes. Changes are applied automatically the next time the shader is bound.
*/
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 std::string &name, GLint value);
void set_uniform(const std::string &name, GLint value1, GLint value2);
void set_uniform(const std::string &name, GLint value1, GLint value2, GLint value3);
void set_uniform(const std::string &name, GLint value1, GLint value2, GLint value3, GLint value4);
void set_uniform(const std::string &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 std::string &name, GLfloat value);
void set_uniform(const std::string &name, GLfloat value1, GLfloat value2);
void set_uniform(const std::string &name, GLfloat value1, GLfloat value2, GLfloat value3);
void set_uniform(const std::string &name, GLfloat value1, GLfloat value2, GLfloat value3, GLfloat value4);
void set_uniform(const std::string &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(const std::string &name, GLuint value);
void set_uniform(const std::string &name, GLuint value1, GLuint value2);
void set_uniform(const std::string &name, GLuint value1, GLuint value2, GLuint value3);
void set_uniform(const std::string &name, GLuint value1, GLuint value2, GLuint value3, GLuint value4);
void set_uniform(const std::string &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);
void set_uniform_matrix(const std::string &name, GLint size, bool transpose, const GLfloat *values);
void set_uniform_matrix(const std::string &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);
void enqueue_function(std::function<void(void)> function);
void flush_functions();
std::list<std::function<void(void)>> _enqueued_functions;
};
}