the usual triangle test with the shader pipeline

This commit is contained in:
Hartmut Seichter 2019-01-16 16:55:37 +01:00
parent 1f6ff8526b
commit 351d29cd54
10 changed files with 263 additions and 105 deletions

View file

@ -32,4 +32,4 @@ target_include_directories(
include
)
target_link_libraries(pwscripting lualib pwcore pwsystem pwscene)
target_link_libraries(pwscripting lualib pwcore pwsystem pwscene pwvisual)

View file

@ -5,6 +5,7 @@
#include "script_core.hpp"
#include "script_system.hpp"
#include "script_scene.hpp"
#include "script_visual.hpp"
namespace pw {
@ -46,6 +47,7 @@ void lua_state::load_modules() {
script_core::load(_namespace);
script_system::load(_namespace);
script_scene::load(_namespace);
script_visual::load(_namespace);
}

View file

@ -6,27 +6,8 @@
#include "pw/core/debug.hpp"
// hijacking
//#include "pw/visual/pipeline.hpp"
namespace pw {
#if defined(__clang)
struct window_lua : public window {
// overridable function
sol::function lua_update;
window_lua(sol::this_state L)
// default is an empty callback
: lua_update(sol::make_reference<sol::function>(L.lua_state(), [](){}))
{
// set this internal callback of the window to the lua callback
_on_update = [this](window&){this->lua_update();};
}
};
#endif
void script_system::load(sol::table &ns)
{
@ -41,30 +22,20 @@ void script_system::load(sol::table &ns)
);
ns.new_usertype<input>("input",
"new", sol::no_constructor,
"get",&input::get,
"mouse_position",sol::readonly_property(&input::mouse_position),
"mouse_button",sol::readonly_property(&input::mouse_button),
"mouse_pressed",sol::readonly_property(&input::mouse_pressed),
"input_string",sol::readonly_property(&input::input_string)
);
ns.new_usertype<input>("input",
"new", sol::no_constructor,
"get",&input::get,
"mouse_position",sol::readonly_property(&input::mouse_position),
"mouse_button",sol::readonly_property(&input::mouse_button),
"mouse_pressed",sol::readonly_property(&input::mouse_pressed),
"input_string",sol::readonly_property(&input::input_string)
);
ns.new_usertype<display>("display",
"all",&display::all,
"name",sol::readonly_property(&display::name)
);
ns.new_usertype<display>("display",
"all",&display::all,
"name",sol::readonly_property(&display::name)
);
// ns.set_function("my_class_func_2", &my_class::func);
//
// // hijack part
// //
// ns.new_usertype<pipeline>("pipeline",
// "create",&pipeline::create
// );
}
}

View file

@ -0,0 +1,18 @@
#include "script_visual.hpp"
#include "pw/core/debug.hpp"
#include "pw/visual/pipeline.hpp"
namespace pw {
void script_visual::load(sol::table &ns)
{
ns.new_usertype<pipeline>("pipeline",
"create",&pipeline::create,
"draw",&pipeline::draw
);
}
}

View file

@ -0,0 +1,17 @@
#ifndef PW_SCRIPTING_PRIVATE_VISUAL_HPP
#define PW_SCRIPTING_PRIVATE_VISUAL_HPP
#include "scripting.hpp"
namespace pw {
struct script_visual {
static void load(scripting::table& ns);
};
}
#endif

View file

@ -70,9 +70,18 @@ local w = pw.window.new()
-- set title
w.title = "pixwerx 0.1"
local pl = pw.pipeline.new()
if pl:create(pw.size.new(800,600)) then
print("pipeline ok")
else
print("pipeline failed")
end
-- setup a lua callback function
w.on_update = function(self)
print("test on update",w.position.x,w.position.y,pw.timer.now)
pl:draw()
-- print("test on update",w.position.x,w.position.y,pw.timer.now)
end
-- set size
@ -90,16 +99,16 @@ local t = pw.timer.new()
while w:update()
do
-- somehow works
if (pw.input.get().input_string == 'f') then
w.fullscreen = not w.fullscreen
end
if (pw.input.get().input_string == 'f') then
w.fullscreen = not w.fullscreen
end
-- just to check
if (pw.input:get().mouse_button == 1) then
print("elapsed",t.elapsed)
print("elapsed",t.elapsed)
t:reset()
print(pw.input:get().mouse_position.x,pw.input:get().mouse_position.y)
end
print(pw.input:get().mouse_position.x,pw.input:get().mouse_position.y)
end
-- print("update")
end

View file

