diff --git a/docs/src/refman/shader.txt b/docs/src/refman/shader.txt index 1eb273062..f47f291a5 100644 --- a/docs/src/refman/shader.txt +++ b/docs/src/refman/shader.txt @@ -263,8 +263,9 @@ is incompatible with the target bitmap. Since: 5.1.6 See also: [al_destroy_shader], [al_set_shader_sampler], [al_set_shader_matrix], -[al_set_shader_int], [al_set_shader_float], [al_set_shader_bool], -[al_set_shader_int_vector], [al_set_shader_float_vector], [al_get_current_shader] +[al_set_shader_int], [al_set_shader_float], [al_set_shader_double], [al_set_shader_bool], +[al_set_shader_int_vector], [al_set_shader_float_vector], [al_set_shader_double_vector], +[al_get_current_shader] ## API: al_get_current_shader @@ -343,6 +344,20 @@ Since: 5.1.0 See also: [al_use_shader] +## API: al_set_shader_double + +Sets a double uniform of the target bitmap's shader. + +Returns true on success. Otherwise returns false, e.g. if the uniform by that +name does not exist in the shader. + +> *Note:* This is not supported on Direct3D backend. The function succeeds, but +> values are passed as floats. + +Since: 5.2.11 + +See also: [al_use_shader] + ## API: al_set_shader_bool Sets a boolean uniform of the target bitmap's shader. @@ -382,7 +397,7 @@ name does not exist in the shader. Since: 5.1.0 -See also: [al_set_shader_float_vector], [al_use_shader] +See also: [al_set_shader_float_vector], [al_set_shader_double_vector], [al_use_shader] ## API: al_set_shader_float_vector @@ -390,6 +405,15 @@ Same as [al_set_shader_int_vector] except all values are float instead of int. Since: 5.1.0 +## API: al_set_shader_double_vector + +Same as [al_set_shader_int_vector] except all values are double instead of int. + +> *Note:* This is not supported on Direct3D backend. The function succeeds, but +> values are passed as floats. + +Since: 5.2.11 + See also: [al_set_shader_int_vector], [al_use_shader] ## API: al_get_default_shader_source diff --git a/include/allegro5/internal/aintern_shader.h b/include/allegro5/internal/aintern_shader.h index fa97e4ce5..74442dae2 100644 --- a/include/allegro5/internal/aintern_shader.h +++ b/include/allegro5/internal/aintern_shader.h @@ -28,10 +28,13 @@ struct ALLEGRO_SHADER_INTERFACE const ALLEGRO_TRANSFORM *matrix); bool (*set_shader_int)(ALLEGRO_SHADER *shader, const char *name, int i); bool (*set_shader_float)(ALLEGRO_SHADER *shader, const char *name, float f); + bool (*set_shader_double)(ALLEGRO_SHADER *shader, const char *name, double d); bool (*set_shader_int_vector)(ALLEGRO_SHADER *shader, const char *name, int elem_size, const int *i, int num_elems); bool (*set_shader_float_vector)(ALLEGRO_SHADER *shader, const char *name, int elem_size, const float *f, int num_elems); + bool (*set_shader_double_vector)(ALLEGRO_SHADER *shader, const char *name, + int elem_size, const double *d, int num_elems); bool (*set_shader_bool)(ALLEGRO_SHADER *shader, const char *name, bool b); }; diff --git a/include/allegro5/shader.h b/include/allegro5/shader.h index 61cb9bf49..bc353ba0f 100644 --- a/include/allegro5/shader.h +++ b/include/allegro5/shader.h @@ -68,10 +68,13 @@ AL_FUNC(bool, al_set_shader_matrix, (const char *name, const ALLEGRO_TRANSFORM *matrix)); AL_FUNC(bool, al_set_shader_int, (const char *name, int i)); AL_FUNC(bool, al_set_shader_float, (const char *name, float f)); +AL_FUNC(bool, al_set_shader_double, (const char *name, double f)); AL_FUNC(bool, al_set_shader_int_vector, (const char *name, int num_components, const int *i, int num_elems)); AL_FUNC(bool, al_set_shader_float_vector, (const char *name, int num_components, const float *f, int num_elems)); +AL_FUNC(bool, al_set_shader_double_vector, (const char *name, int num_components, + const double *f, int num_elems)); AL_FUNC(bool, al_set_shader_bool, (const char *name, bool b)); AL_FUNC(char const *, al_get_default_shader_source, (ALLEGRO_SHADER_PLATFORM platform, diff --git a/src/opengl/ogl_shader.c b/src/opengl/ogl_shader.c index 21762c2ae..78498bd8a 100644 --- a/src/opengl/ogl_shader.c +++ b/src/opengl/ogl_shader.c @@ -342,6 +342,24 @@ static bool glsl_set_shader_float(ALLEGRO_SHADER *shader, return check_gl_error(name); } +static bool glsl_set_shader_double(ALLEGRO_SHADER *shader, + const char *name, double d) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + GLint handle; + + handle = glGetUniformLocation(gl_shader->program_object, name); + + if (handle < 0) { + ALLEGRO_WARN("No uniform variable '%s' in shader program\n", name); + return false; + } + + glUniform1d(handle, d); + + return check_gl_error(name); +} + static bool glsl_set_shader_int_vector(ALLEGRO_SHADER *shader, const char *name, int num_components, const int *i, int num_elems) { @@ -410,6 +428,41 @@ static bool glsl_set_shader_float_vector(ALLEGRO_SHADER *shader, return check_gl_error(name); } + +static bool glsl_set_shader_double_vector(ALLEGRO_SHADER *shader, + const char *name, int num_components, const double *d, int num_elems) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + GLint handle; + + handle = glGetUniformLocation(gl_shader->program_object, name); + + if (handle < 0) { + ALLEGRO_WARN("No uniform variable '%s' in shader program\n", name); + return false; + } + + switch (num_components) { + case 1: + glUniform1dv(handle, num_elems, d); + break; + case 2: + glUniform2dv(handle, num_elems, d); + break; + case 3: + glUniform3dv(handle, num_elems, d); + break; + case 4: + glUniform4dv(handle, num_elems, d); + break; + default: + ASSERT(false); + break; + } + + return check_gl_error(name); +} + static bool glsl_set_shader_bool(ALLEGRO_SHADER *shader, const char *name, bool b) { @@ -429,8 +482,10 @@ static struct ALLEGRO_SHADER_INTERFACE shader_glsl_vt = glsl_set_shader_matrix, glsl_set_shader_int, glsl_set_shader_float, + glsl_set_shader_double, glsl_set_shader_int_vector, glsl_set_shader_float_vector, + glsl_set_shader_double_vector, glsl_set_shader_bool }; diff --git a/src/win/d3d_shader.cpp b/src/win/d3d_shader.cpp index 37388a95a..45c8b32f0 100644 --- a/src/win/d3d_shader.cpp +++ b/src/win/d3d_shader.cpp @@ -119,10 +119,14 @@ static bool hlsl_set_shader_int(ALLEGRO_SHADER *shader, const char *name, int i); static bool hlsl_set_shader_float(ALLEGRO_SHADER *shader, const char *name, float f); +static bool hlsl_set_shader_double(ALLEGRO_SHADER *shader, + const char *name, double d); static bool hlsl_set_shader_int_vector(ALLEGRO_SHADER *shader, const char *name, int num_components, const int *i, int num_elems); static bool hlsl_set_shader_float_vector(ALLEGRO_SHADER *shader, const char *name, int num_components, const float *f, int num_elems); +static bool hlsl_set_shader_double_vector(ALLEGRO_SHADER *shader, + const char *name, int num_components, const double *d, int num_elems); static bool hlsl_set_shader_bool(ALLEGRO_SHADER *shader, const char *name, bool b); @@ -139,8 +143,10 @@ static struct ALLEGRO_SHADER_INTERFACE shader_hlsl_vt = hlsl_set_shader_matrix, hlsl_set_shader_int, hlsl_set_shader_float, + hlsl_set_shader_double, hlsl_set_shader_int_vector, hlsl_set_shader_float_vector, + hlsl_set_shader_double_vector, hlsl_set_shader_bool }; @@ -444,6 +450,17 @@ static bool hlsl_set_shader_float(ALLEGRO_SHADER *shader, return result == D3D_OK; } +static bool hlsl_set_shader_double(ALLEGRO_SHADER *shader, + const char *name, double d) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + HRESULT result; + + result = hlsl_shader->hlsl_shader->SetFloat(name, (float)d); + + return result == D3D_OK; +} + static bool hlsl_set_shader_int_vector(ALLEGRO_SHADER *shader, const char *name, int num_components, const int *i, int num_elems) { @@ -468,6 +485,23 @@ static bool hlsl_set_shader_float_vector(ALLEGRO_SHADER *shader, return result == D3D_OK; } +static bool hlsl_set_shader_double_vector(ALLEGRO_SHADER *shader, + const char *name, int num_components, const double *d, int num_elems) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + HRESULT result; + float *f = (float *)al_malloc(num_components * num_elems * sizeof(float)); + for (int i = 0; i < num_components * num_elems; i++) { + f[i] = (float)d[i]; + } + + result = hlsl_shader->hlsl_shader->SetFloatArray(name, f, + num_components * num_elems); + + al_free(f); + return result == D3D_OK; +} + static bool hlsl_set_shader_bool(ALLEGRO_SHADER *shader, const char *name, bool b) {