lyze237 / gdx-TinyVG

TinyVG parser and renderer for libGDX
https://svg-to-tvg-server.fly.dev/
Apache License 2.0
27 stars 4 forks source link

gdx-TinyVG

A libgdx parser and renderer for TinyVG https://www.tinyvg.tech/

Build, Test, Publish License Jitpack Donate

What is TinyVG?

SVG is a horribly complex format and an overkill for most projects. The specification includes way too many edge cases so implementing a new SVG renderer will always have drawbacks or missing pieces.

TinyVG tries to be simpler. Fewer features, but powerful enough to cover 90% of use cases. ~ https://tinyvg.tech

example

Convert SVG into TVG

Make sure to set the following export settings:

Then simply convert your SVG into a TVG here: https://svg-to-tvg-server.fly.dev/

Only linear and radial gradients with two points are supported. Everything else should convert decently enough.

Video

Here's a youtube video showcasing the library:

Youtube video tutorial

Example

public class Lwjgl3Launcher {
  public static void main(String[] args) {
    createApplication();
  }

  private static Lwjgl3Application createApplication() {
    return new Lwjgl3Application(new Main(), getDefaultConfiguration());
  }

  private static Lwjgl3ApplicationConfiguration getDefaultConfiguration() {
    Lwjgl3ApplicationConfiguration configuration = new Lwjgl3ApplicationConfiguration();
    // By default, stencils are disabled, we need those though. So let's enable them here (It's the 6th value. Change that to >= 2).
    configuration.setBackBufferConfig(8, 8, 8, 8, 16, 2, 0);
    // ...

    // In a legacy desktop project it's:
    config.stencils = 2; // >= 2
    return configuration;
  }
}

public class Example extends ApplicationAdapter {
  private TinyVG tvg;
  private TinyVGShapeDrawer drawer;
  private Viewport viewport = new XXXViewport(xxx, xxx);

  public void create() {
    var assetLoader = new TinyVGAssetLoader();
    tvg = assetLoader.load("file.tvg"); // only works with the binary file format

    // TinyVGShapeDrawer requires a 1x1 white pixel file,
    // so either create one in your favourite art program or
    // use the other constructor which creates one for you.
    // https://github.com/lyze237/gdx-TinyVG/blob/main/src/test/resources/pixel.png
    drawer = new TinyVGShapeDrawer(new SpriteBatch(), new TextureRegion(new Texture("pixel.png")));
    drawer = new TinyVGShapeDrawer(new SpriteBatch());

    // You're also able to create a texture region directly out of a tvg file:
    var tvgRegion = TinyVGIO.toTextureRegion(tvg, drawer);
  }

  public void render() {
    Gdx.gl.glClearColor(0.25f, 0.25f, 0.25f, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    viewport.apply();

    drawer.getBatch().setProjectionMatrix(viewport.getCamera().combined);

    // Centers origin and rotates it.
    tvg.centerOrigin();
    tvg.setRotation(tvg.getRotation() + 10 * Gdx.graphics.getDeltaTime());

    drawer.getBatch().begin();
    tvg.draw(drawer);
    drawer.getBatch().end();
  }

  @Override
  public void resize(int width, int height) {
    viewport.update(width, height, true);
  }
}

Alternatively you can load it via an AssetManager

public class Example extends ApplicationAdapter {
  private TinyVG tvg;
  private TinyVGShapeDrawer drawer;
  private Viewport viewport = new XXXViewport(xxx, xxx);

  public void create() {
    var assetManager = new AssetManager();
    assetManager.setLoader(TinyVG.class, new TinyVGAssetLoader());

    assetManager.load("square.tvg", TinyVG.class);

    assetManager.finishLoading();

    var tvg = assetManager.get("square.tvg", TinyVG.class);
  }
}

Or directly create a texture region out of it:

public class Example extends ApplicationAdapter {
  public void create() {
    var drawer = new TinyVGShapeDrawer(new SpriteBatch(), new TextureRegion(new Texture("pixel.png")));

    var assMan = new AssetManager();
    assMan.setLoader(TinyVG.class, new TinyVGAssetLoader());
    assMan.setLoader(TinyVGTextureAssetLoader.Result.class, new TinyVGTextureAssetLoader());

    assMan.load(file, TinyVGTextureAssetLoader.Result.class, new TinyVGTextureAssetLoader.Parameters(drawer));

    assMan.finishLoading();

    tvg = assMan.get(file, TinyVGTextureAssetLoader.Result.class).getTextureRegion();
  }
}

Setters

The TinyVG class comes with a couple setters to adjust render options:

Specification implementation status

https://tinyvg.tech/download/specification.pdf

Everything is implemented according to the specification.pdf except:

Installation

  1. Add ShapeDrawer as dependency (See their readme for instructions).

  2. Open or create gradle.properties in the root folder of your project, add the following line:

gdxTinyVGVersion=VERSION

Check Jitpack for the latest version and replace VERSION with that.

  1. Add the jitpack repo to your build file.
allprojects {
    repositories {
        // ...
        maven { url 'https://jitpack.io' }
    }
}
  1. Add that to your core modules dependencies inside your root build.gradle
project(":core") {
    // ...

    dependencies {
        // ...
        implementation "com.github.lyze237:gdx-TinyVG:$gdxTinyVGVersion"
    }
}

Html/Gwt project

  1. Gradle dependency:
implementation "com.github.lyze237:gdx-TinyVG:$gdxTinyVGVersion:sources"
  1. In your application's .gwt.xml file add (Normally GdxDefinition.gwt.xml):

<inherits name="dev.lyze.tinyvg"/>

Help

How to test

By default, if you run ./gradlew test gradle runs headless tests. If you want to test lwjgl tests (so with an actual gui), then you need to run them with ./gradlew test -Plwjgl=true

Set environment variable SLEEPY to a millisecond number to sleep between each LWJGL test. (For example: SLEEPY=3000 would wait 3 seconds after every test.)