Major push to get renderer separated and configurable.

Signed-off-by: Hartmut Seichter <hartmut@technotecture.com>
This commit is contained in:
Hartmut Seichter 2021-01-05 00:23:03 +01:00
parent 77e254872f
commit d2c8262c68
22 changed files with 542 additions and 97 deletions

View file

@ -7,6 +7,7 @@
#include "pw/core/time.hpp"
#include "pw/core/geometry.hpp"
#include "pw/core/image.hpp"
#include "pw/core/matrix_transform.hpp"
#include "runtime_lua.hpp"
@ -15,6 +16,7 @@
namespace sol {
template <> struct is_automagical<pw::matrix4x4> : 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 {};
}
@ -44,8 +46,24 @@ void register_core_function(sol::state& lua,sol::table& ns)
,"cross",&vector3::cross
,"transposed",&vector3::transposed
,"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"
,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;})
@ -77,11 +95,6 @@ void register_core_function(sol::state& lua,sol::table& ns)
, "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",
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)
, "vertices", sol::property(&geometry::vertices,&geometry::set_vertices)
, "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
, "lines", geometry::topology_type::lines
, "line_strip", geometry::topology_type::line_strip
, "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
// geoom_type["type"] = lua.create_table_with(
// "points", geometry::topology_type::points

View file

@ -2,6 +2,8 @@
#include "pw/core/debug.hpp"
#include "pw/visual/pipeline.hpp"
#include "pw/visual/shader.hpp"
#include "pw/visual/framebuffer.hpp"
#include "pw/core/size.hpp"
#include "runtime_lua.hpp"
@ -10,26 +12,29 @@ namespace pw {
void register_visual_function(sol::state&,sol::table &ns)
{
ns.new_usertype<pipeline>("pipeline"
ns.new_usertype<pipeline>("pipeline"
,"create",&pipeline::create
,"draw",&pipeline::draw
,"draw",&pipeline::draw
);
ns.new_usertype<shader>("shader"
ns.new_usertype<shader>("shader"
,sol::constructors<shader()>()
,"ready",sol::readonly_property(&shader::ready)
,"use",&shader::use
,"ready",sol::readonly_property(&shader::ready)
,"use",&shader::use
,"build",&shader::build
,"source",&shader::source
,"set_source",&shader::set_source
,"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"
,"fragment",shader::code_type::fragment
,"vertex",shader::code_type::vertex
,"geometry",shader::code_type::geometry
,"compute",shader::code_type::compute);
,"vertex",shader::code_type::vertex
,"geometry",shader::code_type::geometry
,"compute",shader::code_type::compute);
ns.new_usertype<render_pass>("render_pass"
@ -40,7 +45,20 @@ void register_visual_function(sol::state&,sol::table &ns)
,"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)

View file

@ -28,8 +28,18 @@
#include <pw/core/aabb.hpp>
#include <pw/core/resource.hpp>
#include <variant>
#include <tuple>
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 {
public:
@ -51,6 +61,10 @@ public:
using vertex2array_t = std::vector<vector2> ;
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(topology_type t);

View file

@ -43,9 +43,9 @@ public:
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);
@ -65,11 +65,11 @@ public:
typedef shared_ptr<image> ptr;
sizei size() const;
::pw::size size() const;
protected:
sizei _size;
::pw::size _size;
pixel_layout _layout;
uint64_t _change_count;

View file

@ -32,7 +32,9 @@ class resource {
public:
using change_t = std::atomic_int_fast64_t;
int64_t changecount() { return _changecount; }
resource() = default;
int64_t changecount() const { return _changecount; }
void dirty() { ++_changecount; };
protected:

View file

@ -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> sized;
typedef size_<double> sized;
}

View file

@ -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
* of this software and associated documentation files (the "Software"), to deal

View file

@ -27,6 +27,10 @@
namespace pw {
/**
* Basic vector types used in pixwerx.
*/
template <typename 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 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 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 vector3_<T> down() { return vector3_<T> ( { T(0),-T(1), T(0) } ); }
inline static constexpr vector3_<T> forward() { 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 constexpr vector3_<T> right() { 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 constexpr vector3_<T> up() { 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> 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::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 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 project() const { return vector3_<T>({ x()/w(),y()/w(),z()/w() } ); }
};
//

View file

@ -4,12 +4,12 @@
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);
}
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();
@ -24,7 +24,7 @@ bool image::create(const sizei &s, image::pixel_layout t, void *ptr)
} else {
_data.resize(n);
_size = sizei(0,0);
_size = ::pw::size(0,0);
}
return !_data.empty();
@ -53,7 +53,7 @@ uint32_t image::bytes_per_pixel(image::pixel_layout t)
return std::numeric_limits<uint32_t>::max();
}
sizei image::size() const
::pw::size image::size() const
{
return _size;
}

View file

@ -4,7 +4,7 @@
#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_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);
pw::vector4_<float> v4;
pw::vector3f v;
pw::vector3f v = pw::vector3f::backward();
v4.fill(1.5);

View file

@ -24,7 +24,7 @@ struct image_io::impl
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);

View 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

View 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

View file

@ -43,7 +43,7 @@ struct window::impl {
GLFWwindow *_window = nullptr;
sizei _old_size;
::pw::size _old_size;
pointi _old_pos;
// window_context _context;
@ -233,7 +233,7 @@ struct window::impl {
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);
}

View file

@ -1,41 +1,43 @@
set(hdrs
include/pw/visual/shader.hpp
include/pw/visual/pipeline.hpp
include/pw/visual/texture.hpp
include/pw/visual/mesh_renderer.hpp
include/pw/visual/material.hpp
)
include/pw/visual/framebuffer.hpp
include/pw/visual/shader.hpp
include/pw/visual/pipeline.hpp
include/pw/visual/texture.hpp
include/pw/visual/mesh_renderer.hpp
include/pw/visual/material.hpp
)
set(srcs
src/shader.cpp
src/context.cpp
src/pass.cpp
src/pipeline.cpp
src/target.cpp
src/texture.cpp
src/mesh_renderer.cpp
src/material.cpp
)
src/framebuffer.cpp
src/shader.cpp
src/context.cpp
src/pass.cpp
src/pipeline.cpp
src/target.cpp
src/texture.cpp
src/mesh_renderer.cpp
src/material.cpp
)
set(srcs_shader
src/shader/unlit_vs.glsl
src/shader/unlit_fs.glsl
)
src/shader/unlit_vs.glsl
src/shader/unlit_fs.glsl
)
add_library(pwvisual
STATIC
${hdrs}
${srcs}
${srcs_shader}
)
STATIC
${hdrs}
${srcs}
${srcs_shader}
)
target_include_directories(
pwvisual
PUBLIC
include
)
pwvisual
PUBLIC
include
)
target_link_libraries(pwvisual pwscene glad)

