virtual void updateGL( osg::State* state ) const { // Some test drawings... nvgBeginPath( _vg ); nvgRect( _vg, 300, 300, 120, 30 ); nvgFillColor( _vg, nvgRGBA(255, 192, 0, 255) ); nvgFill( _vg ); nvgClosePath( _vg ); nvgBeginPath( _vg ); nvgCircle( _vg, 400, 500, 50 ); nvgFillColor( _vg, nvgRGBA(0, 192, 255, 100) ); nvgFill( _vg ); nvgClosePath( _vg ); if ( _loadedImages.size()>0 ) { NVGpaint imgPaint = nvgImagePattern( _vg, 600, 150, 300, 400, 0.0f, _loadedImages[0], 1.0f ); nvgBeginPath( _vg ); nvgRoundedRect( _vg, 600, 150, 300, 400, 5 ); nvgFillPaint( _vg, imgPaint ); nvgFill( _vg ); nvgClosePath( _vg ); } }
void Application::Impl_::paintEvent(NVGcontext* context){ int winWidth, winHeight; glfwGetWindowSize(window_.get(), &winWidth, &winHeight); int fWidth, fHeight; glfwGetFramebufferSize(window_.get(), &fWidth, &fHeight); float pxRatio = (float)fWidth / (float)winWidth; nvgBeginFrame(context, winWidth, winHeight, pxRatio); Rect textRect(0.f,10.f,winWidth,20.f); Rect boardMaxRect(0.f,textRect.height + textRect.y,winWidth,winHeight - textRect.height); float boardSizeMin = std::min(boardMaxRect.width,boardMaxRect.height); Rect boardRect(20.f, 20.f + textRect.height,boardSizeMin-40.f, boardSizeMin-40.f); if (boardMaxRect.height > boardMaxRect.width){ boardRect.move(0,(boardMaxRect.height - boardMaxRect.width)/2.f); }else{ boardRect.move((boardMaxRect.width - boardMaxRect.height)/2.f,0); } // draw the text rect nvgBeginPath(context); nvgFillColor(context, nvgRGBA(0,0,0,50)); nvgRect(context,textRect); nvgFill(context); nvgClosePath(context); // draw the board boardView_->paint(context,boardRect); if (isEnd_){ // change the color of the board nvgBeginPath(context); nvgFillColor(context, nvgRGBA(0,0,0,30)); nvgRect(context,boardMaxRect); nvgFill(context); nvgClosePath(context); // & display the game over std::string text("GAME OVER"); nvgBeginPath(context); float x= 0; float y= 0; textRect.center(x,y); nvgFontSize(context, 20); nvgFontFace(context, "sans"); nvgTextAlign(context, NVG_ALIGN_MIDDLE|NVG_ALIGN_CENTER); nvgFill(context); nvgFillColor(context, nvgRGBA(0,0,0,255)); nvgText(context,x+1,y+1,text.c_str(),NULL); nvgFillColor(context, nvgRGBA(200,20,20,255)); nvgText(context,x,y,text.c_str(),NULL); } nvgEndFrame(context); }
void vsDropShadow(NVGcontext *ctx, float x, float y, float w, float h, float r, float feather, float alpha) { nvgBeginPath(ctx); y += feather; h -= feather; nvgMoveTo(ctx, x - feather, y - feather); nvgLineTo(ctx, x, y - feather); nvgLineTo(ctx, x, y + h - feather); nvgArcTo(ctx, x, y + h, x + r, y + h, r); nvgArcTo(ctx, x + w, y + h, x + w, y + h - r, r); nvgLineTo(ctx, x + w, y - feather); nvgLineTo(ctx, x + w + feather, y - feather); nvgLineTo(ctx, x + w + feather, y + h + feather); nvgLineTo(ctx, x - feather, y + h + feather); nvgClosePath(ctx); nvgFillPaint(ctx, nvgBoxGradient(ctx, x - feather * 0.5f, y - feather * 0.5f, w + feather, h + feather, r + feather * 0.5f, feather, nvgRGBAf(0, 0, 0, alpha * alpha), nvgRGBAf(0, 0, 0, 0))); nvgFill(ctx); }
void renderFrame() { currentRotation = currentRotation*0.9f + rotation * 0.1f; glStencilMask(0xff); checkGlError("glStencilMask"); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); checkGlError("glClear"); nvgBeginFrame(vg, w, h, w/h); nvgBeginPath(vg); nvgMoveTo(vg, verticeX(90.f), verticeY(90.f)); nvgLineTo(vg, verticeX(90.f + 120.0f), verticeY(90.0f + 120.0f)); nvgLineTo(vg, verticeX(90.f + 240.f), verticeY(90.0f + 240.0f) ); nvgClosePath(vg); nvgFillColor(vg, nvgRGBA(255,192,0,255)); nvgFill(vg); nvgFillColor(vg, nvgRGBA(255,192,0,255)); nvgEndFrame(vg); }
void Renderer2D::drawPath( const attributes_2d& attributes, const float32_t* path, const uint32_t& pathSize, const float32_t& border, const color_argb& color, const color_argb& borderColor, const Image2D& image, const float32_t& image_alpha, const float32_t& image_pos_x, const float32_t& image_pos_y, const float32_t& image_width, const float32_t& image_height, const float32_t& image_rotation ) { Context2D* context = _context2D; if( pathSize < 2 || pathSize % 2 != 0 ) return; nvgSave( context ); nvgBeginPath( context ); nvgTranslate( context, attributes.position[0], attributes.position[1] ); nvgSave( context ); nvgRotate( context, attributes.rotation ); nvgMoveTo( context, path[0], path[1]); for( uint32_t i=2; i<pathSize; i+=2 ) { nvgLineTo( context, path[i] * attributes.scale, path[i+1] * attributes.scale); } nvgClosePath( context ); if( image != 0 ) { NVGpaint paint = nvgImagePattern( context, image_pos_x-image_width/2, image_pos_y-image_height/2, image_width, image_height, image_rotation, image, image_alpha ); nvgFillPaint( context, paint); } else { nvgFillColor( context, nvgRGBA( color.r, color.g, color.b, color.a) ); } nvgFill(context); nvgStrokeColor( context, nvgRGBA( borderColor.r, borderColor.g, borderColor.b, borderColor.a) ); nvgStrokeWidth( context, border ); nvgStroke( context ); nvgRestore( context ); nvgRestore( context ); }
void NanoVG::closePath() { nvgClosePath( m_context() ); }
void NVGRenderer::closePath() { nvgClosePath(m_context); }
void ColorWheel::draw(NVGcontext *ctx) { Widget::draw(ctx); if (!mVisible) return; float x = mPos.x(), y = mPos.y(), w = mSize.x(), h = mSize.y(); NVGcontext* vg = ctx; int i; float r0, r1, ax,ay, bx,by, cx,cy, aeps, r; float hue = mHue; NVGpaint paint; nvgSave(vg); cx = x + w*0.5f; cy = y + h*0.5f; r1 = (w < h ? w : h) * 0.5f - 5.0f; r0 = r1 * .75f; aeps = 0.5f / r1; // half a pixel arc length in radians (2pi cancels out). for (i = 0; i < 6; i++) { float a0 = (float)i / 6.0f * NVG_PI * 2.0f - aeps; float a1 = (float)(i+1.0f) / 6.0f * NVG_PI * 2.0f + aeps; nvgBeginPath(vg); nvgArc(vg, cx,cy, r0, a0, a1, NVG_CW); nvgArc(vg, cx,cy, r1, a1, a0, NVG_CCW); nvgClosePath(vg); ax = cx + cosf(a0) * (r0+r1)*0.5f; ay = cy + sinf(a0) * (r0+r1)*0.5f; bx = cx + cosf(a1) * (r0+r1)*0.5f; by = cy + sinf(a1) * (r0+r1)*0.5f; paint = nvgLinearGradient(vg, ax, ay, bx, by, nvgHSLA(a0 / (NVG_PI * 2), 1.0f, 0.55f, 255), nvgHSLA(a1 / (NVG_PI * 2), 1.0f, 0.55f, 255)); nvgFillPaint(vg, paint); nvgFill(vg); } nvgBeginPath(vg); nvgCircle(vg, cx,cy, r0-0.5f); nvgCircle(vg, cx,cy, r1+0.5f); nvgStrokeColor(vg, nvgRGBA(0,0,0,64)); nvgStrokeWidth(vg, 1.0f); nvgStroke(vg); // Selector nvgSave(vg); nvgTranslate(vg, cx,cy); nvgRotate(vg, hue*NVG_PI*2); // Marker on float u = std::max(r1/50, 1.5f); u = std::min(u, 4.f); nvgStrokeWidth(vg, u); nvgBeginPath(vg); nvgRect(vg, r0-1,-2*u,r1-r0+2,4*u); nvgStrokeColor(vg, nvgRGBA(255,255,255,192)); nvgStroke(vg); paint = nvgBoxGradient(vg, r0-3,-5,r1-r0+6,10, 2,4, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); nvgBeginPath(vg); nvgRect(vg, r0-2-10,-4-10,r1-r0+4+20,8+20); nvgRect(vg, r0-2,-4,r1-r0+4,8); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, paint); nvgFill(vg); // Center triangle r = r0 - 6; ax = cosf(120.0f/180.0f*NVG_PI) * r; ay = sinf(120.0f/180.0f*NVG_PI) * r; bx = cosf(-120.0f/180.0f*NVG_PI) * r; by = sinf(-120.0f/180.0f*NVG_PI) * r; nvgBeginPath(vg); nvgMoveTo(vg, r,0); nvgLineTo(vg, ax, ay); nvgLineTo(vg, bx, by); nvgClosePath(vg); paint = nvgLinearGradient(vg, r, 0, ax, ay, nvgHSLA(hue, 1.0f, 0.5f, 255), nvgRGBA(255, 255, 255, 255)); nvgFillPaint(vg, paint); nvgFill(vg); paint = nvgLinearGradient(vg, (r + ax) * 0.5f, (0 + ay) * 0.5f, bx, by, nvgRGBA(0, 0, 0, 0), nvgRGBA(0, 0, 0, 255)); nvgFillPaint(vg, paint); nvgFill(vg); nvgStrokeColor(vg, nvgRGBA(0, 0, 0, 64)); nvgStroke(vg); // Select circle on triangle float sx = r*(1 - mWhite - mBlack) + ax*mWhite + bx*mBlack; float sy = ay*mWhite + by*mBlack; nvgStrokeWidth(vg, u); nvgBeginPath(vg); nvgCircle(vg, sx,sy,2*u); nvgStrokeColor(vg, nvgRGBA(255,255,255,192)); nvgStroke(vg); nvgRestore(vg); nvgRestore(vg); }
void drawColorwheel(struct NVGcontext* vg, float x, float y, float w, float h, float t) { int i; float r0, r1, ax,ay, bx,by, cx,cy, aeps, r; float hue = sinf(t * 0.12f); struct NVGpaint paint; nvgSave(vg); /* nvgBeginPath(vg); nvgRect(vg, x,y,w,h); nvgFillColor(vg, nvgRGBA(255,0,0,128) ); nvgFill(vg);*/ cx = x + w*0.5f; cy = y + h*0.5f; r1 = (w < h ? w : h) * 0.5f - 5.0f; r0 = r1 - 20.0f; aeps = 0.5f / r1; // half a pixel arc length in radians (2pi cancels out). for (i = 0; i < 6; i++) { float a0 = (float)i / 6.0f * NVG_PI * 2.0f - aeps; float a1 = (float)(i+1.0f) / 6.0f * NVG_PI * 2.0f + aeps; nvgBeginPath(vg); nvgArc(vg, cx,cy, r0, a0, a1, NVG_CW); nvgArc(vg, cx,cy, r1, a1, a0, NVG_CCW); nvgClosePath(vg); ax = cx + cosf(a0) * (r0+r1)*0.5f; ay = cy + sinf(a0) * (r0+r1)*0.5f; bx = cx + cosf(a1) * (r0+r1)*0.5f; by = cy + sinf(a1) * (r0+r1)*0.5f; paint = nvgLinearGradient(vg, ax,ay, bx,by, nvgHSLA(a0/(NVG_PI*2),1.0f,0.55f,255), nvgHSLA(a1/(NVG_PI*2),1.0f,0.55f,255) ); nvgFillPaint(vg, paint); nvgFill(vg); } nvgBeginPath(vg); nvgCircle(vg, cx,cy, r0-0.5f); nvgCircle(vg, cx,cy, r1+0.5f); nvgStrokeColor(vg, nvgRGBA(0,0,0,64) ); nvgStrokeWidth(vg, 1.0f); nvgStroke(vg); // Selector nvgSave(vg); nvgTranslate(vg, cx,cy); nvgRotate(vg, hue*NVG_PI*2); // Marker on nvgStrokeWidth(vg, 2.0f); nvgBeginPath(vg); nvgRect(vg, r0-1,-3,r1-r0+2,6); nvgStrokeColor(vg, nvgRGBA(255,255,255,192) ); nvgStroke(vg); paint = nvgBoxGradient(vg, r0-3,-5,r1-r0+6,10, 2,4, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0) ); nvgBeginPath(vg); nvgRect(vg, r0-2-10,-4-10,r1-r0+4+20,8+20); nvgRect(vg, r0-2,-4,r1-r0+4,8); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, paint); nvgFill(vg); // Center triangle r = r0 - 6; ax = cosf(120.0f/180.0f*NVG_PI) * r; ay = sinf(120.0f/180.0f*NVG_PI) * r; bx = cosf(-120.0f/180.0f*NVG_PI) * r; by = sinf(-120.0f/180.0f*NVG_PI) * r; nvgBeginPath(vg); nvgMoveTo(vg, r,0); nvgLineTo(vg, ax,ay); nvgLineTo(vg, bx,by); nvgClosePath(vg); paint = nvgLinearGradient(vg, r,0, ax,ay, nvgHSLA(hue,1.0f,0.5f,255), nvgRGBA(255,255,255,255) ); nvgFillPaint(vg, paint); nvgFill(vg); paint = nvgLinearGradient(vg, (r+ax)*0.5f,(0+ay)*0.5f, bx,by, nvgRGBA(0,0,0,0), nvgRGBA(0,0,0,255) ); nvgFillPaint(vg, paint); nvgFill(vg); nvgStrokeColor(vg, nvgRGBA(0,0,0,64) ); nvgStroke(vg); // Select circle on triangle ax = cosf(120.0f/180.0f*NVG_PI) * r*0.3f; ay = sinf(120.0f/180.0f*NVG_PI) * r*0.4f; nvgStrokeWidth(vg, 2.0f); nvgBeginPath(vg); nvgCircle(vg, ax,ay,5); nvgStrokeColor(vg, nvgRGBA(255,255,255,192) ); nvgStroke(vg); paint = nvgRadialGradient(vg, ax,ay, 7,9, nvgRGBA(0,0,0,64), nvgRGBA(0,0,0,0) ); nvgBeginPath(vg); nvgRect(vg, ax-20,ay-20,40,40); nvgCircle(vg, ax,ay,7); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, paint); nvgFill(vg); nvgRestore(vg); nvgRestore(vg); }
void QNanoPainter::closePath() { nvgClosePath(nvgCtx()); }
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); }