added singleton shader manager, custom widget attribute forward, parse border thickness and color for Border widget, parse and cache uniform locations, remove unused attrubutes code
This commit is contained in:
@@ -34,7 +34,7 @@
|
|||||||
</plane>
|
</plane>
|
||||||
<!-- content panel -->
|
<!-- content panel -->
|
||||||
<plane width="1" grow="1" height="100%" pad="30" wrap="1">
|
<plane width="1" grow="1" height="100%" pad="30" wrap="1">
|
||||||
<border color=".2" height="100%"></border>
|
<border thickness="5" border-color="1" color=".4" height="100%"></border>
|
||||||
</plane>
|
</plane>
|
||||||
</plane>
|
</plane>
|
||||||
<!-- status bar -->
|
<!-- status bar -->
|
||||||
|
|||||||
@@ -78,10 +78,10 @@ void App::init()
|
|||||||
layout.update(width, height);
|
layout.update(width, height);
|
||||||
|
|
||||||
sampler.create();
|
sampler.create();
|
||||||
shader.create(shader_v, shader_f);
|
ShaderManager::create(kShader::Texture, shader_v, shader_f);
|
||||||
shader_color.create(shader_color_v, shader_color_f);
|
ShaderManager::create(kShader::Color, shader_color_v, shader_color_f);
|
||||||
shader_uv.create(shader_v, shader_uv_f);
|
ShaderManager::create(kShader::UVs, shader_v, shader_uv_f);
|
||||||
plane.create<5>(1, 1);
|
WidgetBorder::m_plane.create<1>(1, 1);
|
||||||
|
|
||||||
if (!tex.load("data/uvs.jpg"))
|
if (!tex.load("data/uvs.jpg"))
|
||||||
printf("error loading image\n");
|
printf("error loading image\n");
|
||||||
@@ -118,10 +118,8 @@ void App::update(float dt)
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
tex.bind();
|
tex.bind();
|
||||||
sampler.bind(0);
|
sampler.bind(0);
|
||||||
shader.use();
|
ShaderManager::use(kShader::Texture);
|
||||||
shader.u_int("tex", 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
shader_color.use();
|
|
||||||
shader_color.u_vec4("col", { .3f, .3f, .3f, 1 });
|
|
||||||
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
@@ -132,15 +130,7 @@ void App::update(float dt)
|
|||||||
|
|
||||||
if (n.m_widget)
|
if (n.m_widget)
|
||||||
{
|
{
|
||||||
shader_color.u_vec4("col", n.color);
|
n.m_widget->draw();
|
||||||
shader_color.use();
|
|
||||||
shader_color.u_mat4("mvp", n.m_widget->mvp);
|
|
||||||
plane.draw_fill();
|
|
||||||
|
|
||||||
shader_color.u_vec4("col", { 1, 1, 1, 1 });
|
|
||||||
shader_color.use();
|
|
||||||
shader_color.u_mat4("mvp", n.m_widget->mvp);
|
|
||||||
plane.draw_stroke();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|||||||
@@ -8,10 +8,6 @@
|
|||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
Sampler sampler;
|
Sampler sampler;
|
||||||
Shader shader;
|
|
||||||
Shader shader_color;
|
|
||||||
Shader shader_uv;
|
|
||||||
Plane plane;
|
|
||||||
Texture2D tex;
|
Texture2D tex;
|
||||||
Node layout;
|
Node layout;
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
Plane* WidgetBorder::m_plane;
|
Plane WidgetBorder::m_plane;
|
||||||
|
|
||||||
void Node::update(float width, float height)
|
void Node::update(float width, float height)
|
||||||
{
|
{
|
||||||
@@ -34,11 +34,11 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj)
|
|||||||
c.update_internal(m_pos, proj);
|
c.update_internal(m_pos, proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::parse_attributes(att::kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
||||||
{
|
{
|
||||||
switch (ka)
|
switch (ka)
|
||||||
{
|
{
|
||||||
case att::kAttribute::Width:
|
case kAttribute::Width:
|
||||||
if (strcmp(attr->Value(), "auto") == 0)
|
if (strcmp(attr->Value(), "auto") == 0)
|
||||||
{
|
{
|
||||||
YGNodeStyleSetWidth(y_node, YGUndefined);
|
YGNodeStyleSetWidth(y_node, YGUndefined);
|
||||||
@@ -52,16 +52,16 @@ void Node::parse_attributes(att::kAttribute ka, const tinyxml2::XMLAttribute* at
|
|||||||
YGNodeStyleSetWidth(y_node, attr->FloatValue());
|
YGNodeStyleSetWidth(y_node, attr->FloatValue());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case att::kAttribute::MinWidth:
|
case kAttribute::MinWidth:
|
||||||
if (strchr(attr->Value(), '%'))
|
if (strchr(attr->Value(), '%'))
|
||||||
YGNodeStyleSetMinWidthPercent(y_node, attr->FloatValue());
|
YGNodeStyleSetMinWidthPercent(y_node, attr->FloatValue());
|
||||||
else
|
else
|
||||||
YGNodeStyleSetMinWidth(y_node, attr->FloatValue());
|
YGNodeStyleSetMinWidth(y_node, attr->FloatValue());
|
||||||
break;
|
break;
|
||||||
case att::kAttribute::MaxWidth:
|
case kAttribute::MaxWidth:
|
||||||
YGNodeStyleSetMaxWidth(y_node, attr->FloatValue());
|
YGNodeStyleSetMaxWidth(y_node, attr->FloatValue());
|
||||||
break;
|
break;
|
||||||
case att::kAttribute::Height:
|
case kAttribute::Height:
|
||||||
if (strcmp(attr->Value(), "auto") == 0)
|
if (strcmp(attr->Value(), "auto") == 0)
|
||||||
{
|
{
|
||||||
YGNodeStyleSetHeight(y_node, YGUndefined);
|
YGNodeStyleSetHeight(y_node, YGUndefined);
|
||||||
@@ -75,19 +75,19 @@ void Node::parse_attributes(att::kAttribute ka, const tinyxml2::XMLAttribute* at
|
|||||||
YGNodeStyleSetHeight(y_node, attr->FloatValue());
|
YGNodeStyleSetHeight(y_node, attr->FloatValue());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case att::kAttribute::MinHeight:
|
case kAttribute::MinHeight:
|
||||||
YGNodeStyleSetMinHeight(y_node, attr->FloatValue());
|
YGNodeStyleSetMinHeight(y_node, attr->FloatValue());
|
||||||
break;
|
break;
|
||||||
case att::kAttribute::MaxHeight:
|
case kAttribute::MaxHeight:
|
||||||
YGNodeStyleSetMaxHeight(y_node, attr->FloatValue());
|
YGNodeStyleSetMaxHeight(y_node, attr->FloatValue());
|
||||||
break;
|
break;
|
||||||
case att::kAttribute::Grow:
|
case kAttribute::Grow:
|
||||||
YGNodeStyleSetFlexGrow(y_node, attr->FloatValue());
|
YGNodeStyleSetFlexGrow(y_node, attr->FloatValue());
|
||||||
break;
|
break;
|
||||||
case att::kAttribute::Shrink:
|
case kAttribute::Shrink:
|
||||||
YGNodeStyleSetFlexShrink(y_node, attr->FloatValue());
|
YGNodeStyleSetFlexShrink(y_node, attr->FloatValue());
|
||||||
break;
|
break;
|
||||||
case att::kAttribute::FlexDir:
|
case kAttribute::FlexDir:
|
||||||
{
|
{
|
||||||
YGFlexDirection dir = YGFlexDirectionRow;
|
YGFlexDirection dir = YGFlexDirectionRow;
|
||||||
if (strcmp("col", attr->Value()) == 0)
|
if (strcmp("col", attr->Value()) == 0)
|
||||||
@@ -101,10 +101,10 @@ void Node::parse_attributes(att::kAttribute ka, const tinyxml2::XMLAttribute* at
|
|||||||
YGNodeStyleSetFlexDirection(y_node, dir);
|
YGNodeStyleSetFlexDirection(y_node, dir);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case att::kAttribute::FlexWrap:
|
case kAttribute::FlexWrap:
|
||||||
YGNodeStyleSetFlexWrap(y_node, attr->IntValue() ? YGWrapWrap : YGWrapNoWrap);
|
YGNodeStyleSetFlexWrap(y_node, attr->IntValue() ? YGWrapWrap : YGWrapNoWrap);
|
||||||
break;
|
break;
|
||||||
case att::kAttribute::Padding:
|
case kAttribute::Padding:
|
||||||
{
|
{
|
||||||
glm::vec4 pad;
|
glm::vec4 pad;
|
||||||
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
|
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
|
||||||
@@ -124,7 +124,7 @@ void Node::parse_attributes(att::kAttribute ka, const tinyxml2::XMLAttribute* at
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case att::kAttribute::Margin:
|
case kAttribute::Margin:
|
||||||
{
|
{
|
||||||
glm::vec4 pad;
|
glm::vec4 pad;
|
||||||
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
|
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
|
||||||
@@ -144,22 +144,9 @@ void Node::parse_attributes(att::kAttribute ka, const tinyxml2::XMLAttribute* at
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case att::kAttribute::Color:
|
|
||||||
{
|
|
||||||
glm::vec4 pad;
|
|
||||||
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
|
|
||||||
if (n == 1)
|
|
||||||
{
|
|
||||||
color = glm::vec4(pad.x);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
color = pad;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
// other_attributes_handler()
|
if (m_widget)
|
||||||
|
m_widget->parse_attributes(ka, attr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,17 +176,17 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
|
|||||||
m_name = x_node->Name();
|
m_name = x_node->Name();
|
||||||
auto attr = x_node->FirstAttribute();
|
auto attr = x_node->FirstAttribute();
|
||||||
|
|
||||||
att::kWidget widget_id = (att::kWidget)const_hash(x_node->Name());
|
kWidget widget_id = (kWidget)const_hash(x_node->Name());
|
||||||
switch (widget_id)
|
switch (widget_id)
|
||||||
{
|
{
|
||||||
case att::kWidget::Border:
|
case kWidget::Border:
|
||||||
m_widget = std::make_unique<WidgetBorder>();
|
m_widget = std::make_unique<WidgetBorder>();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (attr)
|
while (attr)
|
||||||
{
|
{
|
||||||
parse_attributes((att::kAttribute)const_hash(attr->Name()), attr);
|
parse_attributes((kAttribute)const_hash(attr->Name()), attr);
|
||||||
attr = attr->Next();
|
attr = attr->Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
169
engine/layout.h
169
engine/layout.h
@@ -1,104 +1,34 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "shape.hpp"
|
#include "shape.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
#include "shader.hpp"
|
||||||
|
|
||||||
namespace att
|
enum class kAttribute : uint16_t
|
||||||
{
|
{
|
||||||
enum class kAttribute : uint16_t
|
Width = const_hash("width"),
|
||||||
{
|
MinWidth = const_hash("max-width"),
|
||||||
Width = const_hash("width"),
|
MaxWidth = const_hash("min-width"),
|
||||||
MinWidth = const_hash("max-width"),
|
Height = const_hash("height"),
|
||||||
MaxWidth = const_hash("min-width"),
|
MinHeight = const_hash("min-height"),
|
||||||
Height = const_hash("height"),
|
MaxHeight = const_hash("max-height"),
|
||||||
MinHeight = const_hash("min-height"),
|
Divisions = const_hash("divisions"),
|
||||||
MaxHeight = const_hash("max-height"),
|
InnerRadius = const_hash("inner-radius"),
|
||||||
Divisions = const_hash("divisions"),
|
OuterRadius = const_hash("outer-radius"),
|
||||||
InnerRadius = const_hash("inner-radius"),
|
Grow = const_hash("grow"),
|
||||||
OuterRadius = const_hash("outer-radius"),
|
Shrink = const_hash("shrink"),
|
||||||
Grow = const_hash("grow"),
|
FlexDir = const_hash("dir"),
|
||||||
Shrink = const_hash("shrink"),
|
FlexWrap = const_hash("wrap"),
|
||||||
FlexDir = const_hash("dir"),
|
Padding = const_hash("pad"),
|
||||||
FlexWrap = const_hash("wrap"),
|
Margin = const_hash("margin"),
|
||||||
Padding = const_hash("pad"),
|
Color = const_hash("color"),
|
||||||
Margin = const_hash("margin"),
|
Thickness = const_hash("thickness"),
|
||||||
Color = const_hash("color"),
|
BorderColor = const_hash("border-color"),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class kWidget : uint16_t
|
enum class kWidget : uint16_t
|
||||||
{
|
{
|
||||||
Border = const_hash("border"),
|
Border = const_hash("border"),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AttributeBase
|
|
||||||
{
|
|
||||||
kAttribute id;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<att::kAttribute, std::unique_ptr<att::AttributeBase>> AttrubutesMap;
|
|
||||||
|
|
||||||
template<kAttribute T, typename V>
|
|
||||||
struct Attribute : public AttributeBase
|
|
||||||
{
|
|
||||||
static const kAttribute static_id = T;
|
|
||||||
V value;
|
|
||||||
Attribute() : value{ 0 } { id = static_id; }
|
|
||||||
Attribute(V v) : value(v) { id = static_id; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kAttributeMap
|
|
||||||
{
|
|
||||||
kAttribute value;
|
|
||||||
const char* name;
|
|
||||||
};
|
|
||||||
static constexpr kAttributeMap map[] =
|
|
||||||
{
|
|
||||||
{ kAttribute::Width, "width" },
|
|
||||||
{ kAttribute::MinWidth, "min-width" },
|
|
||||||
{ kAttribute::MaxWidth, "max-width" },
|
|
||||||
{ kAttribute::Height, "height" },
|
|
||||||
{ kAttribute::MinHeight, "min-height" },
|
|
||||||
{ kAttribute::MaxHeight, "max-height" },
|
|
||||||
{ kAttribute::Divisions, "divisions" },
|
|
||||||
{ kAttribute::InnerRadius, "inner-radius" },
|
|
||||||
{ kAttribute::OuterRadius, "outer-radius" },
|
|
||||||
{ kAttribute::Grow, "grow" },
|
|
||||||
{ kAttribute::Shrink, "shrink" },
|
|
||||||
{ kAttribute::FlexDir, "dir" },
|
|
||||||
{ kAttribute::FlexWrap, "wrap" },
|
|
||||||
{ kAttribute::Padding, "pad" },
|
|
||||||
{ kAttribute::Margin, "margin" },
|
|
||||||
{ kAttribute::Color, "color" },
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr const char* string(const kAttribute value, int i = 0)
|
|
||||||
{
|
|
||||||
// no check on size, value MUST be found
|
|
||||||
return (map[i].value == value) ? map[i].name : string(value, i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DECLARE_ATTRIBUTE(N,T) \
|
|
||||||
struct N : public Attribute<kAttribute::N,T> \
|
|
||||||
{ using Attribute<kAttribute::N,T>::Attribute; };
|
|
||||||
|
|
||||||
DECLARE_ATTRIBUTE(Width, float);
|
|
||||||
DECLARE_ATTRIBUTE(MinWidth, float);
|
|
||||||
DECLARE_ATTRIBUTE(MaxWidth, float);
|
|
||||||
DECLARE_ATTRIBUTE(Height, float);
|
|
||||||
DECLARE_ATTRIBUTE(MinHeight, float);
|
|
||||||
DECLARE_ATTRIBUTE(MaxHeight, float);
|
|
||||||
DECLARE_ATTRIBUTE(Divisions, int);
|
|
||||||
DECLARE_ATTRIBUTE(InnerRadius, float);
|
|
||||||
DECLARE_ATTRIBUTE(OuterRadius, float);
|
|
||||||
DECLARE_ATTRIBUTE(Grow, float);
|
|
||||||
DECLARE_ATTRIBUTE(Shrink, float);
|
|
||||||
DECLARE_ATTRIBUTE(FlexDir, int);
|
|
||||||
DECLARE_ATTRIBUTE(FlexWrap, int);
|
|
||||||
DECLARE_ATTRIBUTE(Padding, glm::vec4);
|
|
||||||
DECLARE_ATTRIBUTE(Margin, glm::vec4);
|
|
||||||
DECLARE_ATTRIBUTE(Color, glm::vec4);
|
|
||||||
|
|
||||||
#undef DECLARE_ATTRIBUTE
|
|
||||||
}
|
|
||||||
|
|
||||||
class Widget
|
class Widget
|
||||||
{
|
{
|
||||||
@@ -106,15 +36,56 @@ public:
|
|||||||
glm::mat4 mvp;
|
glm::mat4 mvp;
|
||||||
glm::vec4 clip;
|
glm::vec4 clip;
|
||||||
virtual void draw() { };
|
virtual void draw() { };
|
||||||
|
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) { };
|
||||||
};
|
};
|
||||||
|
|
||||||
class WidgetBorder : public Widget
|
class WidgetBorder : public Widget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Plane* m_plane;
|
static Plane m_plane;
|
||||||
|
glm::vec4 m_color;
|
||||||
|
glm::vec4 m_border_color;
|
||||||
|
float m_thinkness{ 1 };
|
||||||
virtual void draw() override
|
virtual void draw() override
|
||||||
{
|
{
|
||||||
m_plane->draw_fill();
|
ShaderManager::use(kShader::Color);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||||
|
|
||||||
|
ShaderManager::u_vec4(kShaderUniform::Col, m_color);
|
||||||
|
m_plane.draw_fill();
|
||||||
|
|
||||||
|
glLineWidth(m_thinkness);
|
||||||
|
ShaderManager::u_vec4(kShaderUniform::Col, m_border_color);
|
||||||
|
m_plane.draw_stroke();
|
||||||
|
}
|
||||||
|
virtual void parse_attributes(kAttribute id, const tinyxml2::XMLAttribute* attr)
|
||||||
|
{
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
case kAttribute::Color:
|
||||||
|
{
|
||||||
|
glm::vec4 pad;
|
||||||
|
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
|
||||||
|
if (n == 1)
|
||||||
|
m_color = glm::vec4(pad.x);
|
||||||
|
else
|
||||||
|
m_color = pad;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kAttribute::BorderColor:
|
||||||
|
{
|
||||||
|
glm::vec4 pad;
|
||||||
|
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
|
||||||
|
if (n == 1)
|
||||||
|
m_border_color = glm::vec4(pad.x);
|
||||||
|
else
|
||||||
|
m_border_color = pad;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kAttribute::Thickness:
|
||||||
|
m_thinkness = attr->FloatValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -131,7 +102,6 @@ public:
|
|||||||
glm::vec2 m_pos;
|
glm::vec2 m_pos;
|
||||||
glm::vec2 m_size;
|
glm::vec2 m_size;
|
||||||
glm::vec4 m_clip;
|
glm::vec4 m_clip;
|
||||||
glm::vec4 color;
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
Node(const Node&) = delete;
|
Node(const Node&) = delete;
|
||||||
Node& operator=(const Node&) = delete;
|
Node& operator=(const Node&) = delete;
|
||||||
@@ -143,7 +113,6 @@ public:
|
|||||||
c.parent = this;
|
c.parent = this;
|
||||||
parent = o.parent;
|
parent = o.parent;
|
||||||
y_node = o.y_node;
|
y_node = o.y_node;
|
||||||
color = o.color;
|
|
||||||
m_pos = o.m_pos;
|
m_pos = o.m_pos;
|
||||||
m_size = o.m_size;
|
m_size = o.m_size;
|
||||||
m_clip = o.m_clip;
|
m_clip = o.m_clip;
|
||||||
@@ -189,7 +158,7 @@ public:
|
|||||||
|
|
||||||
void update(float width, float height);
|
void update(float width, float height);
|
||||||
void update_internal(const glm::vec2& origin, const glm::mat4& proj);
|
void update_internal(const glm::vec2& origin, const glm::mat4& proj);
|
||||||
void parse_attributes(att::kAttribute ka, const tinyxml2::XMLAttribute* attr);
|
void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr);
|
||||||
void load(const char* path);
|
void load(const char* path);
|
||||||
void load_internal(const tinyxml2::XMLElement* x_node);
|
void load_internal(const tinyxml2::XMLElement* x_node);
|
||||||
void reload();
|
void reload();
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "shader.hpp"
|
#include "shader.hpp"
|
||||||
|
|
||||||
bool Shader::create(std::string vertex, std::string fragment)
|
std::map<kShader, Shader> ShaderManager::m_shaders;
|
||||||
|
Shader* ShaderManager::m_current;
|
||||||
|
|
||||||
|
bool Shader::create(const char* vertex, const char* fragment)
|
||||||
{
|
{
|
||||||
GLint status;
|
GLint status;
|
||||||
static char infolog[4096];
|
static char infolog[4096];
|
||||||
@@ -13,7 +16,7 @@ bool Shader::create(std::string vertex, std::string fragment)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
source = vertex.c_str();
|
source = vertex;
|
||||||
glShaderSource(vs, 1, &source, nullptr);
|
glShaderSource(vs, 1, &source, nullptr);
|
||||||
glCompileShader(vs);
|
glCompileShader(vs);
|
||||||
glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
|
glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
|
||||||
@@ -32,7 +35,7 @@ bool Shader::create(std::string vertex, std::string fragment)
|
|||||||
glDeleteShader(vs);
|
glDeleteShader(vs);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
source = fragment.c_str();
|
source = fragment;
|
||||||
glShaderSource(fs, 1, &source, nullptr);
|
glShaderSource(fs, 1, &source, nullptr);
|
||||||
glCompileShader(fs);
|
glCompileShader(fs);
|
||||||
glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
|
glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
|
||||||
@@ -71,6 +74,23 @@ bool Shader::create(std::string vertex, std::string fragment)
|
|||||||
glDeleteProgram(ps);
|
glDeleteProgram(ps);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse shader uniforms
|
||||||
|
{
|
||||||
|
GLint count;
|
||||||
|
GLint size; // size of the variable
|
||||||
|
GLenum type; // type of the variable (float, vec3 or mat4, etc)
|
||||||
|
const GLsizei bufSize = 16; // maximum name length
|
||||||
|
GLchar name[bufSize]; // variable name in GLSL
|
||||||
|
GLsizei length; // name length
|
||||||
|
glGetProgramiv(ps, GL_ACTIVE_UNIFORMS, &count);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
glGetActiveUniform(ps, (GLuint)i, bufSize, &length, &size, &type, name);
|
||||||
|
m_umap[(kShaderUniform)const_hash(name)] = glGetUniformLocation(ps, name);
|
||||||
|
//printf("Uniform #%d Type: %u Name: %s Loc: %d\n", i, type, name, glGetUniformLocation(ps, name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
prog = ps;
|
prog = ps;
|
||||||
|
|
||||||
@@ -80,18 +100,47 @@ void Shader::use()
|
|||||||
{
|
{
|
||||||
glUseProgram(prog);
|
glUseProgram(prog);
|
||||||
}
|
}
|
||||||
void Shader::u_vec4(const char* name, const glm::vec4& v)
|
void Shader::u_vec4(kShaderUniform id, const glm::vec4& v)
|
||||||
{
|
{
|
||||||
auto loc = glGetUniformLocation(prog, name);
|
glUniform4fv(m_umap[id], 1, glm::value_ptr(v));
|
||||||
glUniform4fv(loc, 1, glm::value_ptr(v));
|
|
||||||
}
|
}
|
||||||
void Shader::u_mat4(const char* name, const glm::mat4& m)
|
void Shader::u_mat4(kShaderUniform id, const glm::mat4& m)
|
||||||
{
|
{
|
||||||
auto loc = glGetUniformLocation(prog, name);
|
glUniformMatrix4fv(m_umap[id], 1, GL_FALSE, glm::value_ptr(m));
|
||||||
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(m));
|
|
||||||
}
|
}
|
||||||
void Shader::u_int(const char* name, int i)
|
void Shader::u_int(kShaderUniform id, int i)
|
||||||
{
|
{
|
||||||
auto loc = glGetUniformLocation(prog, name);
|
glUniform1i(m_umap[id], i);
|
||||||
glUniform1i(loc, i);
|
}
|
||||||
|
|
||||||
|
bool ShaderManager::create(kShader id, const char* vertex, const char* fragment)
|
||||||
|
{
|
||||||
|
return m_shaders[id].create(vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderManager::use(kShader id)
|
||||||
|
{
|
||||||
|
m_current = &m_shaders[id];
|
||||||
|
m_current->use();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderManager::use(const char* name)
|
||||||
|
{
|
||||||
|
m_current = &m_shaders[(kShader)const_hash(name)];
|
||||||
|
m_current->use();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderManager::u_vec4(kShaderUniform id, const glm::vec4& v)
|
||||||
|
{
|
||||||
|
m_current->u_vec4(id, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderManager::u_mat4(kShaderUniform id, const glm::mat4& m)
|
||||||
|
{
|
||||||
|
m_current->u_mat4(id, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderManager::u_int(kShaderUniform id, int i)
|
||||||
|
{
|
||||||
|
m_current->u_int(id, i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,41 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
|
enum class kShaderUniform : uint16_t
|
||||||
|
{
|
||||||
|
MVP = const_hash("mvp"),
|
||||||
|
Tex = const_hash("tex"),
|
||||||
|
Col = const_hash("col"),
|
||||||
|
};
|
||||||
|
|
||||||
class Shader
|
class Shader
|
||||||
{
|
{
|
||||||
|
std::map<kShaderUniform, GLuint> m_umap;
|
||||||
GLuint prog;
|
GLuint prog;
|
||||||
public:
|
public:
|
||||||
bool create(std::string vertex, std::string fragment);
|
bool create(const char* vertex, const char* fragment);
|
||||||
void use();
|
void use();
|
||||||
void u_vec4(const char* name, const glm::vec4& v);
|
void u_vec4(kShaderUniform id, const glm::vec4& v);
|
||||||
void u_mat4(const char* name, const glm::mat4& m);
|
void u_mat4(kShaderUniform id, const glm::mat4& m);
|
||||||
void u_int(const char* name, int i);
|
void u_int(kShaderUniform id, int i);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class kShader : uint16_t
|
enum class kShader : uint16_t
|
||||||
{
|
{
|
||||||
Color = const_hash("color"),
|
Color = const_hash("color"),
|
||||||
|
Texture = const_hash("texture"),
|
||||||
|
UVs = const_hash("uvs"),
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShaderManager
|
class ShaderManager
|
||||||
{
|
{
|
||||||
|
static std::map<kShader, Shader> m_shaders;
|
||||||
|
static Shader* m_current;
|
||||||
public:
|
public:
|
||||||
|
static bool create(kShader id, const char* vertex, const char* fragment);
|
||||||
static void use(kShader id);
|
static void use(kShader id);
|
||||||
static void use(const char* name);
|
static void use(const char* name);
|
||||||
|
static void u_vec4(kShaderUniform id, const glm::vec4& v);
|
||||||
|
static void u_mat4(kShaderUniform id, const glm::mat4& m);
|
||||||
|
static void u_int(kShaderUniform id, int i);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
uint16_t constexpr const_hash(char const *input)
|
uint16_t constexpr const_hash(const char* input)
|
||||||
{
|
{
|
||||||
return *input ?
|
return *input ?
|
||||||
static_cast<uint16_t>(*input) + 33 * const_hash(input + 1) :
|
static_cast<uint16_t>(*input) + 33 * const_hash(input + 1) :
|
||||||
|
|||||||
Reference in New Issue
Block a user