added render target and bezier classes, added stroke settings panel
This commit is contained in:
@@ -35,8 +35,8 @@
|
|||||||
|
|
||||||
<!--slider control-->
|
<!--slider control-->
|
||||||
<layout id="tpl-slider-h">
|
<layout id="tpl-slider-h">
|
||||||
<border pad="1" grow="1" height="100%" color="1" dir="row">
|
<border pad="1" color="1">
|
||||||
<node height="100%" grow="1">
|
<node height="100%">
|
||||||
<slider-cursor id="cursor" width="10" height="100%" positioning="absolute" />
|
<slider-cursor id="cursor" width="10" height="100%" positioning="absolute" />
|
||||||
</node>
|
</node>
|
||||||
</border>
|
</border>
|
||||||
@@ -118,8 +118,55 @@
|
|||||||
<text text="Colors" font-face="arial" font-size="11" color="1 1 1 1"/>
|
<text text="Colors" font-face="arial" font-size="11" color="1 1 1 1"/>
|
||||||
</border>
|
</border>
|
||||||
<border color=".3" pad="5" dir="row" height="150">
|
<border color=".3" pad="5" dir="row" height="150">
|
||||||
<color-quad color=".2" height="100%" grow="1"/>
|
<color-quad id="quad" color=".2" height="100%" grow="1"/>
|
||||||
<node width="30" dir="col" pad="0 0 0 5"><slider-hue/></node>
|
<node width="30" dir="col" pad="0 0 0 5"><slider-hue id="hue"/></node>
|
||||||
|
</border>
|
||||||
|
</node>
|
||||||
|
</layout>
|
||||||
|
|
||||||
|
<!--stroke panel-->
|
||||||
|
<layout id="tpl-panel-stroke">
|
||||||
|
<node width="220" margin="0 0 10 0">
|
||||||
|
<border height="30" color=".5" align="center" justify="center">
|
||||||
|
<text text="Stroke" font-face="arial" font-size="11" color="1 1 1 1"/>
|
||||||
|
</border>
|
||||||
|
<border color=".3" pad="5" dir="col" width="100%">
|
||||||
|
<border color=".2" pad="3" margin="0 0 10 0"> <canvas2D id="canvas" width="100%" height="100"/> </border>
|
||||||
|
|
||||||
|
<border color=".2" height="20" justify="center" align="center"><text text="Tip Settings" font-face="arial" font-size="11"/></border>
|
||||||
|
<node dir="row">
|
||||||
|
<node width="30%" dir="col">
|
||||||
|
<node height="20" justify="center"><text text="Size" font-face="arial" font-size="11"/></node>
|
||||||
|
<node height="20" justify="center"><text text="Flow" font-face="arial" font-size="11"/></node>
|
||||||
|
<node height="20" justify="center"><text text="Spacing" font-face="arial" font-size="11"/></node>
|
||||||
|
<node height="20" justify="center"><text text="Angle" font-face="arial" font-size="11"/></node>
|
||||||
|
<node height="20" justify="center"><text text="Mixer" font-face="arial" font-size="11"/></node>
|
||||||
|
</node>
|
||||||
|
<border dir="col" align="center" grow="1" width="1">
|
||||||
|
<node height="20" pad="1" width="100%"><slider-h id="tip-size"/></node>
|
||||||
|
<node height="20" pad="1" width="100%"><slider-h id="tip-flow"/></node>
|
||||||
|
<node height="20" pad="1" width="100%"><slider-h id="tip-spacing"/></node>
|
||||||
|
<node height="20" pad="1" width="100%"><slider-h id="tip-angle"/></node>
|
||||||
|
<node height="20" pad="1" width="100%"><slider-h id="tip-mix"/></node>
|
||||||
|
</border>
|
||||||
|
</node>
|
||||||
|
|
||||||
|
<border color=".2" height="20" justify="center" align="center"><text text="Jitter Settings" font-face="arial" font-size="11"/></border>
|
||||||
|
<node dir="row">
|
||||||
|
<node width="30%" dir="col">
|
||||||
|
<node height="20" justify="center"><text text="Scale" font-face="arial" font-size="11"/></node>
|
||||||
|
<node height="20" justify="center"><text text="Angle" font-face="arial" font-size="11"/></node>
|
||||||
|
<node height="20" justify="center"><text text="Spread" font-face="arial" font-size="11"/></node>
|
||||||
|
<node height="20" justify="center"><text text="Flow" font-face="arial" font-size="11"/></node>
|
||||||
|
</node>
|
||||||
|
<border dir="col" align="center" grow="1" width="1">
|
||||||
|
<node height="20" pad="1" width="100%"><slider-h id="jitter-scale"/></node>
|
||||||
|
<node height="20" pad="1" width="100%"><slider-h id="jitter-angle"/></node>
|
||||||
|
<node height="20" pad="1" width="100%"><slider-h id="jitter-spread"/></node>
|
||||||
|
<node height="20" pad="1" width="100%"><slider-h id="jitter-flow"/></node>
|
||||||
|
</border>
|
||||||
|
</node>
|
||||||
|
|
||||||
</border>
|
</border>
|
||||||
</node>
|
</node>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -346,12 +393,14 @@
|
|||||||
<!-- side bar -->
|
<!-- side bar -->
|
||||||
<node height="100%" dir="row" shrink="1">
|
<node height="100%" dir="row" shrink="1">
|
||||||
<border pad="5 5 5 5" margin="0 0 0 0" color=".3 .3 .3 .4" height="100%" dir="col" wrap="1" shrink="1">
|
<border pad="5 5 5 5" margin="0 0 0 0" color=".3 .3 .3 .4" height="100%" dir="col" wrap="1" shrink="1">
|
||||||
|
<!--Stroke-->
|
||||||
|
<panel-stroke id="panel-stroke"/>
|
||||||
<!--Brushes-->
|
<!--Brushes-->
|
||||||
<panel-brushes id="panel-brushes"/>
|
<panel-brush id="panel-brush"/>
|
||||||
<!--Layers-->
|
<!--Layers-->
|
||||||
<panel-layers id="panel-layers"/>
|
<panel-layer id="panel-layer"/>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<ref id="tpl-panel-color"/>
|
<panel-color id="panel-color"/>
|
||||||
</border>
|
</border>
|
||||||
</node>
|
</node>
|
||||||
<!-- content panel -->
|
<!-- content panel -->
|
||||||
|
|||||||
@@ -152,6 +152,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="engine\app.cpp" />
|
<ClCompile Include="engine\app.cpp" />
|
||||||
<ClCompile Include="engine\asset.cpp" />
|
<ClCompile Include="engine\asset.cpp" />
|
||||||
|
<ClCompile Include="engine\bezier.cpp" />
|
||||||
<ClCompile Include="engine\font.cpp" />
|
<ClCompile Include="engine\font.cpp" />
|
||||||
<ClCompile Include="engine\image.cpp" />
|
<ClCompile Include="engine\image.cpp" />
|
||||||
<ClCompile Include="engine\layout.cpp" />
|
<ClCompile Include="engine\layout.cpp" />
|
||||||
@@ -162,6 +163,7 @@
|
|||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="engine\rtt.cpp" />
|
||||||
<ClCompile Include="engine\shader.cpp" />
|
<ClCompile Include="engine\shader.cpp" />
|
||||||
<ClCompile Include="engine\shape.cpp" />
|
<ClCompile Include="engine\shape.cpp" />
|
||||||
<ClCompile Include="engine\texture.cpp" />
|
<ClCompile Include="engine\texture.cpp" />
|
||||||
@@ -188,15 +190,20 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="engine\app.h" />
|
<ClInclude Include="engine\app.h" />
|
||||||
<ClInclude Include="engine\asset.h" />
|
<ClInclude Include="engine\asset.h" />
|
||||||
|
<ClInclude Include="engine\bezier.h" />
|
||||||
<ClInclude Include="engine\font.h" />
|
<ClInclude Include="engine\font.h" />
|
||||||
<ClInclude Include="engine\image.h" />
|
<ClInclude Include="engine\image.h" />
|
||||||
<ClInclude Include="engine\layout.h" />
|
<ClInclude Include="engine\layout.h" />
|
||||||
<ClInclude Include="engine\pch.h" />
|
<ClInclude Include="engine\pch.h" />
|
||||||
|
<ClInclude Include="engine\rtt.h" />
|
||||||
<ClInclude Include="engine\shader.h" />
|
<ClInclude Include="engine\shader.h" />
|
||||||
<ClInclude Include="engine\shape.h" />
|
<ClInclude Include="engine\shape.h" />
|
||||||
<ClInclude Include="engine\texture.h" />
|
<ClInclude Include="engine\texture.h" />
|
||||||
<ClInclude Include="engine\util.h" />
|
<ClInclude Include="engine\util.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="engine\bezier" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|||||||
@@ -57,6 +57,12 @@
|
|||||||
<ClCompile Include="engine\asset.cpp">
|
<ClCompile Include="engine\asset.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="engine\rtt.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="engine\bezier.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="engine\app.h">
|
<ClInclude Include="engine\app.h">
|
||||||
@@ -89,5 +95,14 @@
|
|||||||
<ClInclude Include="engine\asset.h">
|
<ClInclude Include="engine\asset.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="engine\rtt.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="engine\bezier.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="engine\bezier" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -5,14 +5,6 @@ using namespace ui;
|
|||||||
|
|
||||||
App App::I; // singleton
|
App App::I; // singleton
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#define SHADER_VERSION "#version 300 es\n"
|
|
||||||
#elif __ANDROID__
|
|
||||||
#define SHADER_VERSION "#version 300 es\n"
|
|
||||||
#elif _WIN32
|
|
||||||
#define SHADER_VERSION "#version 150\n"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void App::create()
|
void App::create()
|
||||||
{
|
{
|
||||||
width = 800;
|
width = 800;
|
||||||
@@ -192,15 +184,30 @@ void App::initLayout()
|
|||||||
NodeBorder::static_init();
|
NodeBorder::static_init();
|
||||||
NodeImage::static_init();
|
NodeImage::static_init();
|
||||||
NodeIcon::static_init();
|
NodeIcon::static_init();
|
||||||
|
NodeCanvas2D::static_init();
|
||||||
|
|
||||||
layout.on_loaded = [&] {
|
layout.on_loaded = [&] {
|
||||||
LOG("initializing layout updating after load");
|
LOG("initializing layout updating after load");
|
||||||
|
|
||||||
layout[main_id]->update(width, height, zoom);
|
layout[main_id]->update(width, height, zoom);
|
||||||
|
|
||||||
LOG("initializing layout components");
|
LOG("initializing layout components");
|
||||||
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
|
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
|
||||||
brushes = layout[main_id]->find<NodePanelBrushes>("panel-brushes");
|
brushes = layout[main_id]->find<NodePanelBrush>("panel-brush");
|
||||||
layers = layout[main_id]->find<NodePanelLayers>("panel-layers");
|
layers = layout[main_id]->find<NodePanelLayer>("panel-layer");
|
||||||
|
color = layout[main_id]->find<NodePanelColor>("panel-color");
|
||||||
|
stroke = layout[main_id]->find<NodePanelStroke>("panel-stroke");
|
||||||
|
|
||||||
|
brushes->on_brush_changed = [this](Node* target, int index) {
|
||||||
|
auto tid = brushes->get_texture_id(index);
|
||||||
|
stroke->m_canvas->m_tex_id = tid;
|
||||||
|
stroke->m_canvas->draw_stroke();
|
||||||
|
};
|
||||||
|
|
||||||
|
color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
||||||
|
stroke->m_canvas->m_tip_color = color;
|
||||||
|
stroke->m_canvas->draw_stroke();
|
||||||
|
};
|
||||||
|
|
||||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-close"))
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-close"))
|
||||||
{
|
{
|
||||||
button->on_click = [](Node*) { exit(0); };
|
button->on_click = [](Node*) { exit(0); };
|
||||||
@@ -271,7 +278,8 @@ void App::initLayout()
|
|||||||
};
|
};
|
||||||
LOG("initializing layout xml");
|
LOG("initializing layout xml");
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
layout.load("C:\\Users\\omar\\Desktop\\new_engine\\data\\layout.xml");
|
//layout.load("C:\\Users\\omar\\Desktop\\new_engine\\data\\layout.xml");
|
||||||
|
layout.load("data/layout.xml");
|
||||||
#else
|
#else
|
||||||
layout.load("data/layout.xml");
|
layout.load("data/layout.xml");
|
||||||
#endif
|
#endif
|
||||||
@@ -307,8 +315,6 @@ void App::init()
|
|||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
//glPointSize(5);
|
|
||||||
glLineWidth(2);
|
|
||||||
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glBlendEquation(GL_FUNC_ADD);
|
glBlendEquation(GL_FUNC_ADD);
|
||||||
@@ -336,16 +342,16 @@ void App::update(float dt)
|
|||||||
//glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
//glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
||||||
//glClear(GL_COLOR_BUFFER_BIT);
|
//glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
layout.reload();
|
// layout.reload();
|
||||||
if (auto* main = layout[main_id])
|
// if (auto* main = layout[main_id])
|
||||||
main->update(width, height, zoom);
|
// main->update(width, height, zoom);
|
||||||
|
|
||||||
auto observer = [this](Node* n)
|
auto observer = [this](Node* n)
|
||||||
{
|
{
|
||||||
if (n && n->m_display)
|
if (n && n->m_display)
|
||||||
{
|
{
|
||||||
auto box = n->m_clip;
|
auto box = n->m_clip;
|
||||||
glm::vec4 c = glm::vec4((int)box.x - 1, (int)(height / zoom - box.y - box.w) - 1, (int)box.z + 2, (int)box.w + 2) * zoom;
|
glm::ivec4 c = glm::vec4((int)box.x - 1, (int)(height / zoom - box.y - box.w) - 1, (int)box.z + 2, (int)box.w + 2) * zoom;
|
||||||
glScissor(c.x, c.y, c.z, c.w);
|
glScissor(c.x, c.y, c.z, c.w);
|
||||||
n->draw();
|
n->draw();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ public:
|
|||||||
NodePopupMenu* menu_edit = nullptr;
|
NodePopupMenu* menu_edit = nullptr;
|
||||||
NodePopupMenu* menu_layers = nullptr;
|
NodePopupMenu* menu_layers = nullptr;
|
||||||
NodeBorder* sidebar = nullptr;
|
NodeBorder* sidebar = nullptr;
|
||||||
NodePanelBrushes* brushes;
|
NodePanelBrush* brushes;
|
||||||
NodePanelLayers* layers;
|
NodePanelLayer* layers;
|
||||||
|
NodePanelColor* color;
|
||||||
|
NodePanelStroke* stroke;
|
||||||
const uint16_t main_id = const_hash("main");
|
const uint16_t main_id = const_hash("main");
|
||||||
float width;
|
float width;
|
||||||
float height;
|
float height;
|
||||||
|
|||||||
39
engine/bezier.cpp
Normal file
39
engine/bezier.cpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "bezier.h"
|
||||||
|
|
||||||
|
|
||||||
|
double BezierCurve::FactorialLookup[] = {
|
||||||
|
1.0,
|
||||||
|
1.0,
|
||||||
|
2.0,
|
||||||
|
6.0,
|
||||||
|
24.0,
|
||||||
|
120.0,
|
||||||
|
720.0,
|
||||||
|
5040.0,
|
||||||
|
40320.0,
|
||||||
|
362880.0,
|
||||||
|
3628800.0,
|
||||||
|
39916800.0,
|
||||||
|
479001600.0,
|
||||||
|
6227020800.0,
|
||||||
|
87178291200.0,
|
||||||
|
1307674368000.0,
|
||||||
|
20922789888000.0,
|
||||||
|
355687428096000.0,
|
||||||
|
6402373705728000.0,
|
||||||
|
121645100408832000.0,
|
||||||
|
2432902008176640000.0,
|
||||||
|
51090942171709440000.0,
|
||||||
|
1124000727777607680000.0,
|
||||||
|
25852016738884976640000.0,
|
||||||
|
620448401733239439360000.0,
|
||||||
|
15511210043330985984000000.0,
|
||||||
|
403291461126605635584000000.0,
|
||||||
|
10888869450418352160768000000.0,
|
||||||
|
304888344611713860501504000000.0,
|
||||||
|
8841761993739701954543616000000.0,
|
||||||
|
265252859812191058636308480000000.0,
|
||||||
|
8222838654177922817725562880000000.0,
|
||||||
|
263130836933693530167218012160000000.0,
|
||||||
|
};
|
||||||
66
engine/bezier.h
Normal file
66
engine/bezier.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
class BezierCurve
|
||||||
|
{
|
||||||
|
static double FactorialLookup[33];
|
||||||
|
public:
|
||||||
|
// just check if n is appropriate, then return the result
|
||||||
|
static double factorial(int n)
|
||||||
|
{
|
||||||
|
// if (n < 0) { throw new Exception("n is less than 0"); }
|
||||||
|
// if (n > 32) { throw new Exception("n is greater than 32"); }
|
||||||
|
return FactorialLookup[n]; /* returns the value n! as a SUMORealing point number */
|
||||||
|
}
|
||||||
|
|
||||||
|
static double Ni(int n, int i)
|
||||||
|
{
|
||||||
|
double ni;
|
||||||
|
double a1 = factorial(n);
|
||||||
|
double a2 = factorial(i);
|
||||||
|
double a3 = factorial(n - i);
|
||||||
|
ni = a1 / (a2 * a3);
|
||||||
|
return ni;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate Bernstein basis
|
||||||
|
static double Bernstein(int n, int i, double t)
|
||||||
|
{
|
||||||
|
double basis;
|
||||||
|
double ti; /* t^i */
|
||||||
|
double tni; /* (1 - t)^i */
|
||||||
|
|
||||||
|
/* Prevent problems with pow */
|
||||||
|
|
||||||
|
if (t == 0.0 && i == 0)
|
||||||
|
ti = 1.0;
|
||||||
|
else
|
||||||
|
ti = pow(t, i);
|
||||||
|
|
||||||
|
if (n == i && t == 1.0)
|
||||||
|
tni = 1.0;
|
||||||
|
else
|
||||||
|
tni = pow((1 - t), (n - i));
|
||||||
|
|
||||||
|
//Bernstein basis
|
||||||
|
basis = Ni(n, i) * ti * tni;
|
||||||
|
return basis;
|
||||||
|
}
|
||||||
|
|
||||||
|
static glm::vec2 Bezier2D(const std::vector<glm::vec2>& b, double t)
|
||||||
|
{
|
||||||
|
// if ((1.0 - t) < 5e-6)
|
||||||
|
// t = 1.0;
|
||||||
|
|
||||||
|
double px = 0.0;
|
||||||
|
double py = 0.0;
|
||||||
|
const int npts = (int)b.size();
|
||||||
|
for (int i = 0; i < npts; i++)
|
||||||
|
{
|
||||||
|
double basis = Bernstein(npts - 1, i, t);
|
||||||
|
px += basis * b[i].x;
|
||||||
|
py += basis * b[i].y;
|
||||||
|
}
|
||||||
|
return { px, py };
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -9,6 +9,7 @@ Plane NodeBorder::m_plane;
|
|||||||
Plane NodeImage::m_plane;
|
Plane NodeImage::m_plane;
|
||||||
Sampler NodeImage::m_sampler;
|
Sampler NodeImage::m_sampler;
|
||||||
std::map<std::string, glm::vec4> NodeIcon::m_icons;
|
std::map<std::string, glm::vec4> NodeIcon::m_icons;
|
||||||
|
ui::Shader NodeCanvas2D::m_shader;
|
||||||
|
|
||||||
kEventResult Node::on_event(Event* e)
|
kEventResult Node::on_event(Event* e)
|
||||||
{
|
{
|
||||||
@@ -177,6 +178,7 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj)
|
|||||||
float y = YGNodeLayoutGetTop(y_node);
|
float y = YGNodeLayoutGetTop(y_node);
|
||||||
float w = YGNodeLayoutGetWidth(y_node);
|
float w = YGNodeLayoutGetWidth(y_node);
|
||||||
float h = YGNodeLayoutGetHeight(y_node);
|
float h = YGNodeLayoutGetHeight(y_node);
|
||||||
|
auto old_size = m_size;
|
||||||
m_pos = glm::floor(origin + glm::vec2(x, y));
|
m_pos = glm::floor(origin + glm::vec2(x, y));
|
||||||
m_size = glm::floor(glm::vec2(w, h));
|
m_size = glm::floor(glm::vec2(w, h));
|
||||||
|
|
||||||
@@ -215,6 +217,9 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_size != old_size)
|
||||||
|
handle_resize(old_size, m_size);
|
||||||
|
|
||||||
for (auto& c : m_children)
|
for (auto& c : m_children)
|
||||||
c->update_internal(m_pos, proj);
|
c->update_internal(m_pos, proj);
|
||||||
}
|
}
|
||||||
@@ -433,9 +438,12 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
|
|||||||
CASE(kWidget::Viewport, NodeViewport);
|
CASE(kWidget::Viewport, NodeViewport);
|
||||||
CASE(kWidget::CheckBox, NodeCheckBox);
|
CASE(kWidget::CheckBox, NodeCheckBox);
|
||||||
CASE(kWidget::Layer, NodeLayer);
|
CASE(kWidget::Layer, NodeLayer);
|
||||||
CASE(kWidget::PanelLayers, NodePanelLayers);
|
CASE(kWidget::PanelLayer, NodePanelLayer);
|
||||||
CASE(kWidget::PanelBrushes, NodePanelBrushes);
|
CASE(kWidget::PanelBrush, NodePanelBrush);
|
||||||
|
CASE(kWidget::PanelColor, NodePanelColor);
|
||||||
|
CASE(kWidget::PanelStroke, NodePanelStroke);
|
||||||
CASE(kWidget::ColorQuad, NodeColorQuad);
|
CASE(kWidget::ColorQuad, NodeColorQuad);
|
||||||
|
CASE(kWidget::Canvas2D, NodeCanvas2D);
|
||||||
#undef CASE
|
#undef CASE
|
||||||
case kWidget::Ref:
|
case kWidget::Ref:
|
||||||
{
|
{
|
||||||
@@ -496,7 +504,7 @@ void Node::clone_children(Node* dest) const
|
|||||||
Node* cn = c->clone();
|
Node* cn = c->clone();
|
||||||
dest->m_children.emplace_back(cn);
|
dest->m_children.emplace_back(cn);
|
||||||
cn->parent = dest;
|
cn->parent = dest;
|
||||||
cn->m_manager = m_manager;
|
cn->m_manager = dest->m_manager;
|
||||||
YGNodeInsertChild(dest->y_node, cn->y_node, YGNodeGetChildCount(dest->y_node));
|
YGNodeInsertChild(dest->y_node, cn->y_node, YGNodeGetChildCount(dest->y_node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
411
engine/layout.h
411
engine/layout.h
@@ -4,6 +4,8 @@
|
|||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "asset.h"
|
#include "asset.h"
|
||||||
|
#include "rtt.h"
|
||||||
|
#include "bezier.h"
|
||||||
#include <tinyxml2.h>
|
#include <tinyxml2.h>
|
||||||
#include <yoga/Yoga.h>
|
#include <yoga/Yoga.h>
|
||||||
|
|
||||||
@@ -62,9 +64,12 @@ enum class kWidget : uint16_t
|
|||||||
Ref = const_hash("ref"),
|
Ref = const_hash("ref"),
|
||||||
CheckBox = const_hash("checkbox"),
|
CheckBox = const_hash("checkbox"),
|
||||||
Layer = const_hash("layer"),
|
Layer = const_hash("layer"),
|
||||||
PanelLayers = const_hash("panel-layers"),
|
PanelLayer = const_hash("panel-layer"),
|
||||||
PanelBrushes = const_hash("panel-brushes"),
|
PanelBrush = const_hash("panel-brush"),
|
||||||
|
PanelColor = const_hash("panel-color"),
|
||||||
|
PanelStroke = const_hash("panel-stroke"),
|
||||||
ColorQuad = const_hash("color-quad"),
|
ColorQuad = const_hash("color-quad"),
|
||||||
|
Canvas2D = const_hash("canvas2D"),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class kShapeType : uint16_t
|
enum class kShapeType : uint16_t
|
||||||
@@ -273,6 +278,7 @@ public:
|
|||||||
|
|
||||||
virtual kEventResult on_event(Event* e);
|
virtual kEventResult on_event(Event* e);
|
||||||
virtual kEventResult handle_event(Event* e) { return kEventResult::Available; }
|
virtual kEventResult handle_event(Event* e) { return kEventResult::Available; }
|
||||||
|
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size) { };
|
||||||
virtual void create() { }
|
virtual void create() { }
|
||||||
virtual void init() { }
|
virtual void init() { }
|
||||||
virtual void loaded() { }
|
virtual void loaded() { }
|
||||||
@@ -698,6 +704,7 @@ public:
|
|||||||
class NodePopupMenu : public Node
|
class NodePopupMenu : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
std::function<void(Node* target, int index)> on_select;
|
||||||
virtual Node* clone_instantiate() const override { return new NodePopupMenu(); }
|
virtual Node* clone_instantiate() const override { return new NodePopupMenu(); }
|
||||||
virtual void init() override
|
virtual void init() override
|
||||||
{
|
{
|
||||||
@@ -706,19 +713,34 @@ public:
|
|||||||
SetWidth(100);
|
SetWidth(100);
|
||||||
SetHeight(400);
|
SetHeight(400);
|
||||||
SetPositioning(YGPositionTypeAbsolute);
|
SetPositioning(YGPositionTypeAbsolute);
|
||||||
|
m_mouse_ignore = false;
|
||||||
}
|
}
|
||||||
virtual kEventResult handle_event(Event* e) override
|
virtual kEventResult handle_event(Event* e) override
|
||||||
{
|
{
|
||||||
switch (e->m_type)
|
switch (e->m_type)
|
||||||
{
|
{
|
||||||
case kEventType::MouseDownL:
|
case kEventType::MouseDownL:
|
||||||
|
break;
|
||||||
|
case kEventType::MouseUpL:
|
||||||
if (!m_mouse_inside)
|
if (!m_mouse_inside)
|
||||||
{
|
{
|
||||||
mouse_release();
|
mouse_release();
|
||||||
destroy();
|
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
case kEventType::MouseUpL:
|
{
|
||||||
|
auto pos = ((MouseEvent*)e)->m_pos;
|
||||||
|
for (int i = 0; i < m_children.size(); i++)
|
||||||
|
{
|
||||||
|
if (m_children[i]->m_mouse_inside)
|
||||||
|
{
|
||||||
|
if (on_select)
|
||||||
|
on_select(this, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mouse_release();
|
||||||
|
}
|
||||||
|
destroy();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -833,7 +855,7 @@ public:
|
|||||||
static char name[256];
|
static char name[256];
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
char* s = strtok(data, "\n");
|
char* s = strtok(data, "\n");
|
||||||
int i = strlen(s) + 1;
|
auto i = strlen(s) + 1;
|
||||||
while (i < size && sscanf(s, "%s %d %d %d %d", name, &w, &h, &x, &y) == 5)
|
while (i < size && sscanf(s, "%s %d %d %d %d", name, &w, &h, &x, &y) == 5)
|
||||||
{
|
{
|
||||||
m_icons[name] = glm::vec4(x, y, x + w, y + h);
|
m_icons[name] = glm::vec4(x, y, x + w, y + h);
|
||||||
@@ -899,7 +921,7 @@ public:
|
|||||||
glClearColor(1, 0, 0, 1);
|
glClearColor(1, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
auto box = m_clip * root()->m_zoom;
|
auto box = m_clip * root()->m_zoom;
|
||||||
auto c = glm::vec4(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w);
|
glm::ivec4 c = (glm::ivec4)glm::vec4(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w);
|
||||||
glViewport(c.x, c.y, c.z, c.w);
|
glViewport(c.x, c.y, c.z, c.w);
|
||||||
TextureManager::get(m_tex_id).bind();
|
TextureManager::get(m_tex_id).bind();
|
||||||
m_sampler->bind(0);
|
m_sampler->bind(0);
|
||||||
@@ -963,6 +985,8 @@ class NodeSliderCursor : public NodeButtonCustom
|
|||||||
glm::vec2 old_pos;
|
glm::vec2 old_pos;
|
||||||
public:
|
public:
|
||||||
glm::vec2 m_mask{ 1, 0 };
|
glm::vec2 m_mask{ 1, 0 };
|
||||||
|
glm::vec2 m_value;
|
||||||
|
std::function<void(Node* target, glm::vec2 value)> on_value_changed;
|
||||||
virtual Node* clone_instantiate() const override { return new NodeSliderCursor(); }
|
virtual Node* clone_instantiate() const override { return new NodeSliderCursor(); }
|
||||||
virtual void clone_copy(Node* dest) const override
|
virtual void clone_copy(Node* dest) const override
|
||||||
{
|
{
|
||||||
@@ -992,6 +1016,9 @@ public:
|
|||||||
drag_diff = old_pos + (((MouseEvent*)e)->m_pos - drag_start) * m_mask;
|
drag_diff = old_pos + (((MouseEvent*)e)->m_pos - drag_start) * m_mask;
|
||||||
auto pos = glm::clamp(drag_diff, { 0, 0 }, sz);
|
auto pos = glm::clamp(drag_diff, { 0, 0 }, sz);
|
||||||
SetPosition(pos.x, pos.y);
|
SetPosition(pos.x, pos.y);
|
||||||
|
m_value = pos / glm::max({ 1,1 }, sz); // avoid div0
|
||||||
|
if (on_value_changed)
|
||||||
|
on_value_changed(this, m_value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1005,15 +1032,29 @@ class NodeSliderH : public NodeBorder
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NodeSliderCursor* m_cursor;
|
NodeSliderCursor* m_cursor;
|
||||||
|
std::function<void(Node* target, float value)> on_value_changed;
|
||||||
virtual Node* clone_instantiate() const override { return new NodeSliderH(); }
|
virtual Node* clone_instantiate() const override { return new NodeSliderH(); }
|
||||||
|
virtual void clone_finalize(Node* dest) const override
|
||||||
|
{
|
||||||
|
NodeSliderH* n = static_cast<NodeSliderH*>(dest);
|
||||||
|
n->init_controls();
|
||||||
|
}
|
||||||
virtual void init() override
|
virtual void init() override
|
||||||
{
|
{
|
||||||
const auto& m_template = (NodeBorder*)init_template("tpl-slider-h");
|
const auto& m_template = (NodeBorder*)init_template("tpl-slider-h");
|
||||||
m_color = m_template->m_color;
|
m_color = m_template->m_color;
|
||||||
m_border_color = m_template->m_border_color;
|
m_border_color = m_template->m_border_color;
|
||||||
m_thinkness = m_thinkness;
|
m_thinkness = m_template->m_thinkness;
|
||||||
|
init_controls();
|
||||||
|
}
|
||||||
|
void init_controls()
|
||||||
|
{
|
||||||
m_cursor = find<NodeSliderCursor>("cursor");
|
m_cursor = find<NodeSliderCursor>("cursor");
|
||||||
m_cursor->m_mask = { 1, 0 };
|
m_cursor->m_mask = { 1, 0 };
|
||||||
|
m_cursor->on_value_changed = [this](Node*, glm::vec2 value) {
|
||||||
|
if (on_value_changed)
|
||||||
|
on_value_changed(this, value.x);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1021,15 +1062,29 @@ class NodeSliderV : public NodeBorder
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NodeSliderCursor* m_cursor;
|
NodeSliderCursor* m_cursor;
|
||||||
|
std::function<void(Node* target, float value)> on_value_changed;
|
||||||
virtual Node* clone_instantiate() const override { return new NodeSliderV(); }
|
virtual Node* clone_instantiate() const override { return new NodeSliderV(); }
|
||||||
|
virtual void clone_finalize(Node* dest) const override
|
||||||
|
{
|
||||||
|
NodeSliderV* n = static_cast<NodeSliderV*>(dest);
|
||||||
|
n->init_controls();
|
||||||
|
}
|
||||||
virtual void init() override
|
virtual void init() override
|
||||||
{
|
{
|
||||||
const auto& m_template = (NodeBorder*)init_template("tpl-slider-v");
|
const auto& m_template = (NodeBorder*)init_template("tpl-slider-v");
|
||||||
m_color = m_template->m_color;
|
m_color = m_template->m_color;
|
||||||
m_border_color = m_template->m_border_color;
|
m_border_color = m_template->m_border_color;
|
||||||
m_thinkness = m_thinkness;
|
m_thinkness = m_template->m_thinkness;
|
||||||
|
init_controls();
|
||||||
|
}
|
||||||
|
void init_controls()
|
||||||
|
{
|
||||||
m_cursor = find<NodeSliderCursor>("cursor");
|
m_cursor = find<NodeSliderCursor>("cursor");
|
||||||
m_cursor->m_mask = { 0, 1 };
|
m_cursor->m_mask = { 0, 1 };
|
||||||
|
m_cursor->on_value_changed = [this](Node*, glm::vec2 value) {
|
||||||
|
if (on_value_changed)
|
||||||
|
on_value_changed(this, value.y);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1037,25 +1092,34 @@ class NodeSliderHue : public NodeBorder
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NodeSliderCursor* m_cursor;
|
NodeSliderCursor* m_cursor;
|
||||||
|
glm::vec4 m_color;
|
||||||
|
std::function<void(Node* target, glm::vec4 color)> on_value_changed;
|
||||||
virtual Node* clone_instantiate() const override { return new NodeSliderHue(); }
|
virtual Node* clone_instantiate() const override { return new NodeSliderHue(); }
|
||||||
virtual void clone_finalize(Node* dest) const override
|
virtual void clone_finalize(Node* dest) const override
|
||||||
{
|
{
|
||||||
NodeSliderHue* n = static_cast<NodeSliderHue*>(dest);
|
NodeSliderHue* n = static_cast<NodeSliderHue*>(dest);
|
||||||
n->m_cursor = n->find<NodeSliderCursor>("cursor");
|
n->init_controls();
|
||||||
n->m_cursor->m_color = glm::vec4(0);
|
|
||||||
n->m_cursor->m_border_color = glm::vec4(0, 0, 0, 1);
|
|
||||||
}
|
}
|
||||||
virtual void init() override
|
virtual void init() override
|
||||||
{
|
{
|
||||||
const auto& m_template = (NodeBorder*)init_template("tpl-slider-hue");
|
const auto& m_template = (NodeBorder*)init_template("tpl-slider-hue");
|
||||||
m_color = m_template->m_color;
|
m_color = m_template->m_color;
|
||||||
m_border_color = m_template->m_border_color;
|
m_border_color = m_template->m_border_color;
|
||||||
m_thinkness = m_thinkness;
|
m_thinkness = m_template->m_thinkness;
|
||||||
|
init_controls();
|
||||||
|
}
|
||||||
|
void init_controls()
|
||||||
|
{
|
||||||
m_cursor = find<NodeSliderCursor>("cursor");
|
m_cursor = find<NodeSliderCursor>("cursor");
|
||||||
m_cursor->m_mask = { 0, 1 };
|
m_cursor->m_mask = { 0, 1 };
|
||||||
m_cursor->m_thinkness = 1;
|
m_cursor->m_thinkness = 1;
|
||||||
m_cursor->m_color = glm::vec4(0);
|
m_cursor->m_color = glm::vec4(0);
|
||||||
m_cursor->m_border_color = glm::vec4(0, 0, 0, 1);
|
m_cursor->m_border_color = glm::vec4(0, 0, 0, 1);
|
||||||
|
m_cursor->on_value_changed = [this](Node*, glm::vec2 value) {
|
||||||
|
m_color = glm::vec4(convert_hsv2rgb({ value.y, 1, 1 }), 1);
|
||||||
|
if (on_value_changed)
|
||||||
|
on_value_changed(this, m_color);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
virtual void draw() override
|
virtual void draw() override
|
||||||
{
|
{
|
||||||
@@ -1214,7 +1278,7 @@ public:
|
|||||||
virtual void draw() override
|
virtual void draw() override
|
||||||
{
|
{
|
||||||
auto c = m_selected ? m_color_selected : m_color_normal;
|
auto c = m_selected ? m_color_selected : m_color_normal;
|
||||||
m_thinkness = m_selected ? 1 : 0;
|
m_thinkness = m_selected ? 1.f : 0.f;
|
||||||
m_color = m_mouse_inside ? m_color_hover : c;
|
m_color = m_mouse_inside ? m_color_hover : c;
|
||||||
NodeBorder::draw();
|
NodeBorder::draw();
|
||||||
}
|
}
|
||||||
@@ -1225,7 +1289,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NodePanelLayers : public Node
|
class NodePanelLayer : public Node
|
||||||
{
|
{
|
||||||
NodeButtonCustom* btn_add;
|
NodeButtonCustom* btn_add;
|
||||||
NodeButtonCustom* btn_remove;
|
NodeButtonCustom* btn_remove;
|
||||||
@@ -1239,7 +1303,7 @@ public:
|
|||||||
NodeLayer* m_current_layer = nullptr;
|
NodeLayer* m_current_layer = nullptr;
|
||||||
std::vector<NodeLayer*> m_layers;
|
std::vector<NodeLayer*> m_layers;
|
||||||
NodeBorder* m_layers_container;
|
NodeBorder* m_layers_container;
|
||||||
virtual Node* clone_instantiate() const override { return new NodePanelLayers(); }
|
virtual Node* clone_instantiate() const override { return new NodePanelLayer(); }
|
||||||
virtual void init() override
|
virtual void init() override
|
||||||
{
|
{
|
||||||
init_template("tpl-panel-layers");
|
init_template("tpl-panel-layers");
|
||||||
@@ -1283,7 +1347,7 @@ public:
|
|||||||
l->create();
|
l->create();
|
||||||
l->loaded();
|
l->loaded();
|
||||||
l->set_name(name);
|
l->set_name(name);
|
||||||
l->on_selected = std::bind(&NodePanelLayers::handle_layer_selected, this, std::placeholders::_1);
|
l->on_selected = std::bind(&NodePanelLayer::handle_layer_selected, this, std::placeholders::_1);
|
||||||
m_layers.push_back(l);
|
m_layers.push_back(l);
|
||||||
if (on_layer_add)
|
if (on_layer_add)
|
||||||
on_layer_add(this);
|
on_layer_add(this);
|
||||||
@@ -1294,11 +1358,11 @@ public:
|
|||||||
auto i = m_layers_container->get_child_index(m_current_layer);
|
auto i = m_layers_container->get_child_index(m_current_layer);
|
||||||
m_layers_container->remove_child(m_current_layer);
|
m_layers_container->remove_child(m_current_layer);
|
||||||
m_layers.erase(it);
|
m_layers.erase(it);
|
||||||
i = std::min<int>(i, m_layers.size() - 1);
|
i = std::min<int>(i, (int)m_layers.size() - 1);
|
||||||
m_current_layer = m_layers[i];
|
m_current_layer = m_layers[i];
|
||||||
m_current_layer->m_selected = true;
|
m_current_layer->m_selected = true;
|
||||||
if (on_layer_delete)
|
if (on_layer_delete)
|
||||||
on_layer_delete(this, std::distance(m_layers.begin(), it));
|
on_layer_delete(this, (int)std::distance(m_layers.begin(), it));
|
||||||
if (on_layer_change)
|
if (on_layer_change)
|
||||||
on_layer_change(this, -1, i);
|
on_layer_change(this, -1, i);
|
||||||
}
|
}
|
||||||
@@ -1342,14 +1406,14 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NodePanelBrushes : public Node
|
class NodePanelBrush : public Node
|
||||||
{
|
{
|
||||||
std::vector<NodeButtonBrush*> m_brushes;
|
std::vector<NodeButtonBrush*> m_brushes;
|
||||||
NodeButtonBrush* m_current = nullptr;
|
NodeButtonBrush* m_current = nullptr;
|
||||||
Node* m_container;
|
Node* m_container;
|
||||||
public:
|
public:
|
||||||
std::function<void(Node* target, int id)> on_brush_changed;
|
std::function<void(Node* target, int id)> on_brush_changed;
|
||||||
virtual Node* clone_instantiate() const override { return new NodePanelLayers(); }
|
virtual Node* clone_instantiate() const override { return new NodePanelLayer(); }
|
||||||
virtual void init() override
|
virtual void init() override
|
||||||
{
|
{
|
||||||
init_template("tpl-panel-brushes");
|
init_template("tpl-panel-brushes");
|
||||||
@@ -1369,7 +1433,7 @@ public:
|
|||||||
brush->set_icon(path.c_str());
|
brush->set_icon(path.c_str());
|
||||||
brush->m_brushID = count++;
|
brush->m_brushID = count++;
|
||||||
m_brushes.push_back(brush);
|
m_brushes.push_back(brush);
|
||||||
brush->on_click = std::bind(&NodePanelBrushes::handle_click, this, std::placeholders::_1);
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1402,32 +1466,307 @@ public:
|
|||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
uint16_t get_texture_id(int index) const
|
||||||
|
{
|
||||||
|
return m_brushes[index]->img->m_tex_id;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NodeColorQuad : public NodeBorder
|
class NodeColorQuad : public NodeBorder
|
||||||
{
|
{
|
||||||
|
NodeBorder* m_picker;
|
||||||
|
bool dragging = false;
|
||||||
public:
|
public:
|
||||||
|
glm::vec2 m_value;
|
||||||
|
std::function<void(Node* target, glm::vec2 value)> on_value_changed;
|
||||||
virtual Node* clone_instantiate() const override { return new NodeColorQuad(); }
|
virtual Node* clone_instantiate() const override { return new NodeColorQuad(); }
|
||||||
|
virtual void clone_finalize(Node* dest) const override
|
||||||
|
{
|
||||||
|
auto n = (NodeColorQuad*)dest;
|
||||||
|
n->m_picker = (NodeBorder*)n->m_children[0].get();
|
||||||
|
}
|
||||||
|
virtual void init() override
|
||||||
|
{
|
||||||
|
m_picker = new NodeBorder;
|
||||||
|
m_picker->SetSize({ 20, 20 });
|
||||||
|
m_picker->SetPositioning(YGPositionTypeAbsolute);
|
||||||
|
m_picker->SetPosition(0, 0);
|
||||||
|
m_picker->m_thinkness = 1;
|
||||||
|
m_picker->m_color = glm::vec4(0);
|
||||||
|
add_child(m_picker);
|
||||||
|
}
|
||||||
|
virtual kEventResult handle_event(Event* e) override
|
||||||
|
{
|
||||||
|
NodeBorder::handle_event(e);
|
||||||
|
switch (e->m_type)
|
||||||
|
{
|
||||||
|
case kEventType::MouseDownL:
|
||||||
|
{
|
||||||
|
dragging = true;
|
||||||
|
mouse_capture();
|
||||||
|
auto sz = GetSize();
|
||||||
|
auto pos = glm::clamp(((MouseEvent*)e)->m_pos - m_pos, { 0, 0 }, sz) - m_picker->GetSize() * .5f;
|
||||||
|
m_picker->SetPosition(pos.x, pos.y);
|
||||||
|
m_value = pos / glm::max({ 1,1 }, sz); // avoid div0
|
||||||
|
if (on_value_changed)
|
||||||
|
on_value_changed(this, m_value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case kEventType::MouseUpL:
|
||||||
|
mouse_release();
|
||||||
|
dragging = false;
|
||||||
|
break;
|
||||||
|
case kEventType::MouseMove:
|
||||||
|
if (dragging)
|
||||||
|
{
|
||||||
|
auto sz = GetSize();
|
||||||
|
auto pos = glm::clamp(((MouseEvent*)e)->m_pos - m_pos, { 0, 0 }, sz) - m_picker->GetSize() * .5f;
|
||||||
|
m_picker->SetPosition(pos.x, pos.y);
|
||||||
|
m_value = pos / glm::max({ 1,1 }, sz); // avoid div0
|
||||||
|
if (on_value_changed)
|
||||||
|
on_value_changed(this, m_value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return kEventResult::Consumed;
|
||||||
|
}
|
||||||
virtual void draw() override
|
virtual void draw() override
|
||||||
{
|
{
|
||||||
|
m_picker->m_border_color = m_value.y > .5f ? glm::vec4(1) : glm::vec4(0, 0, 0, 1);
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
ui::ShaderManager::use(kShader::ColorQuad);
|
ui::ShaderManager::use(kShader::ColorQuad);
|
||||||
ui::ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
|
ui::ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
|
||||||
|
|
||||||
// if (m_color.a != 1.f)
|
|
||||||
// glEnable(GL_BLEND);
|
|
||||||
|
|
||||||
ui::ShaderManager::u_vec4(kShaderUniform::Col, m_color);
|
ui::ShaderManager::u_vec4(kShaderUniform::Col, m_color);
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
|
|
||||||
// if (m_thinkness > 0)
|
|
||||||
// {
|
|
||||||
// glLineWidth(m_thinkness);
|
|
||||||
// ui::ShaderManager::u_vec4(kShaderUniform::Col, m_border_color);
|
|
||||||
// m_plane.draw_stroke();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (m_color.a != 1.f)
|
|
||||||
// glDisable(GL_BLEND);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NodePanelColor : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NodeColorQuad* m_quad;
|
||||||
|
NodeSliderHue* m_hue;
|
||||||
|
glm::vec4 m_color;
|
||||||
|
std::function<void(Node* target, glm::vec4 color)> on_color_changed;
|
||||||
|
virtual Node* clone_instantiate() const override { return new NodePanelColor(); }
|
||||||
|
virtual void clone_finalize(Node* dest) const override
|
||||||
|
{
|
||||||
|
NodePanelColor* n = static_cast<NodePanelColor*>(dest);
|
||||||
|
n->init_controls();
|
||||||
|
}
|
||||||
|
virtual void init() override
|
||||||
|
{
|
||||||
|
const auto& m_template = (Node*)init_template("tpl-panel-color");
|
||||||
|
init_controls();
|
||||||
|
}
|
||||||
|
void init_controls()
|
||||||
|
{
|
||||||
|
m_quad = find<NodeColorQuad>("quad");
|
||||||
|
m_hue = find<NodeSliderHue>("hue");
|
||||||
|
m_hue->on_value_changed = [this](Node*, glm::vec4 color) {
|
||||||
|
m_color = m_quad->m_color = color;
|
||||||
|
if (on_color_changed)
|
||||||
|
on_color_changed(this, color);
|
||||||
|
};
|
||||||
|
m_quad->on_value_changed = [this](Node*, glm::vec2 pos)
|
||||||
|
{
|
||||||
|
auto x = glm::mix(m_color, glm::vec4(1, 1, 1, 1), pos.x);
|
||||||
|
auto color = glm::mix(x, glm::vec4(0, 0, 0, 1), pos.y);
|
||||||
|
if (on_color_changed)
|
||||||
|
on_color_changed(this, color);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeCanvas2D : public NodeBorder
|
||||||
|
{
|
||||||
|
RTT m_rtt;
|
||||||
|
Sampler m_sampler;
|
||||||
|
static ui::Shader m_shader;
|
||||||
|
public:
|
||||||
|
uint16_t m_tex_id;
|
||||||
|
glm::vec4 m_tip_color;
|
||||||
|
float m_tip_size;
|
||||||
|
float m_tip_spacing;
|
||||||
|
float m_tip_flow;
|
||||||
|
float m_tip_angle;
|
||||||
|
float m_jitter_scale;
|
||||||
|
float m_jitter_angle;
|
||||||
|
float m_jitter_spread;
|
||||||
|
float m_jitter_flow;
|
||||||
|
static void static_init()
|
||||||
|
{
|
||||||
|
static const char* shader_v =
|
||||||
|
SHADER_VERSION
|
||||||
|
"uniform mat4 mvp;"
|
||||||
|
"in vec4 pos;"
|
||||||
|
"in vec2 uvs;"
|
||||||
|
"out vec3 uv;"
|
||||||
|
"void main(){"
|
||||||
|
" uv = vec3(uvs, pos.w);"
|
||||||
|
" gl_Position = mvp * vec4(pos.xyz, 1.f);"
|
||||||
|
"}";
|
||||||
|
static const char* shader_f =
|
||||||
|
SHADER_VERSION
|
||||||
|
"uniform sampler2D tex;"
|
||||||
|
"uniform vec4 col;"
|
||||||
|
"uniform float alpha;"
|
||||||
|
"in vec3 uv;"
|
||||||
|
"out vec4 frag;"
|
||||||
|
"void main(){"
|
||||||
|
" float a = (1 - texture(tex, uv.xy).r) * alpha;"
|
||||||
|
" frag = vec4(col.rgb, a);"
|
||||||
|
"}";
|
||||||
|
m_shader.create(shader_v, shader_f);
|
||||||
|
}
|
||||||
|
virtual Node* clone_instantiate() const override { return new NodeCanvas2D(); }
|
||||||
|
virtual void clone_copy(Node* dest) const override
|
||||||
|
{
|
||||||
|
NodeBorder::clone_copy(dest);
|
||||||
|
}
|
||||||
|
virtual void clone_children(Node* dest) const override
|
||||||
|
{
|
||||||
|
// stop children cloning
|
||||||
|
}
|
||||||
|
virtual void clone_finalize(Node* dest) const override
|
||||||
|
{
|
||||||
|
NodeCanvas2D* n = (NodeCanvas2D*)dest;
|
||||||
|
n->init_controls();
|
||||||
|
}
|
||||||
|
void init_controls()
|
||||||
|
{
|
||||||
|
m_sampler.create();
|
||||||
|
TextureManager::load("data/Icons/Round-Hard.png");
|
||||||
|
m_tex_id = const_hash("data/Icons/Round-Hard.png");
|
||||||
|
}
|
||||||
|
void draw_stroke()
|
||||||
|
{
|
||||||
|
m_rtt.bindFramebuffer();
|
||||||
|
{
|
||||||
|
using namespace ui;
|
||||||
|
GLint vp[4];
|
||||||
|
GLfloat cc[4];
|
||||||
|
glGetIntegerv(GL_VIEWPORT, vp);
|
||||||
|
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
||||||
|
|
||||||
|
double w = (double)m_rtt.getWidth();
|
||||||
|
double h = (double)m_rtt.getHeight();
|
||||||
|
std::vector<glm::vec2> kp = { {30, 30}, {30, h-30}, {w-30, 30}, { w-30, h-30 } };
|
||||||
|
|
||||||
|
glClearColor(1, 1, 1, 1);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glViewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glm::mat4 proj = glm::ortho<float>(0, (float)m_rtt.getWidth(), 0, (float)m_rtt.getHeight(), -1, 1);
|
||||||
|
auto& t = TextureManager::get(m_tex_id);
|
||||||
|
float alpha = 0;
|
||||||
|
|
||||||
|
std::minstd_rand prng;
|
||||||
|
m_shader.use();
|
||||||
|
m_shader.u_vec4(kShaderUniform::Col, m_tip_color);
|
||||||
|
m_shader.u_int(kShaderUniform::Tex, 0);
|
||||||
|
t.bind();
|
||||||
|
m_sampler.bind(0);
|
||||||
|
while (alpha < 1.f)
|
||||||
|
{
|
||||||
|
auto rnd_nor = [&] { return float((double)prng() / (double)prng.max()); }; // normalized [0, +1]
|
||||||
|
auto rnd_neg = [&] { return float((double)prng() / (double)prng.max() * 2.0 - 1.0); }; // normalized [-1, +1]
|
||||||
|
auto rnd_rad = [&] { return float((double)prng() / (double)prng.max() * M_PI * 2.0); }; // normalized [0, 2pi]
|
||||||
|
auto rnd_vec = [&] { float rad = rnd_rad(); return glm::vec2(cosf(rad), sinf(rad)); }; // normalized direction vector
|
||||||
|
|
||||||
|
float angle = (m_tip_angle + rnd_nor() * m_jitter_angle) * (float)(M_PI * 2.0);
|
||||||
|
glm::vec2 pos = BezierCurve::Bezier2D(kp, alpha) + (rnd_vec() * m_jitter_spread * 100.f);
|
||||||
|
float size = 100.f * m_tip_size * (1.f - rnd_nor() * m_jitter_scale);
|
||||||
|
float flow = m_tip_flow * (1.f - rnd_nor() * m_jitter_flow);
|
||||||
|
|
||||||
|
alpha += glm::max(m_tip_spacing * .2f, .01f);
|
||||||
|
auto mvp = proj *
|
||||||
|
//glm::translate(glm::vec3(i * 40 * m_tip_spacing, m_rtt.getHeight() / 2, 0)) *
|
||||||
|
glm::translate(glm::vec3(pos, 0)) *
|
||||||
|
glm::scale(glm::vec3(size, size, 1)) *
|
||||||
|
glm::eulerAngleZ(angle);
|
||||||
|
m_shader.u_mat4(kShaderUniform::MVP, mvp);
|
||||||
|
m_shader.u_float(kShaderUniform::Alpha, flow);
|
||||||
|
m_plane.draw_fill();
|
||||||
|
}
|
||||||
|
m_sampler.unbind();
|
||||||
|
t.unbind();
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
|
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||||
|
}
|
||||||
|
m_rtt.unbindFramebuffer();
|
||||||
|
}
|
||||||
|
virtual void draw() override
|
||||||
|
{
|
||||||
|
using namespace ui;
|
||||||
|
ui::ShaderManager::use(kShader::Texture);
|
||||||
|
ui::ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
|
||||||
|
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
m_rtt.bindTexture();
|
||||||
|
m_sampler.bind(0);
|
||||||
|
m_plane.draw_fill();
|
||||||
|
m_sampler.unbind();
|
||||||
|
m_rtt.unbindTexture();
|
||||||
|
}
|
||||||
|
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size) override
|
||||||
|
{
|
||||||
|
m_rtt.destroy();
|
||||||
|
m_rtt.create((int)new_size.x, (int)new_size.y);
|
||||||
|
draw_stroke();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodePanelStroke : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NodeCanvas2D* m_canvas;
|
||||||
|
NodeSliderH* m_tip_size;
|
||||||
|
NodeSliderH* m_tip_spacing;
|
||||||
|
NodeSliderH* m_tip_flow;
|
||||||
|
NodeSliderH* m_tip_angle;
|
||||||
|
NodeSliderH* m_jitter_scale;
|
||||||
|
NodeSliderH* m_jitter_angle;
|
||||||
|
NodeSliderH* m_jitter_spread;
|
||||||
|
NodeSliderH* m_jitter_flow;
|
||||||
|
virtual Node* clone_instantiate() const override { return new NodePanelStroke(); }
|
||||||
|
virtual void clone_finalize(Node* dest) const override
|
||||||
|
{
|
||||||
|
NodePanelColor* n = static_cast<NodePanelColor*>(dest);
|
||||||
|
n->init_controls();
|
||||||
|
}
|
||||||
|
virtual void init() override
|
||||||
|
{
|
||||||
|
const auto& m_template = (Node*)init_template("tpl-panel-stroke");
|
||||||
|
init_controls();
|
||||||
|
}
|
||||||
|
void init_controls()
|
||||||
|
{
|
||||||
|
m_canvas = find<NodeCanvas2D>("canvas");
|
||||||
|
|
||||||
|
init_slider(m_tip_size, "tip-size", &NodeCanvas2D::m_tip_size);
|
||||||
|
init_slider(m_tip_spacing, "tip-spacing", &NodeCanvas2D::m_tip_spacing);
|
||||||
|
init_slider(m_tip_flow, "tip-flow", &NodeCanvas2D::m_tip_flow);
|
||||||
|
init_slider(m_tip_angle, "tip-angle", &NodeCanvas2D::m_tip_angle);
|
||||||
|
init_slider(m_jitter_scale, "jitter-scale", &NodeCanvas2D::m_jitter_scale);
|
||||||
|
init_slider(m_jitter_angle, "jitter-angle", &NodeCanvas2D::m_jitter_angle);
|
||||||
|
init_slider(m_jitter_spread, "jitter-spread", &NodeCanvas2D::m_jitter_spread);
|
||||||
|
init_slider(m_jitter_flow, "jitter-flow", &NodeCanvas2D::m_jitter_flow);
|
||||||
|
}
|
||||||
|
void init_slider(NodeSliderH*& slider, const char* id, float NodeCanvas2D::* prop)
|
||||||
|
{
|
||||||
|
slider = find<NodeSliderH>(id);
|
||||||
|
slider->on_value_changed = std::bind(&NodePanelStroke::handle_slide,
|
||||||
|
this, prop, std::placeholders::_1, std::placeholders::_2);
|
||||||
|
}
|
||||||
|
void handle_slide(float NodeCanvas2D::* prop, Node* target, float value)
|
||||||
|
{
|
||||||
|
m_canvas->*prop = value;
|
||||||
|
m_canvas->draw_stroke();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,11 @@
|
|||||||
#include <OpenGL/gl3.h>
|
#include <OpenGL/gl3.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#define LOG printf
|
#define LOG printf
|
||||||
|
#define SHADER_VERSION "#version 300 es\n"
|
||||||
|
|
||||||
#elif __ANDROID__
|
#elif __ANDROID__
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <android/sensor.h>
|
#include <android/sensor.h>
|
||||||
@@ -17,6 +19,7 @@
|
|||||||
#include <android_native_app_glue.h>
|
#include <android_native_app_glue.h>
|
||||||
|
|
||||||
#define LOG(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-engine", __VA_ARGS__))
|
#define LOG(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-engine", __VA_ARGS__))
|
||||||
|
#define SHADER_VERSION "#version 300 es\n"
|
||||||
|
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
@@ -27,6 +30,7 @@
|
|||||||
#include <gl\GL.h>
|
#include <gl\GL.h>
|
||||||
|
|
||||||
#define LOG(M,...) printf(M"\n", ##__VA_ARGS__)
|
#define LOG(M,...) printf(M"\n", ##__VA_ARGS__)
|
||||||
|
#define SHADER_VERSION "#version 150\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -37,6 +41,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <random>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|||||||
134
engine/rtt.cpp
Normal file
134
engine/rtt.cpp
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "rtt.h"
|
||||||
|
|
||||||
|
|
||||||
|
RTT::RTT()
|
||||||
|
{
|
||||||
|
fboID = 0;
|
||||||
|
rboID = 0;
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTT::~RTT()
|
||||||
|
{
|
||||||
|
//destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTT::destroy()
|
||||||
|
{
|
||||||
|
if (rboID)
|
||||||
|
{
|
||||||
|
glDeleteRenderbuffers(1, &rboID);
|
||||||
|
}
|
||||||
|
if (texID)
|
||||||
|
{
|
||||||
|
unbindTexture();
|
||||||
|
glDeleteTextures(1, &texID);
|
||||||
|
}
|
||||||
|
if (fboID)
|
||||||
|
{
|
||||||
|
unbindFramebuffer();
|
||||||
|
glDeleteFramebuffers(1, &fboID);
|
||||||
|
}
|
||||||
|
fboID = 0;
|
||||||
|
rboID = 0;
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RTT::create(int width, int height, int tex/* = -1*/)
|
||||||
|
{
|
||||||
|
// Destroy any previously created object
|
||||||
|
destroy();
|
||||||
|
|
||||||
|
w = width;
|
||||||
|
h = height;
|
||||||
|
|
||||||
|
if (tex == -1)
|
||||||
|
{
|
||||||
|
glGenTextures(1, &texID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
texID = tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texID);
|
||||||
|
|
||||||
|
if (tex == -1)
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, 0);
|
||||||
|
|
||||||
|
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
// Create a renderbuffer object to store depth info
|
||||||
|
glGenRenderbuffers(1, &rboID);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, rboID);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
|
// Create a framebuffer object
|
||||||
|
glGenFramebuffers(1, &fboID);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
|
||||||
|
|
||||||
|
// Attach the texture to FBO color attachment point
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texID, 0);
|
||||||
|
|
||||||
|
// Attach the renderbuffer to depth attachment point
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboID);
|
||||||
|
|
||||||
|
// Check FBO status
|
||||||
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
LOG("createColorBuffer failed");
|
||||||
|
|
||||||
|
// Switch back to window-system-provided framebuffer
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
return status == GL_FRAMEBUFFER_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTT::bindFramebuffer()
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTT::unbindFramebuffer()
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTT::clear(glm::vec4 color)
|
||||||
|
{
|
||||||
|
glClearColor(color.r, color.g, color.b, color.a);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTT::readTextureData(uint8_t* buffer)
|
||||||
|
{
|
||||||
|
bindTexture();
|
||||||
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
|
||||||
|
unbindTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* RTT::createBuffer()
|
||||||
|
{
|
||||||
|
return new uint8_t[w * h * 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTT::bindTexture()
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTT::unbindTexture()
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
28
engine/rtt.h
Normal file
28
engine/rtt.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class RTT
|
||||||
|
{
|
||||||
|
GLuint fboID;
|
||||||
|
GLuint rboID;
|
||||||
|
GLuint texID;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RTT();
|
||||||
|
~RTT();
|
||||||
|
|
||||||
|
void destroy();
|
||||||
|
bool create(int width, int height, int tex = -1);
|
||||||
|
void clear(glm::vec4 color = glm::vec4(0));
|
||||||
|
void readTextureData(uint8_t* buffer);
|
||||||
|
uint8_t* createBuffer();
|
||||||
|
void bindFramebuffer();
|
||||||
|
void unbindFramebuffer();
|
||||||
|
void bindTexture();
|
||||||
|
void unbindTexture();
|
||||||
|
GLuint getTextureID() { return texID; }
|
||||||
|
int getWidth() { return w; }
|
||||||
|
int getHeight() { return h; }
|
||||||
|
GLuint getFBO() { return fboID; }
|
||||||
|
};
|
||||||
@@ -120,6 +120,10 @@ void Shader::u_int(kShaderUniform id, int i)
|
|||||||
{
|
{
|
||||||
glUniform1i(m_umap[id], i);
|
glUniform1i(m_umap[id], i);
|
||||||
}
|
}
|
||||||
|
void Shader::u_float(kShaderUniform id, float f)
|
||||||
|
{
|
||||||
|
glUniform1f(m_umap[id], f);
|
||||||
|
}
|
||||||
|
|
||||||
bool ShaderManager::create(kShader id, const char* vertex, const char* fragment)
|
bool ShaderManager::create(kShader id, const char* vertex, const char* fragment)
|
||||||
{
|
{
|
||||||
@@ -157,3 +161,7 @@ void ShaderManager::u_int(kShaderUniform id, int i)
|
|||||||
{
|
{
|
||||||
m_current->u_int(id, i);
|
m_current->u_int(id, i);
|
||||||
}
|
}
|
||||||
|
void ui::ShaderManager::u_float(kShaderUniform id, float f)
|
||||||
|
{
|
||||||
|
m_current->u_float(id, f);
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ enum class kShaderUniform : uint16_t
|
|||||||
Col = const_hash("col"),
|
Col = const_hash("col"),
|
||||||
Tof = const_hash("tof"),
|
Tof = const_hash("tof"),
|
||||||
Tsz = const_hash("tsz"),
|
Tsz = const_hash("tsz"),
|
||||||
|
Alpha = const_hash("alpha"),
|
||||||
};
|
};
|
||||||
|
|
||||||
class Shader
|
class Shader
|
||||||
@@ -23,6 +24,7 @@ public:
|
|||||||
void u_vec2(kShaderUniform id, const glm::vec2& v);
|
void u_vec2(kShaderUniform id, const glm::vec2& v);
|
||||||
void u_mat4(kShaderUniform id, const glm::mat4& m);
|
void u_mat4(kShaderUniform id, const glm::mat4& m);
|
||||||
void u_int(kShaderUniform id, int i);
|
void u_int(kShaderUniform id, int i);
|
||||||
|
void u_float(kShaderUniform id, float f);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class kShader : uint16_t
|
enum class kShader : uint16_t
|
||||||
@@ -48,6 +50,7 @@ public:
|
|||||||
static void u_vec2(kShaderUniform id, const glm::vec2& v);
|
static void u_vec2(kShaderUniform id, const glm::vec2& v);
|
||||||
static void u_mat4(kShaderUniform id, const glm::mat4& m);
|
static void u_mat4(kShaderUniform id, const glm::mat4& m);
|
||||||
static void u_int(kShaderUniform id, int i);
|
static void u_int(kShaderUniform id, int i);
|
||||||
|
static void u_float(kShaderUniform id, float f);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -13,3 +13,23 @@ glm::vec4 rand_color()
|
|||||||
float b = (rand() % 256) / 256.f;
|
float b = (rand() % 256) / 256.f;
|
||||||
return { r, g, b, 1.f };
|
return { r, g, b, 1.f };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 convert_hsv2rgb(const glm::vec3 c)
|
||||||
|
{
|
||||||
|
glm::vec4 K = glm::vec4(1.0f, 2.0f / 3.0f, 1.0f / 3.0f, 3.0f);
|
||||||
|
glm::vec3 p = glm::abs(glm::fract(glm::vec3(c.xxx + K.xyz)) * 6.0f - K.www);
|
||||||
|
auto tmp = glm::clamp(glm::vec3(p - K.xxx), 0.0f, 1.0f);
|
||||||
|
return c.z * glm::mix(glm::vec3(K.xxx), tmp, c.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 convert_rgb2hsv(const glm::vec3 c)
|
||||||
|
{
|
||||||
|
glm::vec4 K = glm::vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||||
|
//glm::vec4 p = mix(glm::vec4(c.bg, K.wz), glm::vec4(c.gb, K.xy), glm::step(c.b, c.g));
|
||||||
|
//glm::vec4 q = mix(glm::vec4(p.xyw, c.r), glm::vec4(c.r, p.yzx), glm::step(p.x, c.r));
|
||||||
|
glm::vec4 p = c.g < c.b ? glm::vec4(c.bg, K.wz) : glm::vec4(c.gb, K.xy);
|
||||||
|
glm::vec4 q = c.r < p.x ? glm::vec4(p.xyw, c.r) : glm::vec4(c.r, p.yzx);
|
||||||
|
float d = q.x - glm::min(q.w, q.y);
|
||||||
|
float e = 1.0e-10f;
|
||||||
|
return glm::vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,3 +9,5 @@ uint16_t constexpr const_hash(const char* input)
|
|||||||
|
|
||||||
bool point_in_rect(const glm::vec2& point, const glm::vec4& rect);
|
bool point_in_rect(const glm::vec2& point, const glm::vec4& rect);
|
||||||
glm::vec4 rand_color();
|
glm::vec4 rand_color();
|
||||||
|
glm::vec3 convert_hsv2rgb(const glm::vec3 c);
|
||||||
|
glm::vec3 convert_rgb2hsv(const glm::vec3 c);
|
||||||
|
|||||||
Reference in New Issue
Block a user