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
|
@ -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