Skip to content

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

License

Notifications You must be signed in to change notification settings

RuiwenTang/Skity

Folders and files

NameName
Last commit message
Last commit date
Aug 3, 2022
Apr 25, 2023
Apr 25, 2023
Apr 23, 2022
Apr 25, 2023
Feb 23, 2023
Mar 30, 2022
Mar 30, 2023
Oct 9, 2023
Aug 3, 2022
Feb 11, 2023
May 12, 2021
Apr 25, 2023
Aug 3, 2022
Apr 25, 2023
Jan 3, 2023
Aug 9, 2023

Repository files navigation

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 ..

# If build source in M1 Mac please append -DPNG_ARM_NEON=on in cmake argument list to prevent libpng compile error
# cmake ../ -DPNG_ARM_NEON=ON

make
make install

Option B: Using vcpkg

The port config is located in vcpkg-skity.

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.