plenty of additions to rendering. transformation now work almost as expected ...
This commit is contained in:
parent
841b0eeb46
commit
40b84fb78f
18 changed files with 242 additions and 251 deletions
Binary file not shown.
|
@ -24,6 +24,7 @@
|
|||
#define PW_CORE_MATH_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
namespace pw {
|
||||
|
||||
|
@ -45,6 +46,20 @@ inline T deg_to_rad(const T& angle_in_degree) {
|
|||
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
|
||||
|
|
|
@ -39,23 +39,42 @@ struct transform_tools {
|
|||
}
|
||||
|
||||
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();
|
||||
|
||||
frustum(0,0) = T(2) * z_near / (right - left);
|
||||
frustum(1,1) = T(2) * z_near / (top - bottom);
|
||||
|
||||
frustum(2,0) = (right+left)/(right-left); //A
|
||||
frustum(2,1) = (top+bottom)/(top-bottom); //B
|
||||
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(0,2) = (right+left)/(right-left); //A
|
||||
frustum(1,2) = (top+bottom)/(top-bottom); //B
|
||||
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(3,2) = -T(1);
|
||||
|
||||
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
|
||||
matrix_<4,4,T> orthogonal_projection(T left, T right,
|
||||
T bottom,T top,
|
||||
|
@ -78,63 +97,25 @@ struct transform_tools {
|
|||
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> &eye,
|
||||
matrix_<4,4,T> look_at(const vector3_<T> &position,
|
||||
const vector3_<T> &target,
|
||||
const vector3_<T> &up)
|
||||
{
|
||||
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> Ud = S.cross(L).normalized();
|
||||
const vector3_<T> los = (target - position).normalized(); // line of sight
|
||||
const vector3_<T> sid = los.cross(up).normalized();
|
||||
const vector3_<T> upd = sid.cross(los).normalized();
|
||||
|
||||
// set base vectors
|
||||
view_matrix.set_slice(S, 0,0);
|
||||
view_matrix.set_slice(Ud, 0,1);
|
||||
view_matrix.set_slice(L*T(-1), 0,2);
|
||||
view_matrix.set_slice(eye, 0,3);
|
||||
view_matrix.set_slice(sid, 0, 0);
|
||||
view_matrix.set_slice(upd, 0, 1);
|
||||
view_matrix.set_slice(los * T(-1), 0, 2);
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -24,6 +24,9 @@ struct image_io::impl
|
|||
image r;
|
||||
|
||||
r.create(sizei(x,y),image::pixel_layout::RGBA8,data);
|
||||
|
||||
stbi_image_free(data);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
|
||||
using component::component;
|
||||
|
||||
camera();
|
||||
camera(node &host);
|
||||
|
||||
void set_projection(const matrix4x4 &projection);
|
||||
const matrix4x4& projection() const;
|
||||
|
|
|
@ -42,11 +42,9 @@ class component {
|
|||
public:
|
||||
|
||||
friend class node;
|
||||
typedef std::vector<component> array;
|
||||
|
||||
typedef std::shared_ptr<component> ref;
|
||||
typedef std::vector<ref> array;
|
||||
|
||||
component();
|
||||
component(node &host);
|
||||
component(const component& other);
|
||||
virtual ~component();
|
||||
|
||||
|
@ -56,15 +54,14 @@ public:
|
|||
uint32_t weight() const;
|
||||
void set_weight(const uint32_t &weight);
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T* cast() { return static_cast<T*>(this);}
|
||||
|
||||
protected:
|
||||
|
||||
uint32_t _weight = 0;
|
||||
uint32_t _weight = 1;
|
||||
|
||||
node* _node;
|
||||
node &_node;
|
||||
bool _enabled;
|
||||
|
||||
};
|
||||
|
|
|
@ -42,6 +42,8 @@ namespace pw {
|
|||
class node {
|
||||
public:
|
||||
|
||||
friend class component;
|
||||
|
||||
typedef shared_ptr<node> ref;
|
||||
typedef std::vector<ref> ref_array;
|
||||
|
||||
|
@ -67,7 +69,7 @@ public:
|
|||
inline ptr parent() const { return _path.back(); }
|
||||
|
||||
//! add a child node
|
||||
ref add_child();
|
||||
void add_child(ref child_node);
|
||||
|
||||
//! remove a child
|
||||
void remove_child(ref child_node);
|
||||
|
@ -88,26 +90,22 @@ public:
|
|||
const component::array& components() const;
|
||||
|
||||
//! 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
|
||||
void remove_component(component::ref c);
|
||||
void remove_component(component c);
|
||||
|
||||
//! paths to root
|
||||
const ptr_array& path() const;
|
||||
|
||||
void traversal();
|
||||
|
||||
template <typename T>
|
||||
T* find_component()
|
||||
{
|
||||
for (auto c : _components) {
|
||||
T* r = static_cast<T*>(c.get());
|
||||
if (r != nullptr) return r;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// not sure about this
|
||||
const class transform& transform() const { return _transform; }
|
||||
class transform& transform() { return _transform; }
|
||||
|
||||
|
@ -116,10 +114,10 @@ protected:
|
|||
ref_array _children; //!< list of children
|
||||
ptr_array _path; //!< path to root
|
||||
|
||||
component::array _components; //<! components
|
||||
|
||||
class transform _transform;
|
||||
|
||||
component::array _components; //<! components
|
||||
|
||||
std::string _name;
|
||||
|
||||
// change mask
|
||||
|
|
|
@ -5,16 +5,14 @@
|
|||
#include <pw/core/quaternion.hpp>
|
||||
#include <pw/core/vector.hpp>
|
||||
|
||||
#include <pw/scene/component.hpp>
|
||||
|
||||
namespace pw {
|
||||
|
||||
class transform : public component {
|
||||
class node;
|
||||
|
||||
class transform {
|
||||
public:
|
||||
|
||||
using component::component;
|
||||
|
||||
transform();
|
||||
transform(node &host);
|
||||
|
||||
inline const matrix4x4& local() const { return _local; }
|
||||
void set_local(const matrix4x4 &local);
|
||||
|
@ -22,42 +20,59 @@ public:
|
|||
inline const matrix4x4& global() const { return _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;
|
||||
update_global_from_local();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void rotate(const quaternion& q) {
|
||||
_local = _local * q.to_matrix();
|
||||
update_global_from_local();
|
||||
}
|
||||
|
||||
inline void scale(const real_t &x, const real_t &y, const real_t &z) {
|
||||
_local(0,0) *= x; _local(1,1) *= y; _local(2,2) *= z;
|
||||
update_global_from_local();
|
||||
}
|
||||
|
||||
inline void scale(const real_t& uniform_scale) {
|
||||
scale(uniform_scale,uniform_scale,uniform_scale);
|
||||
}
|
||||
|
||||
inline void set_translation(const real_t &x, const real_t &y, const real_t &z) {
|
||||
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();
|
||||
update_global_from_local();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline transform& set_rotation(const quaternion& q) {
|
||||
_local = q.to_matrix();
|
||||
update_global_from_local();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline transform& 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;
|
||||
}
|
||||
|
||||
void update(node &node);
|
||||
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);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
matrix4x4 _local;
|
||||
matrix4x4 _global;
|
||||
|
||||
matrix4x4 _global_inverse;
|
||||
|
||||
private:
|
||||
|
||||
node &_node;
|
||||
|
||||
//! updates the global transform from parent globals and local transform
|
||||
void update_global_from_local();
|
||||
|
||||
|
@ -65,8 +80,6 @@ private:
|
|||
void update_local_from_global();
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
|
||||
namespace pw {
|
||||
|
||||
camera::camera()
|
||||
: _fov(60.0)
|
||||
camera::camera(node &host)
|
||||
: component (host)
|
||||
, _fov(60.0)
|
||||
, _near_plane(0.2f)
|
||||
, _far_plane(1000)
|
||||
{
|
||||
|
@ -16,6 +17,20 @@ void camera::set_projection(const matrix4x4 &projection)
|
|||
this->_projection = projection;
|
||||
|
||||
// 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
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
namespace pw {
|
||||
|
||||
component::component()
|
||||
: _node(nullptr)
|
||||
component::component(node &host)
|
||||
: _node(host)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ component::component(const component &other)
|
|||
|
||||
component::~component()
|
||||
{
|
||||
// if (_node != nullptr) _node->unregister_component(this);
|
||||
}
|
||||
|
||||
bool component::enabled() const
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#include "pw/scene/transform.hpp"
|
||||
#include "pw/scene/node.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include "pw/core/debug.hpp"
|
||||
|
||||
namespace pw {
|
||||
|
||||
node::node()
|
||||
: _transform(*this)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -13,7 +14,9 @@ node::node(const node &node)
|
|||
: _children(node.children())
|
||||
, _components(node.components())
|
||||
, _name(node._name)
|
||||
, _transform(*this)
|
||||
{
|
||||
// _components.push_back(std::make_unique<transform>(*this));
|
||||
}
|
||||
|
||||
node::ref node::clone(const unsigned short ©mode) const
|
||||
|
@ -31,22 +34,16 @@ void node::set_name(const std::string &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 ...
|
||||
if (!this->is_root()) new_node->_path = this->_path;
|
||||
c->_path = this->_path;
|
||||
|
||||
// add itself
|
||||
new_node->_path.push_back(this);
|
||||
// add current node
|
||||
c->_path.push_back(this);
|
||||
|
||||
// add as child
|
||||
_children.push_back(new_node);
|
||||
|
||||
// return
|
||||
return new_node;
|
||||
_children.push_back(c);
|
||||
}
|
||||
|
||||
void node::remove_child(ref child_node)
|
||||
|
@ -72,13 +69,13 @@ node::~node()
|
|||
//
|
||||
// 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
|
||||
_components.push_back(new_component);
|
||||
}
|
||||
|
||||
void node::remove_component(component::ref c)
|
||||
void node::remove_component(component c)
|
||||
{
|
||||
// component::array::iterator it = _components.end();
|
||||
|
||||
|
@ -86,14 +83,8 @@ void node::remove_component(component::ref c)
|
|||
it != _components.end();
|
||||
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
|
||||
|
@ -103,10 +94,11 @@ const node::ptr_array &node::path() const
|
|||
|
||||
void node::traversal()
|
||||
{
|
||||
// for (auto c : _components) c->visit(this);
|
||||
|
||||
}
|
||||
|
||||
const component::array& node::components() const
|
||||
|
||||
const component::array &node::components() const
|
||||
{
|
||||
return _components;
|
||||
}
|
||||
|
|
|
@ -3,46 +3,48 @@
|
|||
|
||||
namespace pw {
|
||||
|
||||
transform::transform()
|
||||
transform::transform(node &host)
|
||||
: _node(host)
|
||||
{
|
||||
_local.set_identity();
|
||||
_global.set_identity();
|
||||
_global_inverse.set_identity();
|
||||
}
|
||||
|
||||
void transform::set_local(const matrix4x4 &local)
|
||||
{
|
||||
// TODO need to rebuild the transforms: both -> global down and global up
|
||||
_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)
|
||||
{
|
||||
//TODO need to rebuild **_local** from parent
|
||||
_global = global;
|
||||
}
|
||||
_global_inverse = global.inverse();
|
||||
|
||||
|
||||
void transform::update(node& node)
|
||||
{
|
||||
update_local_from_global();
|
||||
// TODO need to rebuild the transforms: both -> global down and global up
|
||||
}
|
||||
|
||||
void transform::update_global_from_local()
|
||||
{
|
||||
// update the global transform
|
||||
if (_node && _node->parent())
|
||||
{
|
||||
this->_global = _node->transform()._global * _local;
|
||||
if (_node.is_root()) {
|
||||
this->_global = _local;
|
||||
} else
|
||||
{
|
||||
this->_global = _local;
|
||||
this->_global = _node.parent()->transform().global() * _local;
|
||||
}
|
||||
_global_inverse = _global.inverse();
|
||||
}
|
||||
|
||||
void transform::update_local_from_global()
|
||||
{
|
||||
_local = (_node.is_root()) ? _global :
|
||||
_node.parent()->transform().global_inverse() * _global;
|
||||
|
||||
// _local = this->global()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,41 +24,48 @@ int main(int argc,char **argv) {
|
|||
|
||||
using namespace pw;
|
||||
|
||||
node::ref n = std::make_shared<node>();
|
||||
n->set_name("root");
|
||||
auto n = std::make_shared<node>();
|
||||
n->set_name("root-node");
|
||||
|
||||
// check
|
||||
{
|
||||
n->add_child()->set_name("node");
|
||||
}
|
||||
|
||||
// add a child
|
||||
auto c = std::make_shared<node>();
|
||||
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 leaf: " << n->children()[0]->is_leaf() << std::endl;
|
||||
std::cout << "s root: " << n->children()[0]->is_root() << std::endl;
|
||||
std::cout << "s leaf: " << n->children().front()->is_leaf() << std::endl;
|
||||
std::cout << "s root: " << n->children().front()->is_root() << std::endl;
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
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));
|
||||
|
||||
// auto t = n->transform();
|
||||
|
||||
// if (t)
|
||||
std::cout << n->transform().local()(0,0) << std::endl;
|
||||
// else {
|
||||
// std::cerr << "no transform?" << std::endl;
|
||||
// }
|
||||
// auto t = n->transform();
|
||||
|
||||
// if (t)
|
||||
// std::cout << n->transform().local()(0,0) << std::endl;
|
||||
// else {
|
||||
// std::cerr << "no transform?" << std::endl;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ int main(int argc,char **argv) {
|
|||
|
||||
node::ref root(std::make_shared<node>());
|
||||
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");
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ void register_scene_function(sol::state&,sol::table &ns)
|
|||
sol::constructors<node()>(),
|
||||
"add_child",&node::add_child,
|
||||
"children",sol::readonly_property(&node::children),
|
||||
"parent",sol::readonly_property(&node::parent),
|
||||
"child_count",sol::readonly_property(&node::child_count),
|
||||
"create", []() -> std::shared_ptr<node> { return std::make_shared<node>(); },
|
||||
"is_leaf", sol::readonly_property(&node::is_leaf),
|
||||
|
|
|
@ -30,20 +30,20 @@ public:
|
|||
|
||||
bool ready() const;
|
||||
|
||||
shader& bind(int location,float v);
|
||||
shader& bind(int location,matrix4x4f const & v);
|
||||
shader& bind(int location,vector4f const & v);
|
||||
shader& set(int location,float v);
|
||||
shader& set(int location,matrix4x4f const & v);
|
||||
shader& set(int location,vector4f const & v);
|
||||
|
||||
int uniform_location(std::string const & name) const;
|
||||
|
||||
template<typename T>
|
||||
shader & bind(std::string const & name, T&& value)
|
||||
shader & set(std::string const & name, T&& value)
|
||||
{
|
||||
int location = uniform_location(name);
|
||||
if (location >= 0)
|
||||
return bind(location, std::forward<T>(value));
|
||||
return set(location, std::forward<T>(value));
|
||||
else
|
||||
debug::e() << "missing uniform: "<< name;
|
||||
debug::e() << "missing uniform: '" << name << "'";
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "pw/core/mesh.hpp"
|
||||
#include "pw/core/timer.hpp"
|
||||
#include "pw/core/axisangle.hpp"
|
||||
#include "pw/core/serialize.hpp"
|
||||
#include "pw/core/transform_tools.hpp"
|
||||
|
||||
#include "pw/core/debug.hpp"
|
||||
#include "pw/visual/pipeline.hpp"
|
||||
|
@ -17,6 +19,8 @@ class command {
|
|||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class mesh_command : command {
|
||||
|
||||
// shader
|
||||
|
@ -46,10 +50,13 @@ struct triangle_renderer
|
|||
|
||||
void setup()
|
||||
{
|
||||
|
||||
const float z_val = -5.f;
|
||||
|
||||
mesh::vertex3array_t vertices = {
|
||||
{ 0.0f, 0.5f, 0.0f} // 0
|
||||
,{ 0.5f, -0.5f, 0.0f} // 1
|
||||
,{-0.5f, -0.5f, 0.0f} // 2
|
||||
{ 0.0f, 0.5f, z_val} // 0
|
||||
,{ 0.5f, -0.5f, z_val} // 1
|
||||
,{-0.5f, -0.5f, z_val} // 2
|
||||
};
|
||||
|
||||
// actual indices
|
||||
|
@ -59,71 +66,17 @@ struct triangle_renderer
|
|||
amesh.set_vertices(vertices);
|
||||
|
||||
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"(
|
||||
#version 400
|
||||
uniform mat4 model_mat;
|
||||
uniform mat4 view_mat = mat4
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
in vec3 vertex_p;
|
||||
|
||||
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(fragment_shader,shader::fragment);
|
||||
shader_p.set_source(fragment_shader_2,shader::fragment);
|
||||
|
||||
if (!shader_p.build())
|
||||
exit(-1);
|
||||
|
@ -148,19 +101,34 @@ struct triangle_renderer
|
|||
|
||||
shader_p.use();
|
||||
|
||||
static float v = 0.0f;
|
||||
v+= 0.01f;
|
||||
if (v>1.0f) v = 0.0f;
|
||||
vector4f test({0.5f,1-v,v,1.0f});
|
||||
auto v_col = ping_pong(static_cast<float>(timer::now()),1.0f);
|
||||
|
||||
vector4f col({0.5f,1-v_col,v_col,1.0f});
|
||||
|
||||
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();
|
||||
|
||||
|
||||
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 -
|
||||
shader_p.bind("input_color",test);
|
||||
shader_p.bind("model_mat",model_mat);
|
||||
shader_p.set("input_color",col);
|
||||
shader_p.set("model",model_mat);
|
||||
shader_p.set("view",view_mat);
|
||||
shader_p.set("projection",proj_mat);
|
||||
|
||||
amesh_renderer.draw();
|
||||
|
||||
|
|
|
@ -180,12 +180,12 @@ bool shader::ready() const
|
|||
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;
|
||||
}
|
||||
|
||||
shader &shader::bind(int location, const matrix4x4f &v)
|
||||
shader &shader::set(int location, const matrix4x4f &v)
|
||||
{
|
||||
_impl->bind(location,v); return *this;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue