diff --git a/examples/16-shadowmaps/shadowmaps.cpp b/examples/16-shadowmaps/shadowmaps.cpp index be94a9da8..6f0813ca8 100644 --- a/examples/16-shadowmaps/shadowmaps.cpp +++ b/examples/16-shadowmaps/shadowmaps.cpp @@ -206,14 +206,6 @@ void imguiEnum(LightType::Enum& _enum) ); } -void imguiBool(const char* _str, bool& _flag, bool _enabled = true) -{ - if (imguiCheck(_str, _flag, _enabled) ) - { - _flag = !_flag; - } -} - struct PosNormalTexcoordVertex { float m_x; diff --git a/examples/18-ibl/ibl.cpp b/examples/18-ibl/ibl.cpp index fdd80e7c1..71ab49f9e 100644 --- a/examples/18-ibl/ibl.cpp +++ b/examples/18-ibl/ibl.cpp @@ -382,29 +382,6 @@ void screenSpaceQuad(float _textureWidth, float _textureHeight, bool _originBott } } -void imguiBool(const char* _str, bool& _flag, bool _enabled = true) -{ - if (imguiCheck(_str, _flag, _enabled) ) - { - _flag = !_flag; - } -} - -void imguiColorWheel(const char* _str, float _color[3], bool* _activated, bool _enabled = true) -{ - char buf[128]; - bx::snprintf(buf, 127, "%s [RGB %-2.2f %-2.2f %-2.2f]", _str, _color[0], _color[1], _color[2]); - if (imguiButton(buf, true)) - { - *_activated = !*_activated; - } - - if (*_activated) - { - imguiColorWheel(_color, false, _enabled); - } -} - int _main_(int /*_argc*/, char** /*_argv*/) { uint32_t width = 1280; @@ -595,9 +572,9 @@ int _main_(int /*_argc*/, char** /*_argv*/) imguiSlider("Glossiness" , &settings.m_glossiness, 0.0f, 1.0f, 0.01f); imguiSeparator(); - imguiColorWheel("Diffuse color:", &settings.m_rgbDiff[0], &settings.m_showDiffColorWheel); + imguiColorWheel("Diffuse color:", &settings.m_rgbDiff[0], settings.m_showDiffColorWheel); imguiSeparator(); - imguiColorWheel("Specular color:", &settings.m_rgbSpec[0], &settings.m_showSpecColorWheel); + imguiColorWheel("Specular color:", &settings.m_rgbSpec[0], settings.m_showSpecColorWheel); imguiSeparator(); imguiLabel("Predefined materials:"); diff --git a/examples/common/imgui/imgui.cpp b/examples/common/imgui/imgui.cpp index 99a334b38..82416909e 100644 --- a/examples/common/imgui/imgui.cpp +++ b/examples/common/imgui/imgui.cpp @@ -70,49 +70,213 @@ static void imguiFree(void* _ptr, void* /*_userptr*/) namespace { - -struct PosColorVertex -{ - float m_x; - float m_y; - uint32_t m_abgr; - - static void init() + float sign(float px, float py, float ax, float ay, float bx, float by) { - ms_decl - .begin() - .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) - .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) - .end(); + return (px - bx) * (ay - by) - (ax - bx) * (py - by); } - static bgfx::VertexDecl ms_decl; -}; - -bgfx::VertexDecl PosColorVertex::ms_decl; - -struct PosColorUvVertex -{ - float m_x; - float m_y; - float m_u; - float m_v; - uint32_t m_abgr; - - static void init() + bool pointInTriangle(float px, float py, float ax, float ay, float bx, float by, float cx, float cy) { - ms_decl - .begin() - .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) - .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float) - .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) - .end(); + const bool b1 = sign(px, py, ax, ay, bx, by) < 0.0f; + const bool b2 = sign(px, py, bx, by, cx, cy) < 0.0f; + const bool b3 = sign(px, py, cx, cy, ax, ay) < 0.0f; + + return ((b1 == b2) && (b2 == b3)); } - static bgfx::VertexDecl ms_decl; -}; + void closestPointOnLine(float& ox, float &oy, float px, float py, float ax, float ay, float bx, float by) + { + float dx = px - ax; + float dy = py - ay; -bgfx::VertexDecl PosColorUvVertex::ms_decl; + float lx = bx - ax; + float ly = by - ay; + + float len = sqrtf(lx*lx+ly*ly); + + // Normalize. + float invLen = 1.0f/len; + lx*=invLen; + ly*=invLen; + + float dot = (dx*lx + dy*ly); + + if (dot < 0.0f) + { + ox = ax; + oy = ay; + } + else if (dot > len) + { + ox = bx; + oy = by; + } + else + { + ox = ax + lx*dot; + oy = ay + ly*dot; + } + } + + void closestPointOnTriangle(float& ox, float &oy, float px, float py, float ax, float ay, float bx, float by, float cx, float cy) + { + float abx, aby; + float bcx, bcy; + float cax, cay; + closestPointOnLine(abx, aby, px, py, ax, ay, bx, by); + closestPointOnLine(bcx, bcy, px, py, bx, by, cx, cy); + closestPointOnLine(cax, cay, px, py, cx, cy, ax, ay); + + const float pabx = px - abx; + const float paby = py - aby; + const float pbcx = px - bcx; + const float pbcy = py - bcy; + const float pcax = px - cax; + const float pcay = py - cay; + + const float lab = sqrtf(pabx*pabx+paby*paby); + const float lbc = sqrtf(pbcx*pbcx+pbcy*pbcy); + const float lca = sqrtf(pcax*pcax+pcay*pcay); + + const float m = bx::fmin3(lab, lbc, lca); + if (m == lab) + { + ox = abx; + oy = aby; + } + else if (m == lbc) + { + ox = bcx; + oy = bcy; + } + else// if (m == lca). + { + ox = cax; + oy = cay; + } + } + + /// Reference: http://codeitdown.com/hsl-hsb-hsv-color/ + void rgbToHsv(float _hsv[3], const float _rgb[3]) + { + const float min = bx::fmin3(_rgb[0], _rgb[1], _rgb[2]); + const float max = bx::fmax3(_rgb[0], _rgb[1], _rgb[2]); + const float delta = max - min; + + if (0.0f == delta) + { + _hsv[0] = 0.0f; // Achromatic. + } + else + { + if (max == _rgb[0]) + { + _hsv[0] = (_rgb[1]-_rgb[2])/delta + (_rgb[1]<_rgb[2]?6.0f:0.0f); // Between yellow and magenta. + } + else if(max == _rgb[1]) + { + _hsv[0] = (_rgb[2]-_rgb[0])/delta + 2.0f; // Between cyan and yellow. + } + else //if(max == _rgb[2]). + { + _hsv[0] = (_rgb[0]-_rgb[1])/delta + 4.0f; // Between magenta and cyan. + } + + _hsv[0] /= 6.0f; + } + _hsv[1] = max == 0.0f ? 0.0f : delta/max; + _hsv[2] = max; + } + + /// Reference: http://codeitdown.com/hsl-hsb-hsv-color/ + void hsvToRgb(float _rgb[3], const float _hsv[3]) + { + const int32_t ii = int32_t(_hsv[0]*6.0f); + const float ff = _hsv[0]*6.0f - float(ii); + const float vv = _hsv[2]; + const float pp = vv * (1.0f - _hsv[1]); + const float qq = vv * (1.0f - _hsv[1]*ff); + const float tt = vv * (1.0f - _hsv[1]*(1.0f-ff)); + + switch (ii) + { + case 0: _rgb[0] = vv; _rgb[1] = tt; _rgb[2] = pp; break; + case 1: _rgb[0] = qq; _rgb[1] = vv; _rgb[2] = pp; break; + case 2: _rgb[0] = pp; _rgb[1] = vv; _rgb[2] = tt; break; + case 3: _rgb[0] = pp; _rgb[1] = qq; _rgb[2] = vv; break; + case 4: _rgb[0] = tt; _rgb[1] = pp; _rgb[2] = vv; break; + case 5: _rgb[0] = vv; _rgb[1] = pp; _rgb[2] = qq; break; + } + } + + inline float vec2Dot(const float* __restrict _a, const float* __restrict _b) + { + return _a[0]*_b[0] + _a[1]*_b[1]; + } + + void barycentric(float& _u, float& _v, float& _w + , float _ax, float _ay + , float _bx, float _by + , float _cx, float _cy + , float _px, float _py + ) + { + const float v0[2] = { _bx - _ax, _by - _ay }; + const float v1[2] = { _cx - _ax, _cy - _ay }; + const float v2[2] = { _px - _ax, _py - _ay }; + const float d00 = vec2Dot(v0, v0); + const float d01 = vec2Dot(v0, v1); + const float d11 = vec2Dot(v1, v1); + const float d20 = vec2Dot(v2, v0); + const float d21 = vec2Dot(v2, v1); + const float denom = d00 * d11 - d01 * d01; + _v = (d11 * d20 - d01 * d21) / denom; + _w = (d00 * d21 - d01 * d20) / denom; + _u = 1.0f - _v - _w; + } + + struct PosColorVertex + { + float m_x; + float m_y; + uint32_t m_abgr; + + static void init() + { + ms_decl + .begin() + .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) + .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) + .end(); + } + + static bgfx::VertexDecl ms_decl; + }; + + bgfx::VertexDecl PosColorVertex::ms_decl; + + struct PosColorUvVertex + { + float m_x; + float m_y; + float m_u; + float m_v; + uint32_t m_abgr; + + static void init() + { + ms_decl + .begin() + .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) + .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float) + .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) + .end(); + } + + static bgfx::VertexDecl ms_decl; + }; + + bgfx::VertexDecl PosColorUvVertex::ms_decl; } // namespace @@ -1394,187 +1558,8 @@ struct Imgui } } - /// Assumes _min < _max. - inline float clampf(float _val, float _min, float _max) - { - return ( _val > _max ? _max - : _val < _min ? _min - : _val - ); - } - - float sign(float px, float py, float ax, float ay, float bx, float by) - { - return (px - bx) * (ay - by) - (ax - bx) * (py - by); - } - - bool pointInTriangle(float px, float py, float ax, float ay, float bx, float by, float cx, float cy) - { - const bool b1 = sign(px, py, ax, ay, bx, by) < 0.0f; - const bool b2 = sign(px, py, bx, by, cx, cy) < 0.0f; - const bool b3 = sign(px, py, cx, cy, ax, ay) < 0.0f; - - return ((b1 == b2) && (b2 == b3)); - } - - void closestPointOnLine(float& ox, float &oy, float px, float py, float ax, float ay, float bx, float by) - { - float dx = px - ax; - float dy = py - ay; - - float lx = bx - ax; - float ly = by - ay; - - float len = sqrtf(lx*lx+ly*ly); - - // Normalize. - float invLen = 1.0f/len; - lx*=invLen; - ly*=invLen; - - float dot = (dx*lx + dy*ly); - - if (dot < 0.0f) - { - ox = ax; - oy = ay; - } - else if (dot > len) - { - ox = bx; - oy = by; - } - else - { - ox = ax + lx*dot; - oy = ay + ly*dot; - } - } - - void closestPointOnTriangle(float& ox, float &oy, float px, float py, float ax, float ay, float bx, float by, float cx, float cy) - { - float abx, aby; - float bcx, bcy; - float cax, cay; - closestPointOnLine(abx, aby, px, py, ax, ay, bx, by); - closestPointOnLine(bcx, bcy, px, py, bx, by, cx, cy); - closestPointOnLine(cax, cay, px, py, cx, cy, ax, ay); - - const float pabx = px - abx; - const float paby = py - aby; - const float pbcx = px - bcx; - const float pbcy = py - bcy; - const float pcax = px - cax; - const float pcay = py - cay; - - const float lab = sqrtf(pabx*pabx+paby*paby); - const float lbc = sqrtf(pbcx*pbcx+pbcy*pbcy); - const float lca = sqrtf(pcax*pcax+pcay*pcay); - - const float m = bx::fmin(lab, bx::fmin(lbc, lca)); - if (m == lab) - { - ox = abx; - oy = aby; - } - else if (m == lbc) - { - ox = bcx; - oy = bcy; - } - else// if (m == lca). - { - ox = cax; - oy = cay; - } - } - - /// Reference: http://codeitdown.com/hsl-hsb-hsv-color/ - void rgbToHsv(float _hsv[3], const float _rgb[3]) - { - const float min = bx::fmin(_rgb[0], bx::fmin(_rgb[1], _rgb[2])); - const float max = bx::fmax(_rgb[0], bx::fmax(_rgb[1], _rgb[2])); - const float delta = max - min; - - if (0.0f == delta) - { - _hsv[0] = 0.0f; // Achromatic. - } - else - { - if (max == _rgb[0]) - { - _hsv[0] = (_rgb[1]-_rgb[2])/delta + (_rgb[1]<_rgb[2]?6.0f:0.0f); // Between yellow and magenta. - } - else if(max == _rgb[1]) - { - _hsv[0] = (_rgb[2]-_rgb[0])/delta + 2.0f; // Between cyan and yellow. - } - else //if(max == _rgb[2]). - { - _hsv[0] = (_rgb[0]-_rgb[1])/delta + 4.0f; // Between magenta and cyan. - } - - _hsv[0] /= 6.0f; - } - _hsv[1] = max == 0.0f ? 0.0f : delta/max; - _hsv[2] = max; - } - - /// Reference: http://codeitdown.com/hsl-hsb-hsv-color/ - void hsvToRgb(float _rgb[3], const float _hsv[3]) - { - const int32_t ii = int32_t(_hsv[0]*6.0f); - const float ff = _hsv[0]*6.0f - float(ii); - const float vv = _hsv[2]; - const float pp = vv * (1.0f - _hsv[1]); - const float qq = vv * (1.0f - _hsv[1]*ff); - const float tt = vv * (1.0f - _hsv[1]*(1.0f-ff)); - - switch (ii) - { - case 0: _rgb[0] = vv; _rgb[1] = tt; _rgb[2] = pp; break; - case 1: _rgb[0] = qq; _rgb[1] = vv; _rgb[2] = pp; break; - case 2: _rgb[0] = pp; _rgb[1] = vv; _rgb[2] = tt; break; - case 3: _rgb[0] = pp; _rgb[1] = qq; _rgb[2] = vv; break; - case 4: _rgb[0] = tt; _rgb[1] = pp; _rgb[2] = vv; break; - case 5: _rgb[0] = vv; _rgb[1] = pp; _rgb[2] = qq; break; - } - } - - inline float vec2Dot(const float* __restrict _a, const float* __restrict _b) - { - return _a[0]*_b[0] + _a[1]*_b[1]; - } - - void barycentric(float& _u, float& _v, float& _w - , float _ax, float _ay - , float _bx, float _by - , float _cx, float _cy - , float _px, float _py - ) - { - const float v0[2] = { _bx - _ax, _by - _ay }; - const float v1[2] = { _cx - _ax, _cy - _ay }; - const float v2[2] = { _px - _ax, _py - _ay }; - const float d00 = vec2Dot(v0, v0); - const float d01 = vec2Dot(v0, v1); - const float d11 = vec2Dot(v1, v1); - const float d20 = vec2Dot(v2, v0); - const float d21 = vec2Dot(v2, v1); - const float denom = d00 * d11 - d01 * d01; - _v = (d11 * d20 - d01 * d21) / denom; - _w = (d00 * d21 - d01 * d20) / denom; - _u = 1.0f - _v - _w; - } - void colorWheelWidget(float _color[3], bool _respectIndentation, bool _enabled) { - if (NULL == m_nvg) - { - return; - } - m_widgetId++; const uint32_t wheelId = (m_areaId << 16) | m_widgetId; m_widgetId++; @@ -1635,7 +1620,8 @@ struct Imgui } // Set hue. - if (m_left && isActive(wheelId)) + if (m_left + && isActive(wheelId)) { hsv[0] = atan2f(cmy, cmx)/NVG_PI*0.5f; if (hsv[0] < 0.0f) @@ -1646,7 +1632,9 @@ struct Imgui } - if (_enabled && m_left && isActive(triangleId)) + if (_enabled + && m_left + && isActive(triangleId)) { float an = -hsv[0]*NVG_PI*2.0f; float tmx = (cmx*cosf(an)-cmy*sinf(an)); @@ -1692,111 +1680,112 @@ struct Imgui float uu, vv, ww; barycentric(uu, vv, ww - , aa[0], aa[1] - , bb[0], bb[1] - , cc[0], cc[1] + , aa[0], aa[1] + , bb[0], bb[1] + , cc[0], cc[1] , sel[0], sel[1] ); - const float val = clampf(1.0f-vv, 0.0001f, 1.0f); - const float sat = clampf(uu/val, 0.0001f, 1.0f); + const float val = bx::fclamp(1.0f-vv, 0.0001f, 1.0f); + const float sat = bx::fclamp(uu/val, 0.0001f, 1.0f); const float out[3] = { hsv[0], sat, val }; hsvToRgb(_color, out); // Draw widget. nvgSave(m_nvg); - const float drawSaturation = _enabled ? 1.0f : 0.0f; - - // Circle. - for (uint8_t ii = 0; ii < 6; ii++) { - const float a0 = float(ii)/6.0f * 2.0f*NVG_PI - aeps; - const float a1 = float(ii+1.0f)/6.0f * 2.0f*NVG_PI + aeps; + const float drawSaturation = _enabled ? 1.0f : 0.0f; + + // Circle. + for (uint8_t ii = 0; ii < 6; ii++) + { + const float a0 = float(ii)/6.0f * 2.0f*NVG_PI - aeps; + const float a1 = float(ii+1.0f)/6.0f * 2.0f*NVG_PI + aeps; + nvgBeginPath(m_nvg); + nvgArc(m_nvg, center[0], center[1], ri, a0, a1, NVG_CW); + nvgArc(m_nvg, center[0], center[1], ro, a1, a0, NVG_CCW); + nvgClosePath(m_nvg); + + const float ax = center[0] + cosf(a0) * (ri+ro)*0.5f; + const float ay = center[1] + sinf(a0) * (ri+ro)*0.5f; + const float bx = center[0] + cosf(a1) * (ri+ro)*0.5f; + const float by = center[1] + sinf(a1) * (ri+ro)*0.5f; + NVGpaint paint = nvgLinearGradient(m_nvg + , ax, ay + , bx, by + , nvgHSLA(a0/NVG_PI*0.5f,drawSaturation,0.55f,255) + , nvgHSLA(a1/NVG_PI*0.5f,drawSaturation,0.55f,255) + ); + + nvgFillPaint(m_nvg, paint); + nvgFill(m_nvg); + } + + // Circle stroke. nvgBeginPath(m_nvg); - nvgArc(m_nvg, center[0], center[1], ri, a0, a1, NVG_CW); - nvgArc(m_nvg, center[0], center[1], ro, a1, a0, NVG_CCW); - nvgClosePath(m_nvg); - - const float ax = center[0] + cosf(a0) * (ri+ro)*0.5f; - const float ay = center[1] + sinf(a0) * (ri+ro)*0.5f; - const float bx = center[0] + cosf(a1) * (ri+ro)*0.5f; - const float by = center[1] + sinf(a1) * (ri+ro)*0.5f; - NVGpaint paint = nvgLinearGradient(m_nvg - , ax, ay - , bx, by - , nvgHSLA(a0/NVG_PI*0.5f,drawSaturation,0.55f,255) - , nvgHSLA(a1/NVG_PI*0.5f,drawSaturation,0.55f,255) - ); - - nvgFillPaint(m_nvg, paint); - nvgFill(m_nvg); - } - - // Circle stroke. - nvgBeginPath(m_nvg); - nvgCircle(m_nvg, center[0], center[1], ri-0.5f); - nvgCircle(m_nvg, center[0], center[1], ro+0.5f); - nvgStrokeColor(m_nvg, nvgRGBA(0,0,0,64)); - nvgStrokeWidth(m_nvg, 1.0f); - nvgStroke(m_nvg); - - nvgSave(m_nvg); - { - // Hue selector. - nvgTranslate(m_nvg, center[0], center[1]); - nvgRotate(m_nvg, hsv[0]*NVG_PI*2.0f); - nvgStrokeWidth(m_nvg, 2.0f); - nvgBeginPath(m_nvg); - nvgRect(m_nvg, ri-1.0f,-3.0f,rd+2.0f,6.0f); - nvgStrokeColor(m_nvg, nvgRGBA(255,255,255,192)); - nvgStroke(m_nvg); - - // Hue selector drop shadow. - NVGpaint paint = nvgBoxGradient(m_nvg, ri-3.0f,-5.0f,ro-ri+6.0f,10.0f, 2.0f,4.0f, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); - nvgBeginPath(m_nvg); - nvgRect(m_nvg, ri-2.0f-10.0f,-4.0f-10.0f,ro-ri+4.0f+20.0f,8.0f+20.0f); - nvgRect(m_nvg, ri-2.0f,-4.0f,ro-ri+4.0f,8.0f); - nvgPathWinding(m_nvg, NVG_HOLE); - nvgFillPaint(m_nvg, paint); - nvgFill(m_nvg); - - // Center triangle stroke. - nvgBeginPath(m_nvg); - nvgMoveTo(m_nvg, aa[0], aa[1]); - nvgLineTo(m_nvg, bb[0], bb[1]); - nvgLineTo(m_nvg, cc[0], cc[1]); - nvgClosePath(m_nvg); + nvgCircle(m_nvg, center[0], center[1], ri-0.5f); + nvgCircle(m_nvg, center[0], center[1], ro+0.5f); nvgStrokeColor(m_nvg, nvgRGBA(0,0,0,64)); + nvgStrokeWidth(m_nvg, 1.0f); nvgStroke(m_nvg); - // Center triangle fill. - paint = nvgLinearGradient(m_nvg, aa[0], aa[1], bb[0], bb[1], nvgHSL(hsv[0],drawSaturation,0.5f), nvgRGBA(0,0,0,255)); - nvgFillPaint(m_nvg, paint); - nvgFill(m_nvg); - paint = nvgLinearGradient(m_nvg, (aa[0]+bb[0])*0.5f, (aa[1]+bb[1])*0.5f, cc[0], cc[1], nvgRGBA(0,0,0,0), nvgRGBA(255,255,255,255)); - nvgFillPaint(m_nvg, paint); - nvgFill(m_nvg); + nvgSave(m_nvg); + { + // Hue selector. + nvgTranslate(m_nvg, center[0], center[1]); + nvgRotate(m_nvg, hsv[0]*NVG_PI*2.0f); + nvgStrokeWidth(m_nvg, 2.0f); + nvgBeginPath(m_nvg); + nvgRect(m_nvg, ri-1.0f,-3.0f,rd+2.0f,6.0f); + nvgStrokeColor(m_nvg, nvgRGBA(255,255,255,192)); + nvgStroke(m_nvg); - // Color selector. - nvgStrokeWidth(m_nvg, 2.0f); - nvgBeginPath(m_nvg); - nvgCircle(m_nvg, sel[0], sel[1], 5); - nvgStrokeColor(m_nvg, nvgRGBA(255,255,255,192)); - nvgStroke(m_nvg); + // Hue selector drop shadow. + NVGpaint paint = nvgBoxGradient(m_nvg, ri-3.0f,-5.0f,ro-ri+6.0f,10.0f, 2.0f,4.0f, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); + nvgBeginPath(m_nvg); + nvgRect(m_nvg, ri-2.0f-10.0f,-4.0f-10.0f,ro-ri+4.0f+20.0f,8.0f+20.0f); + nvgRect(m_nvg, ri-2.0f,-4.0f,ro-ri+4.0f,8.0f); + nvgPathWinding(m_nvg, NVG_HOLE); + nvgFillPaint(m_nvg, paint); + nvgFill(m_nvg); - // Color selector stroke. - paint = nvgRadialGradient(m_nvg, sel[0], sel[1], 7.0f, 9.0f, nvgRGBA(0,0,0,64), nvgRGBA(0,0,0,0)); - nvgBeginPath(m_nvg); - nvgRect(m_nvg, sel[0]-20.0f, sel[1]-20.0f, 40.0f, 40.0f); - nvgCircle(m_nvg, sel[0], sel[1], 7.0f); - nvgPathWinding(m_nvg, NVG_HOLE); - nvgFillPaint(m_nvg, paint); - nvgFill(m_nvg); + // Center triangle stroke. + nvgBeginPath(m_nvg); + nvgMoveTo(m_nvg, aa[0], aa[1]); + nvgLineTo(m_nvg, bb[0], bb[1]); + nvgLineTo(m_nvg, cc[0], cc[1]); + nvgClosePath(m_nvg); + nvgStrokeColor(m_nvg, nvgRGBA(0,0,0,64)); + nvgStroke(m_nvg); + + // Center triangle fill. + paint = nvgLinearGradient(m_nvg, aa[0], aa[1], bb[0], bb[1], nvgHSL(hsv[0],drawSaturation,0.5f), nvgRGBA(0,0,0,255)); + nvgFillPaint(m_nvg, paint); + nvgFill(m_nvg); + paint = nvgLinearGradient(m_nvg, (aa[0]+bb[0])*0.5f, (aa[1]+bb[1])*0.5f, cc[0], cc[1], nvgRGBA(0,0,0,0), nvgRGBA(255,255,255,255)); + nvgFillPaint(m_nvg, paint); + nvgFill(m_nvg); + + // Color selector. + nvgStrokeWidth(m_nvg, 2.0f); + nvgBeginPath(m_nvg); + nvgCircle(m_nvg, sel[0], sel[1], 5); + nvgStrokeColor(m_nvg, nvgRGBA(255,255,255,192)); + nvgStroke(m_nvg); + + // Color selector stroke. + paint = nvgRadialGradient(m_nvg, sel[0], sel[1], 7.0f, 9.0f, nvgRGBA(0,0,0,64), nvgRGBA(0,0,0,0)); + nvgBeginPath(m_nvg); + nvgRect(m_nvg, sel[0]-20.0f, sel[1]-20.0f, 40.0f, 40.0f); + nvgCircle(m_nvg, sel[0], sel[1], 7.0f); + nvgPathWinding(m_nvg, NVG_HOLE); + nvgFillPaint(m_nvg, paint); + nvgFill(m_nvg); + } + nvgRestore(m_nvg); } nvgRestore(m_nvg); - - nvgRestore(m_nvg); } int32_t m_mx; @@ -2001,7 +1990,36 @@ int imguiReserve(int _y) return yy; } -void imguiColorWheel(float _color[3], bool _respectIndentation, bool _enabled) +void imguiBool(const char* _text, bool& _flag, bool _enabled) { - s_imgui.colorWheelWidget(_color, _respectIndentation, _enabled); + if (imguiCheck(_text, _flag, _enabled) ) + { + _flag = !_flag; + } +} + +void imguiColorWheel(float _rgb[3], bool _respectIndentation, bool _enabled) +{ + s_imgui.colorWheelWidget(_rgb, _respectIndentation, _enabled); +} + +void imguiColorWheel(const char* _text, float _rgb[3], bool& _activated, bool _enabled) +{ + char buf[128]; + bx::snprintf(buf, sizeof(buf), "%s [RGB %-2.2f %-2.2f %-2.2f]" + , _text + , _rgb[0] + , _rgb[1] + , _rgb[2] + ); + + if (imguiButton(buf, true) ) + { + _activated = !_activated; + } + + if (_activated) + { + imguiColorWheel(_rgb, false, _enabled); + } } diff --git a/examples/common/imgui/imgui.h b/examples/common/imgui/imgui.h index 391e3d1cb..7799b091f 100644 --- a/examples/common/imgui/imgui.h +++ b/examples/common/imgui/imgui.h @@ -83,6 +83,8 @@ void imguiDrawRoundedRect(float _x, float _y, float _w, float _h, float _r, uint void imguiDrawRect(float _x, float _y, float _w, float _h, uint32_t _argb); int imguiReserve(int _y); -void imguiColorWheel(float _color[3], bool _respectIndentation = false, bool _enabled = true); +void imguiBool(const char* _text, bool& _flag, bool _enabled = true); +void imguiColorWheel(float _rgb[3], bool _respectIndentation = false, bool _enabled = true); +void imguiColorWheel(const char* _str, float _rgb[3], bool& _activated, bool _enabled = true); #endif // IMGUI_H_HEADER_GUARD