plenty of additions to rendering. transformation now work almost as expected ...

This commit is contained in:
Hartmut Seichter 2019-02-12 21:28:20 +01:00
parent 841b0eeb46
commit 40b84fb78f
18 changed files with 242 additions and 251 deletions

Binary file not shown.

View file

@ -24,6 +24,7 @@
#define PW_CORE_MATH_HPP #define PW_CORE_MATH_HPP
#include <cmath> #include <cmath>
#include <algorithm>
namespace pw { namespace pw {
@ -45,6 +46,20 @@ inline T deg_to_rad(const T& angle_in_degree) {
return angle_in_degree * __DEG2RAD; return angle_in_degree * __DEG2RAD;
} }
template <typename T>
static inline
T repeat(const T& t, const T& length) {
return std::clamp(t - std::floor(t / length) * length, T(0), length);
}
template <typename T>
static inline
T ping_pong(const T& t,const T& length) {
auto tn = repeat(t, length * T(2));
return length - std::abs(tn - length);
}
} }
#endif #endif

View file

@ -39,23 +39,42 @@ struct transform_tools {
} }
inline static inline static
matrix_<4,4,T> projection_from_frustum(T left,T right,T bottom,T top,T z_near,T z_far) matrix_<4,4,T> projection_from_frustum(const T &left,const T &right,
const T &bottom,const T &top,
const T &z_near,const T &z_far)
{ {
matrix_<4,4,T> frustum; frustum.zero(); matrix_<4,4,T> frustum; frustum.zero();
frustum(0,0) = T(2) * z_near / (right - left); frustum(0,0) = T(2) * z_near / (right - left);
frustum(1,1) = T(2) * z_near / (top - bottom); frustum(1,1) = T(2) * z_near / (top - bottom);
frustum(2,0) = (right+left)/(right-left); //A frustum(0,2) = (right+left)/(right-left); //A
frustum(2,1) = (top+bottom)/(top-bottom); //B frustum(1,2) = (top+bottom)/(top-bottom); //B
frustum(2,2) = - (z_far+z_near)/(z_far-z_near); //C frustum(2,2) = -(z_far+z_near)/(z_far-z_near); //C
frustum(2,3) = -(T(2) * z_far*z_near)/(z_far-z_near); //D frustum(2,3) = -T(2) * z_far*z_near/(z_far-z_near); //D
frustum(3,2) = -T(1); frustum(3,2) = -T(1);
return frustum; return frustum;
} }
inline static
matrix_<4,4,T> perspective_projection(const T &field_of_view,
const T &aspect_ratio,
const T &z_near,const T &z_far)
{
const T tan_half = tan(field_of_view / T(2));
const T right = aspect_ratio * tan_half * z_near;
const T left = -right;
const T top = aspect_ratio * tan_half;
const T bottom = -top;
return projection_from_frustum(left,right,
bottom,top,
z_near,z_far);
}
inline static inline static
matrix_<4,4,T> orthogonal_projection(T left, T right, matrix_<4,4,T> orthogonal_projection(T left, T right,
T bottom,T top, T bottom,T top,
@ -78,63 +97,25 @@ struct transform_tools {
return ortho; return ortho;
} }
inline static
matrix_<4,4,T> perspective_projection(T fov_y, T aspect_ratio, T z_near, T z_far)
{
const T height = z_near * tan(fov_y/T(360) * pi<T>()); // half height of near plane
const T width = height * aspect_ratio; // half width of near plane
return projection_from_frustum(-width, width, -height, height, z_near, z_far ); inline static
} matrix_<4,4,T> look_at(const vector3_<T> &position,
const vector3_<T> &target,
inline static const vector3_<T> &up)
matrix_<4,4,T> look_at( {
const vector3_<T> &eye,
const vector3_<T> &target,
const vector3_<T> &up)
{
matrix_<4,4,T> view_matrix; view_matrix.set_identity(); matrix_<4,4,T> view_matrix; view_matrix.set_identity();
const vector3_<T> L = (target - eye).normalized(); // line of sight
const vector3_<T> S = L.cross(up).normalized(); const vector3_<T> los = (target - position).normalized(); // line of sight
const vector3_<T> Ud = S.cross(L).normalized(); const vector3_<T> sid = los.cross(up).normalized();
const vector3_<T> upd = sid.cross(los).normalized();
// set base vectors // set base vectors
view_matrix.set_slice(S, 0,0); view_matrix.set_slice(sid, 0, 0);
view_matrix.set_slice(Ud, 0,1); view_matrix.set_slice(upd, 0, 1);
view_matrix.set_slice(L*T(-1), 0,2); view_matrix.set_slice(los * T(-1), 0, 2);
view_matrix.set_slice(eye, 0,3); view_matrix.set_slice(position, 0, 3);
return view_matrix;
// matrix<3,1,T> S = matrix31<T>::Cross(L,up);
// S.normalize();
// matrix<3,1,T> Ud = matrix31<T>::Cross(S,L);
// Ud.normalize();
// lookat(0,0) = S.at(0);
// lookat(0,1) = S.at(1);
// lookat(0,2) = S.at(2);
// lookat(0,3) = T(0);
// lookat(1,0) = Ud.at(0);
// lookat(1,1) = Ud.at(1);
// lookat(1,2) = Ud.at(2);
// lookat(1,3) = T(0);
// lookat(2,0) = -L.at(0);
// lookat(2,1) = -L.at(1);
// lookat(2,2) = -L.at(2);
// lookat(3,2) = T(0);
// lookat(3,0) = eye.at(0);
// lookat(3,1) = eye.at(1);
// lookat(3,2) = eye.at(2);
// lookat(3,3) = 1;
// return lookat;
return view_matrix;
} }
}; };

