some small refactorings

This commit is contained in:
Hartmut Seichter 2019-02-18 19:31:53 +01:00
parent d8fac9045b
commit 8eda3df225
23 changed files with 314 additions and 268 deletions

View file

@ -15,11 +15,11 @@ set(hdrs
include/pw/core/rectangle.hpp include/pw/core/rectangle.hpp
include/pw/core/serialize.hpp include/pw/core/serialize.hpp
include/pw/core/size.hpp include/pw/core/size.hpp
include/pw/core/timer.hpp include/pw/core/time.hpp
include/pw/core/mesh.hpp include/pw/core/mesh.hpp
include/pw/core/image.hpp include/pw/core/image.hpp
include/pw/core/vector.hpp include/pw/core/vector.hpp
include/pw/core/transform_tools.hpp include/pw/core/matrix_transform.hpp
) )
set(misc set(misc
@ -29,13 +29,13 @@ set(misc
) )
set(srcs set(srcs
# src/buffer.cpp # src/buffer.cpp
src/image.cpp src/image.cpp
src/debug.cpp src/debug.cpp
src/mesh.cpp src/mesh.cpp
src/core.cpp src/core.cpp
src/serialize.cpp src/serialize.cpp
src/timer.cpp src/time.cpp
src/image.cpp src/image.cpp
) )

View file

@ -31,7 +31,6 @@
namespace pw { namespace pw {
template <std::size_t R,std::size_t C, typename T, bool RowMajor = false> template <std::size_t R,std::size_t C, typename T, bool RowMajor = false>
struct matrix_ : matrixbase_<T, matrix_<R, C, T>> struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
{ {
@ -240,17 +239,17 @@ template <typename T> using matrix2x2_ = matrix_<2, 2, T>;
template <typename T> using matrix3x3_ = matrix_<3, 3, T>; template <typename T> using matrix3x3_ = matrix_<3, 3, T>;
template <typename T> using matrix4x4_ = matrix_<4, 4, T>; template <typename T> using matrix4x4_ = matrix_<4, 4, T>;
using matrix2x2f = matrix_<2, 2,float>; using matrix2x2f = matrix2x2_<float>;
using matrix2x2d = matrix_<2, 2,double>; using matrix2x2d = matrix2x2_<double>;
using matrix2x2 = matrix_<2, 2,real_t>; using matrix2x2 = matrix2x2_<real_t>;
using matrix3x3f = matrix_<3, 3,float>; using matrix3x3f = matrix3x3_<float>;
using matrix3x3d = matrix_<3, 3,double>; using matrix3x3d = matrix3x3_<double>;
using matrix3x3 = matrix_<3, 3,real_t>; using matrix3x3 = matrix3x3_<real_t>;
using matrix4x4f = matrix_<4, 4,float>; using matrix4x4f = matrix4x4_<float>;
using matrix4x4d = matrix_<4, 4,double>; using matrix4x4d = matrix4x4_<double>;
using matrix4x4 = matrix_<4, 4,real_t>; using matrix4x4 = matrix4x4_<real_t>;

View file

@ -1,4 +1,4 @@
/* /*
* Copyright (c) 1999-2019 Hartmut Seichter * Copyright (c) 1999-2019 Hartmut Seichter
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
@ -20,15 +20,15 @@
* SOFTWARE. * SOFTWARE.
* *
*/ */
#ifndef PW_CORE_TRANSFORM_TOOLS_HPP #ifndef PW_CORE_MATRIX_TRANSFORM_HPP
#define PW_CORE_TRANSFORM_TOOLS_HPP #define PW_CORE_MATRIX_TRANSFORM_HPP
#include <pw/core/vector.hpp> #include <pw/core/vector.hpp>
namespace pw { namespace pw {
template <typename T> template <typename T>
struct transform_tools { struct matrix_transform {
inline static inline static
matrix_<4,4,T> scale_matrix(const vector3_<T>& s) matrix_<4,4,T> scale_matrix(const vector3_<T>& s)
@ -39,7 +39,7 @@ struct transform_tools {
} }
inline static inline static
matrix_<4,4,T> projection_from_frustum(const T &left,const T &right, matrix_<4,4,T> perspective_frustum(const T &left,const T &right,
const T &bottom,const T &top, const T &bottom,const T &top,
const T &z_near,const T &z_far) const T &z_near,const T &z_far)
{ {
@ -63,40 +63,47 @@ struct transform_tools {
const T &aspect_ratio, const T &aspect_ratio,
const T &z_near,const T &z_far) const T &z_near,const T &z_far)
{ {
const T tan_half = tan(field_of_view / T(2)); const auto tan_half = tan(field_of_view / T(2));
const T right = aspect_ratio * tan_half * z_near; const auto right = aspect_ratio * tan_half * z_near;
const T left = -right; const auto left = -right;
const T top = aspect_ratio * tan_half; const auto top = aspect_ratio * tan_half;
const T bottom = -top; const auto bottom = -top;
return projection_from_frustum(left,right, return perspective_frustum(left,right,
bottom,top, bottom,top,
z_near,z_far); z_near,z_far);
} }
inline static inline static
matrix_<4,4,T> orthogonal_projection(T left, T right, matrix_<4,4,T> orthographic_frustum(T left, T right,
T bottom,T top, T bottom,T top,
T z_near, T z_far) T z_near, T z_far)
{ {
matrix_<4,4,T> ortho; matrix_<4,4,T> ortho; ortho.fill(0);
ortho.fill(0); ortho(0,0) = static_cast<T>(2) / (right-left);
ortho(0,0) = 2 / (right-left); ortho(1,1) = static_cast<T>(2) / (top-bottom);
ortho(1,1) = 2 / (top-bottom); ortho(2,2) = -static_cast<T>(2) / (z_far-z_near);
ortho(2,2) = -2 / (z_far-z_near);
ortho(0,3) = -(right+left)/(right-left); ortho(3,0) = -(right+left)/(right-left);
ortho(1,3) = -(top+bottom)/(top-bottom); ortho(3,1) = -(top+bottom)/(top-bottom);
ortho(2,3) = -(z_far+z_near)/(z_far-z_near); ortho(3,2) = -(z_far+z_near)/(z_far-z_near);
ortho(3,3) = 1; ortho(3,3) = 1;
return ortho; return ortho;
} }
inline static
matrix_<4,4,T> orthographic_projection(T size,T z_near, T z_far)
{
return orthographic_frustum(-size / 2, size / 2,
-size / 2, size / 2,
z_near,z_far);
}
inline static inline static
matrix_<4,4,T> look_at(const vector3_<T> &position, matrix_<4,4,T> look_at(const vector3_<T> &position,
@ -106,7 +113,7 @@ struct transform_tools {
matrix_<4,4,T> view_matrix; view_matrix.set_identity(); matrix_<4,4,T> view_matrix; view_matrix.set_identity();
const vector3_<T> los = (target - position).normalized(); // line of sight const vector3_<T> los = (target - position).normalized(); // line of sight
const vector3_<T> sid = los.cross(up).normalized(); const vector3_<T> sid = los.cross(up).normalized();
const vector3_<T> upd = sid.cross(los).normalized(); const vector3_<T> upd = sid.cross(los).normalized();
// set base vectors // set base vectors
@ -117,7 +124,6 @@ struct transform_tools {
return view_matrix; return view_matrix;
} }
}; };
} }

View file

@ -40,11 +40,12 @@ struct point_ {
}; };
typedef point_<real_t> point; using point = point_<real_t>;
using pointf = point_<float>;
using pointd = point_<double>;
using pointi = point_<int>;
typedef point_<int> pointi;
typedef point_<float> pointf;
typedef point_<float> pointd;
} }

View file

@ -23,8 +23,8 @@
#ifndef PW_CORE_RECT_HPP #ifndef PW_CORE_RECT_HPP
#define PW_CORE_RECT_HPP #define PW_CORE_RECT_HPP
#include <pw/core/size.hpp>
#include <pw/core/point.hpp> #include <pw/core/point.hpp>
#include <pw/core/size.hpp>
namespace pw { namespace pw {
@ -38,7 +38,7 @@ struct rectangle_ {
rectangle_(point_<T_> const & p,size_<T_> const & s) : size(s), position(p) {} rectangle_(point_<T_> const & p,size_<T_> const & s) : size(s), position(p) {}
bool contains(const point_<T_>& p) const bool contains(const point_<T_>& p) const noexcept
{ {
return p.x >= position.x && p.x <= position.x + size.width && return p.x >= position.x && p.x <= position.x + size.width &&
p.y >= position.y && p.y <= position.y + size.height; p.y >= position.y && p.y <= position.y + size.height;
@ -49,11 +49,9 @@ struct rectangle_ {
}; };
typedef rectangle_<real_t> rectangle; using rectangle = rectangle_<real_t>;
using rectanglef = rectangle_<float>;
typedef rectangle_<int> rectanglei; using rectangled = rectangle_<double>;
typedef rectangle_<float> rectanglef;
typedef rectangle_<double> rectangled;
} }

View file

@ -32,13 +32,13 @@ namespace pw {
/** /**
* @brief A simple timer * @brief A simple timer
*/ */
class timer { class time {
public: public:
typedef std::chrono::time_point<std::chrono::high_resolution_clock> tick_t; typedef std::chrono::time_point<std::chrono::high_resolution_clock> tick_t;
timer(); /// c'tor time(); /// c'tor
~timer(); /// d'tor ~time(); /// d'tor
void reset(); /// reset the timer void reset(); /// reset the timer

View file

@ -20,34 +20,34 @@
* SOFTWARE. * SOFTWARE.
* *
*/ */
#include "pw/core/timer.hpp" #include "pw/core/time.hpp"
namespace pw { namespace pw {
timer::timer() time::time()
{ {
reset(); reset();
} }
timer::~timer() time::~time()
{ {
} }
void timer::reset() void time::reset()
{ {
_start = std::chrono::high_resolution_clock::now(); _start = std::chrono::high_resolution_clock::now();
} }
double timer::elapsed() const double time::elapsed() const
{ {
std::chrono::duration<double> elapsed_seconds = std::chrono::high_resolution_clock::now() - _start; std::chrono::duration<double> elapsed_seconds = std::chrono::high_resolution_clock::now() - _start;
return elapsed_seconds.count(); return elapsed_seconds.count();
} }
double timer::now() double time::now()
{ {
static timer global_timer; static time global_time;
return global_timer.elapsed(); return global_time.elapsed();
} }
} }

View file

@ -1,6 +1,6 @@
#include <pw/core/vector.hpp> #include <pw/core/vector.hpp>
#include <pw/core/serialize.hpp> #include <pw/core/serialize.hpp>
#include <pw/core/transform_tools.hpp> #include <pw/core/matrix_transform.hpp>
#include <pw/core/mesh.hpp> #include <pw/core/mesh.hpp>
#include <pw/core/axisangle.hpp> #include <pw/core/axisangle.hpp>
@ -17,7 +17,7 @@ int main(int argc,char **argv) {
std::cout << pw::serialize::matrix(v.transposed()) << std::endl; std::cout << pw::serialize::matrix(v.transposed()) << std::endl;
} }
auto scale = pw::transform_tools<float>::scale_matrix({2,2,2}); auto scale = pw::matrix_transform<float>::scale_matrix({2,2,2});
amesh.apply(scale); amesh.apply(scale);

View file

@ -1,15 +1,15 @@
#include <pw/core/vector.hpp> #include <pw/core/vector.hpp>
#include <pw/core/serialize.hpp> #include <pw/core/serialize.hpp>
#include <pw/core/transform_tools.hpp> #include <pw/core/matrix_transform.hpp>
#include <iostream> #include <iostream>
int main(int argc,char **argv) { int main(int argc,char **argv) {
auto perspective_mat = pw::transform_tools<float>::perspective_projection(45.f,1.3f,10,100); auto perspective_mat = pw::matrix_transform<float>::perspective_projection(45.f,1.3f,10,100);
auto ortho_mat = pw::transform_tools<float>::orthogonal_projection(-1,1,1,-1,10,100); auto ortho_mat = pw::matrix_transform<float>::orthographic_frustum(-1,1,1,-1,10,100);
auto lookat_mat = pw::transform_tools<float>::look_at(pw::vector3(0,0,5),pw::vector3(0,0,0),pw::vector3(0,1,0)); auto lookat_mat = pw::matrix_transform<float>::look_at(pw::vector3(0,0,5),pw::vector3(0,0,0),pw::vector3(0,1,0));
std::cout << pw::serialize::matrix(perspective_mat) << std::endl; std::cout << pw::serialize::matrix(perspective_mat) << std::endl;

View file

@ -8,6 +8,8 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h" #include "stb_image_write.h"
#include <future>
namespace pw { namespace pw {
struct image_io::impl struct image_io::impl

View file

@ -1,5 +1,5 @@
#include "pw/scene/camera.hpp" #include "pw/scene/camera.hpp"
#include "pw/core/transform_tools.hpp" #include "pw/core/matrix_transform.hpp"
namespace pw { namespace pw {
@ -9,7 +9,7 @@ camera::camera(node &host)
, _near_plane(0.2f) , _near_plane(0.2f)
, _far_plane(1000) , _far_plane(1000)
{ {
set_projection(transform_tools<real_t>::perspective_projection(_fov,1,_near_plane,_far_plane)); set_projection(matrix_transform<real_t>::perspective_projection(_fov,1,_near_plane,_far_plane));
} }
void camera::set_projection(const matrix4x4 &projection) void camera::set_projection(const matrix4x4 &projection)

View file

@ -4,7 +4,7 @@
#include "pw/core/debug.hpp" #include "pw/core/debug.hpp"
#include "pw/core/size.hpp" #include "pw/core/size.hpp"
#include "pw/core/point.hpp" #include "pw/core/point.hpp"
#include "pw/core/timer.hpp" #include "pw/core/time.hpp"
#include "pw/core/mesh.hpp" #include "pw/core/mesh.hpp"
#include "pw/core/image.hpp" #include "pw/core/image.hpp"
@ -97,11 +97,11 @@ void register_core_function(sol::state& lua,sol::table& ns)
); );
ns.new_usertype<timer>("timer", ns.new_usertype<time>("time",
"now",sol::readonly_property(&timer::now), "now",sol::readonly_property(&time::now),
"elapsed",sol::readonly_property(&timer::elapsed), "elapsed",sol::readonly_property(&time::elapsed),
"reset",&timer::reset "reset",&time::reset
); );
auto mesh_type = ns.new_usertype<mesh>("mesh" auto mesh_type = ns.new_usertype<mesh>("mesh"
, sol::constructors<mesh()>() , sol::constructors<mesh()>()
@ -110,11 +110,11 @@ void register_core_function(sol::state& lua,sol::table& ns)
, "indices", sol::property(&mesh::indices,&mesh::set_indices) , "indices", sol::property(&mesh::indices,&mesh::set_indices)
); );
mesh_type.new_enum("topology" mesh_type.new_enum("topology"
, "points", mesh::topology_type::points , "points", mesh::topology_type::points
, "lines", mesh::topology_type::lines , "lines", mesh::topology_type::lines
, "line_strip", mesh::topology_type::line_strip , "line_strip", mesh::topology_type::line_strip
); );
ns.new_usertype<image>("image" ns.new_usertype<image>("image"
,"create",&image::create ,"create",&image::create

View file

@ -22,8 +22,8 @@ void register_visual_function(sol::state&,sol::table &ns)
,"set_source",&shader::set_source ,"set_source",&shader::set_source
,"source",&shader::source ,"source",&shader::source
).new_enum("shader_type" ).new_enum("shader_type"
,"fragment",shader::fragment ,"fragment",shader::code_type::fragment
,"vertex",shader::vertex); ,"vertex",shader::code_type::vertex);
} }
PW_REGISTER_LUA(visual) PW_REGISTER_LUA(visual)

View file

@ -1,3 +1,7 @@
--
-- small demonstrator for Lua binding on pixwerx
--
-- loading our libraries -- loading our libraries
pw.script:load_all() pw.script:load_all()
@ -16,7 +20,6 @@ w.position = pw.point.new(100,100)
print("client size after resize: ",w.client_size.width,w.client_size.height) print("client size after resize: ",w.client_size.width,w.client_size.height)
local pl = pw.pipeline.new() local pl = pw.pipeline.new()
if pl:create(w.client_size) then if pl:create(w.client_size) then
print("pipeline ok") print("pipeline ok")
@ -27,7 +30,7 @@ end
-- setup a lua callback function as callback -- setup a lua callback function as callback
w.on_update = function(self) w.on_update = function(self)
pl:draw() pl:draw()
-- print("test on update",w.position.x,w.position.y,pw.timer.now) -- print("test on update",w.position.x,w.position.y,pw.time.now)
end end
@ -37,7 +40,7 @@ for i = 1,#ds do
print("display ",i,ds[i].name) print("display ",i,ds[i].name)
end end
local t = pw.timer.new() local t = pw.time.new()
w.visible = true w.visible = true

View file

@ -34,12 +34,20 @@ public:
static path& get(); static path& get();
~path(); ~path();
std::string separator(); std::string separator() const;
std::string executable_path(); std::string executable_path() const;
std::string resource_path() const;
typedef std::vector<std::string> path_list; typedef std::vector<std::string> path_list;
std::string find_file(const std::string &filename) const;
path_list resource_paths() const { return _resource_paths; }
std::string get_filename(const std::string &filepath, bool with_extension = true) const;
protected: protected:
path_list _plugin_paths; path_list _plugin_paths;

View file

@ -18,6 +18,9 @@
// Unknown platform // Unknown platform
#endif #endif
// Why? LLVM does not adhere to C++17
//#include <filesystem>
namespace pw { namespace pw {
@ -44,7 +47,7 @@ path::~path()
{ {
} }
std::string path::separator() std::string path::separator() const
{ {
#if defined(WIN32) #if defined(WIN32)
return std::string("\\"); return std::string("\\");
@ -53,7 +56,7 @@ std::string path::separator()
#endif #endif
} }
std::string path::executable_path() std::string path::executable_path() const
{ {
std::string result; std::string result;
const size_t MAXPATHLEN = 2048; const size_t MAXPATHLEN = 2048;
@ -81,9 +84,27 @@ std::string path::executable_path()
return result; return result;
} }
std::string path::find_file(const std::string& filename) const
{
// for ()
}
path::path() path::path()
{ {
_impl = std::make_unique<impl>(*this); _impl = std::make_unique<impl>(*this);
} }
std::string path::get_filename(const std::string& filepath,
bool with_extension) const
{
std::size_t dotPos = filepath.rfind('.');
std::size_t sepPos = filepath.rfind(separator());
if(sepPos != std::string::npos) {
return filepath.substr(sepPos + 1,
filepath.size() - (with_extension || dotPos != std::string::npos ? 1 : dotPos) );
}
return "";
}
} }

View file

@ -17,7 +17,7 @@ public:
shader(); shader();
~shader(); ~shader();
enum code_type { enum class code_type {
vertex, vertex,
fragment, fragment,
geometry, geometry,

View file

@ -9,12 +9,12 @@ namespace pw {
class texture { class texture {
enum texture_type { enum class data_type {
color, color,
normal normal
}; };
enum texture_shape { enum class data_layout {
shape_1d, shape_1d,
shape_2d, shape_2d,
shape_3d shape_3d
@ -35,16 +35,16 @@ class texture {
texture(); texture();
texture(shared_ptr<image> i,texture_shape s,texture_type = color); texture(shared_ptr<image> i,data_layout s,data_type = data_type::color);
void set_image(shared_ptr<image> i); void set_image(shared_ptr<image> i);
shared_ptr<image> get() const { return _image; } shared_ptr<image> get() const { return _image; }
void set_type(texture_type t); void set_type(data_type t);
texture_type type() const { return _type; } data_type type() const { return _type; }
void set_shape(texture_shape s); void set_shape(data_layout s);
texture_shape shape() const { return _shape; } data_layout shape() const { return _shape; }
void set_wrap(wrap_mode w); void set_wrap(wrap_mode w);
wrap_mode wrap() const { return _wrap; } wrap_mode wrap() const { return _wrap; }
@ -55,8 +55,8 @@ protected:
shared_ptr<image> _image; shared_ptr<image> _image;
texture_type _type; data_type _type;
texture_shape _shape; data_layout _shape;
wrap_mode _wrap; wrap_mode _wrap;
struct impl; struct impl;

View file

@ -16,7 +16,7 @@ public:
~vertex_array(); ~vertex_array();
void create(const mesh &m); void create(const mesh &m);
void destroy(); void release();
void draw(); void draw();
bool ready() const; bool ready() const;

View file

@ -1,10 +1,10 @@
#include "pw/core/size.hpp" #include "pw/core/size.hpp"
#include "pw/core/matrix.hpp" #include "pw/core/matrix.hpp"
#include "pw/core/mesh.hpp" #include "pw/core/mesh.hpp"
#include "pw/core/timer.hpp" #include "pw/core/time.hpp"
#include "pw/core/axisangle.hpp" #include "pw/core/axisangle.hpp"
#include "pw/core/serialize.hpp" #include "pw/core/serialize.hpp"
#include "pw/core/transform_tools.hpp" #include "pw/core/matrix_transform.hpp"
#include "pw/core/debug.hpp" #include "pw/core/debug.hpp"
#include "pw/visual/pipeline.hpp" #include "pw/visual/pipeline.hpp"
@ -20,295 +20,301 @@ class command {
}; };
class mesh_command : command { class mesh_command : command {
// shader // shader
// vertexarray // vertexarray
}; };
class queue { class queue {
// vector<commands> ... // vector<commands> ...
}; };
struct triangle_renderer struct triangle_renderer
{ {
// GLuint vbo = 0; // GLuint vbo = 0;
// GLuint vao = 0; // GLuint vao = 0;
// GLuint shader_programme = 0; // GLuint shader_programme = 0;
shader shader_p; shader shader_p;
mesh amesh; mesh amesh;
vertex_array amesh_renderer; vertex_array amesh_renderer;
timer::tick_t tick; time::tick_t tick;
triangle_renderer() triangle_renderer()
{ {
} }
void setup() void setup()
{ {
const float z_val = -5.f; const float z_val = -5.f;
mesh::vertex3array_t vertices = { mesh::vertex3array_t vertices = {
{ 0.0f, 0.5f, z_val} // 0 { 0.0f, 0.5f, z_val} // 0
,{ 0.5f, -0.5f, z_val} // 1 ,{ 0.5f, 0.0f, z_val} // 1
,{-0.5f, -0.5f, z_val} // 2 ,{-0.5f, 0.0f, z_val} // 2
}; };
// actual indices // actual indices
mesh::indexarray_t indices = { 0, 1, 2}; mesh::indexarray_t indices = { 0, 1, 2};
amesh.set_indices(indices); amesh.set_indices(indices);
amesh.set_vertices(vertices); amesh.set_vertices(vertices);
amesh_renderer.create(amesh); amesh_renderer.create(amesh);
const char* vertex_shader_2 = R"( const char* vertex_shader_2 = R"(
#version 400 #version 400
uniform mat4 model; uniform mat4 model;
uniform mat4 view; uniform mat4 view;
uniform mat4 projection; uniform mat4 projection;
in vec3 vertex_p; in vec3 vertex_p;
void main() { void main() {
gl_Position = projection * view * model * vec4(vertex_p, 1.0); gl_Position = projection * view * model * vec4(vertex_p, 1.0);
} }
)"; )";
const char *fragment_shader_2 = R"( const char *fragment_shader_2 = R"(
#version 400 #version 400
uniform vec4 input_color = vec4(1.0, 0.0, 0.0, 1.0); uniform vec4 input_color = vec4(1.0, 0.0, 0.0, 1.0);
out vec4 frag_colour; out vec4 frag_colour;
void main() { void main() {
frag_colour = input_color; frag_colour = input_color;
})"; })";
shader_p.set_source(vertex_shader_2,shader::vertex); shader_p.set_source(vertex_shader_2,shader::code_type::vertex);
shader_p.set_source(fragment_shader_2,shader::fragment); shader_p.set_source(fragment_shader_2,shader::code_type::fragment);
if (!shader_p.build()) if (!shader_p.build())
exit(-1); exit(-1);
} }
void draw() void draw()
{ {
shader_p.use(); shader_p.use();
auto v_col = ping_pong(static_cast<float>(timer::now()),1.0f); auto v_col = ping_pong(static_cast<float>(time::now()),1.0f);
vector4f col({0.5f,1-v_col,v_col,1.0f}); vector4f col({0.5f,1-v_col,v_col,1.0f});
matrix4x4f model_mat; model_mat.set_identity(); matrix4x4f model_mat; model_mat.set_identity();
auto v_angle = ping_pong(static_cast<float>(timer::now()),::pw::pi<float>()); auto v_angle = ping_pong(static_cast<float>(time::now()),2 * ::pw::pi<float>());
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 = matrix_transform<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(60.0f), view_mat.set_identity();
matrix4x4f proj_mat = matrix_transform<float>::perspective_projection(deg_to_rad(33.0f),
1.3f, 1.3f,
0.2f,1000.f); 0.2f,1000.f);
// materials should carry this
// glEnable(GL_CULL_FACE);
// highly inefficient - should be cached -
//proj_mat = transform_tools<float>::orthographic_projection(0.5,0.2f,100.f);
// 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 ... // new version with ...
shader::uniform_set us; shader::uniform_set us;
us["input_color"] = col; us["input_color"] = col;
shader_p.set_uniforms(us); // 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";
}
}
}; };
struct pipeline::impl { struct pipeline::impl {
sizei _size; sizei _size;
GLuint _fbo_draw; GLuint _fbo_draw;
GLuint _fbo_msaa; GLuint _fbo_msaa;
GLuint _rbo_color; GLuint _rbo_color;
GLuint _rbo_depth; GLuint _rbo_depth;
//testing //testing
triangle_renderer tr; triangle_renderer tr;
bool create(sizei size); bool create(sizei size);
void draw(); void draw();
impl() = default; impl() = default;
~impl() = default; ~impl() = default;
}; };
GLuint generate_multisample_texture(const sizei& s,int samples) GLuint generate_multisample_texture(const sizei& s,int samples)
{ {
GLuint texture; GLuint texture;
glGenTextures(1, &texture); glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGB8, s.width, s.height, GL_TRUE); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGB8, s.width, s.height, GL_TRUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
return texture; return texture;
} }
bool pipeline::impl::create(sizei size) bool pipeline::impl::create(sizei size)
{ {
_size = size; _size = size;
int max_msaa; int max_msaa;
// query actual maximum MSAA // query actual maximum MSAA
glGetIntegerv(GL_MAX_SAMPLES,&max_msaa); glGetIntegerv(GL_MAX_SAMPLES,&max_msaa);
// create a 4x MSAA renderbuffer object for colorbuffer // create a 4x MSAA renderbuffer object for colorbuffer
int msaa = std::min(max_msaa,4); int msaa = std::min(max_msaa,4);
debug::d() << "OpenGL multisampling: " << max_msaa << " choosen:" << msaa; debug::d() << "OpenGL multisampling: " << max_msaa << " choosen:" << msaa;
glGenRenderbuffers(1, &_rbo_color); glGenRenderbuffers(1, &_rbo_color);
glBindRenderbuffer(GL_RENDERBUFFER, _rbo_color); glBindRenderbuffer(GL_RENDERBUFFER, _rbo_color);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, _size.width, _size.height); glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, _size.width, _size.height);
// create a 4x MSAA renderbuffer object for depthbuffer // create a 4x MSAA renderbuffer object for depthbuffer
glGenRenderbuffers(1, &_rbo_depth); glGenRenderbuffers(1, &_rbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, _rbo_depth); glBindRenderbuffer(GL_RENDERBUFFER, _rbo_depth);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_DEPTH_COMPONENT, _size.width, _size.height); glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_DEPTH_COMPONENT, _size.width, _size.height);
// create a 4x MSAA framebuffer object // create a 4x MSAA framebuffer object
glGenFramebuffers(1, &_fbo_msaa); glGenFramebuffers(1, &_fbo_msaa);
glBindFramebuffer(GL_FRAMEBUFFER, _fbo_msaa); glBindFramebuffer(GL_FRAMEBUFFER, _fbo_msaa);
// attach colorbuffer image to FBO // attach colorbuffer image to FBO
glFramebufferRenderbuffer(GL_FRAMEBUFFER, // 1. fbo target: GL_FRAMEBUFFER glFramebufferRenderbuffer(GL_FRAMEBUFFER, // 1. fbo target: GL_FRAMEBUFFER
GL_COLOR_ATTACHMENT0, // 2. color attachment point GL_COLOR_ATTACHMENT0, // 2. color attachment point
GL_RENDERBUFFER, // 3. rbo target: GL_RENDERBUFFER GL_RENDERBUFFER, // 3. rbo target: GL_RENDERBUFFER
_rbo_color); // 4. rbo ID _rbo_color); // 4. rbo ID
// attach depthbuffer image to FBO // attach depthbuffer image to FBO
glFramebufferRenderbuffer(GL_FRAMEBUFFER, // 1. fbo target: GL_FRAMEBUFFER glFramebufferRenderbuffer(GL_FRAMEBUFFER, // 1. fbo target: GL_FRAMEBUFFER
GL_DEPTH_ATTACHMENT, // 2. depth attachment point GL_DEPTH_ATTACHMENT, // 2. depth attachment point
GL_RENDERBUFFER, // 3. rbo target: GL_RENDERBUFFER GL_RENDERBUFFER, // 3. rbo target: GL_RENDERBUFFER
_rbo_depth); // 4. rbo ID _rbo_depth); // 4. rbo ID
// check FBO status // check FBO status
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false; return false;
// reset // reset
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
tr.setup(); tr.setup();
return true; return true;
} }
void pipeline::impl::draw() void pipeline::impl::draw()
{ {
glClearColor(0,0,0,1); glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_msaa); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_msaa);
glClearColor(1,1,1,1); glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glViewport(0,0,800,600);
// draw pass
//
tr.draw(); //
// draw pass
//
tr.draw();
// reset // reset
// actuall blitting // actuall blitting
#if 0 #if 0
/* We are going to blit into the window (default framebuffer) */ /* We are going to blit into the window (default framebuffer) */
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffer (GL_BACK); /* Use backbuffer as color dst. */ glDrawBuffer (GL_BACK); /* Use backbuffer as color dst. */
/* Read from your FBO */ /* Read from your FBO */
glBindFramebuffer (GL_READ_FRAMEBUFFER, _fbo_draw ); glBindFramebuffer (GL_READ_FRAMEBUFFER, _fbo_draw );
glReadBuffer (GL_COLOR_ATTACHMENT0); /* Use Color Attachment 0 as color src. */ glReadBuffer (GL_COLOR_ATTACHMENT0); /* Use Color Attachment 0 as color src. */
/* Copy the color and depth buffer from your FBO to the default framebuffer */ /* Copy the color and depth buffer from your FBO to the default framebuffer */
glBlitFramebuffer (0,0, _size.width, _size.height, glBlitFramebuffer (0,0, _size.width, _size.height,
0,0, _size.width, _size.height, 0,0, _size.width, _size.height,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST); GL_NEAREST);
#else #else
glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo_msaa); // src FBO (multi-sample) glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo_msaa); // src FBO (multi-sample)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_draw); // dst FBO (single-sample) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_draw); // dst FBO (single-sample)
glBlitFramebuffer(0, 0, _size.width, _size.height, // src rect glBlitFramebuffer(0, 0, _size.width, _size.height, // src rect
0, 0, _size.width, _size.height, // dst rect 0, 0, _size.width, _size.height, // dst rect
GL_COLOR_BUFFER_BIT, // buffer mask GL_COLOR_BUFFER_BIT, // buffer mask
GL_LINEAR); // scale filter GL_LINEAR); // scale filter
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
// debug::d() << _size.width << "x" << _size.height; // debug::d() << _size.width << "x" << _size.height;
#endif #endif
GLenum err; GLenum err;
while((err = glGetError()) != GL_NO_ERROR) while((err = glGetError()) != GL_NO_ERROR)
{ {
std::string error; std::string error;
switch(err) { switch(err) {
case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break; case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break;
case GL_INVALID_ENUM: error="INVALID_ENUM"; break; case GL_INVALID_ENUM: error="INVALID_ENUM"; break;
case GL_INVALID_VALUE: error="INVALID_VALUE"; break; case GL_INVALID_VALUE: error="INVALID_VALUE"; break;
case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break; case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break; case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break;
} }
debug::e() << "OpenGL error:" << err << " " << error; debug::e() << "OpenGL error:" << err << " " << error;
} }
} }
@ -318,23 +324,23 @@ void pipeline::impl::draw()
// //
pipeline::pipeline() pipeline::pipeline()
: _impl(std::make_unique<pipeline::impl>()) : _impl(std::make_unique<pipeline::impl>())
{ {
} }
pipeline::~pipeline() pipeline::~pipeline()
{ {
// //
} }
void pipeline::draw() void pipeline::draw()
{ {
_impl->draw(); _impl->draw();
} }
bool pipeline::create(size s) bool pipeline::create(size s)
{ {
return _impl->create(s.cast<int>()); return _impl->create(s.cast<int>());
} }
} }

View file

@ -37,16 +37,16 @@ struct shader::impl
{ {
GLuint shader_type = 0; GLuint shader_type = 0;
switch (s.first) { switch (s.first) {
case shader::vertex: case shader::code_type::vertex:
shader_type = GL_VERTEX_SHADER; shader_type = GL_VERTEX_SHADER;
break; break;
case shader::compute: case shader::code_type::compute:
shader_type = GL_COMPUTE_SHADER; shader_type = GL_COMPUTE_SHADER;
break; break;
case shader::geometry: case shader::code_type::geometry:
shader_type = GL_GEOMETRY_SHADER; shader_type = GL_GEOMETRY_SHADER;
break; break;
case shader::fragment: case shader::code_type::fragment:
shader_type = GL_FRAGMENT_SHADER; shader_type = GL_FRAGMENT_SHADER;
break; break;
} }
@ -210,6 +210,7 @@ void shader::set_uniforms(shader::uniform_set s)
// }, // },
// u.second); // u.second);
std::tuple<std::string,int,uniform_t> uuu;
std::visit([u](auto&& arg) { std::visit([u](auto&& arg) {
using T = std::decay_t<decltype(arg)>; using T = std::decay_t<decltype(arg)>;

View file

@ -19,11 +19,11 @@ struct texture::impl {
GLuint gl_shape() { GLuint gl_shape() {
switch (_host.shape()) { switch (_host.shape()) {
case pw::texture::shape_1d: case data_layout::shape_1d:
return GL_TEXTURE_1D; return GL_TEXTURE_1D;
case pw::texture::shape_2d: case data_layout::shape_2d:
return GL_TEXTURE_2D; return GL_TEXTURE_2D;
case pw::texture::shape_3d: case data_layout::shape_3d:
return GL_TEXTURE_3D; return GL_TEXTURE_3D;
} }
} }
@ -74,7 +74,7 @@ texture::texture()
_impl = make_unique<impl>(*this); _impl = make_unique<impl>(*this);
} }
texture::texture(shared_ptr<image> i, texture::texture_shape s, texture::texture_type t) texture::texture(shared_ptr<image> i, texture::data_layout s, texture::data_type t)
{ {
texture(); texture();
set_image(i); set_image(i);
@ -87,12 +87,12 @@ void texture::set_image(shared_ptr<image> i)
_image = i; _image = i;
} }
void texture::set_type(texture::texture_type t) void texture::set_type(texture::data_type t)
{ {
_type = t; _type = t;
} }
void texture::set_shape(texture_shape s) void texture::set_shape(data_layout s)
{ {
_shape = s; _shape = s;
} }

View file

@ -20,7 +20,7 @@ struct vertex_array::impl {
~impl() ~impl()
{ {
destroy(); release();
} }
bool ready() const bool ready() const
@ -32,7 +32,7 @@ struct vertex_array::impl {
{ {
// not sure ... // not sure ...
if (ready()) { if (ready()) {
destroy(); release();
} }
glGenVertexArrays(1,&_vao); glGenVertexArrays(1,&_vao);
@ -54,6 +54,7 @@ struct vertex_array::impl {
glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]); glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(m.vertices().front()) * m.vertices().size(), m.vertices().data(), glBufferData(GL_ARRAY_BUFFER, sizeof(m.vertices().front()) * m.vertices().size(), m.vertices().data(),
GL_STATIC_DRAW); GL_STATIC_DRAW);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
@ -68,7 +69,7 @@ struct vertex_array::impl {
} }
void destroy() void release()
{ {
glDeleteVertexArrays(1,&_vao); glDeleteVertexArrays(1,&_vao);
for (auto vbo : _vbos) for (auto vbo : _vbos)
@ -114,9 +115,9 @@ void vertex_array::create(const mesh &m)
_impl->create(m); _impl->create(m);
} }
void vertex_array::destroy() void vertex_array::release()
{ {
_impl->destroy(); _impl->release();
} }
void vertex_array::draw() void vertex_array::draw()