add Sampler class, add attributes system
This commit is contained in:
@@ -53,6 +53,10 @@ void App::init()
|
|||||||
" frag = col;"
|
" frag = col;"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
|
auto w = att::Width(10.f);
|
||||||
|
printf("type: %d\n", att::value("Height"));
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Shape>> s;
|
||||||
auto y_root = YGNodeNew();
|
auto y_root = YGNodeNew();
|
||||||
tinyxml2::XMLDocument xml;
|
tinyxml2::XMLDocument xml;
|
||||||
auto ret = xml.LoadFile("data\\layout.xml");
|
auto ret = xml.LoadFile("data\\layout.xml");
|
||||||
@@ -63,23 +67,37 @@ void App::init()
|
|||||||
printf("Element %s: ", child->Name());
|
printf("Element %s: ", child->Name());
|
||||||
auto attr = child->FirstAttribute();
|
auto attr = child->FirstAttribute();
|
||||||
auto y_node = YGNodeNew();
|
auto y_node = YGNodeNew();
|
||||||
YGNodeInsertChild(y_root, y_node, 0);
|
std::unique_ptr<Shape> shape = std::make_unique<Plane>();
|
||||||
while (attr)
|
while (attr)
|
||||||
{
|
{
|
||||||
|
const auto ka = att::value(attr->Name());
|
||||||
printf("%s=%s ", attr->Name(), attr->Value());
|
printf("%s=%s ", attr->Name(), attr->Value());
|
||||||
if (strcmp("width", attr->Name()) == 0)
|
switch (ka)
|
||||||
{
|
{
|
||||||
|
case att::kAttribute::Width:
|
||||||
if (strchr(attr->Value(), '%'))
|
if (strchr(attr->Value(), '%'))
|
||||||
YGNodeStyleSetWidthPercent(y_node, attr->FloatValue());
|
YGNodeStyleSetWidthPercent(y_node, attr->FloatValue());
|
||||||
else
|
else
|
||||||
YGNodeStyleSetWidth(y_node, attr->FloatValue());
|
YGNodeStyleSetWidth(y_node, attr->FloatValue());
|
||||||
|
shape->attribs[ka] = std::make_unique<att::Width>(attr->FloatValue());
|
||||||
|
break;
|
||||||
|
case att::kAttribute::Height:
|
||||||
|
if (strchr(attr->Value(), '%'))
|
||||||
|
YGNodeStyleSetHeightPercent(y_node, attr->FloatValue());
|
||||||
|
else
|
||||||
|
YGNodeStyleSetHeight(y_node, attr->FloatValue());
|
||||||
|
shape->attribs[ka] = std::make_unique<att::Height>(attr->FloatValue());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
attr = attr->Next();
|
attr = attr->Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
YGNodeInsertChild(y_root, y_node, 0);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
child = child->NextSiblingElement();
|
child = child->NextSiblingElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sampler.create();
|
||||||
shader.create(shader_v, shader_f);
|
shader.create(shader_v, shader_f);
|
||||||
shader_color.create(shader_color_v, shader_color_f);
|
shader_color.create(shader_color_v, shader_color_f);
|
||||||
shader_uv.create(shader_v, shader_uv_f);
|
shader_uv.create(shader_v, shader_uv_f);
|
||||||
@@ -141,6 +159,7 @@ void App::update(float dt)
|
|||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
tex.bind();
|
tex.bind();
|
||||||
|
sampler.bind(0);
|
||||||
shader.u_int("tex", 0);
|
shader.u_int("tex", 0);
|
||||||
shader.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + h * 1, 75 + h * i, 0.f}) * s);
|
shader.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + h * 1, 75 + h * i, 0.f}) * s);
|
||||||
shapes[i]->draw_fill();
|
shapes[i]->draw_fill();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
|
Sampler sampler;
|
||||||
Shader shader;
|
Shader shader;
|
||||||
Shader shader_color;
|
Shader shader_color;
|
||||||
Shader shader_uv;
|
Shader shader_uv;
|
||||||
|
|||||||
@@ -11,9 +11,11 @@
|
|||||||
#include <gl\GL.h>
|
#include <gl\GL.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define GLM_FORCE_RADIANS
|
#define GLM_FORCE_RADIANS
|
||||||
|
|||||||
@@ -1,5 +1,72 @@
|
|||||||
#pragma once
|
#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
|
class Shape
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@@ -9,9 +76,11 @@ protected:
|
|||||||
GLvoid* ioff[2];
|
GLvoid* ioff[2];
|
||||||
struct vertex_t { glm::vec4 pos; glm::vec2 uvs; };
|
struct vertex_t { glm::vec4 pos; glm::vec2 uvs; };
|
||||||
public:
|
public:
|
||||||
|
att::AttrubutesMap attribs;
|
||||||
bool create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize);
|
bool create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize);
|
||||||
void draw_fill() const;
|
void draw_fill() const;
|
||||||
void draw_stroke() const;
|
void draw_stroke() const;
|
||||||
|
virtual bool create_attrib() { return true; };
|
||||||
protected:
|
protected:
|
||||||
glm::vec2 quad_mid_point(glm::vec2 a, glm::vec2 b, glm::vec2 c, glm::vec2 d)
|
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);
|
create_impl(w, h, div, idx, vertices);
|
||||||
return create_buffers(idx, vertices, sizeof(idx), sizeof(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
|
class Rect : public Shape
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
#include "image.hpp"
|
#include "image.hpp"
|
||||||
|
|
||||||
bool Texture2D::create(int width, int height, GLint format, const uint8_t* data, GLint filter, GLint wrap)
|
bool Texture2D::create(int width, int height, GLint format, const uint8_t* data)
|
||||||
{
|
{
|
||||||
m_width = width;
|
m_width = width;
|
||||||
m_height = height;
|
m_height = height;
|
||||||
@@ -10,10 +10,6 @@ bool Texture2D::create(int width, int height, GLint format, const uint8_t* data,
|
|||||||
glGenTextures(1, &m_tex);
|
glGenTextures(1, &m_tex);
|
||||||
bind();
|
bind();
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
|
|
||||||
unbind();
|
unbind();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -34,3 +30,28 @@ void Texture2D::update(const uint8_t* data)
|
|||||||
bind();
|
bind();
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, m_format, GL_UNSIGNED_BYTE, data);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, m_format, GL_UNSIGNED_BYTE, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sampler::create(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE*/)
|
||||||
|
{
|
||||||
|
glGenSamplers(1, &id);
|
||||||
|
if (id == 0)
|
||||||
|
return false;
|
||||||
|
set(filter, wrap);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void Sampler::set(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE*/)
|
||||||
|
{
|
||||||
|
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, wrap);
|
||||||
|
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, wrap);
|
||||||
|
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, filter);
|
||||||
|
glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, filter);
|
||||||
|
}
|
||||||
|
void Sampler::bind(int unit)
|
||||||
|
{
|
||||||
|
current_unit = unit;
|
||||||
|
glBindSampler(unit, id);
|
||||||
|
}
|
||||||
|
void Sampler::unbind()
|
||||||
|
{
|
||||||
|
glBindSampler(current_unit, 0);
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ class Texture2D
|
|||||||
int m_height;
|
int m_height;
|
||||||
GLint m_format;
|
GLint m_format;
|
||||||
public:
|
public:
|
||||||
bool create(int width, int height, GLint format = GL_RGBA,
|
bool create(int width, int height, GLint format = GL_RGBA, const uint8_t* data = nullptr);
|
||||||
const uint8_t* data = nullptr, GLint filter = GL_LINEAR, GLint wrap = GL_CLAMP_TO_EDGE);
|
|
||||||
bool create(const class Image& img);
|
bool create(const class Image& img);
|
||||||
bool load(std::string filename);
|
bool load(std::string filename);
|
||||||
void destroy() { glDeleteTextures(1, &m_tex); }
|
void destroy() { glDeleteTextures(1, &m_tex); }
|
||||||
@@ -16,3 +15,14 @@ public:
|
|||||||
void unbind() const { glBindTexture(GL_TEXTURE_2D, 0); }
|
void unbind() const { glBindTexture(GL_TEXTURE_2D, 0); }
|
||||||
void update(const uint8_t* data);
|
void update(const uint8_t* data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Sampler
|
||||||
|
{
|
||||||
|
GLuint id;
|
||||||
|
GLint current_unit;
|
||||||
|
public:
|
||||||
|
bool create(GLint filter = GL_LINEAR, GLint wrap = GL_CLAMP_TO_EDGE);
|
||||||
|
void set(GLint filter = GL_LINEAR, GLint wrap = GL_CLAMP_TO_EDGE);
|
||||||
|
void bind(int unit);
|
||||||
|
void unbind();
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user