View file

@ -24,6 +24,9 @@ struct image_io::impl
image r; image r;
r.create(sizei(x,y),image::pixel_layout::RGBA8,data); r.create(sizei(x,y),image::pixel_layout::RGBA8,data);
stbi_image_free(data);
return r; return r;
} }

View file

@ -47,7 +47,7 @@ public:
using component::component; using component::component;
camera(); camera(node &host);
void set_projection(const matrix4x4 &projection); void set_projection(const matrix4x4 &projection);
const matrix4x4& projection() const; const matrix4x4& projection() const;

View file

@ -42,11 +42,9 @@ class component {
public: public:
friend class node; friend class node;
typedef std::vector<component> array;
typedef std::shared_ptr<component> ref; component(node &host);
typedef std::vector<ref> array;
component();
component(const component& other); component(const component& other);
virtual ~component(); virtual ~component();
@ -56,15 +54,14 @@ public:
uint32_t weight() const; uint32_t weight() const;
void set_weight(const uint32_t &weight); void set_weight(const uint32_t &weight);
template <typename T> template <typename T>
inline T* cast() { return static_cast<T*>(this);} inline T* cast() { return static_cast<T*>(this);}
protected: protected:
uint32_t _weight = 0; uint32_t _weight = 1;
node* _node; node &_node;
bool _enabled; bool _enabled;
}; };

View file

