void GraphNodeLink::draw(NVGcontext* ctx) { auto sourceSize = mSource->size().cast<float>(); Eigen::Vector2i inputPosition( mSource->absolutePosition().x() - mParent->absolutePosition().x() + (sourceSize.x() * 0.5f), mSource->absolutePosition().y() - mParent->absolutePosition().y() + (sourceSize.y() * 0.5f) ); Eigen::Vector2i outputPosition(Eigen::Vector2i::Zero()); if (hasTarget()) { // Get relative position of parent (node) of the target (sink) Eigen::Vector2i delta = mSink->parent()->absolutePosition() - mSink->parent()->position(); delta.x() -= (sourceSize.x() * 0.5f); delta.y() -= (sourceSize.y() * 0.5f); outputPosition = mSink->absolutePosition() - delta; } else { Eigen::Vector2i offset = mSource->absolutePosition() - mParent->absolutePosition(); Eigen::Vector2i delta = mTargetPosition - mSource->position(); outputPosition = offset + delta; } Eigen::Vector2i positionDiff = outputPosition - inputPosition; NVGcontext* vg = ctx; nvgStrokeColor(vg, nvgRGBA(131, 148, 150, 255)); nvgStrokeWidth(vg, 2.0f); nvgBeginPath(vg); nvgMoveTo( vg, inputPosition.x(), inputPosition.y() ); nvgQuadTo(vg, 1.2 * positionDiff.x(), positionDiff.y(), outputPosition.x(), outputPosition.y() ); nvgStroke(vg); Widget::draw(ctx); }
void NanoVG::quadTo( float cx, float cy, float x, float y ) { nvgQuadTo( m_context(), cx, cy, x, y ); }
void QNanoPainter::quadTo(float cx, float cy, float x, float y) { _checkAlignPixelsAdjust(&cx, &cy, &x, &y); nvgQuadTo(nvgCtx(), cx, cy, x, y); }
void Shape::render(NVGcontext& nanoVgContext) const { switch(mType) { case Type::ARC: { const ArcInfo& info = mArcInfo; const Point& position = info.position; nvgArc(&nanoVgContext, position.getX(), position.getY(), info.radius, info.startAngle, info.endAngle, info.clockWise ? NVG_CW : NVG_CCW); } break; case Type::TRIANGLE: { const TriangleInfo& info = mTriangleInfo; nvgMoveTo(&nanoVgContext, info.firstVertex.getX(), info.firstVertex.getY()); nvgLineTo(&nanoVgContext, info.secondVertex.getX(), info.secondVertex.getY()); nvgLineTo(&nanoVgContext, info.thirdVertex.getX(), info.thirdVertex.getY()); nvgClosePath(&nanoVgContext); } break; case Type::RECT: { const RectInfo& info = mRectInfo; const Rect& rect = info.rect; if(info.rounded) { nvgRoundedRect(&nanoVgContext, rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), info.cornerRadius); } else { nvgRect(&nanoVgContext, rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); } } break; case Type::ELLIPSE: { const EllipseInfo& info = mEllipseInfo; const Point& position = info.position; nvgEllipse(&nanoVgContext, position.getX(), position.getY(), info.horizontalRadius, info.verticalRadius); } break; case Type::MOVE_TO: { const MoveToInfo& info = mMoveToInfo; const Point& position = info.position; nvgMoveTo(&nanoVgContext, position.getX(), position.getY()); } break; case Type::LINE_TO: { const LineToInfo& info = mLineToInfo; const Point& position = info.position; nvgLineTo(&nanoVgContext, position.getX(), position.getY()); } break; case Type::BEZIER_TO: { const BezierToInfo& info = mBezierToInfo; const Point& control1 = info.controlPosition1; const Point& control2 = info.controlPosition2; const Point& position = info.position; nvgBezierTo(&nanoVgContext, control1.getX(), control1.getY(), control2.getX(), control2.getY(), position.getX(), position.getY()); } break; case Type::QUAD_TO: { const QuadToInfo& info = mQuadToInfo; const Point& control = info.controlPosition; const Point& position = info.position; nvgQuadTo(&nanoVgContext, control.getX(), control.getY(), position.getX(), position.getY()); } break; case Type::CLOSE_PATH: { nvgClosePath(&nanoVgContext); } break; default: return; } }
int main() { constexpr auto width = 1200u; constexpr auto height = 800u; // init ny app auto& backend = ny::Backend::choose(); if(!backend.vulkan()) { dlg_error("ny backend has no vulkan support!"); return 0; } auto ac = backend.createAppContext(); // basic vpp init auto iniExtensions = ac->vulkanExtensions(); iniExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); vk::ApplicationInfo appInfo ("vpp-intro", 1, "vpp", 1, VK_API_VERSION_1_0); vk::InstanceCreateInfo instanceInfo; instanceInfo.pApplicationInfo = &appInfo; instanceInfo.enabledExtensionCount = iniExtensions.size(); instanceInfo.ppEnabledExtensionNames = iniExtensions.data(); #ifdef WithLayers constexpr auto layer = "VK_LAYER_LUNARG_standard_validation"; instanceInfo.enabledLayerCount = 1; instanceInfo.ppEnabledLayerNames = &layer; #endif vpp::Instance instance(instanceInfo); #ifdef WithLayers vpp::DebugCallback debugCallback(instance); #endif // ny init auto run = true; auto listener = MyWindowListener {}; listener.run = &run; auto vkSurface = vk::SurfaceKHR {}; auto ws = ny::WindowSettings {}; ws.surface = ny::SurfaceType::vulkan; ws.listener = &listener; ws.size = {width, height}; ws.vulkan.instance = (VkInstance) instance.vkHandle(); ws.vulkan.storeSurface = &(std::uintptr_t&) (vkSurface); auto wc = ac->createWindowContext(ws); // further vpp init const vpp::Queue* presentQueue; vpp::Device device(instance, vkSurface, presentQueue); vpp::Swapchain swapchain(device, vkSurface, {width, height}, {}); // vvg setup auto nvgContext = vvg::createContext(swapchain); auto font = nvgCreateFont(nvgContext, "sans", "Roboto-Regular.ttf"); using Clock = std::chrono::high_resolution_clock; auto lastFrameTimer = Clock::now(); unsigned int framesCount = 0; std::string fpsString = "420 fps"; // main loop while(run) { if(!ac->dispatchEvents()) break; nvgBeginFrame(nvgContext, width, height, width / (float) height); nvgBeginPath(nvgContext); nvgMoveTo(nvgContext, 10, 10); nvgLineTo(nvgContext, 10, 400); nvgLineTo(nvgContext, 100, 400); nvgQuadTo(nvgContext, 100, 50, 400, 120); nvgLineTo(nvgContext, 450, 10); nvgClosePath(nvgContext); nvgFillColor(nvgContext, nvgRGBAf(0.5, 0.8, 0.7, 1.0)); nvgFill(nvgContext); nvgBeginPath(nvgContext); nvgFontFaceId(nvgContext, font); nvgFontSize(nvgContext, 100.f); nvgFontBlur(nvgContext, .8f); nvgFillColor(nvgContext, nvgRGBAf(1.0, 1.0, 1.0, 1.0)); nvgTextBox(nvgContext, 200, 200, width - 200, "Hello Vulkan Vector Graphics World", nullptr); nvgFontSize(nvgContext, 30.f); nvgFontBlur(nvgContext, .2f); nvgText(nvgContext, 10, height - 20, fpsString.c_str(), nullptr); nvgBeginPath(nvgContext); nvgRect(nvgContext, 700, 400, 300, 300); nvgPathWinding(nvgContext, NVG_HOLE); nvgRect(nvgContext, 750, 450, 50, 50); // auto paint = nvgRadialGradient(nvgContext, 750, 425,20, 50, nvgRGB(0, 0, 200), nvgRGB(200, 200, 0)); // auto paint = nvgRadialGradient(nvgContext, 0.0, 0.0, 0.2, 100.0, nvgRGB(0, 0, 200), nvgRGB(200, 200, 0)); auto paint = nvgLinearGradient(nvgContext, 700, 400, 800, 450, nvgRGB(0, 0, 200), nvgRGB(200, 200, 0)); nvgFillPaint(nvgContext, paint); // nvgFillColor(nvgContext, nvgRGBA(200, 200, 0, 200)); nvgClosePath(nvgContext); nvgFill(nvgContext); nvgEndFrame(nvgContext); // only refresh frame timer every second framesCount++; if(Clock::now() - lastFrameTimer >= std::chrono::seconds(1)) { fpsString = std::to_string(framesCount) + " fps"; lastFrameTimer = Clock::now(); framesCount = 0; } } vvg::destroyContext(*nvgContext); }
JNIEXPORT void JNICALL Java_firststep_internal_NVG_quadTo (JNIEnv *e, jclass c, jlong ctx, jfloat cx, jfloat cy, jfloat x, jfloat y) { nvgQuadTo((NVGcontext*)ctx, cx,cy, x,y); }
void VectorRenderer::curveTo(float cx, float cy, float x, float y) { nvgQuadTo(nvg, cx, cy, x, y); }