/Skity

A light weight 2D Vector Graphic renderer library writing in c++ for OpenGL3.3+ / OpenGLES3.0+ / Vulkan 1.1+/ WebGL2 with WASM

Primary LanguageC++MIT LicenseMIT

Skity

Skity is an open-source 2D graphics library written in c++ using OpenGL and Vulkan (Experimental) as backend. Its API follows the same pattern as Skia and implements the rendering by myself.

MacOS|build Windows|build Android|build CodeFactor License: MIT

Screen Shots

Just like nanovg SVG render Basic Example Android Porting
Blur filter example NanoGUI Porting

Quick Start

Build and Install

Option A: Build from source

Requirements
  • CMake
  • Freetype: If not present, font rendering will not working
  • GLFW: for build test and example
  • optional
    • libpng: for png file decode
    • libjpeg-turbo: for jpg file decode
    • on windows ,need to set environment value: JPEG_PREFIX=path to libjpeg installed directory
# fetch sources from github
git clone --recursive https://github.com/RuiwenTang/Skity.git
cd Skity
# Create build directory
mkdir build
cd build
cmake ..
make
make install

Option B: Using vcpkg

The port config is located in vcpkg-skity.

Using manifest mode

Add the following registry info to vcpkg-configuration.json as a git registry:

{
  "default-registry": {
      "kind": "git",
      "repository": "https://github.com/microsoft/vcpkg.git",
      "baseline": "82e03905f54fc49d11346e5148e3860747604d86"
  },
  "registries": [
    {
      "kind": "git",
      "repository": "https://github.com/RuiwenTang/vcpkg-skity.git",
      "baseline": "8223a29413aaa1869e6d106d341eaf90ddf7ca47",
      "packages": [ "skity" ]
    }
  ]
}

And then add skity to vcpkg.json as a dependency:

{
  "name": "my-application",
  "version-string": "0.1.0",
  "dependencies": [
    "skity"
  ]
}
Using overlay-ports

Clone vcpkg-skity repo and pass a port-overlay to vcpkg:

vcpkg install skity --overlay-ports=/path/to/vcpkg-skity/ports/skity

Linking in CMake

In CMakeLists.txt, find and link skity:

find_package(skity CONFIG REQUIRED)
target_link_library(main skity::skity)

Initialization

The code below shows how to create a skity::Canvas instance using GLFW with OpenGL backend. The full code can look at gl_app.cc

GLFWwindow* window = glfwCreateWindow(800, 600, "Demo", nullptr, nullptr);

int32_t pp_width, pp_height;
glfwGetFramebufferSize(window_, &pp_width, &pp_height);

float density = (float)(pp_width * pp_width + pp_height * pp_height) /
                  (float)(800 * 800 + 600 * 600);

skity::GPUContext ctx{skity::GPUBackendType::kOpenGL, (void*) glfwGetProcAddress};

auto canvas = skity::Canvas::MakeHardwareAccelationCanvas(800, 600, density, &ctx);

Drawing Path

// paint controls the color and style when geometry is rendered
skity::Paint paint;
paint.setStyle(skity::Paint::kFill_Style);
paint.setColor(skity::ColorSetRGB(0x42, 0x85, 0xF4));

// create path
skity::Path path;
path.moveTo(199, 34);
path.lineTo(253, 143);
path.lineTo(374, 160);
path.lineTo(287, 244);
path.lineTo(307, 365);
path.lineTo(199, 309);
path.lineTo(97, 365);
path.lineTo(112, 245);
path.lineTo(26, 161);
path.lineTo(146, 143);
path.close();

canvas->drawPath(path, paint);

The code generates the following result:

Blur Effect

By using MaskFilter, can make some Post-processing effect, currently only support Blur effect.

paint.setMaskFilter(
      skity::MaskFilter::MakeBlur(skity::BlurStyle::kNormal, 10.f));

canvas->drawPath(path /* previouse created star path */, paint);

Build

Third party dependencies

  • glad Uesd in example for OpenGL context creation
  • glm Used in this library for all geometric mathematical claculations
  • gtest Used in test for some unit test only used when build for debug
  • pugixml Used in this library for xml parse when drawing svg image.
  • spdlog Used in this library for logging. (Optional can trun off by setting ENABLE_LOG=OFF)
  • VulkanMemoryAllocator Used when enable VULKAN_BACKEND for internal memory management

CMake options

CMake Option Default Value Description
ENABLE_LOG ON Enable logging. If turn off the spdlog is no longer needed.
VULKAN_BACKEND OFF Enable Vulkan backend. If turn on, the VulkanMemoryAllocator dependence is needed.
OPENGL_BACKEND ON Enable OpenGL backend
BUILD_SVG_MODULE ON Build SVG module. If turn off the pugixml is no longer needed.
BUILD_EXAMPLE ON Build example code. Need GLFW .
BUILD_TEST ON Build test code

Current status:

  • Fill (stencil, even-odd supported)

  • Stroke (done)

  • Clip (stencil)

  • Font (basic drawing api)

    • draw simple text, no glyph cache, no text layout
  • Line caps and joins (done)

  • PathEffect dash

    • implement a simple discrete path effect
    • implement a path measure algorithm and dash path effect
  • Image (in progress)

    • Cocec interface
    • png image decode (need install libpng)
    • jpg image decode (need install libjpeg-turbo)
  • SVG (done)

    • basic svg tag parser
      • <svg> <g> <path> <circle> <rect>
  • Maskfilter (done with Blur effect filter)

    • Gaussian Blur with inner and outer effect
      • OpenGL backend
        • Using FBO and off screen rendering to do blur calculation
      • Vulkan backend
        • Use compute shader to do blur calculation

Reference

TODO

  • Vulkan backend support (Experimental done)

  • Support mask filters like SkMaskFilter

  • Use Geometry Shader if possible to optimize GPU raster

  • CPU backend support (planning)

  • Support lottie anmiation.