clean up some headers
This commit is contained in:
parent
c70c18e41c
commit
a5d42995b2
5 changed files with 251 additions and 358 deletions
|
@ -14,6 +14,13 @@ struct geometry_n {
|
||||||
std::vector<std::size_t> indices{};
|
std::vector<std::size_t> indices{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mesh_n {
|
||||||
|
|
||||||
|
geometry_n geometry{};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace pw
|
} // namespace pw
|
||||||
|
|
||||||
auto main() -> int {
|
auto main() -> int {
|
||||||
|
@ -27,6 +34,8 @@ auto main() -> int {
|
||||||
std::print("({}) ",pw::serialize::to_string(geom.vertices[i]));
|
std::print("({}) ",pw::serialize::to_string(geom.vertices[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// pw::geometry geo;
|
// pw::geometry geo;
|
||||||
|
|
||||||
// pw::vector3_array vs = {
|
// pw::vector3_array vs = {
|
||||||
|
|
|
@ -1,25 +1,23 @@
|
||||||
#ifndef PW_VISUAL_MESH_RENDERER_HPP
|
#ifndef PW_VISUAL_MESH_RENDERER_HPP
|
||||||
#define PW_VISUAL_MESH_RENDERER_HPP
|
#define PW_VISUAL_MESH_RENDERER_HPP
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
class geometry;
|
struct geometry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief builds a renderer for geometry
|
* @brief builds a renderer for geometry
|
||||||
*/
|
*/
|
||||||
class renderer {
|
struct renderer final {
|
||||||
public:
|
|
||||||
|
|
||||||
renderer();
|
renderer();
|
||||||
renderer(const geometry& m);
|
renderer(const geometry& m);
|
||||||
|
|
||||||
~renderer();
|
~renderer();
|
||||||
|
|
||||||
bool update(const geometry &m);
|
bool update(const geometry& m);
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
|
@ -27,13 +25,12 @@ public:
|
||||||
|
|
||||||
uint64_t change_count() const;
|
uint64_t change_count() const;
|
||||||
void set_change_count(uint64_t n);
|
void set_change_count(uint64_t n);
|
||||||
protected:
|
|
||||||
|
|
||||||
|
protected:
|
||||||
struct impl;
|
struct impl;
|
||||||
std::unique_ptr<impl> _impl;
|
std::unique_ptr<impl> _impl;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace pw
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
#ifndef PW_VISUAL_SHADER_HPP
|
#ifndef PW_VISUAL_SHADER_HPP
|
||||||
#define PW_VISUAL_SHADER_HPP
|
#define PW_VISUAL_SHADER_HPP
|
||||||
|
|
||||||
|
#include <pw/core/debug.hpp>
|
||||||
#include <pw/core/globals.hpp>
|
#include <pw/core/globals.hpp>
|
||||||
#include <pw/core/matrix.hpp>
|
#include <pw/core/matrix.hpp>
|
||||||
#include <pw/core/vector.hpp>
|
#include <pw/core/vector.hpp>
|
||||||
#include <pw/core/debug.hpp>
|
|
||||||
|
|
||||||
#include <pw/visual/texture.hpp>
|
#include <pw/visual/texture.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -13,60 +12,56 @@
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
class shader {
|
struct shader final {
|
||||||
public:
|
|
||||||
|
|
||||||
shader();
|
shader();
|
||||||
~shader();
|
~shader();
|
||||||
|
|
||||||
enum class code_type {
|
enum class code_type { vertex, fragment, geometry, compute };
|
||||||
vertex,
|
|
||||||
fragment,
|
|
||||||
geometry,
|
|
||||||
compute
|
|
||||||
};
|
|
||||||
|
|
||||||
void set_source(code_type t, const std::string& c) { _source[t] = c; }
|
void set_source(code_type t, const std::string& c) { _source[t] = c; }
|
||||||
std::string source(code_type t) { return _source[t]; }
|
std::string source(code_type t) { return _source[t]; }
|
||||||
|
|
||||||
bool ready() const;
|
bool ready() const;
|
||||||
|
|
||||||
shader& set_uniform_at_location(int location,float v);
|
shader& set_uniform_at_location(int location, float v);
|
||||||
shader& set_uniform_at_location(int location, uint32_t v);
|
shader& set_uniform_at_location(int location, uint32_t v);
|
||||||
shader &set_uniform_at_location(int location, int32_t v);
|
shader& set_uniform_at_location(int location, int32_t v);
|
||||||
shader& set_uniform_at_location(int location,matrix4x4f const &v);
|
shader& set_uniform_at_location(int location, matrix4x4f const& v);
|
||||||
shader& set_uniform_at_location(int location,vector4f const &v);
|
shader& set_uniform_at_location(int location, vector4f const& v);
|
||||||
shader& set_uniform_at_location(int location,texture const &t);
|
shader& set_uniform_at_location(int location, texture const& t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief retrieves the position of a uniform
|
* @brief retrieves the position of a uniform
|
||||||
* @param name of the uniform
|
* @param name of the uniform
|
||||||
* @return position of the uniform or negative if it doesn't exist
|
* @return position of the uniform or negative if it doesn't exist
|
||||||
*/
|
*/
|
||||||
int uniform_location(std::string const & name) const;
|
int uniform_location(std::string const& name) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief check if a uniform with the given name exists
|
* @brief check if a uniform with the given name exists
|
||||||
* @param name of the uniform
|
* @param name of the uniform
|
||||||
* @return true if found
|
* @return true if found
|
||||||
*/
|
*/
|
||||||
bool has_uniform(std::string const &name) const { return uniform_location(name) >= 0; }
|
bool has_uniform(std::string const& name) const {
|
||||||
|
return uniform_location(name) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets data of the
|
* sets data of the
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template <typename T>
|
||||||
shader & set_uniform(std::string const & name, T &&value)
|
shader& set_uniform(std::string const& name, T&& value) {
|
||||||
{
|
return set_uniform_at_location(uniform_location(name),
|
||||||
return set_uniform_at_location( uniform_location(name), std::forward<T>(value) );
|
std::forward<T>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool build();
|
bool build();
|
||||||
|
|
||||||
void use();
|
void use();
|
||||||
|
|
||||||
using uniform_t = std::variant<bool,int,float,double,vector2f,vector3f,vector4f,matrix4x4f>;
|
using uniform_t = std::variant<bool, int, float, double, vector2f, vector3f,
|
||||||
using uniform_entry_t = std::tuple<std::string,uniform_t,int>;
|
vector4f, matrix4x4f>;
|
||||||
|
using uniform_entry_t = std::tuple<std::string, uniform_t, int>;
|
||||||
|
|
||||||
using uniform_cache_t = std::vector<uniform_entry_t>;
|
using uniform_cache_t = std::vector<uniform_entry_t>;
|
||||||
|
|
||||||
|
@ -74,16 +69,13 @@ public:
|
||||||
|
|
||||||
uint32_t native_handle() const;
|
uint32_t native_handle() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::unordered_map<code_type, std::string> _source;
|
||||||
std::unordered_map<code_type,std::string> _source;
|
|
||||||
|
|
||||||
struct impl;
|
struct impl;
|
||||||
std::unique_ptr<impl> _impl;
|
std::unique_ptr<impl> _impl;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace pw
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,42 +1,35 @@
|
||||||
#include "pw/visual/renderer.hpp"
|
#include "pw/visual/renderer.hpp"
|
||||||
|
|
||||||
#include "pw/core/geometry.hpp"
|
|
||||||
#include "pw/core/size.hpp"
|
|
||||||
#include "pw/core/debug.hpp"
|
#include "pw/core/debug.hpp"
|
||||||
|
#include "pw/core/geometry.hpp"
|
||||||
#include "pw/core/matrix.hpp"
|
#include "pw/core/matrix.hpp"
|
||||||
|
#include "pw/core/size.hpp"
|
||||||
|
|
||||||
#include "glad/glad.h"
|
#include "glad/glad.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
struct renderer::impl {
|
struct renderer::impl {
|
||||||
|
|
||||||
uint64_t _change_count { 0 };
|
uint64_t _change_count{0};
|
||||||
|
|
||||||
uint32_t _vao { 0 };
|
uint32_t _vao{0};
|
||||||
uint32_t _ebo { 0 };
|
uint32_t _ebo{0};
|
||||||
std::vector<uint32_t> _vbos { };
|
std::vector<uint32_t> _vbos{};
|
||||||
|
|
||||||
|
GLint _mesh_elements = {0};
|
||||||
GLint _mesh_elements = { 0 };
|
|
||||||
|
|
||||||
impl() = default;
|
impl() = default;
|
||||||
|
|
||||||
~impl()
|
~impl() { release(); }
|
||||||
{
|
|
||||||
release();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ready() const
|
bool ready() const {
|
||||||
{
|
|
||||||
return glIsVertexArray != nullptr && GL_TRUE == glIsVertexArray(_vao);
|
return glIsVertexArray != nullptr && GL_TRUE == glIsVertexArray(_vao);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(const geometry& m)
|
bool update(const geometry& m) {
|
||||||
{
|
|
||||||
if (_change_count == m.change_count())
|
if (_change_count == m.change_count())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -47,83 +40,70 @@ struct renderer::impl {
|
||||||
_mesh_elements = m.indices().size();
|
_mesh_elements = m.indices().size();
|
||||||
|
|
||||||
//
|
//
|
||||||
glGenVertexArrays(1,&_vao);
|
glGenVertexArrays(1, &_vao);
|
||||||
glBindVertexArray(_vao);
|
glBindVertexArray(_vao);
|
||||||
|
|
||||||
glGenBuffers(1, &_ebo);
|
glGenBuffers(1, &_ebo);
|
||||||
|
|
||||||
|
|
||||||
// TODO binding separate VBOs to the
|
// TODO binding separate VBOs to the
|
||||||
// vertexarray should be avoided
|
// vertexarray should be avoided
|
||||||
|
|
||||||
// indices
|
// indices
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||||
m.indices().size() * sizeof (uint32_t),
|
m.indices().size() * sizeof(uint32_t), m.indices().data(),
|
||||||
m.indices().data(),
|
|
||||||
GL_STATIC_DRAW);
|
GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
_vbos.resize(_vbos.size() + 1);
|
||||||
_vbos.resize(_vbos.size()+1);
|
|
||||||
glGenBuffers(1, &_vbos.back());
|
glGenBuffers(1, &_vbos.back());
|
||||||
|
|
||||||
|
|
||||||
// vertices
|
// vertices
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vbos.back());
|
glBindBuffer(GL_ARRAY_BUFFER, _vbos.back());
|
||||||
glVertexAttribPointer(_vbos.size()-1, vector3::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr);
|
glVertexAttribPointer(_vbos.size() - 1, vector3::coefficients, GL_FLOAT,
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
GL_FALSE, 0, nullptr);
|
||||||
m.vertices().size() * sizeof(vector3),
|
glBufferData(GL_ARRAY_BUFFER, m.vertices().size() * sizeof(vector3),
|
||||||
m.vertices().data(),
|
m.vertices().data(), GL_STATIC_DRAW);
|
||||||
GL_STATIC_DRAW);
|
glEnableVertexAttribArray(_vbos.size() - 1);
|
||||||
glEnableVertexAttribArray(_vbos.size()-1);
|
|
||||||
|
|
||||||
debug::d() << "vertices at " << _vbos.size()-1;
|
debug::d() << "vertices at " << _vbos.size() - 1;
|
||||||
|
|
||||||
if (!m.normals().empty())
|
if (!m.normals().empty()) {
|
||||||
{
|
_vbos.resize(_vbos.size() + 1);
|
||||||
_vbos.resize(_vbos.size()+1);
|
|
||||||
glGenBuffers(1, &_vbos.back());
|
glGenBuffers(1, &_vbos.back());
|
||||||
|
|
||||||
// normals
|
// normals
|
||||||
glBindBuffer(GL_ARRAY_BUFFER,_vbos.back());
|
glBindBuffer(GL_ARRAY_BUFFER, _vbos.back());
|
||||||
glVertexAttribPointer(_vbos.size()-1, vector3::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr);
|
glVertexAttribPointer(_vbos.size() - 1, vector3::coefficients,
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
m.normals().size() * sizeof(vector3),
|
glBufferData(GL_ARRAY_BUFFER, m.normals().size() * sizeof(vector3),
|
||||||
m.normals().data(),
|
m.normals().data(), GL_STATIC_DRAW);
|
||||||
GL_STATIC_DRAW);
|
glEnableVertexAttribArray(_vbos.size() - 1);
|
||||||
glEnableVertexAttribArray(_vbos.size()-1);
|
|
||||||
|
|
||||||
debug::d() << "normals at " << _vbos.size()-1;
|
|
||||||
|
|
||||||
|
debug::d() << "normals at " << _vbos.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m.texture_coordinates().empty())
|
if (!m.texture_coordinates().empty()) {
|
||||||
{
|
for (const auto& tc : m.texture_coordinates()) {
|
||||||
for (const auto& tc : m.texture_coordinates())
|
_vbos.resize(_vbos.size() + 1);
|
||||||
{
|
|
||||||
_vbos.resize(_vbos.size()+1);
|
|
||||||
glGenBuffers(1, &_vbos.back());
|
glGenBuffers(1, &_vbos.back());
|
||||||
|
|
||||||
// texture coordinates
|
// texture coordinates
|
||||||
glBindBuffer(GL_ARRAY_BUFFER,_vbos.back());
|
glBindBuffer(GL_ARRAY_BUFFER, _vbos.back());
|
||||||
glVertexAttribPointer(_vbos.size()-1, vector2::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr);
|
glVertexAttribPointer(_vbos.size() - 1, vector2::coefficients,
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
tc.size() * sizeof(vector2),
|
glBufferData(GL_ARRAY_BUFFER, tc.size() * sizeof(vector2),
|
||||||
tc.data(),
|
tc.data(), GL_STATIC_DRAW);
|
||||||
GL_STATIC_DRAW);
|
glEnableVertexAttribArray(_vbos.size() - 1);
|
||||||
glEnableVertexAttribArray(_vbos.size()-1);
|
|
||||||
|
|
||||||
debug::d() << "texture coordinates at " << _vbos.size()-1;
|
debug::d() << "texture coordinates at " << _vbos.size() - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop binding
|
// stop binding
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
|
||||||
this->_change_count = m.change_count();
|
this->_change_count = m.change_count();
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// get errors
|
// get errors
|
||||||
auto error = glGetError();
|
auto error = glGetError();
|
||||||
|
@ -136,19 +116,16 @@ struct renderer::impl {
|
||||||
return ready();
|
return ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void release() {
|
||||||
|
|
||||||
void release()
|
for (auto & vbo : _vbos)
|
||||||
{
|
glDeleteBuffers(1, &vbo);
|
||||||
|
glDeleteBuffers(1, &_ebo);
|
||||||
|
|
||||||
for (auto vbo : _vbos)
|
glDeleteVertexArrays(1, &_vao);
|
||||||
glDeleteBuffers(1,&vbo);
|
|
||||||
glDeleteBuffers(1,&_ebo);
|
|
||||||
|
|
||||||
glDeleteVertexArrays(1,&_vao);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw()
|
void draw() {
|
||||||
{
|
|
||||||
glBindVertexArray(_vao);
|
glBindVertexArray(_vao);
|
||||||
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
@ -163,57 +140,32 @@ struct renderer::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLint get_mode(vertex_array::)
|
// GLint get_mode(vertex_array::)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Outer wrapper
|
// Outer wrapper
|
||||||
//
|
//
|
||||||
|
|
||||||
renderer::renderer()
|
renderer::renderer() : _impl(std::make_unique<renderer::impl>()) {}
|
||||||
: _impl(std::make_unique<renderer::impl>())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer::renderer(const geometry &m)
|
renderer::renderer(const geometry& m) {
|
||||||
{
|
|
||||||
renderer();
|
renderer();
|
||||||
// directly update
|
// directly update
|
||||||
_impl->update(m);
|
_impl->update(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer::~renderer()
|
renderer::~renderer() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool renderer::ready() const
|
bool renderer::ready() const { return _impl->ready(); }
|
||||||
{
|
|
||||||
return _impl->ready();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool renderer::update(const geometry &m)
|
bool renderer::update(const geometry& m) { return _impl->update(m); }
|
||||||
{
|
|
||||||
return _impl->update(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::release()
|
void renderer::release() { _impl->release(); }
|
||||||
{
|
|
||||||
_impl->release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::draw()
|
void renderer::draw() { _impl->draw(); }
|
||||||
{
|
|
||||||
_impl->draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t renderer::change_count() const
|
uint64_t renderer::change_count() const { return _impl->_change_count; }
|
||||||
{
|
|
||||||
return _impl->_change_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::set_change_count(uint64_t n)
|
void renderer::set_change_count(uint64_t n) { _impl->_change_count = n; }
|
||||||
{
|
|
||||||
_impl->_change_count = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
} // namespace pw
|
||||||
|
|
|
@ -6,35 +6,25 @@
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
struct shader::impl
|
struct shader::impl {
|
||||||
{
|
|
||||||
shader& _shader;
|
shader& _shader;
|
||||||
|
|
||||||
GLuint _shader_program;
|
GLuint _shader_program;
|
||||||
std::vector<GLuint> _shader_stages;
|
std::vector<GLuint> _shader_stages;
|
||||||
|
|
||||||
impl(shader& s)
|
impl(shader& s) : _shader(s) {}
|
||||||
: _shader(s)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~impl()
|
~impl() { destroy(); }
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_valid()
|
bool is_valid() {
|
||||||
{
|
|
||||||
// we potentially haul in is_valid while no context is given
|
// we potentially haul in is_valid while no context is given
|
||||||
return glIsProgram != nullptr && glIsProgram(_shader_program);
|
return glIsProgram != nullptr && glIsProgram(_shader_program);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool build()
|
bool build() {
|
||||||
{
|
// if (!is_valid()) return false;
|
||||||
// if (!is_valid()) return false;
|
|
||||||
|
|
||||||
for (const auto & [type,code] : _shader._source)
|
for (const auto& [type, code] : _shader._source) {
|
||||||
{
|
|
||||||
GLuint shader_type = 0;
|
GLuint shader_type = 0;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case shader::code_type::vertex:
|
case shader::code_type::vertex:
|
||||||
|
@ -58,14 +48,13 @@ struct shader::impl
|
||||||
char* src = const_cast<char*>(code.c_str());
|
char* src = const_cast<char*>(code.c_str());
|
||||||
GLint size = static_cast<GLint>(code.length());
|
GLint size = static_cast<GLint>(code.length());
|
||||||
|
|
||||||
glShaderSource(shaderId , 1, &src, &size);
|
glShaderSource(shaderId, 1, &src, &size);
|
||||||
|
|
||||||
glCompileShader(shaderId);
|
glCompileShader(shaderId);
|
||||||
|
|
||||||
GLint is_compiled = GL_FALSE;
|
GLint is_compiled = GL_FALSE;
|
||||||
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &is_compiled);
|
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &is_compiled);
|
||||||
if(is_compiled == GL_FALSE)
|
if (is_compiled == GL_FALSE) {
|
||||||
{
|
|
||||||
|
|
||||||
GLint log_length;
|
GLint log_length;
|
||||||
|
|
||||||
|
@ -73,7 +62,8 @@ struct shader::impl
|
||||||
|
|
||||||
std::vector<char> log_buffer(static_cast<size_t>(log_length));
|
std::vector<char> log_buffer(static_cast<size_t>(log_length));
|
||||||
|
|
||||||
glGetShaderInfoLog(shaderId, log_length, &log_length, log_buffer.data());
|
glGetShaderInfoLog(shaderId, log_length, &log_length,
|
||||||
|
log_buffer.data());
|
||||||
|
|
||||||
// TODO - handle errors!
|
// TODO - handle errors!
|
||||||
debug::e() << log_buffer.data();
|
debug::e() << log_buffer.data();
|
||||||
|
@ -82,19 +72,17 @@ struct shader::impl
|
||||||
}
|
}
|
||||||
|
|
||||||
_shader_stages.push_back(shaderId);
|
_shader_stages.push_back(shaderId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_shader_program = glCreateProgram();
|
_shader_program = glCreateProgram();
|
||||||
|
|
||||||
|
|
||||||
for (auto s : _shader_stages)
|
for (auto s : _shader_stages)
|
||||||
glAttachShader(_shader_program,s);
|
glAttachShader(_shader_program, s);
|
||||||
|
|
||||||
|
|
||||||
// TODO attribute binding ...
|
// TODO attribute binding ...
|
||||||
|
|
||||||
/* Bind attribute index 0 (coordinates) to in_Position and attribute index 1 (color) to in_Color */
|
/* Bind attribute index 0 (coordinates) to in_Position and attribute
|
||||||
|
* index 1 (color) to in_Color */
|
||||||
/* Attribute locations must be setup before calling glLinkProgram. */
|
/* Attribute locations must be setup before calling glLinkProgram. */
|
||||||
// glBindAttribLocation(shaderprogram, 0, "in_Position");
|
// glBindAttribLocation(shaderprogram, 0, "in_Position");
|
||||||
// glBindAttribLocation(shaderprogram, 1, "in_Color");
|
// glBindAttribLocation(shaderprogram, 1, "in_Color");
|
||||||
|
@ -103,23 +91,25 @@ struct shader::impl
|
||||||
|
|
||||||
GLint is_linked = 0;
|
GLint is_linked = 0;
|
||||||
glGetProgramiv(_shader_program, GL_LINK_STATUS, &is_linked);
|
glGetProgramiv(_shader_program, GL_LINK_STATUS, &is_linked);
|
||||||
if(is_linked == GL_FALSE)
|
if (is_linked == GL_FALSE) {
|
||||||
{
|
|
||||||
|
|
||||||
GLint log_length;
|
GLint log_length;
|
||||||
|
|
||||||
/* Noticed that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv. */
|
/* Noticed that glGetProgramiv is used to get the length for a
|
||||||
|
* shader program, not glGetShaderiv. */
|
||||||
glGetProgramiv(_shader_program, GL_INFO_LOG_LENGTH, &log_length);
|
glGetProgramiv(_shader_program, GL_INFO_LOG_LENGTH, &log_length);
|
||||||
|
|
||||||
/* The maxLength includes the NULL character */
|
/* The maxLength includes the NULL character */
|
||||||
std::vector<char> info_log(static_cast<size_t>(log_length));
|
std::vector<char> info_log(static_cast<size_t>(log_length));
|
||||||
|
|
||||||
/* Notice that glGetProgramInfoLog, not glGetShaderInfoLog. */
|
/* Notice that glGetProgramInfoLog, not glGetShaderInfoLog. */
|
||||||
glGetProgramInfoLog(_shader_program, log_length, &log_length, info_log.data());
|
glGetProgramInfoLog(_shader_program, log_length, &log_length,
|
||||||
|
info_log.data());
|
||||||
|
|
||||||
debug::e() << info_log.data();
|
debug::e() << info_log.data();
|
||||||
|
|
||||||
/* Handle the error in an appropriate way such as displaying a message or writing to a log file. */
|
/* 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 */
|
/* In this simple program, we'll just leave */
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -128,21 +118,15 @@ struct shader::impl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void use() { glUseProgram(_shader_program); }
|
||||||
|
|
||||||
void use()
|
void destroy() {
|
||||||
{
|
|
||||||
glUseProgram(_shader_program);
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy()
|
|
||||||
{
|
|
||||||
// potentially the GL driver hasn't been loaded
|
// potentially the GL driver hasn't been loaded
|
||||||
if (is_valid()) {
|
if (is_valid()) {
|
||||||
|
|
||||||
// deleting and detaching should happen much earlier
|
// deleting and detaching should happen much earlier
|
||||||
|
|
||||||
for (auto s : _shader_stages)
|
for (auto s : _shader_stages) {
|
||||||
{
|
|
||||||
glDeleteShader(s);
|
glDeleteShader(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,109 +136,74 @@ struct shader::impl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int uniform_location(std::string const& name) const
|
int uniform_location(std::string const& name) const {
|
||||||
{
|
return glGetUniformLocation(_shader_program, name.c_str());
|
||||||
return glGetUniformLocation(_shader_program,name.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(int location,const matrix3x3f& m)
|
void bind(int location, const matrix3x3f& m) {
|
||||||
{
|
glUniformMatrix3fv(location, 1, GL_FALSE, m.ptr());
|
||||||
glUniformMatrix3fv(location,1,GL_FALSE,m.ptr());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(int location,const matrix4x4f& m)
|
void bind(int location, const matrix4x4f& m) {
|
||||||
{
|
glUniformMatrix4fv(location, 1, GL_FALSE, m.ptr());
|
||||||
glUniformMatrix4fv(location,1,GL_FALSE,m.ptr());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(int location,const vector4f& v)
|
void bind(int location, const vector4f& v) {
|
||||||
{
|
glUniform4fv(location, 1, v.ptr());
|
||||||
glUniform4fv(location,1,v.ptr());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(int location,const float& v)
|
void bind(int location, const float& v) { glUniform1f(location, v); }
|
||||||
{
|
|
||||||
glUniform1f(location,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bind(int location,const uint32_t& i)
|
void bind(int location, const uint32_t& i) { glUniform1ui(location, i); }
|
||||||
{
|
|
||||||
glUniform1ui(location,i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bind(int location,const int32_t& i)
|
void bind(int location, const int32_t& i) { glUniform1i(location, i); }
|
||||||
{
|
|
||||||
glUniform1i(location,i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bind(int location,const texture& v)
|
|
||||||
{
|
|
||||||
this->bind(location,(int)v.native_handle());
|
|
||||||
|
|
||||||
|
void bind(int location, const texture& v) {
|
||||||
|
this->bind(location, (int)v.native_handle());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
shader::shader() { _impl = make_unique<impl>(*this); }
|
||||||
|
|
||||||
shader::shader()
|
shader::~shader() {}
|
||||||
{
|
|
||||||
_impl = make_unique<impl>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
shader::~shader()
|
bool shader::ready() const { return _impl->is_valid(); }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
shader& shader::set_uniform_at_location(int location, float v) {
|
||||||
|
_impl->bind(location, v);
|
||||||
bool shader::ready() const
|
|
||||||
{
|
|
||||||
return _impl->is_valid();
|
|
||||||
}
|
|
||||||
|
|
||||||
shader &shader::set_uniform_at_location(int location, float v)
|
|
||||||
{
|
|
||||||
_impl->bind(location,v);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader &shader::set_uniform_at_location(int location, uint32_t v)
|
shader& shader::set_uniform_at_location(int location, uint32_t v) {
|
||||||
{
|
_impl->bind(location, v);
|
||||||
_impl->bind(location,v); return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader &shader::set_uniform_at_location(int location, int32_t v)
|
shader& shader::set_uniform_at_location(int location, int32_t v) {
|
||||||
{
|
_impl->bind(location, v);
|
||||||
_impl->bind(location,v); return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shader& shader::set_uniform_at_location(int location, vector4f const& v) {
|
||||||
shader &shader::set_uniform_at_location(int location, vector4f const &v)
|
_impl->bind(location, v);
|
||||||
{
|
return *this;
|
||||||
_impl->bind(location,v); return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shader &shader::set_uniform_at_location(int location, matrix4x4f const &v)
|
shader& shader::set_uniform_at_location(int location, matrix4x4f const& v) {
|
||||||
{
|
_impl->bind(location, v);
|
||||||
_impl->bind(location,v); return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shader& shader::set_uniform_at_location(int location, texture const& v) {
|
||||||
shader &shader::set_uniform_at_location(int location, texture const &v)
|
_impl->bind(location, v);
|
||||||
{
|
return *this;
|
||||||
_impl->bind(location,v); return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shader::build()
|
bool shader::build() { return _impl->build(); }
|
||||||
{
|
|
||||||
return _impl->build();
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader::use()
|
void shader::use() { _impl->use(); }
|
||||||
{
|
|
||||||
_impl->use();
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader::set_uniforms(uniform_cache_t c)
|
void shader::set_uniforms(uniform_cache_t c) {
|
||||||
{
|
|
||||||
// TODO rewrite in proper C++17
|
// TODO rewrite in proper C++17
|
||||||
|
|
||||||
for (auto& u : c) {
|
for (auto& u : c) {
|
||||||
|
@ -271,16 +220,15 @@ void shader::set_uniforms(uniform_cache_t c)
|
||||||
|
|
||||||
auto var = std::get<1>(u);
|
auto var = std::get<1>(u);
|
||||||
|
|
||||||
std::visit([this,loc](auto&& arg) {
|
std::visit([this, loc](auto&& arg) {
|
||||||
|
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
|
|
||||||
// TODO query the std::variant of uniform_t
|
// TODO query the std::variant of uniform_t
|
||||||
|
|
||||||
if constexpr ((std::is_same_v<T, vector4f>) ||
|
if constexpr ((std::is_same_v<T, vector4f>) ||
|
||||||
(std::is_same_v<T, matrix4x4f>) ||
|
(std::is_same_v<T, matrix4x4f>) ||
|
||||||
(std::is_same_v<T, float>) ) {
|
(std::is_same_v<T, float>)) {
|
||||||
set_uniform_at_location( loc, std::forward<T>(arg));
|
set_uniform_at_location(loc, std::forward<T>(arg));
|
||||||
} else {
|
} else {
|
||||||
debug::e() << "unknown uniform type";
|
debug::e() << "unknown uniform type";
|
||||||
}
|
}
|
||||||
|
@ -288,15 +236,10 @@ void shader::set_uniforms(uniform_cache_t c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t shader::native_handle() const
|
uint32_t shader::native_handle() const { return _impl->_shader_program; }
|
||||||
{
|
|
||||||
return _impl->_shader_program;
|
|
||||||
}
|
|
||||||
|
|
||||||
int shader::uniform_location(const std::string &name) const
|
int shader::uniform_location(const std::string& name) const {
|
||||||
{
|
|
||||||
return _impl->uniform_location(name);
|
return _impl->uniform_location(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace pw
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue