refactoring and cleaning while searching for a problem in the demo code

This commit is contained in:
Hartmut Seichter 2021-01-07 23:02:08 +01:00
parent d2c8262c68
commit 0d2138c9f2
14 changed files with 427 additions and 453 deletions

View file

@ -45,12 +45,12 @@ void register_visual_function(sol::state&,sol::table &ns)
,"color",sol::property(&material::_color));
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<renderer>("mesh_renderer"
,sol::constructors<renderer(),renderer(const geometry&)>()
,"create",&renderer::create
,"ready",sol::readonly_property(&renderer::ready)
,"release",&renderer::release
,"draw",&renderer::draw
);
ns.new_usertype<framebuffer>("framebuffer"

View file

@ -14,7 +14,7 @@ struct mesh {
geometry geom;
};
struct mesh_renderer {
struct renderer {
std::unique_ptr<int> state;
// std::vector<matrials> mat;
};

View file

@ -66,10 +66,6 @@ while w:update() do
t:reset()
print(pw.input:get().mouse_position.x,pw.input:get().mouse_position.y,w.client_size.width,w.client_size.height)
end
-- print("update")
end
--local scene = pw:scene.new()

View file

@ -1,16 +1,14 @@
--
-- small demonstrator for Lua binding on pixwerx
-- 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"
w.title = "My Cool 3D Content"
-- set size
w.size = pw.size.new(640,480)
@ -18,26 +16,24 @@ w.size = pw.size.new(640,480)
-- move window
w.position = pw.point.new(100,100)
-- create a new geometry
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
z = 1.0
g.vertices:add(pw.vector3:new(-1, 1, z)) -- 0
g.vertices:add(pw.vector3:new(-1,-1, z)) -- 1
g.vertices:add(pw.vector3:new( 1,-1, z)) -- 2
g.vertices:add(pw.vector3:new( 1, 1, z)) -- 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)
@ -46,32 +42,15 @@ 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
@ -95,24 +74,41 @@ void main() {
}
]])
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
-- setup a lua callback function as callback
w.on_update = function(self)
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, 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)
renderer:draw()
end
w.visible = true
while w:update() do
-- somehow works
if (pw.input.get().input_string == 'f') then
w.fullscreen = not w.fullscreen
@ -131,36 +127,4 @@ while w:update() do
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

@ -44,6 +44,7 @@ protected:
on_update_t _on_update;
};
}

View file

