Major push to get renderer separated and configurable.
Signed-off-by: Hartmut Seichter <hartmut@technotecture.com>
This commit is contained in:
parent
77e254872f
commit
d2c8262c68
22 changed files with 542 additions and 97 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "pw/core/time.hpp"
|
#include "pw/core/time.hpp"
|
||||||
#include "pw/core/geometry.hpp"
|
#include "pw/core/geometry.hpp"
|
||||||
#include "pw/core/image.hpp"
|
#include "pw/core/image.hpp"
|
||||||
|
#include "pw/core/matrix_transform.hpp"
|
||||||
|
|
||||||
#include "runtime_lua.hpp"
|
#include "runtime_lua.hpp"
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
namespace sol {
|
namespace sol {
|
||||||
template <> struct is_automagical<pw::matrix4x4> : std::false_type {};
|
template <> struct is_automagical<pw::matrix4x4> : std::false_type {};
|
||||||
template <> struct is_automagical<pw::vector3> : std::false_type {};
|
template <> struct is_automagical<pw::vector3> : std::false_type {};
|
||||||
|
template <> struct is_automagical<pw::vector4> : std::false_type {};
|
||||||
template <> struct is_automagical<pw::quaternion> : std::false_type {};
|
template <> struct is_automagical<pw::quaternion> : std::false_type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +46,24 @@ void register_core_function(sol::state& lua,sol::table& ns)
|
||||||
,"cross",&vector3::cross
|
,"cross",&vector3::cross
|
||||||
,"transposed",&vector3::transposed
|
,"transposed",&vector3::transposed
|
||||||
,"lerp",&vector3::lerp
|
,"lerp",&vector3::lerp
|
||||||
|
,"forward",&vector3::forward
|
||||||
|
,"backward",&vector3::backward
|
||||||
|
,"left",&vector3::left
|
||||||
|
,"right",&vector3::right
|
||||||
|
,"up",&vector3::up
|
||||||
|
,"down",&vector3::down
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ns.new_usertype<vector4>("vector4"
|
||||||
|
,sol::constructors<vector4(),vector4(vector4::value_type,vector4::value_type,vector4::value_type,vector4::value_type)>()
|
||||||
|
,"x", sol::property(sol::resolve<const vector4::value_type&() const>(&vector4::x), [](vector4& v,vector4::value_type val){ v.x() = val;})
|
||||||
|
,"y", sol::property(sol::resolve<const vector4::value_type&() const>(&vector4::y), [](vector4& v,vector4::value_type val){ v.y() = val;})
|
||||||
|
,"z", sol::property(sol::resolve<const vector4::value_type&() const>(&vector4::z), [](vector4& v,vector4::value_type val){ v.z() = val;})
|
||||||
|
,"w", sol::property(sol::resolve<const vector4::value_type&() const>(&vector4::w), [](vector4& v,vector4::value_type val){ v.w() = val;})
|
||||||
|
,"project",&vector4::project
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
ns.new_usertype<quaternion>("quaternion"
|
ns.new_usertype<quaternion>("quaternion"
|
||||||
,sol::constructors<quaternion(), quaternion(quaternion::value_type,quaternion::value_type,quaternion::value_type,quaternion::value_type)>()
|
,sol::constructors<quaternion(), quaternion(quaternion::value_type,quaternion::value_type,quaternion::value_type,quaternion::value_type)>()
|
||||||
,"x", sol::property(sol::resolve<const quaternion::value_type&() const>(&quaternion::x), [](quaternion& v,quaternion::value_type val){ v.x() = val;})
|
,"x", sol::property(sol::resolve<const quaternion::value_type&() const>(&quaternion::x), [](quaternion& v,quaternion::value_type val){ v.x() = val;})
|
||||||
|
@ -77,11 +95,6 @@ void register_core_function(sol::state& lua,sol::table& ns)
|
||||||
, "height",&size::height
|
, "height",&size::height
|
||||||
);
|
);
|
||||||
|
|
||||||
ns.new_usertype<sizei>("sizei"
|
|
||||||
, sol::constructors<sizei(),sizei(int,int)>()
|
|
||||||
, "width",&sizei::width
|
|
||||||
, "height",&sizei::height
|
|
||||||
);
|
|
||||||
|
|
||||||
ns.new_usertype<point>("point",
|
ns.new_usertype<point>("point",
|
||||||
sol::constructors<point(),point(Scalar,Scalar)>(),
|
sol::constructors<point(),point(Scalar,Scalar)>(),
|
||||||
|
@ -109,13 +122,18 @@ void register_core_function(sol::state& lua,sol::table& ns)
|
||||||
, "topology", sol::property(&geometry::topology,&geometry::set_topology)
|
, "topology", sol::property(&geometry::topology,&geometry::set_topology)
|
||||||
, "vertices", sol::property(&geometry::vertices,&geometry::set_vertices)
|
, "vertices", sol::property(&geometry::vertices,&geometry::set_vertices)
|
||||||
, "indices", sol::property(&geometry::indices,&geometry::set_indices)
|
, "indices", sol::property(&geometry::indices,&geometry::set_indices)
|
||||||
).new_enum<false>("type"
|
, "", &geometry::compute_normals
|
||||||
|
).new_enum<false>("geometry_type"
|
||||||
,"points", geometry::topology_type::points
|
,"points", geometry::topology_type::points
|
||||||
, "lines", geometry::topology_type::lines
|
, "lines", geometry::topology_type::lines
|
||||||
, "line_strip", geometry::topology_type::line_strip
|
, "line_strip", geometry::topology_type::line_strip
|
||||||
, "triangles", geometry::topology_type::triangles);
|
, "triangles", geometry::topology_type::triangles);
|
||||||
|
|
||||||
|
|
||||||
|
ns.new_usertype<matrix_transform<real_t>>("matrixtransform"
|
||||||
|
,"new",sol::no_constructor
|
||||||
|
,"look_at",&matrix_transform<real_t>::look_at
|
||||||
|
,"perspective_projection",&matrix_transform<real_t>::perspective_projection);
|
||||||
// SOL3
|
// SOL3
|
||||||
// geoom_type["type"] = lua.create_table_with(
|
// geoom_type["type"] = lua.create_table_with(
|
||||||
// "points", geometry::topology_type::points
|
// "points", geometry::topology_type::points
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include "pw/core/debug.hpp"
|
#include "pw/core/debug.hpp"
|
||||||
#include "pw/visual/pipeline.hpp"
|
#include "pw/visual/pipeline.hpp"
|
||||||
#include "pw/visual/shader.hpp"
|
#include "pw/visual/shader.hpp"
|
||||||
|
#include "pw/visual/framebuffer.hpp"
|
||||||
|
#include "pw/core/size.hpp"
|
||||||
|
|
||||||
#include "runtime_lua.hpp"
|
#include "runtime_lua.hpp"
|
||||||
|
|
||||||
|
@ -25,6 +27,9 @@ void register_visual_function(sol::state&,sol::table &ns)
|
||||||
,"source",&shader::source
|
,"source",&shader::source
|
||||||
,"set_source",&shader::set_source
|
,"set_source",&shader::set_source
|
||||||
,"set_uniforms",&shader::set_uniforms
|
,"set_uniforms",&shader::set_uniforms
|
||||||
|
,"set_uniform_float",&shader::set_uniform<float>
|
||||||
|
,"set_uniform_mat4",&shader::set_uniform<matrix4x4&>
|
||||||
|
,"set_uniform_vec4",&shader::set_uniform<vector4&>
|
||||||
).new_enum<false>("shader_type"
|
).new_enum<false>("shader_type"
|
||||||
,"fragment",shader::code_type::fragment
|
,"fragment",shader::code_type::fragment
|
||||||
,"vertex",shader::code_type::vertex
|
,"vertex",shader::code_type::vertex
|
||||||
|
@ -40,7 +45,20 @@ void register_visual_function(sol::state&,sol::table &ns)
|
||||||
,"color",sol::property(&material::_color));
|
,"color",sol::property(&material::_color));
|
||||||
|
|
||||||
|
|
||||||
ns.new_usertype<mesh_renderer>("mesh_renderer");
|
ns.new_usertype<mesh_renderer>("mesh_renderer"
|
||||||
|
,sol::constructors<mesh_renderer(),mesh_renderer(const geometry&)>()
|
||||||
|
,"create",&mesh_renderer::create
|
||||||
|
,"ready",sol::readonly_property(&mesh_renderer::ready)
|
||||||
|
,"release",&mesh_renderer::release
|
||||||
|
,"draw",&mesh_renderer::draw
|
||||||
|
);
|
||||||
|
|
||||||
|
ns.new_usertype<framebuffer>("framebuffer"
|
||||||
|
,sol::constructors<framebuffer()>()
|
||||||
|
,"create",&framebuffer::create
|
||||||
|
,"bind",&framebuffer::bind
|
||||||
|
,"unbind",&framebuffer::unbind
|
||||||
|
,"blit",&framebuffer::blit);
|
||||||
}
|
}
|
||||||
|
|
||||||
PW_REGISTER_LUA(visual)
|
PW_REGISTER_LUA(visual)
|
||||||
|
|
|
@ -28,8 +28,18 @@
|
||||||
#include <pw/core/aabb.hpp>
|
#include <pw/core/aabb.hpp>
|
||||||
#include <pw/core/resource.hpp>
|
#include <pw/core/resource.hpp>
|
||||||
|
|
||||||
|
#include <variant>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE this needs to be rewritten to take into account for *any* kind of geometry
|
||||||
|
* Some ideas are drafted down there to separate out the attribute buffers. Things to
|
||||||
|
* consider: multiple UVs, triangle soup, per-vertex-color, texture transforms, weights,
|
||||||
|
* etc. pp.
|
||||||
|
*/
|
||||||
|
|
||||||
class geometry {
|
class geometry {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -51,6 +61,10 @@ public:
|
||||||
using vertex2array_t = std::vector<vector2> ;
|
using vertex2array_t = std::vector<vector2> ;
|
||||||
using vertex3array_t = std::vector<vector3> ;
|
using vertex3array_t = std::vector<vector3> ;
|
||||||
|
|
||||||
|
using __attribute_t = std::variant<valuearray_t,indexarray_t,vertex2array_t,vertex3array_t>;
|
||||||
|
|
||||||
|
using __attribute_set = std::tuple<uint32_t,__attribute_t,int>;
|
||||||
|
|
||||||
geometry() = default;
|
geometry() = default;
|
||||||
geometry(topology_type t);
|
geometry(topology_type t);
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,9 @@ public:
|
||||||
HDR
|
HDR
|
||||||
};
|
};
|
||||||
|
|
||||||
image(const sizei& s, pixel_layout t, void *ptr = nullptr);
|
image(const size& s, pixel_layout t, void *ptr = nullptr);
|
||||||
|
|
||||||
bool create(const sizei& s, pixel_layout t, void *ptr = nullptr);
|
bool create(const size& s, pixel_layout t, void *ptr = nullptr);
|
||||||
|
|
||||||
void release(bool release_memory = false);
|
void release(bool release_memory = false);
|
||||||
|
|
||||||
|
@ -65,11 +65,11 @@ public:
|
||||||
|
|
||||||
typedef shared_ptr<image> ptr;
|
typedef shared_ptr<image> ptr;
|
||||||
|
|
||||||
sizei size() const;
|
::pw::size size() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
sizei _size;
|
::pw::size _size;
|
||||||
pixel_layout _layout;
|
pixel_layout _layout;
|
||||||
uint64_t _change_count;
|
uint64_t _change_count;
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,9 @@ class resource {
|
||||||
public:
|
public:
|
||||||
using change_t = std::atomic_int_fast64_t;
|
using change_t = std::atomic_int_fast64_t;
|
||||||
|
|
||||||
int64_t changecount() { return _changecount; }
|
resource() = default;
|
||||||
|
|
||||||
|
int64_t changecount() const { return _changecount; }
|
||||||
void dirty() { ++_changecount; };
|
void dirty() { ++_changecount; };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -43,11 +43,10 @@ struct size_ {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef size_<real_t> size;
|
typedef size_<int> size;
|
||||||
|
|
||||||
typedef size_<int> sizei;
|
|
||||||
typedef size_<float> sizef;
|
typedef size_<float> sizef;
|
||||||
typedef size_<float> sized;
|
typedef size_<double> sized;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2019 Hartmut Seichter
|
* Copyright (c) 1999-2021 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
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic vector types used in pixwerx.
|
||||||
|
*/
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct vector2_ : matrix_<2,1,T> {
|
struct vector2_ : matrix_<2,1,T> {
|
||||||
|
|
||||||
|
@ -90,12 +94,12 @@ struct vector3_ : matrix_<3,1,T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline static vector3_<T> forward() { return vector3_<T> ( { T(0), T(0),-T(1) } ); }
|
inline static constexpr vector3_<T> forward() { return vector3_<T> ( { T(0), T(0),-T(1) } ); }
|
||||||
inline static vector3_<T> backward() { return vector3_<T>( { T(0), T(0), T(1) } ); }
|
inline static constexpr vector3_<T> backward() { return vector3_<T>( { T(0), T(0), T(1) } ); }
|
||||||
inline static vector3_<T> right() { return vector3_<T> ( { T(1), T(0), T(0) } ); }
|
inline static constexpr vector3_<T> right() { return vector3_<T> ( { T(1), T(0), T(0) } ); }
|
||||||
inline static vector3_<T> left() { return vector3_<T> ( {-T(1), T(0), T(0) } ); }
|
inline static constexpr vector3_<T> left() { return vector3_<T> ( {-T(1), T(0), T(0) } ); }
|
||||||
inline static vector3_<T> up() { return vector3_<T> ( { T(0), T(1), T(0) } ); }
|
inline static constexpr vector3_<T> up() { return vector3_<T> ( { T(0), T(1), T(0) } ); }
|
||||||
inline static vector3_<T> down() { return vector3_<T> ( { T(0),-T(1), T(0) } ); }
|
inline static constexpr vector3_<T> down() { return vector3_<T> ( { T(0),-T(1), T(0) } ); }
|
||||||
|
|
||||||
inline static vector3_<T> x_axis() { return vector3_<T> ( { T(1), T(0), T(0) } ); }
|
inline static vector3_<T> x_axis() { return vector3_<T> ( { T(1), T(0), T(0) } ); }
|
||||||
inline static vector3_<T> y_axis() { return vector3_<T> ( { T(0), T(1), T(0) } ); }
|
inline static vector3_<T> y_axis() { return vector3_<T> ( { T(0), T(1), T(0) } ); }
|
||||||
|
@ -110,7 +114,7 @@ struct vector4_ : matrix_<4,1,T> {
|
||||||
using base_type::base_type;
|
using base_type::base_type;
|
||||||
using base_type::operator = ;
|
using base_type::operator = ;
|
||||||
|
|
||||||
vector4_(T x_,T y_,T z_,T w_) : base_type({x_,y_,z_,w_}) {}
|
vector4_(T x_,T y_,T z_,T w_) : base_type( {x_,y_,z_,w_} ) {}
|
||||||
vector4_(const base_type& m) : base_type(m) {}
|
vector4_(const base_type& m) : base_type(m) {}
|
||||||
vector4_(const vector3_<T> &m, T w) : base_type({m(0),m(1),m(2),w}) {}
|
vector4_(const vector3_<T> &m, T w) : base_type({m(0),m(1),m(2),w}) {}
|
||||||
|
|
||||||
|
@ -129,6 +133,7 @@ struct vector4_ : matrix_<4,1,T> {
|
||||||
inline auto xyz() const { return vector3_<T>({ x(),y(),z() } ); }
|
inline auto xyz() const { return vector3_<T>({ x(),y(),z() } ); }
|
||||||
|
|
||||||
inline auto project() const { return vector3_<T>({ x()/w(),y()/w(),z()/w() } ); }
|
inline auto project() const { return vector3_<T>({ x()/w(),y()/w(),z()/w() } ); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
image::image(const sizei &s, image::pixel_layout t, void *ptr)
|
image::image(const ::pw::size &s, image::pixel_layout t, void *ptr)
|
||||||
{
|
{
|
||||||
this->create(s,t,ptr);
|
this->create(s,t,ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool image::create(const sizei &s, image::pixel_layout t, void *ptr)
|
bool image::create(const ::pw::size &s, image::pixel_layout t, void *ptr)
|
||||||
{
|
{
|
||||||
size_t n = bytes_per_pixel(t) * s.area();
|
size_t n = bytes_per_pixel(t) * s.area();
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ bool image::create(const sizei &s, image::pixel_layout t, void *ptr)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
_data.resize(n);
|
_data.resize(n);
|
||||||
_size = sizei(0,0);
|
_size = ::pw::size(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !_data.empty();
|
return !_data.empty();
|
||||||
|
@ -53,7 +53,7 @@ uint32_t image::bytes_per_pixel(image::pixel_layout t)
|
||||||
return std::numeric_limits<uint32_t>::max();
|
return std::numeric_limits<uint32_t>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
sizei image::size() const
|
::pw::size image::size() const
|
||||||
{
|
{
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
int main(int argc,char **argv) {
|
int main(int ,char **) {
|
||||||
|
|
||||||
pw::vector2_<float> v2_A = { 3.2, 1.2 };
|
pw::vector2_<float> v2_A = { 3.2, 1.2 };
|
||||||
pw::vector2_<float> v2_B = { 3.2, 1.2 };
|
pw::vector2_<float> v2_B = { 3.2, 1.2 };
|
||||||
|
@ -12,7 +12,7 @@ int main(int argc,char **argv) {
|
||||||
auto AB_lerp = pw::vector2f::lerp(v2_A,v2_B,0.5);
|
auto AB_lerp = pw::vector2f::lerp(v2_A,v2_B,0.5);
|
||||||
|
|
||||||
pw::vector4_<float> v4;
|
pw::vector4_<float> v4;
|
||||||
pw::vector3f v;
|
pw::vector3f v = pw::vector3f::backward();
|
||||||
|
|
||||||
v4.fill(1.5);
|
v4.fill(1.5);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ struct image_io::impl
|
||||||
|
|
||||||
image r;
|
image r;
|
||||||
|
|
||||||
r.create(sizei(x,y),image::pixel_layout::RGBA8,data);
|
r.create(size(x,y),image::pixel_layout::RGBA8,data);
|
||||||
|
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
|
|
||||||
|
|
48
src/scene/include/pw/scene/components/camera.hpp
Normal file
48
src/scene/include/pw/scene/components/camera.hpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1999-2020 Hartmut Seichter
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef PW_SCENE_COMPONENT_PROJECTION_HPP
|
||||||
|
#define PW_SCENE_COMPONENT_PROJECTION_HPP
|
||||||
|
|
||||||
|
#include <pw/core/matrix.hpp>
|
||||||
|
#include <pw/core/matrix_transform.hpp>
|
||||||
|
#include <pw/core/rectangle.hpp>
|
||||||
|
|
||||||
|
namespace pw {
|
||||||
|
|
||||||
|
struct camera {
|
||||||
|
matrix4x4 view = matrix4x4::identity();
|
||||||
|
matrix4x4 projection = matrix_transform<float>::look_at(vector3{0,0,0},
|
||||||
|
vector3{0,0,1},
|
||||||
|
vector3{0,1,0});
|
||||||
|
|
||||||
|
rectangle viewport = pw::rectangle({0, 0, 1, 1});
|
||||||
|
|
||||||
|
uint32_t mask = 0xFFFFFF;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
166
src/scripts/demos/simple_002.lua
Normal file
166
src/scripts/demos/simple_002.lua
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
--
|
||||||
|
-- small demonstrator for Lua binding on pixwerx
|
||||||
|
--
|
||||||
|
|
||||||
|
pw.script:load_all()
|
||||||
|
|
||||||
|
print("hello pixwerx!")
|
||||||
|
|
||||||
|
local w = pw.window.new()
|
||||||
|
w.visible = false
|
||||||
|
|
||||||
|
-- set title
|
||||||
|
w.title = "pixwerx 0.1"
|
||||||
|
|
||||||
|
-- set size
|
||||||
|
w.size = pw.size.new(640,480)
|
||||||
|
|
||||||
|
-- move window
|
||||||
|
w.position = pw.point.new(100,100)
|
||||||
|
|
||||||
|
|
||||||
|
local g = pw.geometry:new()
|
||||||
|
|
||||||
|
g.topology = pw.geometry.triangles -- meh
|
||||||
|
|
||||||
|
|
||||||
|
g.vertices:clear()
|
||||||
|
|
||||||
|
g.vertices:add(pw.vector3:new(-1, 1, 0)) -- 0
|
||||||
|
g.vertices:add(pw.vector3:new(-1,-1, 0)) -- 1
|
||||||
|
g.vertices:add(pw.vector3:new( 1,-1, 0)) -- 2
|
||||||
|
g.vertices:add(pw.vector3:new( 1, 1, 0)) -- 3
|
||||||
|
|
||||||
|
|
||||||
|
-- 0 --- 3
|
||||||
|
-- | \ |
|
||||||
|
-- 1 --- 2
|
||||||
|
|
||||||
|
print(g.vertices,#g.vertices,g.vertices[1].x)
|
||||||
|
|
||||||
|
g.indices:add(0)
|
||||||
|
g.indices:add(1)
|
||||||
|
g.indices:add(2)
|
||||||
|
|
||||||
|
g.indices:add(2)
|
||||||
|
g.indices:add(3)
|
||||||
|
g.indices:add(0)
|
||||||
|
|
||||||
|
print(g.indices)
|
||||||
|
|
||||||
|
|
||||||
|
local mm = pw.matrix4x4:new()
|
||||||
|
local mv = pw.matrix4x4:new()
|
||||||
|
local mp = pw.matrix4x4:new()
|
||||||
|
|
||||||
|
|
||||||
|
w.visible = true
|
||||||
|
|
||||||
|
|
||||||
|
local fb = pw.framebuffer:new()
|
||||||
|
|
||||||
|
print(w.client_size.width,"x",w.client_size.height)
|
||||||
|
|
||||||
|
if fb:create(w.client_size) then
|
||||||
|
print("framebuffer ok")
|
||||||
|
else
|
||||||
|
print("framebuffer failed")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local s = pw.shader:new()
|
||||||
|
|
||||||
|
print(s.ready)
|
||||||
|
|
||||||
|
s:set_source(pw.shader_type.vertex,[[
|
||||||
|
#version 400
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
in vec3 vertex_p;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = projection * view * model * vec4(vertex_p, 1.0);
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
s:set_source(pw.shader_type.fragment,[[
|
||||||
|
#version 400
|
||||||
|
uniform vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
out vec4 frag_colour;
|
||||||
|
void main() {
|
||||||
|
frag_colour = color;
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
print(s.ready)
|
||||||
|
|
||||||
|
if not s:build() then
|
||||||
|
print("Error!")
|
||||||
|
end
|
||||||
|
|
||||||
|
print(s.ready)
|
||||||
|
|
||||||
|
local renderer = pw.mesh_renderer:new()
|
||||||
|
|
||||||
|
if not renderer:create(g) then
|
||||||
|
print("couldn't create renderer")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
while w:update() do
|
||||||
|
|
||||||
|
|
||||||
|
-- somehow works
|
||||||
|
if (pw.input.get().input_string == 'f') then
|
||||||
|
w.fullscreen = not w.fullscreen
|
||||||
|
end
|
||||||
|
|
||||||
|
-- keycode for quit
|
||||||
|
if (pw.input.get().input_string == 'q') then
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- just to check
|
||||||
|
if (pw.input:get().mouse_button == 1) then
|
||||||
|
|
||||||
|
print("elapsed",t.elapsed)
|
||||||
|
t:reset()
|
||||||
|
print(pw.input:get().mouse_position.x,pw.input:get().mouse_position.y,w.client_size.width,w.client_size.height)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mm:set_identity()
|
||||||
|
|
||||||
|
mv = pw.matrixtransform.look_at(pw.vector3:new(0,0,0),pw.vector3.forward(),pw.vector3.up())
|
||||||
|
mp = pw.matrixtransform.perspective_projection(1.3,1.0,0.2,100)
|
||||||
|
|
||||||
|
local cl = pw.vector4:new( 1.0, 0, 0, 1.0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
s:use()
|
||||||
|
|
||||||
|
s:set_uniform_mat4("model",mm)
|
||||||
|
s:set_uniform_mat4("view",mv)
|
||||||
|
s:set_uniform_mat4("projection",mp)
|
||||||
|
s:set_uniform_vec4("color",cl)
|
||||||
|
|
||||||
|
|
||||||
|
fb:bind()
|
||||||
|
|
||||||
|
|
||||||
|
renderer:draw()
|
||||||
|
|
||||||
|
fb:blit()
|
||||||
|
|
||||||
|
fb:unbind()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ struct window::impl {
|
||||||
|
|
||||||
GLFWwindow *_window = nullptr;
|
GLFWwindow *_window = nullptr;
|
||||||
|
|
||||||
sizei _old_size;
|
::pw::size _old_size;
|
||||||
pointi _old_pos;
|
pointi _old_pos;
|
||||||
|
|
||||||
// window_context _context;
|
// window_context _context;
|
||||||
|
@ -233,7 +233,7 @@ struct window::impl {
|
||||||
glfwSetWindowTitle(_window,title.c_str());
|
glfwSetWindowTitle(_window,title.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_size(const ::pw::sizei& s)
|
void set_size(const ::pw::size& s)
|
||||||
{
|
{
|
||||||
glfwSetWindowSize(_window,s.width,s.height);
|
glfwSetWindowSize(_window,s.width,s.height);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
set(hdrs
|
set(hdrs
|
||||||
|
include/pw/visual/framebuffer.hpp
|
||||||
include/pw/visual/shader.hpp
|
include/pw/visual/shader.hpp
|
||||||
include/pw/visual/pipeline.hpp
|
include/pw/visual/pipeline.hpp
|
||||||
include/pw/visual/texture.hpp
|
include/pw/visual/texture.hpp
|
||||||
|
@ -8,6 +9,7 @@ set(hdrs
|
||||||
)
|
)
|
||||||
|
|
||||||
set(srcs
|
set(srcs
|
||||||
|
src/framebuffer.cpp
|
||||||
src/shader.cpp
|
src/shader.cpp
|
||||||
src/context.cpp
|
src/context.cpp
|
||||||
src/pass.cpp
|
src/pass.cpp
|
||||||
|
|
27
src/visual/include/pw/visual/framebuffer.hpp
Normal file
27
src/visual/include/pw/visual/framebuffer.hpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef PW_VISUAL_FRAMEBUFFER_HPP
|
||||||
|
#define PW_VISUAL_FRAMEBUFFER_HPP
|
||||||
|
|
||||||
|
#include <pw/core/globals.hpp>
|
||||||
|
#include <pw/core/size.hpp>
|
||||||
|
|
||||||
|
namespace pw {
|
||||||
|
|
||||||
|
class framebuffer {
|
||||||
|
public:
|
||||||
|
framebuffer();
|
||||||
|
~framebuffer();
|
||||||
|
|
||||||
|
bool create(const size& s);
|
||||||
|
|
||||||
|
void bind();
|
||||||
|
void blit();
|
||||||
|
void unbind();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
struct impl;
|
||||||
|
std::unique_ptr<impl> _impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -19,7 +19,7 @@ public:
|
||||||
|
|
||||||
~mesh_renderer();
|
~mesh_renderer();
|
||||||
|
|
||||||
void create(const geometry &m);
|
bool create(const geometry &m);
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
|
|
|
@ -24,26 +24,36 @@ public:
|
||||||
compute
|
compute
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_source(const std::string& c,code_type t) { _source[t] = c; }
|
void set_source(code_type t, const std::string& c) { _source[t] = c; }
|
||||||
std::string source(code_type t) { return _source[t]; }
|
std::string source(code_type t) { return _source[t]; }
|
||||||
|
|
||||||
bool ready() const;
|
bool ready() const;
|
||||||
|
|
||||||
shader& set(int location,float v);
|
shader& set_uniform_at_location(int location,float v);
|
||||||
shader& set(int location,matrix4x4f const & v);
|
shader& set_uniform_at_location(int location,matrix4x4f const &v);
|
||||||
shader& set(int location,vector4f const & v);
|
shader& set_uniform_at_location(int location,vector4f const &v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief retrieves the position of a uniform
|
||||||
|
* @param name of the uniform
|
||||||
|
* @return position of the uniform or negative if it doesn't exist
|
||||||
|
*/
|
||||||
int uniform_location(std::string const & name) const;
|
int uniform_location(std::string const & name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if a uniform with the given name exists
|
||||||
|
* @param name of the uniform
|
||||||
|
* @return true if found
|
||||||
|
*/
|
||||||
|
bool has_uniform(std::string const &name) const { return uniform_location(name) >= 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets data of the
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
shader & set(std::string const & name, T&& value)
|
shader & set_uniform(std::string const & name, T &&value)
|
||||||
{
|
{
|
||||||
int location = uniform_location(name);
|
return set_uniform_at_location( uniform_location(name), std::forward<T>(value) );
|
||||||
if (location >= 0)
|
|
||||||
return set(location, std::forward<T>(value));
|
|
||||||
else
|
|
||||||
debug::w() << "missing uniform: '" << name << "'";
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool build();
|
bool build();
|
||||||
|
|
131
src/visual/src/framebuffer.cpp
Normal file
131
src/visual/src/framebuffer.cpp
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#include "pw/visual/framebuffer.hpp"
|
||||||
|
|
||||||
|
#include "pw/core/size.hpp"
|
||||||
|
#include "pw/core/debug.hpp"
|
||||||
|
|
||||||
|
#include "glad/glad.h"
|
||||||
|
|
||||||
|
namespace pw {
|
||||||
|
|
||||||
|
struct framebuffer::impl {
|
||||||
|
|
||||||
|
size _size;
|
||||||
|
|
||||||
|
GLuint _fbo_draw;
|
||||||
|
GLuint _fbo_msaa;
|
||||||
|
|
||||||
|
GLuint _rbo_color;
|
||||||
|
GLuint _rbo_depth;
|
||||||
|
|
||||||
|
bool create(const size &s)
|
||||||
|
{
|
||||||
|
|
||||||
|
_size = s;
|
||||||
|
|
||||||
|
int max_msaa;
|
||||||
|
|
||||||
|
// query actual maximum MSAA
|
||||||
|
glGetIntegerv(GL_MAX_SAMPLES,&max_msaa);
|
||||||
|
|
||||||
|
|
||||||
|
// create a 4x MSAA renderbuffer object for colorbuffer
|
||||||
|
int msaa = std::min(max_msaa,4);
|
||||||
|
|
||||||
|
|
||||||
|
debug::d() << "OpenGL multisampling: " << max_msaa << " choosen:" << msaa;
|
||||||
|
debug::d() << "Framebuffer size " << _size.width << " x " << _size.height;
|
||||||
|
|
||||||
|
glGenRenderbuffers(1, &_rbo_color);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, _rbo_color);
|
||||||
|
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, _size.width, _size.height);
|
||||||
|
|
||||||
|
// create a 4x MSAA renderbuffer object for depthbuffer
|
||||||
|
|
||||||
|
glGenRenderbuffers(1, &_rbo_depth);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, _rbo_depth);
|
||||||
|
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_DEPTH_COMPONENT, _size.width, _size.height);
|
||||||
|
|
||||||
|
// create a 4x MSAA framebuffer object
|
||||||
|
glGenFramebuffers(1, &_fbo_msaa);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, _fbo_msaa);
|
||||||
|
|
||||||
|
// attach colorbuffer image to FBO
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, // 1. fbo target: GL_FRAMEBUFFER
|
||||||
|
GL_COLOR_ATTACHMENT0, // 2. color attachment point
|
||||||
|
GL_RENDERBUFFER, // 3. rbo target: GL_RENDERBUFFER
|
||||||
|
_rbo_color); // 4. rbo ID
|
||||||
|
|
||||||
|
// attach depthbuffer image to FBO
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, // 1. fbo target: GL_FRAMEBUFFER
|
||||||
|
GL_DEPTH_ATTACHMENT, // 2. depth attachment point
|
||||||
|
GL_RENDERBUFFER, // 3. rbo target: GL_RENDERBUFFER
|
||||||
|
_rbo_depth); // 4. rbo ID
|
||||||
|
|
||||||
|
// check FBO status
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unbind();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void bind()
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_msaa);
|
||||||
|
}
|
||||||
|
|
||||||
|
void blit()
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo_msaa); // src FBO (multi-sample)
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_draw); // dst FBO (single-sample)
|
||||||
|
|
||||||
|
glBlitFramebuffer(0, 0, _size.width, _size.height, // src rect
|
||||||
|
0, 0, _size.width, _size.height, // dst rect
|
||||||
|
GL_COLOR_BUFFER_BIT, // buffer mask
|
||||||
|
GL_LINEAR); // scale filter
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void unbind()
|
||||||
|
{
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
framebuffer::framebuffer()
|
||||||
|
{
|
||||||
|
_impl = std::make_unique<impl>();
|
||||||
|
}
|
||||||
|
|
||||||
|
framebuffer::~framebuffer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool framebuffer::create(const size &s)
|
||||||
|
{
|
||||||
|
return _impl->create(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void framebuffer::bind()
|
||||||
|
{
|
||||||
|
_impl->bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void framebuffer::blit()
|
||||||
|
{
|
||||||
|
_impl->blit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void framebuffer::unbind()
|
||||||
|
{
|
||||||
|
_impl->unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -28,10 +28,10 @@ struct mesh_renderer::impl {
|
||||||
|
|
||||||
bool ready() const
|
bool ready() const
|
||||||
{
|
{
|
||||||
return GL_TRUE == glIsVertexArray(_vao);
|
return glIsVertexArray != nullptr && GL_TRUE == glIsVertexArray(_vao);
|
||||||
}
|
}
|
||||||
|
|
||||||
void create(const geometry& m)
|
bool create(const geometry& m)
|
||||||
{
|
{
|
||||||
// reset if the renderer already in use
|
// reset if the renderer already in use
|
||||||
if (ready()) {
|
if (ready()) {
|
||||||
|
@ -81,6 +81,8 @@ struct mesh_renderer::impl {
|
||||||
if (error != GL_NO_ERROR) {
|
if (error != GL_NO_ERROR) {
|
||||||
debug::e() << "GL error: " << error;
|
debug::e() << "GL error: " << error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,9 +137,9 @@ bool mesh_renderer::ready() const
|
||||||
return _impl->ready();
|
return _impl->ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mesh_renderer::create(const geometry &m)
|
bool mesh_renderer::create(const geometry &m)
|
||||||
{
|
{
|
||||||
_impl->create(m);
|
return _impl->create(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mesh_renderer::release()
|
void mesh_renderer::release()
|
||||||
|
|
|
@ -132,8 +132,8 @@ struct triangle_renderer
|
||||||
frag_colour = input_color;
|
frag_colour = input_color;
|
||||||
})";
|
})";
|
||||||
|
|
||||||
shader_p.set_source(vertex_shader_2,shader::code_type::vertex);
|
shader_p.set_source(shader::code_type::vertex,vertex_shader_2);
|
||||||
shader_p.set_source(fragment_shader_2,shader::code_type::fragment);
|
shader_p.set_source(shader::code_type::fragment,fragment_shader_2);
|
||||||
|
|
||||||
if (!shader_p.build())
|
if (!shader_p.build())
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
@ -220,7 +220,7 @@ struct triangle_renderer
|
||||||
|
|
||||||
struct pipeline::impl {
|
struct pipeline::impl {
|
||||||
|
|
||||||
sizei _size;
|
size _size;
|
||||||
|
|
||||||
GLuint _fbo_draw;
|
GLuint _fbo_draw;
|
||||||
GLuint _fbo_msaa;
|
GLuint _fbo_msaa;
|
||||||
|
@ -231,7 +231,7 @@ struct pipeline::impl {
|
||||||
//testing
|
//testing
|
||||||
triangle_renderer tr;
|
triangle_renderer tr;
|
||||||
|
|
||||||
bool create(sizei size);
|
bool create(size s);
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ struct pipeline::impl {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint generate_multisample_texture(const sizei& s,int samples)
|
GLuint generate_multisample_texture(const size& s,int samples)
|
||||||
{
|
{
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
glGenTextures(1, &texture);
|
glGenTextures(1, &texture);
|
||||||
|
@ -252,10 +252,10 @@ GLuint generate_multisample_texture(const sizei& s,int samples)
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pipeline::impl::create(sizei size)
|
bool pipeline::impl::create(::pw::size s)
|
||||||
{
|
{
|
||||||
|
|
||||||
_size = size;
|
_size = s;
|
||||||
|
|
||||||
int max_msaa;
|
int max_msaa;
|
||||||
|
|
||||||
|
@ -309,10 +309,12 @@ bool pipeline::impl::create(sizei size)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void pipeline::impl::draw()
|
void pipeline::impl::draw()
|
||||||
{
|
{
|
||||||
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_msaa);
|
|
||||||
|
|
||||||
// glClearColor(1.0,0,0,1);
|
// glClearColor(1.0,0,0,1);
|
||||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct shader::impl
|
||||||
|
|
||||||
bool build()
|
bool build()
|
||||||
{
|
{
|
||||||
if (!is_valid()) return false;
|
// if (!is_valid()) return false;
|
||||||
|
|
||||||
for (const auto & [type,code] : _shader._source)
|
for (const auto & [type,code] : _shader._source)
|
||||||
{
|
{
|
||||||
|
@ -180,6 +180,7 @@ shader::shader()
|
||||||
|
|
||||||
shader::~shader()
|
shader::~shader()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shader::ready() const
|
bool shader::ready() const
|
||||||
|
@ -187,17 +188,17 @@ bool shader::ready() const
|
||||||
return _impl->is_valid();
|
return _impl->is_valid();
|
||||||
}
|
}
|
||||||
|
|
||||||
shader &shader::set(int location, float v)
|
shader &shader::set_uniform_at_location(int location, float v)
|
||||||
{
|
{
|
||||||
_impl->bind(location,v); return *this;
|
_impl->bind(location,v); return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader &shader::set(int location, const vector4f &v)
|
shader &shader::set_uniform_at_location(int location, vector4f const &v)
|
||||||
{
|
{
|
||||||
_impl->bind(location,v); return *this;
|
_impl->bind(location,v); return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader &shader::set(int location, const matrix4x4f &v)
|
shader &shader::set_uniform_at_location(int location, matrix4x4f const &v)
|
||||||
{
|
{
|
||||||
_impl->bind(location,v); return *this;
|
_impl->bind(location,v); return *this;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +240,7 @@ void shader::set_uniforms(uniform_cache_t c)
|
||||||
if constexpr ((std::is_same_v<T, vector4f>) ||
|
if constexpr ((std::is_same_v<T, vector4f>) ||
|
||||||
(std::is_same_v<T, matrix4x4f>) ||
|
(std::is_same_v<T, matrix4x4f>) ||
|
||||||
(std::is_same_v<T, float>) ) {
|
(std::is_same_v<T, float>) ) {
|
||||||
set(loc, std::forward<T>(arg));
|
set_uniform_at_location( loc, std::forward<T>(arg));
|
||||||
} else {
|
} else {
|
||||||
debug::e() << "unknown uniform type";
|
debug::e() << "unknown uniform type";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue