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

@ -2,6 +2,7 @@
* rename rect to rectangle
* fields - maybe std::variant?
* add more tests for linear algebra
# scripting
@ -14,7 +15,7 @@
# system
* filesystem walker with C++17
* filesystem walker with C++17 (or inotify, FindFirstChangeNotification or FSEvents)
# visual

View file

@ -1,6 +1,7 @@
set(hdrs
include/pw/core/axisangle.hpp
include/pw/core/color.hpp
include/pw/core/core.hpp
include/pw/core/debug.hpp
include/pw/core/globals.hpp
@ -10,7 +11,7 @@ set(hdrs
include/pw/core/quaternion.hpp
include/pw/core/image.hpp
include/pw/core/point.hpp
include/pw/core/rect.hpp
include/pw/core/rectangle.hpp
include/pw/core/serialize.hpp
include/pw/core/size.hpp
include/pw/core/timer.hpp

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 1999-2019 Hartmut Seichter
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#ifndef PW_CORE_COLOR_HPP
#define PW_CORE_COLOR_HPP
#include <pw/core/vector.hpp>
#include <limits>
namespace pw {
struct color {
vector4 components;
color(uint8_t r8,uint8_t g8,uint8_t b8,uint8_t a8)
: color(static_cast<real_t>(r8 / std::numeric_limits<uint8_t>::max()),
static_cast<real_t>(g8 / std::numeric_limits<uint8_t>::max()),
static_cast<real_t>(b8 / std::numeric_limits<uint8_t>::max()),
static_cast<real_t>(a8 / std::numeric_limits<uint8_t>::max()))
{
}
color(real_t r,real_t g,real_t b,real_t a)
: components({r,g,b,a})
{
}
uint32_t to_rgb8888() const {
return 0;
}
};
}
#endif

View file

@ -43,6 +43,7 @@ struct quaternion_ : vector4_<T> {
using base_type::z;
using base_type::w;
using base_type::lerp;
using base_type::xyz;
// using base_type::operator*;
// using base_type::operator/;

View file

@ -29,14 +29,14 @@
namespace pw {
template <typename T_>
struct rect_ {
struct rectangle_ {
size_<T_> size;
point_<T_> position;
rect_() = default;
rectangle_() = default;
rect_(point_<T_> const & p,size_<T_> const & s) : size(s), position(p) {}
rectangle_(point_<T_> const & p,size_<T_> const & s) : size(s), position(p) {}
bool contains(const point_<T_>& p) const
{
@ -45,16 +45,15 @@ struct rect_ {
}
template <typename To_>
rect_<To_> cast() const { return rect_<To_>(position.template cast<To_>(),size.template cast<To_>()); }
rectangle_<To_> cast() const { return rectangle_<To_>(position.template cast<To_>(),size.template cast<To_>()); }
};
typedef rect_<real_t> rect;
typedef rectangle_<real_t> rectangle;
typedef rect_<int> recti;
typedef rect_<float> rectf;
typedef rect_<float> rectd;
typedef rectangle_<int> rectanglei;
typedef rectangle_<float> rectanglef;
typedef rectangle_<double> rectangled;
}

View file

@ -30,7 +30,7 @@ int main(int argc,char **argv) {
auto v3_h = v.homogenous();
// auto v3_lerp = vector4f::lerp()
// auto v3_lerp = vector4f::
std::cout << "v3 = " << pw::serialize::matrix(v3) << std::endl;

View file

@ -3,7 +3,6 @@ set(hdrs
include/pw/scene/camera.hpp
include/pw/scene/component.hpp
include/pw/scene/node.hpp
# include/pw/scene/mesh.hpp
include/pw/scene/scene.hpp
include/pw/scene/transform.hpp
include/pw/scene/traverser.hpp
@ -13,7 +12,6 @@ set(srcs
src/node.cpp
src/camera.cpp
src/component.cpp
# src/mesh.cpp
src/scene.cpp
src/transform.cpp
src/traverser.cpp

View file

@ -47,6 +47,19 @@ void component::set_weight(const uint32_t &weight)
}
class material_component {
enum shading_input {
albedo,
specular
};
// std::map<shading_input,vector4> _colors;
// std::shared_ptr<image> _albedo;
};
//class trs : public transform {

View file

@ -3,6 +3,8 @@
#include <pw/scene/node.hpp>
#include <pw/scene/transform.hpp>
#include <pw/core/serialize.hpp>
#include <iostream>
void print_node_path(pw::node::ref node) {
@ -49,7 +51,6 @@ int main(int argc,char **argv) {
print_node_path((n));
// auto t = n->transform();
// if (t)

View file

@ -30,6 +30,9 @@ void register_core_function(sol::state& lua,sol::table& ns)
ns.new_usertype<matrix4x4>("matrix4x4"
, sol::constructors<matrix4x4()>()
, "row",&matrix4x4::row
, "column",&matrix4x4::column
, "set_identity",&matrix4x4::set_identity
, "inverse",&matrix4x4::inverse
);
ns.new_usertype<vector3>("vector3"
@ -60,15 +63,16 @@ void register_core_function(sol::state& lua,sol::table& ns)
("axisangle",
sol::constructors<axisangle(), axisangle(vector3,Scalar)>(),
"axis",&axisangle::axis,
"angle",&axisangle::angle
"angle",&axisangle::angle,
"from_matrix",&axisangle::from_matrix,
"to_matrix",&axisangle::to_matrix
);
ns.new_usertype<size>("size",
sol::constructors<size(),size(Scalar,Scalar)>(),
"width",&size::width,
"height",&size::height
// "none",sol::debug::level::none
ns.new_usertype<size>("size"
, sol::constructors<size(),size(Scalar,Scalar)>()
, "width",&size::width
, "height",&size::height
);
ns.new_usertype<point>("point",

View file

@ -16,6 +16,7 @@ public:
std::string name() const { return _name; }
protected:
friend class window;
std::string _name;

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();
@ -79,17 +85,12 @@ struct triangle_renderer
}
)";
// "#version 400\n"
// "in vec3 vp;"
// "void main() {"
// " gl_Position = vec4(vp, 1.0);"
// "}";
const char *fragment_shader = R"(#version 400
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,7 +111,8 @@ 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);
}
@ -118,9 +120,20 @@ struct triangle_renderer
void draw()
{
shader_p.use();
glBindVertexArray(vao);
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);
}