Getting back to work! (Google Test, vgc::graphics::Engine, vgc::core::Array)

February 5, 2020

Hi everyone!

Now that VPaint 1.7 has been released, I was able to work 100% on the actual application code for VGC, and life feels productive again!

I made the chart above to get a better overview of where I have spent my time in the year 2019. And it was indeed mostly just work on the website, on the installers, and on VPaint, so there was basically zero new features added to VGC in 2019. We can see this clearly on the chart: the number of lines of code is quite flat in 2019 (note that the website and installers require a lot of lines of code too, but they are not counted in this chart). All of this was very frustrating for me, and I can imagine frustrating for you too.

But this necessary evil being in the past, let's now focus on the future :-)

It felt really good the past 3 weeks to see good progress on VGC. Well... progress you can't see by opening the app, but progress regardless. I have been working on three things:

Google Test

I integrated a new testing framework called Google Test (as you can imagine, this is developed by Google, and this is what they use internally), which makes it possible to write unit tests for my C++ code. A unit test is a small additional piece of code which is written to ensure that the actual primary code does what it is supposed to do. For example, if you test a hypothetical vgc::add(x, y) function, you might test it like this:

int x = vgc::add(1, 1);
EXPECT_TRUE(x == 2);

All these tests are automatically run each time any change is made to the code, so not only they make it possible to verify during development that everything works as excepted, but it also verifies that everything keeps working as expected when we modify the code later. This is very important as the codebase becomes larger over time.

Note that I already had a way to do unit tests in Python, and I had written a few of such tests already. What's new is that I can now write tests in C++ too, which is important for testing C++ code which won't have Python bindings (low-level stuff that doesn't make sense in Python).

vgc::graphics::Engine

As I have mentioned in previous posts, I have decided to rely less and less on Qt (a library for UI development), in order to have more fine-grain control over performance. Indeed, currently, the QtWidgets module which I use can only use OpenGL as backend for GPU acceleration, and OpenGL is notably getting phased out by Apple, in favor of their own graphics API called Metal.

And overall, I just slowly started to lose trust in Qt for desktop applications. Since the past few years, they've spent a lot of time to support embedded devices, but their support for desktop applications is in my experience getting worse every year, with new bugs surfacing every release and no positive signs of fixing them.

In light of all this, I am writing my own low-level graphics API, called vgc::graphics::Engine, which I will use throughout VGC to draw the UI myself, for example, things like:

engine->drawRectangle(...);
engine->drawTriangles(...);

So instead of using the builtin UI widgets provided by Qt (QPushButton, QCheckBox, etc.), I will create my own widget classes (vgc::ui::Button, vgc::ui::CheckBox, etc.), which will directly call the low-level functions from vgc::graphics::Engine to draw themselves.

In turn, the vgc::graphics::Engine will either call OpenGL, or Metal, or Direct3D, or Vulkan, depending on platform and availability.

So far, I have implemented a very basic architecture, which only allows me to draw the whole widget with a constant color, and receive mouse clicks (for example, I did a test where clicking on the widget changes its color). And for now, it's still just using the same OpenGL backend as Qt.

My plan is to keep adding features to vgc::graphics::Engine in order to be able to implement a new Color Palette exclusively using this new engine. Once this is done, I will slowly transition existing widgets to this new Engine. One of the biggest task will be to implement text rendering, but I need this anyway to support a text tool in VGC, so it's not wasted time.

Once all existing VGC widgets are transitioned to using vgc::graphics::Engine, I will be able to completely remove the dependency with QtWidgets, which I firmly believe is the best decision in the long term. The architecture of VGC will then more closely resemble the one of Google Chrome, Blender, or Unity for example (none of them use Qt, but their own UI and graphics engine).

vgc::core::Array

This is a fundamental class I will use throughout the VGC codebase to store "sequences of elements", for example, a sequence of 2D positions to represent a drawn curve.

I was using a built-in C++ feature for this before (called std::vector), but I have now finished to implement my own, which is more adapted to the needs of VGC: it provides additional bug-detection functionality, and a more consistent API between the C++ API and the Python API.

Alright, this is all for today. Once again, thank you for your support!

Cheers,

Boris

Stay tuned

Found this news interesting? We can send the next ones straight to your inbox (around twice a month). Or we can simply let you know when VGC 1.0 is released. No spam guaranteed. You can unsubscribe at any time.