Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.

Related tags

Graphics nanovg
Overview

This project is not actively maintained.

NanoVG

NanoVG is small antialiased vector graphics rendering library for OpenGL. It has lean API modeled after HTML5 canvas API. It is aimed to be a practical and fun toolset for building scalable user interfaces and visualizations.

Screenshot

screenshot of some text rendered witht the sample program

Usage

The NanoVG API is modeled loosely on HTML5 canvas API. If you know canvas, you're up to speed with NanoVG in no time.

Creating drawing context

The drawing context is created using platform specific constructor function. If you're using the OpenGL 2.0 back-end the context is created as follows:

#define NANOVG_GL2_IMPLEMENTATION	// Use GL2 implementation.
#include "nanovg_gl.h"
...
struct NVGcontext* vg = nvgCreateGL2(NVG_ANTIALIAS | NVG_STENCIL_STROKES);

The first parameter defines flags for creating the renderer.

  • NVG_ANTIALIAS means that the renderer adjusts the geometry to include anti-aliasing. If you're using MSAA, you can omit this flags.
  • NVG_STENCIL_STROKES means that the render uses better quality rendering for (overlapping) strokes. The quality is mostly visible on wider strokes. If you want speed, you can omit this flag.

Currently there is an OpenGL back-end for NanoVG: nanovg_gl.h for OpenGL 2.0, OpenGL ES 2.0, OpenGL 3.2 core profile and OpenGL ES 3. The implementation can be chosen using a define as in above example. See the header file and examples for further info.

NOTE: The render target you're rendering to must have stencil buffer.

Drawing shapes with NanoVG

Drawing a simple shape using NanoVG consists of four steps: 1) begin a new shape, 2) define the path to draw, 3) set fill or stroke, 4) and finally fill or stroke the path.

nvgBeginPath(vg);
nvgRect(vg, 100,100, 120,30);
nvgFillColor(vg, nvgRGBA(255,192,0,255));
nvgFill(vg);

Calling nvgBeginPath() will clear any existing paths and start drawing from blank slate. There are number of number of functions to define the path to draw, such as rectangle, rounded rectangle and ellipse, or you can use the common moveTo, lineTo, bezierTo and arcTo API to compose the paths step by step.

Understanding Composite Paths

Because of the way the rendering backend is build in NanoVG, drawing a composite path, that is path consisting from multiple paths defining holes and fills, is a bit more involved. NanoVG uses even-odd filling rule and by default the paths are wound in counter clockwise order. Keep that in mind when drawing using the low level draw API. In order to wind one of the predefined shapes as a hole, you should call nvgPathWinding(vg, NVG_HOLE), or nvgPathWinding(vg, NVG_CW) after defining the path.

nvgBeginPath(vg);
nvgRect(vg, 100,100, 120,30);
nvgCircle(vg, 120,120, 5);
nvgPathWinding(vg, NVG_HOLE);	// Mark circle as a hole.
nvgFillColor(vg, nvgRGBA(255,192,0,255));
nvgFill(vg);

Rendering is wrong, what to do?

  • make sure you have created NanoVG context using one of the nvgCreatexxx() calls
  • make sure you have initialised OpenGL with stencil buffer
  • make sure you have cleared stencil buffer
  • make sure all rendering calls happen between nvgBeginFrame() and nvgEndFrame()
  • to enable more checks for OpenGL errors, add NVG_DEBUG flag to nvgCreatexxx()
  • if the problem still persists, please report an issue!

OpenGL state touched by the backend

The OpenGL back-end touches following states:

When textures are uploaded or updated, the following pixel store is set to defaults: GL_UNPACK_ALIGNMENT, GL_UNPACK_ROW_LENGTH, GL_UNPACK_SKIP_PIXELS, GL_UNPACK_SKIP_ROWS. Texture binding is also affected. Texture updates can happen when the user loads images, or when new font glyphs are added. Glyphs are added as needed between calls to nvgBeginFrame() and nvgEndFrame().

