From 964795b44d46b17c0e98280175a21cf6570fbdb6 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sat, 30 Sep 2017 16:35:12 +0100 Subject: [PATCH] add support for high res brush textures, implement mipmaps on brush --- .gitignore | 3 +++ data/brushes/Round-Brush.png | Bin 0 -> 2520 bytes data/brushes/Round-Hard.png | Bin 0 -> 1105 bytes data/brushes/Square-Hard.png | Bin 0 -> 228 bytes data/thumbs/Round-Brush.png | Bin 0 -> 2520 bytes data/thumbs/Round-Hard.png | Bin 0 -> 1105 bytes data/thumbs/Square-Hard.png | Bin 0 -> 228 bytes engine/app_layout.cpp | 6 +++--- engine/brush.cpp | 4 ++-- engine/canvas.cpp | 8 +++++--- engine/canvas.h | 1 + engine/node_panel_brush.cpp | 20 +++++++++++++++----- engine/node_panel_brush.h | 5 ++++- engine/node_stroke_preview.cpp | 8 +++++--- engine/node_stroke_preview.h | 1 + engine/texture.cpp | 21 +++++++++++++++++++-- engine/texture.h | 4 +++- 17 files changed, 61 insertions(+), 20 deletions(-) create mode 100644 data/brushes/Round-Brush.png create mode 100644 data/brushes/Round-Hard.png create mode 100644 data/brushes/Square-Hard.png create mode 100644 data/thumbs/Round-Brush.png create mode 100644 data/thumbs/Round-Hard.png create mode 100644 data/thumbs/Square-Hard.png diff --git a/.gitignore b/.gitignore index 2a7d08a..69d9247 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,6 @@ android/.gradle/ android/.externalNativeBuild/ android/src/main/assets/ +android/.idea +android/android.iml +android/local.properties diff --git a/data/brushes/Round-Brush.png b/data/brushes/Round-Brush.png new file mode 100644 index 0000000000000000000000000000000000000000..591b6fcb6391f798e1eab79b970fa4d3d0fff1b3 GIT binary patch literal 2520 zcmaJ@d0dR^9)C0K4N}Tj%4^zAX!faQYD~+t45mGls4+9us9Da;q-oklj*5FpgoG9< zb7VuKRvI&-*N&@Avy#p6?&e5f3+)rJ8Fr0RUJ^ zb)|SIX1j%H>BSQA zA_NSU0&cVricfSDu;?P5z=y{RU+khsC{M%_hVuBJqa*msPBxdxixirFgVSh4Dpx3? za~Uiug#=d!AlPgs5oM1-qnvP#IFvmajdrrMwzr~KJ2+U{J32bxaaOoRE``U4;IO!& zMK1GiF6F1(1t)O$ipUg}fPH|)bQbV9;J1p2?4Rdi|5Ls1T;|Vnarh}0sYnL7aIgP$ z&x=P2^DHcXxK^?G;d>TWVRnJS)y6&c833S4r&8>FLJxLl^q;wE4W(4T-ha*N*J%8Z z?UA;vEJr8^Zhd?3wVSYzLoE-7Z8NX``m}S^gzvH&U!qq|a_k)RKB>UQOb1qgCBlFtehaSwhRH1A~b4 zp^8&aNkG9LcN$?QTMeahHG}0-!R98v1|{XFfy05tXVB5&N&e>~wZ^ovPYfY=-6Ij8=Sls`EK%Hu!Cze!M1# zO%o4%iup1>FII1VteN9lbuoYze<^d52{lm@@b%xMl&)m_r~BA%w@goBT7@c)n^zx? z4#bSjwc!I*9(%3Fpb{e!lyM;?qWCt#g&Xw=%c1;x8bLDT_pKN`VooM8uX}qHyTDd#of}x#hRHF0dce$!iDx{KZCY1#^ zn`OO<3vS_7O{!{7orM}6YBHWPa95G4{C=90e(hdIVewv=oAlyet`3REt(Kj{>Ym7l zN*kI{P`P!$UlJD*tPAo&Z_D*!R3<+`rY&pndo*m**+3au8)Ut4;?=03bHFXQUuxZ@ z%;K?a)AzC~-b+z4%dAnxwQas8j6Nh#Vsg6h$~mzdWQXI;AtTpJ%c?u}Bmn)g(SyH~ z4L4wNbf4OE=hBO#&7dzO*|%Q@yj`C%WHdGfeJZIZ4WB8K4%wAVJ96-dz&xX44<T^m`G8o(&I+YFh%np~Y$?Yn7!o?X!csnr;nozY8dk3$ux`44+@ z+=yq6hrAB2Cj+Mb+QlQYVq3$MraML3;qLFSq03N?E>*5g#tkG{VCuOY1xZs?bC>EBOh{j$IVSj0ICn&a@5U# zgkn1Uq!e(ULR?#Ex%cw{MqoihNzq7|a-4Qz2hZZDTIb}8jYHv(`HsRX7{j{Ux!s1^ zX5i}KG!Jr1(|t49dT~&G??v-G*%*^wn9NMTY%VsgP|o@_%8G&K?)Si(m6YQm@+%jQ*p*bwj3?fQ>_z+6>yNhWch^zJ zj}3X8-mY0|v>7pYgT*&eZWzF&hcW8vB(;X#`%ej7J@7LRl&zjeyEL8xy81m;FFlO4 zTLDRvhaKkY^=f8bpKQ$26J**4F~O5>c}t*8{Vn{~jlNIjU%b$`Q={^jt_>qAM-{fN zl6@#$uA&mzHMgYjx!AiMCSXcELMFT+@yAk>$x)v)m-jXY9C>FRasBd_B|*8XGQ5h) z)VKHHc7L4>(`&R_Yxd8Mxchi137GR>@-mgmk X5N@h>T`6QMo@xNq$&FIv5R~w5{wpM_ literal 0 HcmV?d00001 diff --git a/data/brushes/Round-Hard.png b/data/brushes/Round-Hard.png new file mode 100644 index 0000000000000000000000000000000000000000..0ec829d8b58a066c543111dfef21218c807bed4a GIT binary patch literal 1105 zcmV-X1g`suP)(1-7@hVSRlarlzLC4TvGgG)-(Y8YoE;#^Z4W0AG&B<0wfIHX02y zO*4$B7$^Wu)39EzV=9&MUE0m5R0`|$I%=90WaMA~7>0q>Y85$-3%t199LHg`T1CS! zf{6Zg0L^9-bGcmT#qAbF5u42>I{?Gs5G$1m_2PE#@9*PqIHU`p*Xv=SP+(sE-GxE{ zd%YeV0PS`g^Z7jU(st+bd2F}a;Q~-q71QZ7^RjMEr_-paYB&Hooeq9o-dp{0VtQt%u9{xa=9D~07X%lm+@;wQN9LXFc@GalVM)OuQQnp z_WOPR0AyKaUgE2kW!WD9P1C4c+lOtAC>uEW*U6){c#xVX5W5{QM)&(Dc50zkXnrV@sQoVpPJ z?(grZgkd44ZUlhG$44q*Sjedx0pRuZl}Z>EdU<&v#v+LSpB|4yBGdx0kge{|njDQr zqr?~iU}k29N*EU6IF1-203;F#Dq&d2>Bl7iQ zEiF+A!$MBo2mqU#n^eNE(AL%#IXJl;wkZ~iL9tjI74F!pSS&&;79++TFNAh>c0vzC zTdtkl9*Tys&WDvpekdA^MqzJn&pX~R*Y57F<7F@aI3EFs-)myz>FLR>ru)Q5DwTqR zg9ERS$5xd}1q4BGe}gL;MC|wbKYMZ%5%Ki&lz9=qJ~=u0te&?85~Wg!d6`jNDwVuc z^9H~$3|w1VV_wRuS65d(uOuC5k<|SBJo9p&Ih)M}zews`cyEam;WfkFi@6dY8xhGSw>yggNPpdmYG_uhRI|y z@Z!m25^J^Ecy5`o%d#v~6a^(oLZ0V+m*#mMB}qa>QC#omzbayGFlc?;Hg|J#0}l@m z(Cv2N`S}?P!+`1OY2Y{x5{U%N&CS8W!oq*s<~BAqLf2BR0px`u5 z7srr_Id3mG3LY?EIJ{xaAIoxsFDqIPJkP&<_i!KI1*rwhTi9MOtYx%v$Znt$_cvp} X7RGu8t(2cY7czLd`njxgN@xNABJ)gB literal 0 HcmV?d00001 diff --git a/data/thumbs/Round-Brush.png b/data/thumbs/Round-Brush.png new file mode 100644 index 0000000000000000000000000000000000000000..591b6fcb6391f798e1eab79b970fa4d3d0fff1b3 GIT binary patch literal 2520 zcmaJ@d0dR^9)C0K4N}Tj%4^zAX!faQYD~+t45mGls4+9us9Da;q-oklj*5FpgoG9< zb7VuKRvI&-*N&@Avy#p6?&e5f3+)rJ8Fr0RUJ^ zb)|SIX1j%H>BSQA zA_NSU0&cVricfSDu;?P5z=y{RU+khsC{M%_hVuBJqa*msPBxdxixirFgVSh4Dpx3? za~Uiug#=d!AlPgs5oM1-qnvP#IFvmajdrrMwzr~KJ2+U{J32bxaaOoRE``U4;IO!& zMK1GiF6F1(1t)O$ipUg}fPH|)bQbV9;J1p2?4Rdi|5Ls1T;|Vnarh}0sYnL7aIgP$ z&x=P2^DHcXxK^?G;d>TWVRnJS)y6&c833S4r&8>FLJxLl^q;wE4W(4T-ha*N*J%8Z z?UA;vEJr8^Zhd?3wVSYzLoE-7Z8NX``m}S^gzvH&U!qq|a_k)RKB>UQOb1qgCBlFtehaSwhRH1A~b4 zp^8&aNkG9LcN$?QTMeahHG}0-!R98v1|{XFfy05tXVB5&N&e>~wZ^ovPYfY=-6Ij8=Sls`EK%Hu!Cze!M1# zO%o4%iup1>FII1VteN9lbuoYze<^d52{lm@@b%xMl&)m_r~BA%w@goBT7@c)n^zx? z4#bSjwc!I*9(%3Fpb{e!lyM;?qWCt#g&Xw=%c1;x8bLDT_pKN`VooM8uX}qHyTDd#of}x#hRHF0dce$!iDx{KZCY1#^ zn`OO<3vS_7O{!{7orM}6YBHWPa95G4{C=90e(hdIVewv=oAlyet`3REt(Kj{>Ym7l zN*kI{P`P!$UlJD*tPAo&Z_D*!R3<+`rY&pndo*m**+3au8)Ut4;?=03bHFXQUuxZ@ z%;K?a)AzC~-b+z4%dAnxwQas8j6Nh#Vsg6h$~mzdWQXI;AtTpJ%c?u}Bmn)g(SyH~ z4L4wNbf4OE=hBO#&7dzO*|%Q@yj`C%WHdGfeJZIZ4WB8K4%wAVJ96-dz&xX44<T^m`G8o(&I+YFh%np~Y$?Yn7!o?X!csnr;nozY8dk3$ux`44+@ z+=yq6hrAB2Cj+Mb+QlQYVq3$MraML3;qLFSq03N?E>*5g#tkG{VCuOY1xZs?bC>EBOh{j$IVSj0ICn&a@5U# zgkn1Uq!e(ULR?#Ex%cw{MqoihNzq7|a-4Qz2hZZDTIb}8jYHv(`HsRX7{j{Ux!s1^ zX5i}KG!Jr1(|t49dT~&G??v-G*%*^wn9NMTY%VsgP|o@_%8G&K?)Si(m6YQm@+%jQ*p*bwj3?fQ>_z+6>yNhWch^zJ zj}3X8-mY0|v>7pYgT*&eZWzF&hcW8vB(;X#`%ej7J@7LRl&zjeyEL8xy81m;FFlO4 zTLDRvhaKkY^=f8bpKQ$26J**4F~O5>c}t*8{Vn{~jlNIjU%b$`Q={^jt_>qAM-{fN zl6@#$uA&mzHMgYjx!AiMCSXcELMFT+@yAk>$x)v)m-jXY9C>FRasBd_B|*8XGQ5h) z)VKHHc7L4>(`&R_Yxd8Mxchi137GR>@-mgmk X5N@h>T`6QMo@xNq$&FIv5R~w5{wpM_ literal 0 HcmV?d00001 diff --git a/data/thumbs/Round-Hard.png b/data/thumbs/Round-Hard.png new file mode 100644 index 0000000000000000000000000000000000000000..0ec829d8b58a066c543111dfef21218c807bed4a GIT binary patch literal 1105 zcmV-X1g`suP)(1-7@hVSRlarlzLC4TvGgG)-(Y8YoE;#^Z4W0AG&B<0wfIHX02y zO*4$B7$^Wu)39EzV=9&MUE0m5R0`|$I%=90WaMA~7>0q>Y85$-3%t199LHg`T1CS! zf{6Zg0L^9-bGcmT#qAbF5u42>I{?Gs5G$1m_2PE#@9*PqIHU`p*Xv=SP+(sE-GxE{ zd%YeV0PS`g^Z7jU(st+bd2F}a;Q~-q71QZ7^RjMEr_-paYB&Hooeq9o-dp{0VtQt%u9{xa=9D~07X%lm+@;wQN9LXFc@GalVM)OuQQnp z_WOPR0AyKaUgE2kW!WD9P1C4c+lOtAC>uEW*U6){c#xVX5W5{QM)&(Dc50zkXnrV@sQoVpPJ z?(grZgkd44ZUlhG$44q*Sjedx0pRuZl}Z>EdU<&v#v+LSpB|4yBGdx0kge{|njDQr zqr?~iU}k29N*EU6IF1-203;F#Dq&d2>Bl7iQ zEiF+A!$MBo2mqU#n^eNE(AL%#IXJl;wkZ~iL9tjI74F!pSS&&;79++TFNAh>c0vzC zTdtkl9*Tys&WDvpekdA^MqzJn&pX~R*Y57F<7F@aI3EFs-)myz>FLR>ru)Q5DwTqR zg9ERS$5xd}1q4BGe}gL;MC|wbKYMZ%5%Ki&lz9=qJ~=u0te&?85~Wg!d6`jNDwVuc z^9H~$3|w1VV_wRuS65d(uOuC5k<|SBJo9p&Ih)M}zews`cyEam;WfkFi@6dY8xhGSw>yggNPpdmYG_uhRI|y z@Z!m25^J^Ecy5`o%d#v~6a^(oLZ0V+m*#mMB}qa>QC#omzbayGFlc?;Hg|J#0}l@m z(Cv2N`S}?P!+`1OY2Y{x5{U%N&CS8W!oq*s<~BAqLf2BR0px`u5 z7srr_Id3mG3LY?EIJ{xaAIoxsFDqIPJkP&<_i!KI1*rwhTi9MOtYx%v$Znt$_cvp} X7RGu8t(2cY7czLd`njxgN@xNABJ)gB literal 0 HcmV?d00001 diff --git a/engine/app_layout.cpp b/engine/app_layout.cpp index 1534e65..da4229e 100644 --- a/engine/app_layout.cpp +++ b/engine/app_layout.cpp @@ -129,8 +129,8 @@ void App::init_sidebar() } brushes->on_brush_changed = [this](Node* target, int index) { - auto tid = brushes->get_texture_id(index); - stroke->m_canvas->m_brush.m_tex_id = tid; + stroke->m_canvas->m_brush.m_tex_id = brushes->get_texture_id(index); + stroke->m_canvas->m_brush.id = brushes->get_brush_id(index); stroke->m_canvas->draw_stroke(); canvas->m_brush = stroke->m_canvas->m_brush; if (on_brush_select) @@ -375,7 +375,7 @@ void App::init_menu_edit() void App::brush_update() { - brushes->set_texture_id(canvas->m_brush.m_tex_id); + brushes->select_brush(canvas->m_brush.id); stroke->set_params(canvas->m_brush); } diff --git a/engine/brush.cpp b/engine/brush.cpp index b3d1cc5..aaaad8b 100644 --- a/engine/brush.cpp +++ b/engine/brush.cpp @@ -226,7 +226,7 @@ void ui::Stroke::add_point(glm::vec2 pos, float pressure) pressure = pressure * glm::pow(m_curve, 2.f); if (m_brush.m_tip_size_pressure) - m_step = glm::max(m_brush.m_tip_spacing * m_brush.m_tip_size * 100 * pressure, 1.f); + m_step = glm::max(glm::pow(m_brush.m_tip_spacing * 4.f, 2.f) * glm::pow(m_brush.m_tip_size, 3.f) * 800.f * pressure, 1.f); float dist = m_keypoints.empty() ? 0.f : m_keypoints.back().dist + glm::distance(m_keypoints.back().pos, pos); @@ -244,7 +244,7 @@ void ui::Stroke::start(const ui::Brush& brush) m_curve_angles.clear(); m_last_kp = 0; m_dist = 0.f; - m_step = glm::max(brush.m_tip_spacing * brush.m_tip_size * 100, 1.f); m_brush = brush; + m_step = glm::max(glm::pow(m_brush.m_tip_spacing * 4.f, 2.f) * glm::pow(m_brush.m_tip_size, 3.f) * 800.f, 1.f); prng.seed(0); } diff --git a/engine/canvas.cpp b/engine/canvas.cpp index c0428c0..54a2333 100644 --- a/engine/canvas.cpp +++ b/engine/canvas.cpp @@ -196,7 +196,7 @@ void ui::Canvas::stroke_draw() auto samples = m_current_stroke->compute_samples(); auto& tex = TextureManager::get(m_brush.m_tex_id); tex.bind(); - m_sampler.bind(0); + m_sampler_brush.bind(0); m_sampler_bg.bind(1); m_sampler_mask.bind(2); @@ -233,7 +233,7 @@ void ui::Canvas::stroke_draw() ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height }); for (const auto& s : samples) { - glm::vec2 dx(s.size, 0), dy(0, s.size); + glm::vec2 dx(s.size * 0.5f, 0), dy(0, s.size * 0.5f); glm::vec2 off[4] = { - dx - dy, // A - bottom-left - dx + dy, // B - top-left @@ -317,7 +317,7 @@ void ui::Canvas::stroke_draw() glDisable(GL_BLEND); glActiveTexture(GL_TEXTURE0); - m_sampler.unbind(); + m_sampler_brush.unbind(); m_sampler_bg.unbind(); m_sampler_mask.unbind(); tex.unbind(); @@ -695,6 +695,8 @@ bool ui::Canvas::create(int width, int height) m_tex2[i].create(width, height); // TODO: destroy before recreating } m_sampler.create(GL_NEAREST); + m_sampler_brush.create(); + m_sampler_brush.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR); m_sampler_bg.create(GL_NEAREST); m_sampler_mask.create(GL_NEAREST); m_plane.create<1>(1, 1); diff --git a/engine/canvas.h b/engine/canvas.h index 3d2dc61..82f4e4e 100644 --- a/engine/canvas.h +++ b/engine/canvas.h @@ -74,6 +74,7 @@ public: static glm::vec3 m_plane_tangent[6]; static glm::mat4 m_plane_transform[6]; Sampler m_sampler; + Sampler m_sampler_brush; Sampler m_sampler_bg; Sampler m_sampler_mask; glm::vec2 m_cam_rot; diff --git a/engine/node_panel_brush.cpp b/engine/node_panel_brush.cpp index e68ce5c..86b48b0 100644 --- a/engine/node_panel_brush.cpp +++ b/engine/node_panel_brush.cpp @@ -2,6 +2,7 @@ #include "log.h" #include "node_panel_brush.h" #include "asset.h" +#include "texture.h" #ifdef __APPLE__ #include @@ -44,14 +45,15 @@ void NodePanelBrush::init() { init_template("tpl-panel-brushes"); //m_layers_container = find("layers-container"); - static auto icons = Asset::list_files("data/Icons", true, ".*\\.png$"); + static auto icons = Asset::list_files("data/thumbs", true, ".*\\.png$"); if ((m_container = find("brushes"))) { int count = 0; for (auto& i : icons) { - std::string path = "data/Icons/" + i; + std::string path = "data/thumbs/" + i; + std::string path_hi = "data/brushes/" + i; NodeButtonBrush* brush = new NodeButtonBrush; m_container->add_child(brush); brush->init(); @@ -59,6 +61,8 @@ void NodePanelBrush::init() brush->loaded(); brush->set_icon(path.c_str()); brush->m_brushID = count++; + brush->high_path = path_hi; + brush->high_id = const_hash(path_hi.c_str()); m_brushes.push_back(brush); brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1); } @@ -79,17 +83,23 @@ void NodePanelBrush::handle_click(Node* target) uint16_t NodePanelBrush::get_texture_id(int index) const { - return m_brushes[index]->img->m_tex_id; + TextureManager::load(m_brushes[index]->high_path.c_str(), true); + return m_brushes[index]->high_id; +} + +int NodePanelBrush::get_brush_id(int index) const +{ + return m_brushes[index]->m_brushID; } // select the current brush based on the texture id -void NodePanelBrush::set_texture_id(int texid) +void NodePanelBrush::select_brush(int brush_id) { if (m_current) m_current->m_selected = false; for (auto b : m_brushes) { - if (b->img->m_tex_id == texid) + if (b->m_brushID == brush_id) { b->m_selected = true; m_current = b; diff --git a/engine/node_panel_brush.h b/engine/node_panel_brush.h index 3d154ac..a766615 100644 --- a/engine/node_panel_brush.h +++ b/engine/node_panel_brush.h @@ -8,6 +8,8 @@ class NodeButtonBrush : public NodeButtonCustom public: int m_brushID; bool m_selected = false; + std::string high_path; + uint16_t high_id; NodeImage* img; virtual Node* clone_instantiate() const override; virtual void init() override; @@ -27,5 +29,6 @@ public: void handle_click(Node* target); std::vector FindAllBrushes(const std::string& folder); uint16_t get_texture_id(int index) const; - void set_texture_id(int texid); + int get_brush_id(int index) const; + void select_brush(int brush_id); }; diff --git a/engine/node_stroke_preview.cpp b/engine/node_stroke_preview.cpp index ca0d1b3..234c409 100644 --- a/engine/node_stroke_preview.cpp +++ b/engine/node_stroke_preview.cpp @@ -30,6 +30,7 @@ void NodeStrokePreview::init_controls() { m_mesh.create(); m_sampler.create(); + m_sampler_brush.create(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR); TextureManager::load("data/Icons/Round-Hard.png"); m_brush.m_tex_id = const_hash("data/Icons/Round-Hard.png"); } @@ -66,7 +67,7 @@ void NodeStrokePreview::draw_stroke() glm::mat4 proj = glm::ortho(0, (float)m_rtt.getWidth(), 0, (float)m_rtt.getHeight(), -1, 1); auto b = m_brush; - b.m_tip_size *= .7f; // reduce the size in the preview + //b.m_tip_size *= .7f; // reduce the size in the preview m_stroke.reset(); m_stroke.start(b); if (!m_stroke.m_keypoints.empty()) @@ -74,7 +75,7 @@ void NodeStrokePreview::draw_stroke() auto samples = m_stroke.compute_samples(); auto& tex = TextureManager::get(m_brush.m_tex_id); tex.bind(); - m_sampler.bind(0); + m_sampler_brush.bind(0); if (true) { @@ -100,7 +101,7 @@ void NodeStrokePreview::draw_stroke() // } //} - m_sampler.unbind(); + m_sampler_brush.unbind(); tex.unbind(); glDisable(GL_BLEND); @@ -126,6 +127,7 @@ void NodeStrokePreview::draw() void NodeStrokePreview::handle_resize(glm::vec2 old_size, glm::vec2 new_size) { float pad = 30.f; + new_size *= root()->m_zoom; float w = new_size.x; float h = new_size.y; std::vector kp = { { pad, pad },{ pad, h - pad },{ w - pad, pad },{ w - pad, h - pad } }; diff --git a/engine/node_stroke_preview.h b/engine/node_stroke_preview.h index 7a1d625..4feba46 100644 --- a/engine/node_stroke_preview.h +++ b/engine/node_stroke_preview.h @@ -8,6 +8,7 @@ class NodeStrokePreview : public NodeBorder { RTT m_rtt; Sampler m_sampler; + Sampler m_sampler_brush; ui::BrushMesh m_mesh; public: ui::Brush m_brush; diff --git a/engine/texture.cpp b/engine/texture.cpp index bd9c5be..2aca1a7 100644 --- a/engine/texture.cpp +++ b/engine/texture.cpp @@ -5,12 +5,15 @@ std::map TextureManager::m_textures; -bool TextureManager::load(const char* path) +bool TextureManager::load(const char* path, bool generate_mipmaps) { uint16_t id = const_hash(path); if (m_textures.count(id) == 0 || !m_textures[id].ready()) { - return m_textures[id].load(path); + if (!m_textures[id].load(path)) + return false; + if (generate_mipmaps) + m_textures[id].create_mipmaps(); } return true; } @@ -54,6 +57,13 @@ bool Texture2D::create(const ui::Image& img) return create(img.width, img.height, iformats[img.comp - 1], formats[img.comp - 1], img.data()); } +void Texture2D::create_mipmaps() +{ + bind(); + glGenerateMipmap(GL_TEXTURE_2D); + unbind(); +} + void Texture2D::assign(GLuint tex, int w/* = -1*/, int h/* = -1*/, GLuint internal_format/* = GL_RGBA8*/, GLuint format/* = GL_RGBA*/) { m_tex = tex; @@ -102,6 +112,13 @@ void Sampler::set(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE* glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, filter); #endif // USE_SAMPLER } +void Sampler::set_filter(GLint filter_min, GLint filter_mag) +{ +#if USE_SAMPLER + glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, filter_min); + glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, filter_mag); +#endif // USE_SAMPLER +} void Sampler::bind(int unit) { current_unit = unit; diff --git a/engine/texture.h b/engine/texture.h index 880fe26..74ee20d 100644 --- a/engine/texture.h +++ b/engine/texture.h @@ -18,6 +18,7 @@ public: void unbind() const { glBindTexture(GL_TEXTURE_2D, 0); } void update(const uint8_t* data); bool ready() const { return m_tex != 0; } + void create_mipmaps(); glm::vec2 size() const; }; @@ -28,6 +29,7 @@ class Sampler 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 set_filter(GLint filter_min, GLint filter_mag); void bind(int unit); void unbind(); bool ready() const { return id != 0; } @@ -37,7 +39,7 @@ class TextureManager { public: static std::map m_textures; - static bool load(const char* path); + static bool load(const char* path, bool generate_mipmpas = false); static void assign(uint16_t id, GLuint tex, int w = -1, int h = -1, GLuint internal_format = GL_RGBA8, GLuint format = GL_RGBA); static Texture2D& get(uint16_t id); static void invalidate();