working mesh rendering and shader uniforms

This commit is contained in:
Hartmut Seichter 2019-01-30 23:52:38 +01:00
parent ad13cea0ca
commit d9bbef876e
19 changed files with 262 additions and 83 deletions

View file

@ -12,10 +12,17 @@ set(srcs
src/pipeline.cpp
)
set(srcs_shader
src/shader/unlit_vs.glsl
src/shader/unlit_fs.glsl
)
add_library(pwvisual
STATIC
${hdrs}
${srcs}
${srcs_shader}
)
target_include_directories(

View file

@ -11,11 +11,23 @@ namespace pw {
class mesh_renderer {
public:
void render(const mesh& mesh,
const matrix4x4& model_matrix,
const matrix4x4& view_matrix,
const matrix4x4& projection_matrix
);
mesh_renderer();
~mesh_renderer();
bool ready() const;
void create(const mesh &m);
void destroy();
void draw();
// void render(const mesh& mesh,
// const matrix4x4& model_matrix,
// const matrix4x4& view_matrix,
// const matrix4x4& projection_matrix
// );
protected:

View file

@ -3,6 +3,7 @@
#include <pw/core/globals.hpp>
#include <pw/core/matrix.hpp>
#include <pw/core/vector.hpp>
#include <pw/core/debug.hpp>
#include <map>
@ -31,18 +32,21 @@ public:
shader& bind(int location,float v);
shader& bind(int location,matrix4x4f const & v);
shader& bind(int location,vector4f const & v);
int uniform_location(std::string const & name);
int uniform_location(std::string const & name) const;
template<typename T> shader & bind(std::string const & name, T&& value)
{
int location = uniform_location(name);
if (location == -1) debug::e() << "missing uniform: "<< name;
else bind(location, std::forward<T>(value));
if (location >= 0)
return bind(location, std::forward<T>(value));
else
debug::e() << "missing uniform: "<< name;
return *this;
}
void build();
bool build();
void use();

View file

@ -15,11 +15,21 @@ struct mesh_renderer::impl {
GLuint _vao = 0;
std::vector<GLuint> _vbos;
impl(mesh_renderer& )
impl()
{
}
void create(std::shared_ptr<mesh> mesh)
~impl()
{
destroy();
}
bool ready() const
{
return GL_TRUE == glIsVertexArray(_vao);
}
void create(const mesh& m)
{
glGenVertexArrays(1,&_vao);
glBindVertexArray(_vao);
@ -27,8 +37,8 @@ struct mesh_renderer::impl {
size_t arrays_needed = 0;
// should bail out here
if (!mesh->vertices().empty()) arrays_needed++;
if (!mesh->indices().empty()) arrays_needed++;
if (!m.vertices().empty()) arrays_needed++;
if (!m.indices().empty()) arrays_needed++;
// TODO: implement the other arrays
@ -38,22 +48,22 @@ struct mesh_renderer::impl {
// vertices
glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(mesh->vertices().front()) * mesh->vertices().size(), mesh->vertices().data(),
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(mesh->indices().front()) * mesh->indices().size(), mesh->indices().data(),
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m.indices().front()) * m.indices().size(), m.indices().data(),
GL_STATIC_DRAW);
// stop binding
glBindVertexArray(0);
}
void destroy()
{
glDeleteVertexArrays(1,&_vao);
@ -65,12 +75,44 @@ struct mesh_renderer::impl {
void draw()
{
glBindVertexArray(_vao);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
}
};
//
//
//
mesh_renderer::mesh_renderer()
: _impl(std::make_unique<mesh_renderer::impl>())
{
}
mesh_renderer::~mesh_renderer()
{
}
bool mesh_renderer::ready() const
{
return _impl->ready();
}
void mesh_renderer::create(const mesh &m)
{
_impl->create(m);
}
void mesh_renderer::destroy()
{
_impl->destroy();
}
void mesh_renderer::draw()
{
_impl->draw();
}
}

View file

@ -7,6 +7,7 @@
#include "pw/core/debug.hpp"
#include "pw/visual/pipeline.hpp"
#include "pw/visual/shader.hpp"
#include "pw/visual/mesh_renderer.hpp"
#include "glad/glad.h"
@ -22,6 +23,7 @@ struct triangle_renderer
shader shader_p;
mesh amesh;
mesh_renderer amesh_renderer;
triangle_renderer()
{
@ -48,6 +50,10 @@ struct triangle_renderer
amesh.set_indices(indices);
amesh.set_vertices(vertices);
amesh_renderer.create(amesh);
size_t vertex_size_bytes = amesh.vertices().size() * sizeof(mesh::vertex3array_t::value_type);
size_t vertex_stride = amesh.vertices().front().size();
@ -72,24 +78,19 @@ struct triangle_renderer
glVertexAttribPointer(0, vertex_stride, GL_FLOAT, GL_FALSE, 0, nullptr);
const char* vertex_shader = R"(
#version 400
in vec3 vp;
void main() {
#version 400
in vec3 vp;
void main() {
gl_Position = vec4(vp, 1.0);
}
)";
// "#version 400\n"
// "in vec3 vp;"
// "void main() {"
// " gl_Position = vec4(vp, 1.0);"
// "}";
const char *fragment_shader = R"(#version 400
out vec4 frag_colour;
const char *fragment_shader = R"(
#version 400
uniform vec4 input_color = vec4(1.0, 0.0, 0.0, 1.0);
out vec4 frag_colour;
void main() {
frag_colour = vec4(0.5, 0.5, 0.5, 1.0);
frag_colour = input_color;
})";
#if 0
@ -110,17 +111,29 @@ struct triangle_renderer
shader_p.set_source(fragment_shader,shader::fragment);
shader_p.set_source(vertex_shader,shader::vertex);
shader_p.build();
if (!shader_p.build())
exit(-1);
}
void draw()
{
shader_p.use();
glBindVertexArray(vao);
shader_p.use();
static float v = 0.0f;
v+= 0.01f;
if (v>1.0f) v = 0.0f;
vector4f test({0.5f,1-v,v,1.0f});
shader_p.bind("input_color",test);
amesh_renderer.draw();
// glBindVertexArray(vao);
// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays(GL_TRIANGLES, 0, 3);
// glDrawArrays(GL_TRIANGLES, 0, 3);
}
};

View file

@ -29,7 +29,7 @@ struct shader::impl
return glIsProgram(_shader_program);
}
void build()
bool build()
{
for (auto s : _shader._source)
@ -75,7 +75,7 @@ struct shader::impl
// TODO - handle errors!
debug::e() << log_buffer.get();
break;
return false;
}
_shader_stages.push_back(shaderId);
@ -120,8 +120,10 @@ struct shader::impl
/* Handle the error in an appropriate way such as displaying a message or writing to a log file. */
/* In this simple program, we'll just leave */
return;
return false;
}
return true;
}
@ -142,14 +144,24 @@ struct shader::impl
}
}
int uniform_location(std::string const& name)
int uniform_location(std::string const& name) const
{
return glGetUniformLocation(_shader_program,name.c_str());
}
void bind(int location,const matrix4x4f& m)
{
glUniformMatrix4fv(location,1,GL_FALSE,m.data); // TODO transpose?
glUniformMatrix4fv(location,1,GL_FALSE,m.data);
}
void bind(int location,const vector4f& v)
{
glUniform4fv(location,1,v.data);
}
void bind(int location,const float& v)
{
glUniform1f(location,v);
}
};
@ -169,9 +181,14 @@ bool shader::ready() const
return _impl->is_valid();
}
void shader::build()
shader &shader::bind(int location, const vector4f &v)
{
_impl->build();
_impl->bind(location,v); return *this;
}
bool shader::build()
{
return _impl->build();
}
void shader::use()
@ -179,7 +196,7 @@ void shader::use()
_impl->use();
}
int shader::uniform_location(const std::string &name)
int shader::uniform_location(const std::string &name) const
{
return _impl->uniform_location(name);
}

View file

@ -0,0 +1,5 @@
#version 400
out vec4 frag_colour;
void main() {
frag_colour = vec4(0.5, 0.5, 0.5, 1.0);
}

View file

@ -0,0 +1,5 @@
#version 400
in vec3 vp;
void main() {
gl_Position = vec4(vp, 1.0);
}