The data for the whole frame is buffered and flushed in nvgEndFrame(). The following code illustrates the OpenGL state touched by the rendering code:

	glUseProgram(prog);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
	glFrontFace(GL_CCW);
	glEnable(GL_BLEND);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_SCISSOR_TEST);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	glStencilMask(0xffffffff);
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
	glStencilFunc(GL_ALWAYS, 0, 0xffffffff);
	glActiveTexture(GL_TEXTURE0);
	glBindBuffer(GL_UNIFORM_BUFFER, buf);
	glBindVertexArray(arr);
	glBindBuffer(GL_ARRAY_BUFFER, buf);
	glBindTexture(GL_TEXTURE_2D, tex);
	glUniformBlockBinding(... , GLNVG_FRAG_BINDING);

API Reference

See the header file nanovg.h for API reference.

Ports

Projects using NanoVG

License

The library is licensed under zlib license Fonts used in examples:

Discussions

NanoVG mailing list

Links

Uses stb_truetype (or, optionally, freetype) for font rendering. Uses stb_image for image loading.

Issues
  • The rendered result doesn't look nice

    The rendered result doesn't look nice

    I was trying to render circles on iPhone 5S. But the circle doesn't look smooth as a circle even in Retina display. I tried to change the mediump to highp but the result was not improved.

    This picture shows the result I got, and I enlarged it 2x in Photoshop so it's more clear to see the result is not smooth. nanovg_circle

    The code I was using to render the circle is as follow.

    const int kCenterX = (GetWidth() + 1) / 2;
    const int kCenterY = (GetHeight() + 1) / 2;
    
    nvgBeginPath(context);
    nvgCircle(context, kCenterX, kCenterY, (GetWidth() - 1) / 2 - 2);
    nvgFillColor(context, nvgRGBA(110, 201, 235, 180));
    nvgFill(context);
    
    nvgBeginPath(context);
    nvgCircle(context, kCenterX, kCenterY, (GetWidth() - 1) / 2 - 1);
    nvgStrokeColor(context, nvgRGBA(255, 255, 255, 255));
    nvgStrokeWidth(context, 3);
    nvgStroke(context);
    
    nvgBeginPath(context);
    nvgCircle(context, kCenterX, kCenterY, (GetWidth() - 1) / 2 - 7);
    nvgFillColor(context, nvgRGBA(255, 255, 255, 255));
    nvgFill(context);
    

    The environment for setting OpenGL and nanovg context up is also very intuitive like this: https://github.com/ollix/moui/blob/master/moui/widgets/widget_view.cc

    opened by olliwang 29
  • Weird line on shape boundary

    Weird line on shape boundary

    This snippet tries to stroke and fill a rectangle with the same color. The result should still look like a rectangle without stroke, but it isn't.

    struct NVGcontext* context = nvgCreateGLES2(GetWidth(), GetHeight(), NVG_ANTIALIAS);
    
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);
    
    // Fill and stroke for the same rectangle with the same color.
    nvgBeginFrame(context, GetWidth(), GetHeight(), GetContentScaleFactor());
    nvgBeginPath(context);
    nvgRect(context, 0, 0, width(), height());
    nvgFillColor(context, nvgRGBA(110, 201, 235, 255));
    nvgStrokeColor(context, nvgRGBA(110, 201, 235, 255));
    nvgStrokeWidth(context, 10.0f);
    nvgFill(context);
    nvgStroke(context);
    nvgEndFrame(context);
    

    The result picture looks like this, pretty weird. nanovg

    opened by olliwang 27
  • Two framebuffers conflict with each other

    Two framebuffers conflict with each other

    I'm trying to make two dynamic framebuffer brushes and draw with them, but I have problem with color rendering - colors change and blink randomly.

    The exact code:

        // Creating framebuffer 1
    
        if (fb == NULL) fb = nvgluCreateFramebuffer(vg, 100, 100, NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
        if (fb == NULL) {
            printf("Could not create FBO.\n");
            return;
        }
    
        nvgluBindFramebuffer(fb);
        glViewport(0, 0, 100, 100);
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
        nvgBeginFrame(vg, 100, 100, 1);
    
        nvgBeginPath(vg);
        nvgRoundedRect(vg, 0, 0, 50.0f, 50.0f, 10.0f);      // Round rect
        nvgFillColor(vg, nvgRGB(255, 128, 128));            // Red color
        nvgFill(vg);
    
        nvgEndFrame(vg);
    
        // Creating framebuffer 2
    
        if (fb2 == NULL) fb2 = nvgluCreateFramebuffer(vg, 100, 100, NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
        if (fb2 == NULL) {
            printf("Could not create FBO.\n");
            return;
        }
        nvgluBindFramebuffer(fb2);
        glViewport(0, 0, 100, 100);
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
        nvgBeginFrame(vg, 100, 100, 1);
    
        nvgBeginPath(vg);
        nvgRect(vg, 0, 0, 50.0f, 50.0f);                // Rectangle
        nvgFillColor(vg, nvgRGB(128, 255, 128));        // Green color
        nvgFill(vg);
    
        nvgEndFrame(vg);
    
        // Rendering the main screen
    
        nvgluBindFramebuffer(0);
    
        NVGpaint fbPaint = nvgImagePattern(vg, 0, 0, 50, 50, 0, fb->image, 1.0f);
        NVGpaint fbPaint2 = nvgImagePattern(vg, 0, 0, 200, 200, 0, fb2->image, 0.5f);
    
        glfwGetWindowSize(window, &winWidth, &winHeight);
        glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
    
        // Calculate pixel ration for hi-dpi devices.
        pxRatio = (float)fbWidth / (float)winWidth;
    
        // Update and render
        glViewport(0, 0, fbWidth, fbHeight);
        glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    
        nvgBeginFrame(vg, fbWidth, fbHeight, pxRatio);
    
        nvgBeginPath(vg);
        nvgRect(vg, 0.0f, 0.0f, winWidth, winHeight);
        nvgFillPaint(vg, fbPaint);
        nvgFill(vg);
    
        nvgBeginPath(vg);
        nvgRect(vg, 0.0f, 0.0f, winWidth, winHeight);
        nvgFillPaint(vg, fbPaint2);
        nvgFill(vg);
    
        nvgEndFrame(vg);
    

    Result: ss1 ss2

    The correct result (as I expect it) should be big green semi-transparent squares over little pink round-rect squares. The actual result has correct shape, but colors blink and change randomly each frame between green, pink and black. Colors of both layers change independently.

    What am I doing wrong?

    opened by bigfatbrowncat 19
  • android example?

    android example?

    Hello, in the issues, several people seem to talk about using nanovg on android like it was nothing. However, the examples all use glfw, which is not available on android. Someone was making SDL port (judging from the issues), but didn't share it anywhere. And the bgfx port is plagued with c++, and their 'c99 api' doesn't extend to nanovg, that they felt the need to c++-ize as well. What is it that I am missing? Why can't I just make a simple app for android without using java? Can someone please help me understand how to use nanovg on android? Just drawing, touch and ideally keyboard, but I guess I would rather make my own keyboard then use c++ just because bgfx author does. Sorry to bother you, but it seems like making C apps shouldn't be as difficult as it seems to me right now. Thanks for help :)

    opened by Mis012 18
  • Can't get font-rendering to work at all

    Can't get font-rendering to work at all

    For technical reasons I can't use glfw, so I had to roll my own window and context creation. After some fidgeting, I got NanoVG to work, so I can draw lines etc. now.

    But no text will ever render.

    I've reduced my render function to

    nvgBeginFrame(vg, width, height, 1.f);
    renderGraph(vg, 10, 10, &fps);
    nvgEndFrame(vg); 
    

    I've loaded a font etc. and in renderGraph the cursor position changes (nvgText returns a higher X coordinate than I feed in), but still I can't see any text.

    I've made sure the font is loaded correctly etc. It seems to be some sort of culling is going on, but no amount of glEnable/glDisable calls has been able to fix it.

    The weirdest thing is that I can't run a debug-version. It crashes during the first memset() in fonsCreateInternal(). No crashes in release...

    Please help if you can.

    opened by reFX-Mike 18
  • Image color is wrong in OpenGL ES 2

    Image color is wrong in OpenGL ES 2

    I was trying to draw an image with white background and 0.5 alpha value as this one: screen shot 2014-06-26 at 21 41 15

    It works fine when running on Mac (OpenGL 2).. screen shot 2014-06-26 at 21 57 00

    And works fine for iPhone simulator.. screen shot 2014-06-26 at 21 48 45

    But shows weird color when running on a real iPhone device (OpenGL ES 2) img_2552

    The drawing code is as follow:

    nvgBeginPath(context);
    nvgRect(context, 0, 0, GetWidth(), GetHeight());
    nvgFillColor(context, nvgRGBA(255, 0, 0, 255));
    nvgFill(context);
    
    struct NVGpaint paint = nvgImagePattern(context, 0, 0, 256, 256, 0, image_handle, NVG_NOREPEAT, 1);
    nvgBeginPath(context);
    nvgRect(context, 30, 30, 256, 256);
    nvgFillPaint(context, paint);
    nvgFill(context);
    

    So I guess something is wrong in the latest update?

    opened by olliwang 18
  • Incorrect width of

    Incorrect width of " " (space) character

    It looks like if I measure a single white space character with nvgTextBounds(..., bounds), I every time get bounds[0] = -1 and bounds[2] = 1, no matter which font size is selected. That leads to different behavior if I render "Some text" by a single string and "Some" + " " + "text" word by word with spaces between.

    What's the cause of this? Is this a bug?

    opened by bigfatbrowncat 17
  • nanovg is super slow on iPad 2/iPad 3/iPhone 4s

    nanovg is super slow on iPad 2/iPad 3/iPhone 4s

    Hi, is it possible to improve the performance on OpenGL ES further? I am developing an app for iOS 8 and usually I can get over 50 FPS for iPhone 6/5s without problem. But, it's pretty hard to get over 10 FPS on iPad 2/iPad 3/iPhone 4s and unfortunately all of these devices are still supported by iOS 8.

    I was trying to run the Instruments with the OpenGL ES Analyzer module for iPad 2/3, and it seems the reason all pointing to the glDrawArrays(GL_TRIANGLE_XXXXX, XX, XX) command.

    screen shot 2014-11-20 at 23 30 12

    Here are some suggestions from the Instruments for the top four situations that happened mostly. Does this help? Thanks.

    1. Dependent Texture Sampling

    The fragment shader performed dependent texture reads, which are slower than non-dependent texture reads. Dependent texture reads happen when the texture coordinates are modified in the fragment shader, or when the Project or Bias variants of the texture sampling functions are called. Use dependent texture samples sparingly. If you modify texture coordinates in the fragment shader, try to move the calculations of the texture coordinates to the vertex shader so that they occur once per vertex instead of once per fragment. This can help improve performance.

    screen shot 2014-11-20 at 23 46 52

    1. Fragment Shader Dynamic Branching + Memory Access

    Your fragment shader contains dynamic branch instructions and accesses main memory (either because of data spilling or a dependent texture sampling operation), which is an expensive combination for the GPU. To improve performance, rework the shader to eliminate one or more of these characteristics.

    screen shot 2014-11-20 at 23 47 14

    1. Loss Of Depth Test Hardware Optimizations

    Depth test hardware optimizations allow the GPU to skip calculations for pixels that would be discarded by the depth test.

    Your application used the following feature: discard fragment in a fragment shader. If possible, rework your rendering pipeline to avoid using this feature. If you must draw using this feature, attempt to do so at the end of each frame while covering the fewest number of pixels possible.

    screen shot 2014-11-20 at 23 47 23

    1. Uninitialized Texture Data

    Your application made a drawing call using a texture that contains uninitialized data. If a draw call uses uninitialized data, the rendering results are incorrect and unpredictable. One way to fix this issue is to provide image data to any TexImage2D calls instead of a NULL pointer.

    screen shot 2014-11-20 at 23 47 38

    opened by olliwang 15
  • How to Get Feature Pull Requests Accepted

    How to Get Feature Pull Requests Accepted

    I am currently working on a project that is using NanoVG. It's called Wima, and NanoVG is what does all of the drawing.

    However, I have a problem: in order for Wima to be feature complete, I need a certain feature, specifically Picking/Hit Regions (#401). I have already created the pull request and I keep merging changes from this repo into mine to keep it merge-ready. Despite all of that, nothing has been said about it, even though bug fix pull requests have been accepted.

    How can I get this pull request accepted?

    opened by gavinhoward 14
  • Proposal: Ensure all required GL states are correct in beginFrame

    Proposal: Ensure all required GL states are correct in beginFrame

    It appears NanoVG doesn't set all states required for it to render correctly, which increases the amount of boilerplate needed on the client side, and also causes all kinds of hard to diagnose side effects if the user is making use of other blackbox GL components.

    I'm not sure why this was done, perhaps to make multiple subsequent draw calls more efficient, but in practice, this should not make any noticeable differences in performance.

    Among the states mentioned in the docs, which are glEnable(GL_CULL_FACE) glCullFace(GL_BACK) glEnable(GL_BLEND) glDisable(GL_DEPTH_TEST)

    I also had to take care that these states are initialized as follows (still probably not a complete list): glDisable(GL_SCISSOR_TEST) glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE) glStencilMask(0xffffffff) glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) glStencilFunc(GL_ALWAYS, 0, 0xffffffff)

    And then there are other obvious ones, which are glViewport(0,0,frame_width,frame_height) glClearColor(0,0,0,0) glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)

    I would like to propose that the alpha_blend argument in beginFrame is converted to a general flags field, NVG_PREMULTIPLIED_ALPHA and NVG_STRAIGHT_ALPHA control bit 0, and a new NVG_NAKED_FRAME field is introduced, which, when set, does not make any of the above calls; so the default would be that all states are set correctly and the framebuffer is cleared for drawing.

    For more granular control, if desired, NVG_NAKED_FRAME could also be a composite of three bits, which is at most NVG_KEEP_STATES (no state changes), NVG_KEEP_VIEWPORT (no viewport change) and NVG_KEEP_FRAMEBUFFER (no clear).

    If none or not all of the proposed changes find their way into the codebase, I'd appreciate if the docs would be expanded by the additionally required boilerplate so others don't run into the same problems.

    opened by paniq 14
  • Bug ? The glyphs rendered are not on the same line

    Bug ? The glyphs rendered are not on the same line

    Strange text rendering results when I render English and Chinese characters at the same time

    Here is the rendering results of nanovg and sdl_ttf Screenshot_20220210_182822

    Compared to SDL_ TTF,The Chinese glyphs and English glyphs seem to be not in the same line It was much lower than English glyphs

    It looks doesnot very good

    Here is the code

    
    //text and the fontsize
    const char *text = "啊AB啊C啊D啊E啊F界 Hello哈哈哈World";
    float fontsize = 12;
    
    //Setup nanovg ctxt
    ...
    //Load ttf
    //Microsoft Ya Hei
    int f = nvgCreateFont(ctxt,"font","./msyh.ttc");
    TTF_Font *ttf = TTF_OpenFont("./msyh.ttc",fontsize);
    
    //SDL_TTF Render text 
    SDL_Color color;
    color.r = 0;
    color.g = 0;
    color.b = 0;
    color.a = 255;
    
    SDL_Surface *surf = TTF_RenderUTF8_Blended(ttf,text,color);
    
    TTF_CloseFont(font);
    
    int image = nvgCreateImageRGBA(
            ctxt,
            surf->w,
            surf->h,
            NVG_IMAGE_NEAREST,
            (Uint8*)surf->pixels
    );
    ...
    
    //Clear background
    //nvgBeginFrame ...
    
    //nanovg draw text
    nvgBeginPath(ctxt);
    nvgFillColor(ctxt,nvgRGB(0,0,0));
    nvgFontFaceId(ctxt,f);
    nvgFontSize(ctxt,fontsize);
    nvgTextAlign(ctxt,NVG_ALIGN_TOP |  NVG_ALIGN_LEFT);
    nvgText(ctxt,100,300,text,nullptr);
    nvgFill(ctxt);
    //SDL_ttf draw text
    nvgBeginPath(ctxt);
    nvgRect(ctxt,100,100,surf->w,surf->h);
    nvgFillPaint(ctxt,nvgImagePattern(ctxt,
          100,
          100,
          surf->w,
          surf->h,
          0.0f/180.0f*NVG_PI,
          image,
          1.0f
     ));
    nvgFill(ctxt);
    
    
    //EndFrame ...
    //SwapBuffer ...
    

    Here is the font msyh.zip

    Can anyone help me?

    opened by BusyStudent 13
  • Fixed Issue #631

    Fixed Issue #631

    My idea to fix issue #631 is to have a list for vaos (like how textures are handled) that is updated each frame and a new vao is created when a valid one doesn't exist. Therefore, this fixes the problem by creating a vao for each context that doesn't already have one. However, I can see the potential problem that a vao handle that is valid in one context for the correct nvg vao could also be correct in a different context for a different vao. However, to solve this problem would require a major overhaul to the nanovg api. We'd need a way for users to separate shared context state from per-context state and such. Let me know your thoughts and I am open to any ideas.

    opened by lochnessdragon 0
  • OpenGL 3 context sharing is broken

    OpenGL 3 context sharing is broken

    I'm trying to use NanoVG to render to multiple windows whilst sharing the same OpenGL context to resolve the reasons outlined in Issue #379. However, since the OpenGL 3 implementation uses VAOs, this breaks rendering on the second window.

    Expected:

    • I'd expect both windows to render the content correctly.

    Actual:

    • The second window doesn't render anything and the error 0x000501 after tex paint tex is printed to the console.

    To recreate:

    • Create a window with an OpenGL3 context
    • Create an OpenGL 3 NanoVG object
    • Create a second window w/ a shared context
    • Render something to both windows
    opened by lochnessdragon 2
  • NanoVG string width

    NanoVG string width

    Hi. I am currently trying to calculate the width of my text using nvgTextBounds, however it seems to only work with a font size of 12px. I have tried to divide the result by 12 then multiply it by the target font size, yet this still leads to small deviations especially after a lot of characters.

    Is there any other way to get string width, or how can I improve my current method?

    Can anyone help me?

    opened by nxtdaydelivery 12
  • Restore previous shader program on nvgEndFrame

    Restore previous shader program on nvgEndFrame

    This change restores the previous shader program instead of setting it to 0 on nvgEndFrame()/renderFlush().

    This will also help when using nanovg with other graphics libraries that manage a default shader like Cinder.

    opened by clinthidinger 2