View 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

View file

@ -19,7 +19,7 @@ public:
~mesh_renderer();
void create(const geometry &m);
bool create(const geometry &m);
void release();
void draw();

View file

@ -24,26 +24,36 @@ public:
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]; }
bool ready() const;
shader& set(int location,float v);
shader& set(int location,matrix4x4f const & v);
shader& set(int location,vector4f const & v);
shader& set_uniform_at_location(int location,float v);
shader& set_uniform_at_location(int location,matrix4x4f 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;
/**
* @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>
shader & set(std::string const & name, T&& value)
{
int location = uniform_location(name);
if (location >= 0)
return set(location, std::forward<T>(value));
else
debug::w() << "missing uniform: '" << name << "'";
return *this;
shader & set_uniform(std::string const & name, T &&value)
{
return set_uniform_at_location( uniform_location(name), std::forward<T>(value) );
}
bool build();

View 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();
}
}

View file

@ -28,10 +28,10 @@ struct mesh_renderer::impl {
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
if (ready()) {
@ -81,6 +81,8 @@ struct mesh_renderer::impl {
if (error != GL_NO_ERROR) {
debug::e() << "GL error: " << error;
}
return ready();
}
@ -135,9 +137,9 @@ bool mesh_renderer::ready() const
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()

View file

@ -132,8 +132,8 @@ struct triangle_renderer
frag_colour = input_color;
})";
shader_p.set_source(vertex_shader_2,shader::code_type::vertex);
shader_p.set_source(fragment_shader_2,shader::code_type::fragment);
shader_p.set_source(shader::code_type::vertex,vertex_shader_2);
shader_p.set_source(shader::code_type::fragment,fragment_shader_2);
if (!shader_p.build())
exit(-1);
@ -220,7 +220,7 @@ struct triangle_renderer
struct pipeline::impl {
sizei _size;
size _size;
GLuint _fbo_draw;
GLuint _fbo_msaa;
@ -231,7 +231,7 @@ struct pipeline::impl {
//testing
triangle_renderer tr;
bool create(sizei size);
bool create(size s);
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;
glGenTextures(1, &texture);
@ -252,10 +252,10 @@ GLuint generate_multisample_texture(const sizei& s,int samples)
return texture;
}
bool pipeline::impl::create(sizei size)
bool pipeline::impl::create(::pw::size s)
{
_size = size;
_size = s;
int max_msaa;
@ -309,10 +309,12 @@ bool pipeline::impl::create(sizei size)
return true;
}
void pipeline::impl::draw()
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_msaa);
// glClearColor(1.0,0,0,1);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

View file

@ -31,7 +31,7 @@ struct shader::impl
bool build()
{
if (!is_valid()) return false;
// if (!is_valid()) return false;
for (const auto & [type,code] : _shader._source)
{
@ -180,6 +180,7 @@ shader::shader()
shader::~shader()
{
}
bool shader::ready() const
@ -187,17 +188,17 @@ bool shader::ready() const
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;
}
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;
}
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;
}
@ -239,7 +240,7 @@ void shader::set_uniforms(uniform_cache_t c)
if constexpr ((std::is_same_v<T, vector4f>) ||
(std::is_same_v<T, matrix4x4f>) ||
(std::is_same_v<T, float>) ) {
set(loc, std::forward<T>(arg));
set_uniform_at_location( loc, std::forward<T>(arg));
} else {
debug::e() << "unknown uniform type";
}