C++17 std::variant and shader uniforms are a match made in heaven ; )

This commit is contained in:
Hartmut Seichter 2019-02-12 22:23:06 +01:00
parent 40b84fb78f
commit f9fbf44391
4 changed files with 35 additions and 19 deletions

View file

@ -29,32 +29,30 @@
namespace pw { namespace pw {
const static double __PW_PI = 3.1415926535897932384626433832795028841971693993751058209; const static double __PW_PI = 3.1415926535897932384626433832795028841971693993751058209;
const static double __RAD2DEG = 180.0 / __PW_PI;
const static double __DEG2RAD = __PW_PI / 180.0;
template <typename T> template <typename T>
inline const T pi() { return static_cast<T>(__PW_PI); } inline const T pi() { return static_cast<T>(__PW_PI); }
template <typename T>
inline const T one_over_pi() { return static_cast<T>(1 / __PW_PI); }
template <typename T> template <typename T>
inline T rad_to_deg(const T& angle_in_radian) { inline T rad_to_deg(const T& angle_in_radian) {
return angle_in_radian * __RAD2DEG; return angle_in_radian * static_cast<T>(180) * one_over_pi<T>();
} }
template <typename T> template <typename T>
inline T deg_to_rad(const T& angle_in_degree) { inline T deg_to_rad(const T& angle_in_degree) {
return angle_in_degree * __DEG2RAD; return angle_in_degree * pi<T>() / static_cast<T>(180);
} }
template <typename T> template <typename T>
static inline inline T repeat(const T& t, const T& length) {
T repeat(const T& t, const T& length) {
return std::clamp(t - std::floor(t / length) * length, T(0), length); return std::clamp(t - std::floor(t / length) * length, T(0), length);
} }
template <typename T> template <typename T>
static inline inline T ping_pong(const T& t,const T& length) {
T ping_pong(const T& t,const T& length) {
auto tn = repeat(t, length * T(2)); auto tn = repeat(t, length * T(2));
return length - std::abs(tn - length); return length - std::abs(tn - length);
} }

View file

@ -7,6 +7,7 @@
#include <pw/core/debug.hpp> #include <pw/core/debug.hpp>
#include <map> #include <map>
#include <variant>
namespace pw { namespace pw {
@ -26,8 +27,6 @@ public:
void set_source(const std::string& c,code_type t) { _source[t] = c; } void set_source(const std::string& c,code_type t) { _source[t] = c; }
std::string source(code_type t) { return _source[t]; } std::string source(code_type t) { return _source[t]; }
// void set_attributes(const std::vector<std::string> > &attributes);
bool ready() const; bool ready() const;
shader& set(int location,float v); shader& set(int location,float v);
@ -51,6 +50,12 @@ public:
void use(); void use();
using uniform_t = std::variant<bool,int,float,double,vector2f,vector3f,vector4f,matrix4x4f>;
using uniform_set = std::map<std::string,uniform_t>;
void set_uniforms(uniform_set s);
protected: protected:
std::map<code_type,std::string> _source; std::map<code_type,std::string> _source;

View file

@ -97,7 +97,6 @@ struct triangle_renderer
void draw() void draw()
{ {
double t0 = timer::now();
shader_p.use(); shader_p.use();
@ -112,27 +111,30 @@ struct triangle_renderer
axisangle rot(vector3::forward(),v_angle); axisangle rot(vector3::forward(),v_angle);
model_mat = rot.to_matrix(); model_mat = rot.to_matrix();
matrix4x4f view_mat = transform_tools<float>::look_at(vector3({0,0,0}), matrix4x4f view_mat = transform_tools<float>::look_at(vector3({0,0,0}),
vector3::forward(), vector3::forward(),
vector3::up()); vector3::up());
matrix4x4f proj_mat = transform_tools<float>::perspective_projection(deg_to_rad(45.f), matrix4x4f proj_mat = transform_tools<float>::perspective_projection(deg_to_rad(60.0f),
1.3f, 1.3f,
0.2f,1000.f); 0.2f,1000.f);
// debug::d() << serialize::matrix(proj_mat);
// highly inefficient - should be cached - // highly inefficient - should be cached -
shader_p.set("input_color",col); shader_p.set("input_color",col);
shader_p.set("model",model_mat); shader_p.set("model",model_mat);
shader_p.set("view",view_mat); shader_p.set("view",view_mat);
shader_p.set("projection",proj_mat); shader_p.set("projection",proj_mat);
// new version with ...
shader::uniform_set us;
us["input_color"] = col;
shader_p.set_uniforms(us);
amesh_renderer.draw(); amesh_renderer.draw();
debug::d() << 100 * (timer::now() - t0) << "ms"; // debug::d() << 100 * (timer::now() - t0) << "ms";
} }
}; };

View file

@ -200,6 +200,17 @@ void shader::use()
_impl->use(); _impl->use();
} }
void shader::set_uniforms(shader::uniform_set s)
{
for (auto& u : s) {
std::visit(
[u](auto&& arg){
std::cout << u.first << " " << typeid(arg).name() << std::endl;
},
u.second);
}
}
int shader::uniform_location(const std::string &name) const int shader::uniform_location(const std::string &name) const
{ {
return _impl->uniform_location(name); return _impl->uniform_location(name);