Owner
Mikko Mononen
Mikko Mononen
OpenGL®-Starter is a template for your upcoming OpenGL Projects which has been compiled to run the most basic Hello World OpenGL Program from LearnOpenGL.com.

OpenGL®-Starter OpenGL®-Starter is a template for your upcoming OpenGL Projects which has been compiled to run the most basic Hello World OpenGL Progr

Kushagra 8 May 27, 2022
Orbit is a multiplatform-focus graphical engine build on top of OpenGl, ImGui

Orbit Engine Orbit is a multiplatform-focus graphical engine build on top of OpenGl, ImGui and more... The development of the engine is documented via

Madsycode 11 Jul 3, 2021
A very simple and light-weight drawing app made with qt and C++.

Blackboard A very simple and light-weight drawing app made with qt and C++. It supports tablet and pen pressure with the help of QTabletEvents. So you

null 1 Nov 15, 2021
Pencil2D is an animation/drawing software for Windows, macOS, Linux, and FreeBSD.

Pencil2D is an animation/drawing software for Windows, macOS, Linux, and FreeBSD. It lets you create traditional hand-drawn animation (cartoon) using both bitmap and vector graphics. Pencil2D is free and open source.

Pencil2D 1.1k Jul 1, 2022
An immediate-mode, renderer agnostic, lightweight debug drawing API for C++

