the usual triangle test with the shader pipeline
This commit is contained in:
parent
1f6ff8526b
commit
351d29cd54
10 changed files with 263 additions and 105 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
// );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue