From aecbd044f19cec20ece0e17397cc77c12a774be7 Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 27 May 2014 14:17:15 +0100 Subject: [PATCH] Add missing files --- examples/demo_res/ico5.png | Bin 0 -> 539 bytes examples/nanovg2.cpp | 236 ++++++++++++++++++++++++++ examples/widgets/NanoPerfWidget.hpp | 249 ++++++++++++++++++++++++++++ 3 files changed, 485 insertions(+) create mode 100644 examples/demo_res/ico5.png create mode 100644 examples/nanovg2.cpp create mode 100644 examples/widgets/NanoPerfWidget.hpp diff --git a/examples/demo_res/ico5.png b/examples/demo_res/ico5.png new file mode 100644 index 0000000000000000000000000000000000000000..dc85b73d340df1761ae55057cbd83efafbd8982e GIT binary patch literal 539 zcmV+$0_6RPP)Oc^OclJ+$5Cu^Ph=mB2);4xlHol6l;rsXoDp*;IwrXn-HM$#T=N1bh zoKu|0xi`YyuLw!lu;1o4I|*YRkH_Qjcs&0UV2lC4hu9F2WQ<8EIp>9|Fvg5A5Jk~s zGAWnK*4hGv5Rr(+*d!0 zKP0!1l=3-!7>0~7Yb^jsDT5%e)*>PRaL%6t{+19CDWx`>&G~#z)AaFp%;)nYNrE7_ zUa#x*dbL_Pt>f`{I2?>Ii^alKYmNoy5(>j`xmo0rSw8Q*X?jH1XGbHCr?I6j?D zLI|alQYu&D%_o#)S-agPqF%4(?pSL%=hoV8x9f_@1r*1zdpCLOTE4f-UXQL{AmZz` zBBH0 + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +// ------------------------------------------------------ +// DGL Stuff + +#include "StandaloneWindow.hpp" + +// ------------------------------------------------------ +// NanoVG Stuff + +#include "NanoVG.hpp" +#include "widgets/NanoPerfWidget.hpp" + +// ------------------------------------------------------ +// use namespace + +using namespace DGL; + +// ------------------------------------------------------ +// NanoVG Example Widget + +int blowup = 0; +int premult = 0; + +int mx = 0; +int my = 0; + +class NanoExampleWidget : public NanoWidget, + public IdleCallback +{ +public: + NanoExampleWidget(Window& parent) + : NanoWidget(parent) + { + parent.addIdleCallback(this); + + for (int i = 0; i < 12; ++i) + { + char file[128]; + std::snprintf(file, 128, "./nanovg_res/images/image%d.jpg", i+1); + fImages[i] = createImage(file); + + if (! fImages[i].isValid()) + { + d_stdout("Could not load %s.", file); + return; + } + } + + fFontIcons = createFont("icons", "./nanovg_res/entypo.ttf"); + fFontNormal = createFont("sans", "./nanovg_res/Roboto-Regular.ttf"); + fFontBold = createFont("sans-bold", "./nanovg_res/Roboto-Bold.ttf"); + } + +protected: + void idleCallback() override + { + repaint(); + } + + void onNanoDisplay() override + { + const int width = getWidth(); + const int height = getHeight(); + const double t = gTime.getTime(); + + if (premult) + glClearColor(0, 0, 0, 0); + else + glClearColor(0.3f, 0.3f, 0.32f, 1.0f); + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + + drawEyes(width - 250, 50, 150, 100, mx, my, t); + } + + bool onKeyboard(const KeyboardEvent& ev) override + { + if (! ev.press) + return false; + + switch (ev.key) + { + case CHAR_ESCAPE: + getParentApp().quit(); + break; + case ' ': + blowup = !blowup; + break; + case 'p': + case 'P': + premult = !premult; + break; + } + + return true; + } + + bool onMotion(const MotionEvent& ev) override + { + mx = ev.pos.getX(); + my = ev.pos.getY(); + + return false; + } + +private: + FontId fFontNormal, fFontBold, fFontIcons; + NanoImage fImages[12]; + + void drawEyes(float x, float y, float w, float h, float mx, float my, float t) + { + Paint gloss, bg; + float ex = w *0.23f; + float ey = h * 0.5f; + float lx = x + ex; + float ly = y + ey; + float rx = x + w - ex; + float ry = y + ey; + float dx,dy,d; + float br = (ex < ey ? ex : ey) * 0.5f; + float blink = 1 - std::pow(std::sin(t*0.5f),200)*0.8f; + + bg = linearGradient(x,y+h*0.5f,x+w*0.1f,y+h, RGBA(0,0,0,32), RGBA(0,0,0,16)); + beginPath(); + ellipse(lx+3.0f,ly+16.0f, ex,ey); + ellipse(rx+3.0f,ry+16.0f, ex,ey); + fillPaint(bg); + fill(); + + bg = linearGradient(x,y+h*0.25f,x+w*0.1f,y+h, RGBA(220,220,220,255), RGBA(128,128,128,255)); + beginPath(); + ellipse(lx,ly, ex,ey); + ellipse(rx,ry, ex,ey); + fillPaint(bg); + fill(); + + dx = (mx - rx) / (ex * 10); + dy = (my - ry) / (ey * 10); + d = std::sqrt(dx*dx+dy*dy); + if (d > 1.0f) { + dx /= d; dy /= d; + } + dx *= ex*0.4f; + dy *= ey*0.5f; + beginPath(); + ellipse(lx+dx,ly+dy+ey*0.25f*(1-blink), br,br*blink); + fillColor(RGBA(32,32,32,255)); + fill(); + + dx = (mx - rx) / (ex * 10); + dy = (my - ry) / (ey * 10); + d = std::sqrt(dx*dx+dy*dy); + if (d > 1.0f) { + dx /= d; dy /= d; + } + dx *= ex*0.4f; + dy *= ey*0.5f; + beginPath(); + ellipse(rx+dx,ry+dy+ey*0.25f*(1-blink), br,br*blink); + fillColor(RGBA(32,32,32,255)); + fill(); + + gloss = radialGradient(lx-ex*0.25f,ly-ey*0.5f, ex*0.1f,ex*0.75f, RGBA(255,255,255,128), RGBA(255,255,255,0)); + beginPath(); + ellipse(lx,ly, ex,ey); + fillPaint(gloss); + fill(); + + gloss = radialGradient(rx-ex*0.25f,ry-ey*0.5f, ex*0.1f,ex*0.75f, RGBA(255,255,255,128), RGBA(255,255,255,0)); + beginPath(); + ellipse(rx,ry, ex,ey); + fillPaint(gloss); + fill(); + } +}; + +// ----------------------------------------------------------------------- +// We need a custom window for multiple widgets + +class NanoExampleWindow : public Window +{ +public: + NanoExampleWindow(App& app) + : Window(app), + fDemo(*this), + fPerf(*this, NanoPerfWidget::RENDER_FPS, "Frame Time") + { + fPerf.setAbsolutePos(5, 5); + + setSize(1000, 600); + setTitle("NanoVG"); + } + +protected: + void onReshape(int width, int height) + { + fDemo.setSize(width, height); + + Window::onReshape(width, height); + } + +private: + NanoExampleWidget fDemo; + NanoPerfWidget fPerf; +}; + +// ------------------------------------------------------ +// main entry point + +int main() +{ + App app; + NanoExampleWindow win(app); + + win.show(); + app.exec(); + + return 0; +} + +// ------------------------------------------------------ diff --git a/examples/widgets/NanoPerfWidget.hpp b/examples/widgets/NanoPerfWidget.hpp new file mode 100644 index 0000000..48c0fa9 --- /dev/null +++ b/examples/widgets/NanoPerfWidget.hpp @@ -0,0 +1,249 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef NANO_PERF_WIDGET_HPP_INCLUDED +#define NANO_PERF_WIDGET_HPP_INCLUDED + +// ------------------------------------------------------ +// DGL Stuff + +#include "NanoVG.hpp" +#include "../../dpf/distrho/extra/d_string.hpp" + +// ------------------------------------------------------ +// use namespace + +using DGL::IdleCallback; +using DGL::NanoVG; +using DGL::NanoWidget; +using DGL::Widget; +using DGL::Window; + +// ------------------------------------------------------ +// get time + +#include +#include + +#ifdef DISTRHO_OS_WINDOWS +#else +struct TimePOSIX { + bool monotonic; + double resolution; + uint64_t base; + + TimePOSIX() + : monotonic(false), + resolution(1e-6), + base(0) + { +#if defined(CLOCK_MONOTONIC) + struct timespec ts; + + if (::clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + { + monotonic = true; + resolution = 1e-9; + } +#endif + + base = getRawTime(); + } + + uint64_t getRawTime() + { +#if defined(CLOCK_MONOTONIC) + if (monotonic) + { + struct timespec ts; + + ::clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec; + } + else +#endif + { + struct timeval tv; + + ::gettimeofday(&tv, NULL); + return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec; + } + } + + double getTime() + { + return (double)(getRawTime() - base) * resolution; + } +}; + +static TimePOSIX gTime; +#endif + +// ------------------------------------------------------ +// our widget + +class NanoPerfWidget : public NanoWidget, + public IdleCallback +{ +public: + static const int kHistoryCount = 100; + + enum RenderStyle { + RENDER_FPS, + RENDER_MS, + }; + + NanoPerfWidget(Window& parent, RenderStyle style, const char* name) + : NanoWidget(parent), + fHead(0), + fStyle(style), + fName(name) + { + parent.addIdleCallback(this); + setSize(200, 35); + + std::memset(fValues, 0, sizeof(float)*kHistoryCount); + + createFont("sans", "./nanovg_res/Roboto-Regular.ttf"); + + prevt = gTime.getTime(); + } + +protected: + void idleCallback() override + { + repaint(); + } + + void onNanoDisplay() override + { + double t, dt; + + t = gTime.getTime(); + dt = t - prevt; + prevt = t; + update(dt); + + const int w = 200; //getWidth(); + const int h = 35; //getHeight(); + + int i; + float avg; + char str[64]; + + avg = getAverage(); + + beginPath(); + rect(0, 0, w, h); + fillColor(RGBA(0,0,0,128)); + fill(); + + beginPath(); + moveTo(0, h); + + if (fStyle == RENDER_FPS) + { + for (i = 0; i < kHistoryCount; ++i) + { + float v = 1.0f / (0.00001f + fValues[(fHead+i) % kHistoryCount]); + float vx, vy; + if (v > 80.0f) v = 80.0f; + vx = ((float)i/(kHistoryCount-1)) * w; + vy = h - ((v / 80.0f) * h); + lineTo(vx, vy); + } + } + else + { + for (i = 0; i < kHistoryCount; ++i) + { + float v = fValues[(fHead+i) % kHistoryCount] * 1000.0f; + float vx, vy; + if (v > 20.0f) v = 20.0f; + vx = ((float)i/(kHistoryCount-1)) * w; + vy = h - ((v / 20.0f) * h); + lineTo(vx, vy); + } + } + + lineTo(w, h); + fillColor(RGBA(255,192,0,128)); + fill(); + + fontFace("sans"); + + if (fName.isNotEmpty()) + { + fontSize(14.0f); + textAlign(ALIGN_LEFT|ALIGN_TOP); + fillColor(RGBA(240,240,240,192)); + text(3, 1, fName, nullptr); + } + + if (fStyle == RENDER_FPS) + { + fontSize(18.0f); + textAlign(ALIGN_RIGHT|ALIGN_TOP); + fillColor(RGBA(240,240,240,255)); + std::sprintf(str, "%.2f FPS", 1.0f / avg); + text(w-3, 1, str, nullptr); + + fontSize(15.0f); + textAlign(ALIGN_RIGHT|ALIGN_BOTTOM); + fillColor(RGBA(240,240,240,160)); + std::sprintf(str, "%.2f ms", avg * 1000.0f); + text(w-3, h-1, str, nullptr); + } + else + { + fontSize(18.0f); + textAlign(ALIGN_RIGHT|ALIGN_TOP); + fillColor(RGBA(240,240,240,255)); + std::sprintf(str, "%.2f ms", avg * 1000.0f); + text(w-3, 1, str, nullptr); + } + } + +private: + int fHead; + float fValues[kHistoryCount]; + + const int fStyle; + const d_string fName; + + double prevt; + + void update(float frameTime) noexcept + { + fHead = (fHead+1) % kHistoryCount; + fValues[fHead] = frameTime; + } + + float getAverage() const noexcept + { + int i; + float avg = 0; + + for (i = 0; i < kHistoryCount; ++i) + avg += fValues[i]; + + return avg / (float)kHistoryCount; + } +}; + +// ------------------------------------------------------ + +#endif // NANO_PERF_WIDGET_HPP_INCLUDED