06 Screen Space & Vectors - inanevin/LinaVG GitHub Wiki

Before getting into drawing, I'd like to give a small side-note about the vector structures & screen space coordinates used in LinaVG.

Vectors

LinaVG uses it's own vector structures to handle data, respectively LinaVG::Vec2 and LinaVG::Vec4. You can use these in your code while passing data, but this is usually not convenient in many apps where you would have your own vector structs with all the functionality. In such cases, it's a good idea to convert these structures into each other and keep using your own vectors instead of LinaVG's. You can do this in two ways:

First, the obvious way is to write helper functions:

LinaVG::Vec2 MyVecToLina(const MyVec2& v)
{
    return LinaVG::Vec2(v.x, v.y);
}

Or a better way, you can write conversion constructors on your own vector to auto-convert and keep using your own vectors:

struct MyVec2
{
    explicit MyVec2(const Vec2& v)
        : x(v.x), y(v.y){};
    explicit MyVec2(float x, float y)
        : x(x), y(y){};
    operator Vec2()
    {
        return Vec2{x, y};
    }

    float x = 0.0f;
    float y = 0.0f;
};

Thus, you can call LinaVG API and pass your own vectors inside the functions, which the explicit conversion will convert to LinaVG::Vec2 during the call.

const MyVec2 min = MyVec2(0,0), max = MyVec2(100,100);
LinaVG::DrawRect(min, max, ....);

Coordinate Systems

LinaVG assumes that the coordinates (0,0) corresponds to the top-left corner of your screen, while the coordinates (screenWidth, screenHeight) corresponds to the bottom-right corner. Everything in LinaVG is drawn & used by this assumption, e.g. increasing the Y coordinate of a rectangles max coordinate property will stretch the rectangle downwards on the screen. This is also true for UVs, for instance:

  • Rectangle top-left corner, is indexed as 0, and it's UV is: 0,0
  • Rectangle top-right corner, index 1, UV: 1,0
  • Rectangle bottom-right, index 2, UV: 1,1
  • Rectangle bottom-left, index 3, UV: 0, 1

If your application does not use this approach, it may be a better idea to to write some explicit vector conversion functions so that when you pass a coordinate vector to LinaVG it converts from your coordinate space into LinaVGs. In most cases only Y coordinates would differ, e.g. some apps assume top-left is (0, screenHeight), in which case a simple y = screenHeight - y conversion would suffice.