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

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