add Sampler class, add attributes system

This commit is contained in:
2017-01-21 00:16:36 +00:00
parent eb7282e0d4
commit 21622fd24c
6 changed files with 146 additions and 9 deletions

View File

@@ -1,5 +1,72 @@
#pragma once
namespace att
{
enum class kAttribute : uint8_t { Width, Height, Divisions, InnerRadius, OuterRadius };
struct AttributeBase
{
kAttribute id;
};
typedef std::map<att::kAttribute, std::unique_ptr<att::AttributeBase>> AttrubutesMap;
template<kAttribute T, typename V>
struct Attribute : public AttributeBase
{
using type = V;
static const kAttribute static_id = T;
V value;
Attribute() : value{ 0 }, { id = static_id; }
Attribute(type v) : value(v) { id = static_id; }
};
struct typemap
{
const char* name;
kAttribute value;
};
static constexpr typemap map[] =
{
{ "width", kAttribute::Width },
{ "height", kAttribute::Height },
{ "divisions", kAttribute::Divisions },
{ "inner_radius", kAttribute::InnerRadius },
{ "outer_radius", kAttribute::OuterRadius },
};
constexpr int map_size = sizeof(map) / sizeof(typemap) - 1;
constexpr bool same(const char* a, const char* b)
{
return (*a && *b) ? (*a == *b && same(a + 1, b + 1)) : !(*a || *b);
}
constexpr const kAttribute value(char const *name, int i = 0)
{
return ((i >= map_size) || same(map[i].name, name)) ?
map[i].value : value(name, i + 1);
}
constexpr const char* string(const kAttribute value, int i = 0)
{
return (map[i].value == value) ? map[i].name : string(value, i + 1);
}
//constexpr const char* string(kAttribute a) { return names[(int)a]; }
template<kAttribute T, typename V>
constexpr const char* string(const Attribute<T, V> a) { return names[(int)a.id]; }
#define DECLARE_ATTRIBUTE(N,T) \
struct N : public Attribute<kAttribute::N,T> \
{ using Attribute<kAttribute::N,T>::Attribute; };
DECLARE_ATTRIBUTE(Width, float);
DECLARE_ATTRIBUTE(Height, float);
DECLARE_ATTRIBUTE(Divisions, int);
DECLARE_ATTRIBUTE(InnerRadius, float);
DECLARE_ATTRIBUTE(OuterRadius, float);
#undef DECLARE_ATTRIBUTE
}
class Shape
{
protected:
@@ -9,9 +76,11 @@ protected:
GLvoid* ioff[2];
struct vertex_t { glm::vec4 pos; glm::vec2 uvs; };
public:
att::AttrubutesMap attribs;
bool create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize);
void draw_fill() const;
void draw_stroke() const;
virtual bool create_attrib() { return true; };
protected:
glm::vec2 quad_mid_point(glm::vec2 a, glm::vec2 b, glm::vec2 c, glm::vec2 d)
{
@@ -49,6 +118,21 @@ public:
create_impl(w, h, div, idx, vertices);
return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices));
}
bool create(att::Divisions divisions, att::Width w, att::Height h)
{
const int div = divisions.value;
auto idx = std::make_unique<GLushort[]>(div * div * 6 + 8);
auto vertices = std::make_unique<vertex_t[]>((div + 1)*(div + 1));
create_impl(w.value, h.value, div, idx.get(), vertices.get());
return create_buffers(idx.get(), vertices.get(), sizeof(idx), sizeof(vertices));
}
bool create_attrib() override
{
const att::Width* w = reinterpret_cast<att::Width*>(attribs[att::kAttribute::Width].get());
const att::Height* h = reinterpret_cast<att::Height*>(attribs[att::kAttribute::Height].get());
const att::Divisions* div = reinterpret_cast<att::Divisions*>(attribs[att::kAttribute::Height].get());
return create(*div, *w, *h);
}
};
class Rect : public Shape