@ -42,6 +42,8 @@ namespace pw {
class node { class node {
public: public:
friend class component;
typedef shared_ptr<node> ref; typedef shared_ptr<node> ref;
typedef std::vector<ref> ref_array; typedef std::vector<ref> ref_array;
@ -66,8 +68,8 @@ public:
//! return parent of this node //! return parent of this node
inline ptr parent() const { return _path.back(); } inline ptr parent() const { return _path.back(); }
//! add a child node //! add a child node
ref add_child(); void add_child(ref child_node);
//! remove a child //! remove a child
void remove_child(ref child_node); void remove_child(ref child_node);
@ -85,29 +87,25 @@ public:
inline bool is_root() const { return _path.empty(); } inline bool is_root() const { return _path.empty(); }
//! list of components //! list of components
const component::array& components() const; const component::array& components() const;
//! add a node component //! add a node component
void add_component(component::ref new_component); void add_component(component new_component);
template<typename T>
void add_component_() {
_components.push_back(T(*this));
}
//! remove a node component //! remove a node component
void remove_component(component::ref c); void remove_component(component c);
//! paths to root //! paths to root
const ptr_array& path() const; const ptr_array& path() const;
void traversal(); void traversal();
template <typename T> // not sure about this
T* find_component()
{
for (auto c : _components) {
T* r = static_cast<T*>(c.get());
if (r != nullptr) return r;
}
return nullptr;
}
const class transform& transform() const { return _transform; } const class transform& transform() const { return _transform; }
class transform& transform() { return _transform; } class transform& transform() { return _transform; }
@ -116,10 +114,10 @@ protected:
ref_array _children; //!< list of children ref_array _children; //!< list of children
ptr_array _path; //!< path to root ptr_array _path; //!< path to root
component::array _components; //<! components
class transform _transform; class transform _transform;
component::array _components; //<! components
std::string _name; std::string _name;
// change mask // change mask

View file

@ -5,16 +5,14 @@
#include <pw/core/quaternion.hpp> #include <pw/core/quaternion.hpp>
#include <pw/core/vector.hpp> #include <pw/core/vector.hpp>
#include <pw/scene/component.hpp>
namespace pw { namespace pw {
class transform : public component { class node;
class transform {
public: public:
using component::component; transform(node &host);
transform();
inline const matrix4x4& local() const { return _local; } inline const matrix4x4& local() const { return _local; }
void set_local(const matrix4x4 &local); void set_local(const matrix4x4 &local);
@ -22,42 +20,59 @@ public:
inline const matrix4x4& global() const { return _global; } inline const matrix4x4& global() const { return _global; }
void set_global(const matrix4x4 &global); void set_global(const matrix4x4 &global);
inline void translate(const real_t &x, const real_t &y, const real_t &z) { inline const matrix4x4& global_inverse() const { return _global_inverse; }
inline transform& translate(const real_t &x, const real_t &y, const real_t &z) {
_local(0,3) += x;_local(1,3) += y;_local(2,3) += z; _local(0,3) += x;_local(1,3) += y;_local(2,3) += z;
update_global_from_local(); update_global_from_local();
return *this;
} }
inline void rotate(const quaternion& q) { inline transform& set_translation(const real_t &x, const real_t &y, const real_t &z) {
_local(0,3) = x;_local(1,3) = y;_local(2,3) = z;
update_global_from_local();
return *this;
}
inline transform& rotate(const quaternion& q) {
_local = _local * q.to_matrix(); _local = _local * q.to_matrix();
update_global_from_local(); update_global_from_local();
return *this;
} }
inline void scale(const real_t &x, const real_t &y, const real_t &z) { inline transform& set_rotation(const quaternion& q) {
_local(0,0) *= x; _local(1,1) *= y; _local(2,2) *= z; _local = q.to_matrix();
update_global_from_local(); update_global_from_local();
return *this;
} }
inline void scale(const real_t& uniform_scale) { inline transform& scale(const real_t &sx, const real_t &sy, const real_t &sz) {
scale(uniform_scale,uniform_scale,uniform_scale); _local(0,0) *= sx; _local(1,1) *= sy; _local(2,2) *= sz;
}
inline void set_translation(const real_t &x, const real_t &y, const real_t &z) {
_local(0,3) = x;_local(1,3) = y;_local(2,3) = z;
update_global_from_local(); update_global_from_local();
return *this;
} }
inline transform& set_scale(const real_t &sx, const real_t &sy, const real_t &sz) {
_local(0,0) = sx; _local(1,1) = sy; _local(2,2) = sz;
update_global_from_local();
return *this;
}
inline transform& scale(const real_t& uniform_scale) {
return scale(uniform_scale,uniform_scale,uniform_scale);
void update(node &node); }
protected: protected:
matrix4x4 _local; matrix4x4 _local;
matrix4x4 _global; matrix4x4 _global;
matrix4x4 _global_inverse;
private: private:
node &_node;
//! updates the global transform from parent globals and local transform //! updates the global transform from parent globals and local transform
void update_global_from_local(); void update_global_from_local();
@ -65,8 +80,6 @@ private:
void update_local_from_global(); void update_local_from_global();
}; };
} }
#endif #endif

View file

@ -3,8 +3,9 @@
namespace pw { namespace pw {
camera::camera() camera::camera(node &host)
: _fov(60.0) : component (host)
, _fov(60.0)
, _near_plane(0.2f) , _near_plane(0.2f)
, _far_plane(1000) , _far_plane(1000)
{ {
@ -16,6 +17,20 @@ void camera::set_projection(const matrix4x4 &projection)
this->_projection = projection; this->_projection = projection;
// recompute the simplified parameters // recompute the simplified parameters
auto near = _projection(3,4);
auto far = _projection(3,4);
// right = (1-m14) / m11
// near = (1+m34)/m33;
// far = -(1-m34)/m33;
// bottom = (1-m24)/m22;
// top = -(1+m24)/m22;
// left = -(1+m14)/m11;
// right = (1-m14)/m11;
// real_t fov_raw = float( atan (top / near_)) * * 2.0f;
} }
const matrix4x4 &camera::projection() const const matrix4x4 &camera::projection() const

View file

@ -11,8 +11,8 @@
namespace pw { namespace pw {
component::component() component::component(node &host)
: _node(nullptr) : _node(host)
{ {
} }
@ -23,7 +23,6 @@ component::component(const component &other)
component::~component() component::~component()
{ {
// if (_node != nullptr) _node->unregister_component(this);
} }
bool component::enabled() const bool component::enabled() const

View file

@ -1,11 +1,12 @@
#include "pw/scene/transform.hpp" #include "pw/scene/transform.hpp"
#include "pw/scene/node.hpp" #include "pw/scene/node.hpp"
#include <iostream> #include "pw/core/debug.hpp"
namespace pw { namespace pw {
node::node() node::node()
: _transform(*this)
{ {
} }
@ -13,7 +14,9 @@ node::node(const node &node)
: _children(node.children()) : _children(node.children())
, _components(node.components()) , _components(node.components())
, _name(node._name) , _name(node._name)
, _transform(*this)
{ {
// _components.push_back(std::make_unique<transform>(*this));
} }
node::ref node::clone(const unsigned short &copymode) const node::ref node::clone(const unsigned short &copymode) const
@ -31,22 +34,16 @@ void node::set_name(const std::string &name)
_name = name; _name = name;
} }
node::ref node::add_child() void node::add_child(node::ref c)
{ {
// create new node
node::ref new_node = std::make_shared<node>();
// take parent nodepath ... // take parent nodepath ...
if (!this->is_root()) new_node->_path = this->_path; c->_path = this->_path;
// add itself // add current node
new_node->_path.push_back(this); c->_path.push_back(this);
// add as child // add as child
_children.push_back(new_node); _children.push_back(c);
// return
return new_node;
} }
void node::remove_child(ref child_node) void node::remove_child(ref child_node)
@ -72,28 +69,22 @@ node::~node()
// //
// components // components
// //
void node::add_component(component::ref new_component) void node::add_component(component new_component)
{ {
// assumption is that only transform is a "singular" node // assumption is that only transform is a "singular" node
_components.push_back(new_component); _components.push_back(new_component);
} }
void node::remove_component(component::ref c) void node::remove_component(component c)
{ {
// component::array::iterator it = _components.end(); // component::array::iterator it = _components.end();
for (component::array::iterator it = _components.begin(); for (component::array::iterator it = _components.begin();
it != _components.end(); it != _components.end();
it++) it++)
{ {
if (*it == c) it = _components.erase(it); // if (*it == c) it = _components.erase(it);
} }
// while ((it = std::find(_components.begin(),_components.end(),c)) != _components.end()) {
// (*it)->_node = nullptr;
// _components.erase(it);
// }
} }
const node::ptr_array &node::path() const const node::ptr_array &node::path() const
@ -103,10 +94,11 @@ const node::ptr_array &node::path() const
void node::traversal() void node::traversal()
{ {
// for (auto c : _components) c->visit(this);
} }
const component::array& node::components() const
const component::array &node::components() const
{ {
return _components; return _components;
} }

View file

@ -3,46 +3,48 @@
namespace pw { namespace pw {
transform::transform() transform::transform(node &host)
: _node(host)
{ {
_local.set_identity(); _local.set_identity();
_global.set_identity(); _global.set_identity();
_global_inverse.set_identity();
} }
void transform::set_local(const matrix4x4 &local) void transform::set_local(const matrix4x4 &local)
{ {
// TODO need to rebuild the transforms: both -> global down and global up _local = local;
_local = local; update_global_from_local();
// TODO need to rebuild the transforms: both -> global down and global up
} }
void transform::set_global(const matrix4x4 &global) void transform::set_global(const matrix4x4 &global)
{ {
//TODO need to rebuild **_local** from parent //TODO need to rebuild **_local** from parent
_global = global; _global = global;
} _global_inverse = global.inverse();
update_local_from_global();
void transform::update(node& node) // TODO need to rebuild the transforms: both -> global down and global up
{
} }
void transform::update_global_from_local() void transform::update_global_from_local()
{ {
// update the global transform // update the global transform
if (_node && _node->parent()) if (_node.is_root()) {
{ this->_global = _local;
this->_global = _node->transform()._global * _local;
} else } else
{ {
this->_global = _local; this->_global = _node.parent()->transform().global() * _local;
} }
_global_inverse = _global.inverse();
} }
void transform::update_local_from_global() void transform::update_local_from_global()
{ {
_local = (_node.is_root()) ? _global :
_node.parent()->transform().global_inverse() * _global;
// _local = this->global()
} }
} }

View file

@ -22,45 +22,52 @@ void print_node_path(pw::node::ref node) {
int main(int argc,char **argv) { int main(int argc,char **argv) {
using namespace pw; using namespace pw;
node::ref n = std::make_shared<node>(); auto n = std::make_shared<node>();
n->set_name("root"); n->set_name("root-node");
// check
{
n->add_child()->set_name("node");
}
std::cout << "n name: " << n->name() << std::endl; // add a child
std::cout << "n leaf: " << n->is_leaf() << std::endl; auto c = std::make_shared<node>();
std::cout << "n root: " << n->is_root() << std::endl; c->set_name("child-node");
n->add_child(c);
std::cout << "n name: " << n->name() << std::endl;
std::cout << "n leaf: " << n->is_leaf() << std::endl;
std::cout << "n root: " << n->is_root() << std::endl;
std::cout << "s name: " << n->children().front()->name() << std::endl; std::cout << "s name: " << n->children().front()->name() << std::endl;
std::cout << "s leaf: " << n->children()[0]->is_leaf() << std::endl; std::cout << "s leaf: " << n->children().front()->is_leaf() << std::endl;
std::cout << "s root: " << n->children()[0]->is_root() << std::endl; std::cout << "s root: " << n->children().front()->is_root() << std::endl;
// thats the only and most ugly way to register a component // thats the only and most ugly way to register a component
// new component(n.get()); // new component(n.get());
n->add_component(std::make_shared<transform>());
std::cout << "n components: " << n->components().size() << std::endl; std::cout << "n components: " << n->components().size() << std::endl;
n->transform().set_translation(5,4,3);
std::cout << "c transform g " << serialize::matrix(n->transform().global()) << std::endl;
std::cout << "c transform gi " << serialize::matrix(n->transform().global_inverse()) << std::endl;
std::cout << "c transform l " << serialize::matrix(n->transform().local()) << std::endl;
//n->add_component_<transform>();
print_node_path((n)); print_node_path((n));
// auto t = n->transform(); // auto t = n->transform();
// if (t) // if (t)
std::cout << n->transform().local()(0,0) << std::endl; // std::cout << n->transform().local()(0,0) << std::endl;
// else { // else {
// std::cerr << "no transform?" << std::endl; // std::cerr << "no transform?" << std::endl;
// } // }
return 0;
return 0;
} }

View file

@ -42,7 +42,7 @@ int main(int argc,char **argv) {
node::ref root(std::make_shared<node>()); node::ref root(std::make_shared<node>());
root->set_name("root"); root->set_name("root");
root->add_child()->set_name("sub-1"); // root->add_child()->set_name("sub-1");
// node::ref sub_2_1 = std::make_shared<node>("sub-2-1"); // node::ref sub_2_1 = std::make_shared<node>("sub-2-1");

View file

@ -12,6 +12,7 @@ void register_scene_function(sol::state&,sol::table &ns)
sol::constructors<node()>(), sol::constructors<node()>(),
"add_child",&node::add_child, "add_child",&node::add_child,
"children",sol::readonly_property(&node::children), "children",sol::readonly_property(&node::children),
"parent",sol::readonly_property(&node::parent),
"child_count",sol::readonly_property(&node::child_count), "child_count",sol::readonly_property(&node::child_count),
"create", []() -> std::shared_ptr<node> { return std::make_shared<node>(); }, "create", []() -> std::shared_ptr<node> { return std::make_shared<node>(); },
"is_leaf", sol::readonly_property(&node::is_leaf), "is_leaf", sol::readonly_property(&node::is_leaf),

View file

@ -30,20 +30,20 @@ public:
bool ready() const; bool ready() const;
shader& bind(int location,float v); shader& set(int location,float v);
shader& bind(int location,matrix4x4f const & v); shader& set(int location,matrix4x4f const & v);
shader& bind(int location,vector4f const & v); shader& set(int location,vector4f const & v);
int uniform_location(std::string const & name) const; int uniform_location(std::string const & name) const;
template<typename T> template<typename T>
shader & bind(std::string const & name, T&& value) shader & set(std::string const & name, T&& value)
{ {
int location = uniform_location(name); int location = uniform_location(name);
if (location >= 0) if (location >= 0)
return bind(location, std::forward<T>(value)); return set(location, std::forward<T>(value));
else else
debug::e() << "missing uniform: "<< name; debug::e() << "missing uniform: '" << name << "'";
return *this; return *this;
} }

View file

@ -3,6 +3,8 @@
#include "pw/core/mesh.hpp" #include "pw/core/mesh.hpp"
#include "pw/core/timer.hpp" #include "pw/core/timer.hpp"
#include "pw/core/axisangle.hpp" #include "pw/core/axisangle.hpp"
#include "pw/core/serialize.hpp"
#include "pw/core/transform_tools.hpp"
#include "pw/core/debug.hpp" #include "pw/core/debug.hpp"
#include "pw/visual/pipeline.hpp" #include "pw/visual/pipeline.hpp"
@ -17,6 +19,8 @@ class command {
}; };
class mesh_command : command { class mesh_command : command {
// shader // shader
@ -46,10 +50,13 @@ struct triangle_renderer
void setup() void setup()
{ {
const float z_val = -5.f;
mesh::vertex3array_t vertices = { mesh::vertex3array_t vertices = {
{ 0.0f, 0.5f, 0.0f} // 0 { 0.0f, 0.5f, z_val} // 0
,{ 0.5f, -0.5f, 0.0f} // 1 ,{ 0.5f, -0.5f, z_val} // 1
,{-0.5f, -0.5f, 0.0f} // 2 ,{-0.5f, -0.5f, z_val} // 2
}; };
// actual indices // actual indices
@ -59,71 +66,17 @@ struct triangle_renderer
amesh.set_vertices(vertices); amesh.set_vertices(vertices);
amesh_renderer.create(amesh); amesh_renderer.create(amesh);
#if 0
size_t vertex_size_bytes = amesh.vertices().size() * sizeof(mesh::vertex3array_t::value_type);
size_t vertex_stride = amesh.vertices().front().size();
debug::d() << 9 * sizeof(mesh::vertex3array_t::value_type::value_type) << " "
<< vertex_size_bytes;
// sizeof(mesh::vertex3array_t::value_type)
// 9 * sizeof(mesh::vertex3array_t::value_type::value_type)
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertex_size_bytes , amesh.vertices().data(), GL_STATIC_DRAW);
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, vertex_stride, GL_FLOAT, GL_FALSE, 0, nullptr);
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
#endif
const char* vertex_shader = R"(
#version 400
in vec3 vp;
void main() {
gl_Position = vec4(vp, 1.0);
}
)";
const char *fragment_shader = R"(
#version 400
uniform vec4 input_color = vec4(1.0, 0.0, 0.0, 1.0);
out vec4 frag_colour;
void main() {
frag_colour = input_color;
})";
const char* vertex_shader_2 = R"( const char* vertex_shader_2 = R"(
#version 400 #version 400
uniform mat4 model_mat; uniform mat4 model;
uniform mat4 view_mat = mat4 uniform mat4 view;
uniform mat4 projection;
in vec3 vertex_p; in vec3 vertex_p;
void main() { void main() {
gl_Position = model_mat * vec4(vertex_p, 1.0); gl_Position = projection * view * model * vec4(vertex_p, 1.0);
} }
)"; )";
@ -136,7 +89,7 @@ struct triangle_renderer
})"; })";
shader_p.set_source(vertex_shader_2,shader::vertex); shader_p.set_source(vertex_shader_2,shader::vertex);
shader_p.set_source(fragment_shader,shader::fragment); shader_p.set_source(fragment_shader_2,shader::fragment);
if (!shader_p.build()) if (!shader_p.build())
exit(-1); exit(-1);
@ -148,19 +101,34 @@ struct triangle_renderer
shader_p.use(); shader_p.use();
static float v = 0.0f; auto v_col = ping_pong(static_cast<float>(timer::now()),1.0f);
v+= 0.01f;
if (v>1.0f) v = 0.0f; vector4f col({0.5f,1-v_col,v_col,1.0f});
vector4f test({0.5f,1-v,v,1.0f});
matrix4x4f model_mat; model_mat.set_identity(); matrix4x4f model_mat; model_mat.set_identity();
axisangle rot(vector3::right(),v); auto v_angle = ping_pong(static_cast<float>(timer::now()),::pw::pi<float>());
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}),
vector3::forward(),
vector3::up());
matrix4x4f proj_mat = transform_tools<float>::perspective_projection(deg_to_rad(45.f),
1.3f,
0.2f,1000.f);
// debug::d() << serialize::matrix(proj_mat);
// highly inefficient - should be cached - // highly inefficient - should be cached -
shader_p.bind("input_color",test); shader_p.set("input_color",col);
shader_p.bind("model_mat",model_mat); shader_p.set("model",model_mat);
shader_p.set("view",view_mat);
shader_p.set("projection",proj_mat);
amesh_renderer.draw(); amesh_renderer.draw();

View file

@ -180,12 +180,12 @@ bool shader::ready() const
return _impl->is_valid(); return _impl->is_valid();
} }
shader &shader::bind(int location, const vector4f &v) shader &shader::set(int location, const vector4f &v)
{ {
_impl->bind(location,v); return *this; _impl->bind(location,v); return *this;
} }
shader &shader::bind(int location, const matrix4x4f &v) shader &shader::set(int location, const matrix4x4f &v)
{ {
_impl->bind(location,v); return *this; _impl->bind(location,v); return *this;
} }