@ -135,9 +135,9 @@ struct window::impl {
update_display_list();
// request specific version 3.2
// request specific version 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

View file

@ -13,6 +13,7 @@ class shader {
public:
shader();
~shader();
enum code_type {
vertex, //<
@ -21,7 +22,7 @@ public:
compute
};
void set_source(const std::string& c,code_type t);
void set_source(const std::string& c,code_type t) { _source[t] = c; }
std::string source(code_type t) { return _source[t]; }
// void set_attributes(const std::vector<std::string> > &attributes);
@ -41,6 +42,10 @@ public:
return *this;
}
void build();
void use();
protected:
std::map<code_type,std::string> _source;

View file

@ -2,91 +2,208 @@
#include "pw/core/size.hpp"
#include "pw/core/matrix.hpp"
#include "pw/core/debug.hpp"
#include "pw/visual/pipeline.hpp"
#include "pw/visual/shader.hpp"
#include "glad/glad.h"
namespace pw {
struct triangle_renderer
{
GLuint vbo = 0;
GLuint vao = 0;
GLuint shader_programme = 0;
shader shader_p;
triangle_renderer()
{
}
void setup()
{
float points[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
const char* vertex_shader =
"#version 400\n"
"in vec3 vp;"
"void main() {"
" gl_Position = vec4(vp, 1.0);"
"}";
const char* fragment_shader =
"#version 400\n"
"out vec4 frag_colour;"
"void main() {"
" frag_colour = vec4(0.5, 0.0, 0.5, 1.0);"
"}";
#if 0
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
#endif
shader_p.set_source(fragment_shader,shader::fragment);
shader_p.set_source(vertex_shader,shader::vertex);
shader_p.build();
}
void draw()
{
// glUseProgram(shader_programme);
shader_p.use();
glBindVertexArray(vao);
// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays(GL_TRIANGLES, 0, 3);
}
};
struct pipeline::impl {
sizei _size;
sizei _size;
GLuint _fbo_draw;
GLuint _fbo_msaa;
GLuint _fbo_draw;
GLuint _fbo_msaa;
GLuint rboColorId;
GLuint rboDepthId;
GLuint rboColorId;
GLuint rboDepthId;
bool create(sizei size);
//testing
triangle_renderer tr;
void draw();
bool create(sizei size);
impl() = default;
~impl() = default;
void draw();
impl() = default;
~impl() = default;
};
bool pipeline::impl::create(sizei size)
{
int max_msaa;
// query actual maximum MSAA
glGetIntegerv(GL_MAX_SAMPLES,&max_msaa);
_size = size;
// create a 4x MSAA renderbuffer object for colorbuffer
int msaa = 4;
int max_msaa;
// msaa = std::clamp(msaa,max_msaa);
// query actual maximum MSAA
glGetIntegerv(GL_MAX_SAMPLES,&max_msaa);
glGenRenderbuffers(1, &rboColorId);
glBindRenderbuffer(GL_RENDERBUFFER, rboColorId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGB8, _size.width, _size.height);
// create a 4x MSAA renderbuffer object for depthbuffer
// create a 4x MSAA renderbuffer object for colorbuffer
int msaa = std::min(max_msaa,4);
glGenRenderbuffers(1, &rboDepthId);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
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);
debug::d() << "OpenGL multisampling: " << max_msaa << " choosen:" << 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
rboColorId); // 4. rbo ID
// msaa = std::clamp(msaa,max_msaa);
// 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
rboDepthId); // 4. rbo ID
glGenRenderbuffers(1, &rboColorId);
glBindRenderbuffer(GL_RENDERBUFFER, rboColorId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGB8, _size.width, _size.height);
// check FBO status
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
// create a 4x MSAA renderbuffer object for depthbuffer
return true;
glGenRenderbuffers(1, &rboDepthId);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
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
rboColorId); // 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
rboDepthId); // 4. rbo ID
// check FBO status
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
tr.setup();
return true;
}
void pipeline::impl::draw()
{
/* 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. */
glBindBuffer(GL_DRAW_FRAMEBUFFER, _fbo_draw);
/* 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);
glClearColor(1,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
tr.draw();
// reset
glBindBuffer(GL_DRAW_FRAMEBUFFER, 0);
// actuall blitting
/* 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. */
/* 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_LINEAR);
}
@ -95,7 +212,7 @@ void pipeline::impl::draw()
//
pipeline::pipeline()
: _impl(std::make_unique<pipeline::impl>())
: _impl(std::make_unique<pipeline::impl>())
{
}
@ -104,9 +221,14 @@ pipeline::~pipeline()
//
}
void pipeline::draw()
{
_impl->draw();
}
bool pipeline::create(size s)
{
return _impl->create(sizei(s.width,s.height));
return _impl->create(s.cast<int>());
}
}

View file

@ -159,7 +159,11 @@ struct shader::impl
shader::shader()
{
_impl = make_unique<impl>(*this);
_impl = make_unique<impl>(*this);
}
shader::~shader()
{
}
bool shader::ready() const
@ -167,6 +171,16 @@ bool shader::ready() const
return _impl->is_valid();
}
void shader::build()
{
_impl->build();
}
void shader::use()
{
_impl->use();
}
int shader::uniform_location(const std::string &name)
{
return _impl->uniform_location(name);