From 21622fd24c8dd81c301578e740ef727be4a36dd1 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sat, 21 Jan 2017 00:16:36 +0000 Subject: [PATCH] add Sampler class, add attributes system --- engine/app.cpp | 23 +++++++++++-- engine/app.hpp | 1 + engine/pch.h | 2 ++ engine/shape.hpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++ engine/texture.cpp | 31 ++++++++++++++--- engine/texture.hpp | 14 ++++++-- 6 files changed, 146 insertions(+), 9 deletions(-) diff --git a/engine/app.cpp b/engine/app.cpp index 54e9d7b..425d0ec 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -53,6 +53,10 @@ void App::init() " frag = col;" "}"; + auto w = att::Width(10.f); + printf("type: %d\n", att::value("Height")); + + std::vector> s; auto y_root = YGNodeNew(); tinyxml2::XMLDocument xml; auto ret = xml.LoadFile("data\\layout.xml"); @@ -63,23 +67,37 @@ void App::init() printf("Element %s: ", child->Name()); auto attr = child->FirstAttribute(); auto y_node = YGNodeNew(); - YGNodeInsertChild(y_root, y_node, 0); + std::unique_ptr shape = std::make_unique(); while (attr) { + const auto ka = att::value(attr->Name()); printf("%s=%s ", attr->Name(), attr->Value()); - if (strcmp("width", attr->Name()) == 0) + switch (ka) { + case att::kAttribute::Width: if (strchr(attr->Value(), '%')) YGNodeStyleSetWidthPercent(y_node, attr->FloatValue()); else YGNodeStyleSetWidth(y_node, attr->FloatValue()); + shape->attribs[ka] = std::make_unique(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(attr->FloatValue()); + break; } attr = attr->Next(); } + + YGNodeInsertChild(y_root, y_node, 0); printf("\n"); child = child->NextSiblingElement(); } + sampler.create(); shader.create(shader_v, shader_f); shader_color.create(shader_color_v, shader_color_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); glActiveTexture(GL_TEXTURE0); tex.bind(); + sampler.bind(0); shader.u_int("tex", 0); shader.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + h * 1, 75 + h * i, 0.f}) * s); shapes[i]->draw_fill(); diff --git a/engine/app.hpp b/engine/app.hpp index f88370f..4a1e200 100644 --- a/engine/app.hpp +++ b/engine/app.hpp @@ -6,6 +6,7 @@ class App { + Sampler sampler; Shader shader; Shader shader_color; Shader shader_uv; diff --git a/engine/pch.h b/engine/pch.h index 0cd8bcf..c578d9c 100644 --- a/engine/pch.h +++ b/engine/pch.h @@ -11,9 +11,11 @@ #include #endif +#include #include #include #include +#include #include #define GLM_FORCE_RADIANS diff --git a/engine/shape.hpp b/engine/shape.hpp index 47a940f..380b9d7 100644 --- a/engine/shape.hpp +++ b/engine/shape.hpp @@ -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> AttrubutesMap; + + template + 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 + constexpr const char* string(const Attribute a) { return names[(int)a.id]; } + +#define DECLARE_ATTRIBUTE(N,T) \ + struct N : public Attribute \ + { using Attribute::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(div * div * 6 + 8); + auto vertices = std::make_unique((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(attribs[att::kAttribute::Width].get()); + const att::Height* h = reinterpret_cast(attribs[att::kAttribute::Height].get()); + const att::Divisions* div = reinterpret_cast(attribs[att::kAttribute::Height].get()); + return create(*div, *w, *h); + } }; class Rect : public Shape diff --git a/engine/texture.cpp b/engine/texture.cpp index 2f0938b..c9670c5 100644 --- a/engine/texture.cpp +++ b/engine/texture.cpp @@ -2,7 +2,7 @@ #include "texture.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_height = height; @@ -10,10 +10,6 @@ bool Texture2D::create(int width, int height, GLint format, const uint8_t* data, glGenTextures(1, &m_tex); bind(); 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(); return true; } @@ -34,3 +30,28 @@ void Texture2D::update(const uint8_t* data) bind(); 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); +} diff --git a/engine/texture.hpp b/engine/texture.hpp index 08b40b5..c009cd8 100644 --- a/engine/texture.hpp +++ b/engine/texture.hpp @@ -7,8 +7,7 @@ class Texture2D int m_height; GLint m_format; public: - bool create(int width, int height, GLint format = GL_RGBA, - const uint8_t* data = nullptr, GLint filter = GL_LINEAR, GLint wrap = GL_CLAMP_TO_EDGE); + bool create(int width, int height, GLint format = GL_RGBA, const uint8_t* data = nullptr); bool create(const class Image& img); bool load(std::string filename); void destroy() { glDeleteTextures(1, &m_tex); } @@ -16,3 +15,14 @@ public: void unbind() const { glBindTexture(GL_TEXTURE_2D, 0); } 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(); +};