Debug Draw An immediate-mode, renderer agnostic, lightweight debug drawing API for C++. License This software is in the public domain. Where that dedi

Guilherme Lampert 433 Jun 25, 2022
A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input

GLFW Introduction GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platf

GLFW 9.3k Jul 5, 2022
A legacy OpenGL simulator for OpenGL 4.4, written in C++.

the-ancient-tri A legacy OpenGL simulator for OpenGL 4.4, written in C++. Why? My Uni forces us to use legacy OpenGL (eww!), and I didn't want to lear

Mohammad Issawi 4 Feb 10, 2022
rlottie is a platform independent standalone c++ library for rendering vector based animations and art in realtime

rlottie rlottie is a platform independent standalone c++ library for rendering vector based animations and art in realtime. Lottie loads and renders a

Samsung 697 Jun 28, 2022
2D Vector Graphics Engine Powered by a JIT Compiler

Blend2D 2D Vector Graphics Powered by a JIT Compiler. Official Home Page (blend2d.com) Official Repository (blend2d/blend2d) Public Chat Channel Zlib

Blend2D 1.1k Jun 25, 2022
Utility on top of the Flutter Driver API that facilitates measuring the performance of your app in an automated way created by Very Good Ventures 🦄

Very Good Performance Developed with ?? by Very Good Ventures ?? Utility on top of the Flutter Driver API that facilitates measuring the performance o