@ -152,11 +152,15 @@ struct window::impl {
glfwGetVersion(&glfw_major,&glfx_minor,&glfw_rev);
debug::d() << "GLFW " << glfw_major << "." << glfx_minor << "." << glfw_rev;
debug::d() << "GLFW header " << GLFW_VERSION_MAJOR << "." << GLFW_VERSION_MINOR << "." << GLFW_VERSION_REVISION;
// debug::d() << "GLFW " << glfw_major << "." << glfx_minor << "." << glfw_rev;
// debug::d() << "GLFW header " << GLFW_VERSION_MAJOR << "." << GLFW_VERSION_MINOR << "." << GLFW_VERSION_REVISION;
update_display_list();
// we default to window invisible by default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
// OpenGL
// request specific version 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
@ -182,7 +186,7 @@ struct window::impl {
rev = glfwGetWindowAttrib(_window, GLFW_CONTEXT_REVISION);
// maybe something to pass to the outside
debug::d() << "OpenGL " << major << "." << minor << "." << rev;
// debug::d() << "OpenGL " << major << "." << minor << "." << rev;
glfwSetWindowUserPointer(_window,this);
@ -213,6 +217,7 @@ struct window::impl {
{
if (_window && !glfwWindowShouldClose(_window))
{
// TODO lock an unlock the current input system to allow for late events coming in
input::get().reset();
// get new events

View file

@ -4,7 +4,7 @@ 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/renderer.hpp
include/pw/visual/material.hpp
)
@ -16,7 +16,7 @@ set(srcs
src/pipeline.cpp
src/target.cpp
src/texture.cpp
src/mesh_renderer.cpp
src/renderer.cpp
src/material.cpp
)

View file

@ -7,7 +7,7 @@
#include <pw/core/color.hpp>
#include <pw/visual/shader.hpp>
#include <pw/visual/mesh_renderer.hpp>
#include <pw/visual/renderer.hpp>
#include <pw/visual/material.hpp>
@ -45,7 +45,7 @@ struct render_pass {
const material& mat);
shader _shader;
mesh_renderer _renderer;
renderer _renderer;
};

View file

@ -12,12 +12,12 @@ class geometry;
/**
* @brief Connects mesh data with the render backend
*/
class mesh_renderer {
class renderer {
public:
mesh_renderer();
mesh_renderer(const geometry& m);
renderer();
renderer(const geometry& m);
~mesh_renderer();
~renderer();
bool create(const geometry &m);
void release();

View file

@ -7,27 +7,28 @@
namespace pw {
// TODO stencil buffer?
struct framebuffer::impl {
size _size;
GLuint _fbo_draw;
GLuint _fbo_msaa;
GLuint _fbo_draw { std::numeric_limits<GLuint>::max() };
GLuint _fbo_msaa { std::numeric_limits<GLuint>::max() };
GLuint _rbo_color;
GLuint _rbo_depth;
GLuint _rbo_color { std::numeric_limits<GLuint>::max() };
GLuint _rbo_depth { std::numeric_limits<GLuint>::max() };
bool create(const size &s)
{
// TODO mak color resolution and
_size = s;
int max_msaa;
int max_msaa { 0 };
// 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);
@ -39,13 +40,13 @@ struct framebuffer::impl {
glBindRenderbuffer(GL_RENDERBUFFER, _rbo_color);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, _size.width, _size.height);
// create a 4x MSAA renderbuffer object for depthbuffer
// create a 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
// create a MSAA framebuffer object
glGenFramebuffers(1, &_fbo_msaa);
glBindFramebuffer(GL_FRAMEBUFFER, _fbo_msaa);
@ -71,16 +72,16 @@ struct framebuffer::impl {
}
void bind()
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_msaa);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_draw);
}
void blit()
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo_msaa); // src FBO (multi-sample)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_draw); // dst FBO (single-sample)
// 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
@ -91,10 +92,7 @@ struct framebuffer::impl {
void unbind()
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
};

View file

@ -1,156 +0,0 @@
#include "pw/visual/mesh_renderer.hpp"
#include "pw/core/geometry.hpp"
#include "pw/core/size.hpp"
#include "pw/core/debug.hpp"
#include "glad/glad.h"
#include <algorithm>
namespace pw {
struct mesh_renderer::impl {
GLuint _vao = 0;
std::vector<GLuint> _vbos;
GLint _mesh_elements = {0};
impl()
{
}
~impl()
{
release();
}
bool ready() const
{
return glIsVertexArray != nullptr && GL_TRUE == glIsVertexArray(_vao);
}
bool create(const geometry& m)
{
// reset if the renderer already in use
if (ready()) {
release();
}
glGenVertexArrays(1,&_vao);
glBindVertexArray(_vao);
size_t arrays_needed = 0;
// should bail out here
if (!m.vertices().empty()) arrays_needed++;
if (!m.indices().empty()) arrays_needed++;
_mesh_elements = m.indices().size();
// TODO: implement the other arrays
_vbos.resize(arrays_needed);
glGenBuffers(_vbos.size(), _vbos.data());
// vertices
glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]);
glBufferData(GL_ARRAY_BUFFER,
sizeof(m.vertices().front()) * m.vertices().size(),
m.vertices().data(),
GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbos[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(m.indices().front()) * m.indices().size(), m.indices().data(),
GL_STATIC_DRAW);
// stop binding
glBindVertexArray(0);
auto error = glGetError();
if (error != GL_NO_ERROR) {
debug::e() << "GL error: " << error;
}
return ready();
}
void release()
{
glDeleteVertexArrays(1,&_vao);
for (auto vbo : _vbos)
glDeleteBuffers(1,&vbo);
_vbos.clear();
}
void draw()
{
if (glIsVertexArray(_vao)) {
glBindVertexArray(_vao);
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);
auto error = glGetError();
if (error != GL_NO_ERROR) {
debug::e() << "GL error: " << error;
}
}
}
// GLint get_mode(vertex_array::)
};
//
//
//
mesh_renderer::mesh_renderer()
: _impl(std::make_unique<mesh_renderer::impl>())
{
}
mesh_renderer::mesh_renderer(const geometry &m)
{
mesh_renderer();
_impl->create(m);
}
mesh_renderer::~mesh_renderer()
{
}
bool mesh_renderer::ready() const
{
return _impl->ready();
}
bool mesh_renderer::create(const geometry &m)
{
return _impl->create(m);
}
void mesh_renderer::release()
{
_impl->release();
}
void mesh_renderer::draw()
{
_impl->draw();
}
}

View file

@ -7,7 +7,7 @@
#include <pw/visual/material.hpp>
#include <pw/visual/shader.hpp>
#include <pw/visual/mesh_renderer.hpp>
#include <pw/visual/renderer.hpp>
namespace pw {

View file

@ -9,38 +9,20 @@
#include "pw/core/debug.hpp"
#include "pw/visual/pipeline.hpp"
#include "pw/visual/shader.hpp"
#include "pw/visual/mesh_renderer.hpp"
#include "pw/visual/renderer.hpp"
#include "pw/visual/material.hpp"
#include "pw/visual/framebuffer.hpp"
#include "glad/glad.h"
namespace pw {
class command {
};
class mesh_command : command {
// shader
// vertexarray
};
class queue {
// vector<commands> ...
};
void render_pass::submit(const geometry &g,
const matrix4x4 &model_mat,
const matrix4x4 &view_mat,
const matrix4x4 &projection_mat,
const material &mat)
const matrix4x4 &model_mat,
const matrix4x4 &view_mat,
const matrix4x4 &projection_mat,
const material &mat)
{
if (!_shader.ready())
{ //
@ -71,46 +53,46 @@ struct triangle_renderer
{
shader shader_p;
geometry amesh;
mesh_renderer renderer;
time::tick_t tick;
shader shader_p;
geometry amesh;
renderer r;
time::tick_t tick;
triangle_renderer()
{
}
triangle_renderer()
{
}
void setup()
{
void setup()
{
const float z_val = -5.f;
const float s = 1.0f;
const float z_val = -5.f;
const float s = 1.0f;
//
// 0 -- 1
// | / |
// 2 -- 3
//
// 0 -- 1
// | / |
// 2 -- 3
// geometry
geometry::vertex3array_t vertices = {
{-s, s, z_val} // 0
,{ s, s, z_val} // 1
,{-s, -s, z_val} // 2
,{ s, -s, z_val} // 3
};
// geometry
geometry::vertex3array_t vertices = {
{-s, s, z_val} // 0
,{ s, s, z_val} // 1
,{-s, -s, z_val} // 2
,{ s, -s, z_val} // 3
};
// topology / indices
geometry::indexarray_t indices = { 2, 1, 0,
2, 3, 1};
// topology / indices
geometry::indexarray_t indices = { 2, 1, 0,
2, 3, 1};
amesh.set_indices(indices);
amesh.set_vertices(vertices);
amesh.set_indices(indices);
amesh.set_vertices(vertices);
amesh.compute_normals();
amesh.compute_normals();
const char* vertex_shader_2 = R"(
const char* vertex_shader_2 = R"(
#version 400
uniform mat4 model;
uniform mat4 view;
@ -124,7 +106,7 @@ struct triangle_renderer
}
)";
const char *fragment_shader_2 = R"(
const char *fragment_shader_2 = R"(
#version 400
uniform vec4 input_color = vec4(1.0, 0.0, 0.0, 1.0);
out vec4 frag_colour;
@ -135,178 +117,188 @@ struct triangle_renderer
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);
}
if (!shader_p.build())
exit(-1);
}
void draw()
{
if (!renderer.ready())
renderer.create(amesh);
void draw()
{
if (!r.ready())
r.create(amesh);
// input needed here -
// model view projection
// input needed here -
// model view projection
shader_p.use();
shader_p.use();
auto v_col = ping_pong(static_cast<float>(time::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>(time::now()),2 * ::pw::pi<float>());
auto v_angle = ping_pong(static_cast<float>(time::now()),2 * ::pw::pi<float>());
axisangle rot(vector3::forward(),v_angle);
model_mat = rot.to_matrix();
axisangle rot(vector3::forward(),v_angle);
model_mat = rot.to_matrix();
matrix4x4f view_mat = matrix_transform<float>::look_at(vector3({0,0,0}),
vector3::forward(),
vector3::up());
matrix4x4f view_mat = matrix_transform<float>::look_at(vector3({0,0,0}),
vector3::forward(),
vector3::up());
// materials should carry this
// materials should carry this
#if 1
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
#endif
// now bind textures
// now bind textures
#if 1
auto proj_mat = matrix_transform<float>::orthographic_projection(1.3,1.0,
0.2f,100.f);
auto proj_mat = matrix_transform<float>::orthographic_projection(1.3,1.0,
0.2f,100.f);
#else
auto proj_mat = matrix_transform<float>::perspective_projection(deg_to_rad(60.f),
1.3f,
0.2f,1000.f);
auto proj_mat = matrix_transform<float>::perspective_projection(deg_to_rad(60.f),
1.3f,
0.2f,1000.f);
#endif
#if 0
// highly inefficient - should be cached -
shader_p.set("input_color",col);
shader_p.set("model",model_mat);
shader_p.set("view",view_mat);
shader_p.set("projection",proj_mat);
#if 1
// highly inefficient - should be cached -
shader_p.set_uniform("input_color",col);
shader_p.set_uniform("model",model_mat);
shader_p.set_uniform("view",view_mat);
shader_p.set_uniform("projection",proj_mat);
#else
// new version with ...
shader::uniform_cache_t us;
us.push_back(std::make_tuple("input_color",col,-1));
us.push_back(std::make_tuple("model",model_mat,-1));
us.push_back(std::make_tuple("view",view_mat,-1));
us.push_back(std::make_tuple("projection",proj_mat,-1));
// new version with ...
shader::uniform_cache_t us;
us.push_back(std::make_tuple("input_color",col,-1));
us.push_back(std::make_tuple("model",model_mat,-1));
us.push_back(std::make_tuple("view",view_mat,-1));
us.push_back(std::make_tuple("projection",proj_mat,-1));
shader_p.set_uniforms(us);
shader_p.set_uniforms(us);
#endif
renderer.draw();
r.draw();
auto error = glGetError();
if (error != GL_NO_ERROR){
debug::e() << "GL error " << error;
}
// debug::d() << 100 * (timer::now() - t0) << "ms";
}
// debug::d() << 100 * (timer::now() - t0) << "ms";
}
};
struct pipeline::impl {
#if 0
size _size;
GLuint _fbo_draw;
GLuint _fbo_msaa;
GLuint _fbo_draw;
GLuint _fbo_msaa;
GLuint _rbo_color;
GLuint _rbo_depth;
GLuint _rbo_color;
GLuint _rbo_depth;
#endif
//testing
triangle_renderer tr;
framebuffer fb;
//testing
triangle_renderer tr;
bool create(size s);
void draw();
void draw();
impl() = default;
~impl() = default;
impl() = default;
~impl() = default;
};
GLuint generate_multisample_texture(const size& s,int samples)
{
GLuint texture;
glGenTextures(1, &texture);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
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, texture);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGB8, s.width, s.height, GL_TRUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
return texture;
return texture;
}
bool pipeline::impl::create(::pw::size s)
{
#if 0
_size = s;
int max_msaa;
int max_msaa;
// query actual maximum MSAA
glGetIntegerv(GL_MAX_SAMPLES,&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);
// 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() << "OpenGL multisampling: " << max_msaa << " choosen:" << msaa;
glGenRenderbuffers(1, &_rbo_color);
glBindRenderbuffer(GL_RENDERBUFFER, _rbo_color);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, _size.width, _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
// 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);
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);
// 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 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
// 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;
// check FBO status
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
// reset
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// reset
glBindFramebuffer(GL_FRAMEBUFFER, 0);
#endif
tr.setup();
tr.setup();
return true;
return true;
}
@ -316,75 +308,84 @@ void pipeline::impl::draw()
{
// glClearColor(1.0,0,0,1);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glViewport(0,0,800,600);
glClearColor(1.0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
// draw pass
//
// glViewport(0,0,800,600);
tr.draw();
//
// draw pass
//
tr.draw();
// reset
// reset
// actuall blitting
// actuall blitting
#if 0
/* We are going to blit into the window (default framebuffer) */
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffer (GL_BACK); /* Use backbuffer as color dst. */
/* We are going to blit into the window (default framebuffer) */
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffer (GL_BACK); /* Use backbuffer as color dst. */
/* Read from your FBO */
glBindFramebuffer (GL_READ_FRAMEBUFFER, _fbo_draw );
glReadBuffer (GL_COLOR_ATTACHMENT0); /* Use Color Attachment 0 as color src. */
/* Read from your FBO */
glBindFramebuffer (GL_READ_FRAMEBUFFER, _fbo_draw );
glReadBuffer (GL_COLOR_ATTACHMENT0); /* Use Color Attachment 0 as color src. */
/* Copy the color and depth buffer from your FBO to the default framebuffer */
glBlitFramebuffer (0,0, _size.width, _size.height,
0,0, _size.width, _size.height,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
/* Copy the color and depth buffer from your FBO to the default framebuffer */
glBlitFramebuffer (0,0, _size.width, _size.height,
0,0, _size.width, _size.height,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
#else
glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo_msaa); // src FBO (multi-sample)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_draw); // dst FBO (single-sample)
#if 0
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
glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo_msaa); // src FBO (multi-sample)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_draw); // dst FBO (single-sample)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
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
// debug::d() << _size.width << "x" << _size.height;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
// debug::d() << _size.width << "x" << _size.height;
#endif
#endif
// fb.bind();
GLenum err;
while((err = glGetError()) != GL_NO_ERROR)
{
std::string error;
// fb.blit();
switch(err) {
case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break;
case GL_INVALID_ENUM: error="INVALID_ENUM"; break;
case GL_INVALID_VALUE: error="INVALID_VALUE"; break;
case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break;
}
// fb.unbind();
debug::e() << "OpenGL error:" << err << " " << error;
}
GLenum err;
while((err = glGetError()) != GL_NO_ERROR)
{
std::string error;
switch(err) {
case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break;
case GL_INVALID_ENUM: error="INVALID_ENUM"; break;
case GL_INVALID_VALUE: error="INVALID_VALUE"; break;
case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break;
}
debug::e() << "OpenGL error:" << err << " " << error;
}
}
@ -394,23 +395,23 @@ void pipeline::impl::draw()
//
pipeline::pipeline()
: _impl(std::make_unique<pipeline::impl>())
: _impl(std::make_unique<pipeline::impl>())
{
}
pipeline::~pipeline()
{
//
//
}
void pipeline::draw()
{
_impl->draw();
_impl->draw();
}
bool pipeline::create(size s)
{
return _impl->create(s.cast<int>());
return _impl->create(s.cast<int>());
}
}

165
src/visual/src/renderer.cpp Normal file
View file

@ -0,0 +1,165 @@
#include "pw/visual/renderer.hpp"
#include "pw/core/geometry.hpp"
#include "pw/core/size.hpp"
#include "pw/core/debug.hpp"
#include "glad/glad.h"
#include <algorithm>
namespace pw {
struct renderer::impl {
GLuint _vao = 0;
std::vector<GLuint> _vbos;
GLint _mesh_elements = { 0 };
impl() = default;
~impl()
{
release();
}
bool ready() const
{
return glIsVertexArray != nullptr && GL_TRUE == glIsVertexArray(_vao);
}
bool create(const geometry& m)
{
// reset if the renderer already in use
if (ready()) {
release();
}
glGenVertexArrays(1,&_vao);
// TODO check if valid?
glBindVertexArray(_vao);
size_t arrays_needed = 0;
// should bail out here
if (!m.vertices().empty()) arrays_needed++;
if (!m.indices().empty()) arrays_needed++;
_mesh_elements = m.indices().size();
// TODO: implement the other arrays
_vbos.resize(arrays_needed);
glGenBuffers(_vbos.size(), _vbos.data());
// vertices
glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]);
glBufferData(GL_ARRAY_BUFFER,
sizeof(m.vertices().front()) * m.vertices().size(),
m.vertices().data(),
GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbos[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(m.indices().front()) * m.indices().size(), m.indices().data(),
GL_STATIC_DRAW);
// stop binding
glBindVertexArray(0);
auto error = glGetError();
if (error != GL_NO_ERROR) {
debug::e() << "GL error: " << error;
}
return ready();
}
void release()
{
glDeleteVertexArrays(1,&_vao);
for (auto vbo : _vbos)
glDeleteBuffers(1,&vbo);
_vbos.clear();
}
void draw()
{
#if 1
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
#endif
glClearColor(0.0,1.0,0,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (glIsVertexArray(_vao))
{
glBindVertexArray(_vao);
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);
auto error = glGetError();
if (error != GL_NO_ERROR)
{
debug::e() << "GL error: " << error;
}
}
}
// GLint get_mode(vertex_array::)
};
//
//
//
renderer::renderer()
: _impl(std::make_unique<renderer::impl>())
{
}
renderer::renderer(const geometry &m)
{
renderer();
_impl->create(m);
}
renderer::~renderer()
{
}
bool renderer::ready() const
{
return _impl->ready();
}
bool renderer::create(const geometry &m)
{
return _impl->create(m);
}
void renderer::release()
{
_impl->release();
}
void renderer::draw()
{
_impl->draw();
}
}