Very Good Open Source 72 Jun 24, 2022
Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal

Low Level Graphics Library (LLGL) Documentation NOTE: This repository receives bug fixes only, but no major updates. Pull requests may still be accept

Lukas Hermanns 1.4k Jul 2, 2022
Yet another Chip-8 interpreter, this time written in C++ using GLFW and OpenGL as its graphics library 💻

Yet another Chip-8 interpreter, but this time with a beautiful interface ??

Akshit Garg 26 Jun 4, 2022
Epoxy is a library for handling OpenGL function pointer management for you

Epoxy is a library for handling OpenGL function pointer management for you. It hides the complexity of dlopen(), dlsym(), glXGetProcAddress(), eglGetP

Eric Anholt 545 Jun 27, 2022
3D engine from scratch (without OpenGL or any other 3D graphics library)

Simple 3d engine based on SFML library. I tried to make this engine powerful and easy to understand.

Vectozavr 21 Jun 4, 2022
OpenGL Object Loading can load virtually every 3d.obj file you can find on the internet, without using another object loading library

OpenGL Object Loading can load virtually every 3d.obj file you can find on the internet, without using another object loading library (assimp for example). The program can load Object with 12M+ triangles and more

Phan Sang 4 Jun 21, 2022
NodeEditor basiced on Qt and OpenGL/CV

Vapour 基于Qt的轻量级的节点式几何建模工具与shader材质生成工具 可能加入图像处理(合成)的功能 日志: 2021-5-17: 完成背景绘制,右键菜单,节点连线,节点删除,初步拓扑排序 (细节)连线位于节点层级之下,使用lambda处理右键菜单slot,节点创建生成在鼠标位置处 2021

Cuimi 13 Apr 14, 2022
Tetris written with C++ and OpenGL.

Tetrec This is yet another Tetris game, which is in 3D, written using C++ and OpenGL 2.1, aiming at being lightweight towards not-so-beefy computers (

Lê Duy Quang 14 Jan 17, 2022
A simple single point light shadow mapping with OpenGL 3.3 and C++

omni-directional-light-example Using OpenGL 3.3 with C++ Basically a single light map, no lighting model was used Usage Build the executable outside A

Mohammad Issawi 4 Feb 10, 2022
A simple mirror simulator made with OpenGL 3.3 and C++

Mirror-Example A simple mirror example using OpenGL 3.3 with C++. Theory It basically constructs a camera at the mirror location, by determining its v

Mohammad Issawi 4 Feb 10, 2022