Based on a quick doodle I made during a D&D session when the rest of the party were having a conversation in Dwarven with an NPC. I find it easier to roleplay and avoid meta-gaming when I'm not aware of things my character isn't supposed to know, so I try to distract myself when conversations happen in a language she doesn't understand.
This started out as a speed painting attempt in Krita, but I ended up spending too much time getting the face to look decent. I also had way too much fun fiddling with refractions and caustics. Total time spent on this was 3-4 evenings and half a Saturday.
I tried to go for a friendly-happy-kinda-drunk smile. A large part of that involved not making the smile look super creepy or malicious, which was extra difficult due to the angle and sharp teeth. Lots of dog references were used!
This time around I relied on the default distort brushes that comes with Krita. They provide similar functionality to the liquify tool in Photoshop, and were super useful in tweaking facial features during the early stages, as well as creating the refraction and caustics effect. Much easier to control than using the transform tool directly!
The recently released version 4.1 also has a new reference images tool that allows you to rotate and place multiple reference images in the viewport for quicker access. While I didn't use it a lot this time, having your reference images next to the drawing itself is useful, and saves a bit of time between sessions as the references and their positions can be stored in the .kra file itself! I'll probably end up using it a lot more in the future.
I'm a bit intimidated by how clean the line art of some artists' "doodles" are, so I figured I'd show how horrible mine can be in comparison. Maybe it's indictive of how little I practice, though for the purpose of "snapshotting" ideas and concepts they're still plenty useful! It doesn't really matter how bad they are, as long as they help you remember an idea later on.
This is what I started out with, which is something I scribbled down in a minute or two:
"Nyx" grew up on the streets, taking on odd jobs when available, stealing when necessary. Most of the jobs were mediated by the local thieves' guild. Some jobs were risky, some dangerous. One ended with her group being betrayed, used a diversion, and trapped in a cave along with the kobolds that lived there. As her employers sealed off the entrances and turned the place into a death trap, the situation quickly turned into a massacre. Venturing deeper into the cave, she eventually found herself in a room with a young kobold, backed into a corner by one of the men who had hired her.
Seeing an opportunity for revenge, she attacked. The kobold—whom she would later come to know as Ix—joined the fray, and together the two managed to bring him down.
After an awkward conversation involving broken Common, new nicknames, and lots of hand gestures, the two agreed to team up, and managed to escape together.
This drawing took a long time to complete. My goal was to draw Nyx reasonably close to how I had imagined and described her to the rest of the group, which was a bit of a problem as I could barely draw decent stick figures at the time!
In total, this iteration took me the better part of two months worth of spare time. Counting all previous attempts I've probably spent a few hundred hours on it, although that includes watching tutorials and redrawing whatever I had difficulties with until I got it mostly right.
Nyx is supposed to be a bit on the shorter side (5'3"-5'4", or 160-163cm), and one thing I found surprisingly little information on was how to draw someone at a specific height; nearly every tutorial and book I read describes how to measure proportions in "heads" (probably from Andrew Loomis' Figure drawing for all it's worth), and that the ideal height is about 8 heads tall. While heads themselves can vary a bit in size, the common scale people use still gives you a total height of around 5'8" (173cm) for women and 6' (183cm) for men. I found very few examples going into details about what to do if you wish to deviate from that.
A decent rule of thumb I eventually arrived at was that the legs would account for most of the height difference, with the torso changing some, but not much. Supposedly the head size also changes with height, but unless you are drawing a really tall or short person, it's way less noticeable. I ended up using a scale of about 7.5 heads for Nyx, with a close to average head size.
When it comes to facial details, I would've probably saved a lot of time if I had followed Andrew Loomis' method instead of kinda winging it, and then trying to correct everything after I had started coloring. If there's one thing I'd do differently next time, it's to ensure I'm really happy with the sketch or line art before moving further. It doesn't have to be perfect, but the whole image should at least feel complete before moving on to the next stage.
While it is possible to fix things after the fact, there were a lot of things I decided to leave in simply because I found them too daunting or time consuming to fix.
As with Ix, I drew Nyx with her current armor and gear. It was a fun challenge to try to incorporate everything without making it look ridiculous.
Drawn in Krita 4.0. This time on a Cintiq Pro.
When I finished this drawing I got a bit curious and decided to incorporate my drawing of Ix with this one, to see if it held up when scaled to the right relative height:
Even though the art styles and lighting don't mesh, it does kinda work! Now I just need to draw the rest of the party...
For the most part I would try to find resources as needed. The resources below contain tips and techniques I found especially useful and ended up coming back to whenever I needed to correct or tweak something.
- [Book] Andrew Loomis - Figure drawing for all it's worth (human figures, perspective, proportions)
- [Video] Sinix Design - Quick Anatomy Tips (noses, mouths, coloring)
- [Video] CG Cookie Concept - Female Character Series (sketching, coloring, hair, materials)
- [Video] koizu - How to Draw Relaxed Hands, 5 ways (hands)
After spending way too much time digging through inadequate documentation and fighting obscure errors, I figured I'd write something on my experience with writing custom widget plugins for Qt Designer, why I decided to do it, and how to debug them when things go wrong. Including Windows and Linux specific issues.
I haven't tried building this on a Mac. I imagine the experience would be similar to Linux, although there appears to be some additional steps required.
What is Qt Designer?
Qt Designer is the official UI design tool for Qt. It is used to author .ui files that describe the UI and layout of a widget using XML. UI files can be used to generate C++ code and then compiled into the application, or it can be loaded at runtime.
Qt Designer is available as both a standalone application, and integrated into Qt Creator IDE.
If used properly this system can help you separate logic and design, allowing designers to focus on UI design, and programmers to focus on the underlying logic. Of course, this rarely works out perfectly, and you will occasionally have to modify some code with your UI changes. Still, there are benefits to UI files: Prototyping, fast iteration times, tweaking, WYSIWYG design, etc.
Whether this is useful or not depends on the project, and the people working on it.
Why make a Qt Designer plugin?
While Qt Designer is not the best UI designer application I've used, it works reasonably well with the standard Qt widgets. The keyword here is standard Qt widgets; if you've ever worked on a larger project using Qt, you've almost certainly ended up making or using custom widgets. Custom widgets are great, and can vastly improve the user experience over generic widgets. The only problem is that Qt Designer doesn't know how to use them.
A common workaround is to use the base class—typically QWidget—and "promote" it in the designer. While this will compile and run just fine, you immediately lose much of what makes Qt Designer useful: it's no longer WYSIWYG. Your placeholder widget won't look correct, and won't behave like your custom widget; you need to compile and run the program to see it in action. Not only that, if your custom widget has custom properties, you can't set them from within Qt Designer.
For me, this is such a huge drawback that in the past, I've often ended up moving UI into code entirely. I assumed—incorrectly—that getting Qt Designer to work with custom widgets was a lot of work. Turns out it's actually pretty simple! Even better, the plugin code is pretty easy to maintain. In fact, I've barely touched the plugin code for my widgets since I first wrote it, even though the widgets themselves have been updated plenty of times since.
The biggest issue turned out to be loading the plugin, and—somewhat surprisingly for Qt—the documentation around that.
Writing a Qt Designer plugin
Qt does provide a pretty comprehensive example for how to write a Qt Designer plugin for a single widget. If you want to build a collection of widgets, like I've done here, you'll want to take a look at the QDesignerCustomWidgetCollectionInterface class.
The API documentation provides enough of an example to get you started. In short, you'll need to implement QDesignerCustomWidgetInterface for each widget you wish to expose as a QDesigner plugin, then you need to implement QDesignerCustomWidgetCollectionInterface to create a collection. The result will be one library with all your plugins bundled into it. Code-wise that's it really. It's not a lot of boiler-plate; most of the code is just telling Qt Designer which widgets should be bundled and how they should be presented.
The tricky part is getting Qt Designer to load your plugin. This part of the manual tells you to place the compiled library in bin/plugins/designer subdirectory of your Qt installation. But, what if you don't want or can't install your plugin in the install directory?
Gaps in the documentation
When I first attempted to write a plugin, my collection of widgets were built using QMake, and a series of .pro files. There is plenty of official HOWTOs for setting this up, and the example mentioned previously will guide you through the essential parts, assuming you're using QMake. The example and most other documentation available fails to mention some of the configuration steps QMake itself is doing behind the scenes, which is quite frustrating when you're not using QMake. Additionally, documentation on how to debug a plugin that is not working properly—along with common issues for certain platforms—is a bit scattered, and can be hard to find. If it exists at all.
Building your plugin using CMake
CMake ships with Qt modules, so building Qt programs using CMake in general works quite well. I'm not going to go through how CMake works, or how to set up a typical Qt project; there are plenty of examples out there (including my own, which also includes sip bindings for Python/PyQt5). For Qt plugins there are not as many examples and there are a few gotchas to be aware of:
Typically, a Qt project would depend on the Core, Widgets, and maybe Gui components of Qt. Since we're building a designer plugin, we'll also need to depend on the Designer component:
We also need to tell CMake where the header files are for the Designer component. If we don't, compilation will fail with a somewhat confusing "Undefined interface" error.
The rest of the setup should be similar to a normal Qt project, which I won't go through here.
A fully functional example is available on my github.
If you are using a different build system, there are a few other things you need to consider (see below).
Debugging your plugin
There is a tiny section containing some tips for debugging your plugin, but it's a bit vague and, at the time of writing makes references to QMake specific solutions.
So, if your plugin works and Qt Designer finds it, great! It'll show up in the widget list on the left, under the name and category you've specified in your plugin.
If your plugin does not work, there is... Nothing. Was there a problem loading the plugin? Did Qt Designer even find it? By default you'll get zero error messages and zero output.
Obtaining debug output
Fortunately, Qt Designer can provide debug information, if you enable it and know where to look:
If you're running Qt Designer directly you might get some hints by checking the dialog under Help->About Plugins... If the plugins were found but couldn't be loaded, this might provide a clue. If you're using Qt Creator, this might not help much, as designer plugins do not appear to show up in the list, even if they have been successfully loaded.
Set the environment variable
QT_DEBUG_PLUGINS to a non-zero value before launching Qt Designer or Qt Creator to get additional information. A pretty huge gotcha here realizing that these messages are printed using Qt's logging facilities.
On Linux (and probably Mac), this goes to the standard output, so make sure you launch Qt Designer from a terminal.
On Windows, they're sent to the debugger. In other words, you won't see anything at all unless you specifically look at the debug log stream. If you don't have a debugger attached, you can use DebugView.
Qt Designer does not mention the plugin
OK, so neither the plugin dialog, nor the debug output even mentions your plugin. This very likely means it cannot find it. Or more accurately, it's not in its search path. Qt will look for plugins in a number of places. If you don't want to install your plugin in the Qt installation directory, and if you don't want to build a custom version of Qt Designer with additional search paths, the best way is to simply set the
QT_PLUGIN_PATH environment variable before you launch Qt Designer. The linked documentation mentions this, but it fails to mention what it expects that directory to contain. A Qt plugin path should point to a directory with subdirectories, one for each plugin type. For designer plugins, this directory is called "designer". So if you have a plugin called myplugin.dll, or myplugin.so, you can place that file in e.g. "my_qt_plugins/designer/" and point
QT_PLUGIN_PATH to "my_qt_plugins".
Qt Designer complains about mixing debug and release
One platform specific issue you can run into under Windows is this warning:
The plugin 'C:/my_qt_plugins/designer/myplugin.dll' uses incompatible Qt library. (Cannot mix debug and release libraries.)
If you're not using QMake, this warning is very misleading.
It has nothing to do with the library being built in release or debug. At least not in the traditional sense; this warning is derived from json metadata embedded in the plugin. A section of this metadata is user specific and can be pretty useful if you are loading custom plugins in your application using QPluginLoader. This metadata is also printed by Qt Designer if you set
QT_DEBUG_PLUGINS as mentioned above.
As it turns out, there is a "debug" key embedded in this metadata that is set during compile. If you use QMake, this is set to false if you build release, and true if you build debug. However, this is specific to QMake. If you build your plugin using another build system that isn't Qt-aware, you'll have to set it yourself.
CMake comes with Qt modules and should do this for you.
As far as I can tell, there is no documentation for this, and I ended up having to check the source code responsible for creating the metadata. In short, if
QT_NO_DEBUG is not set when building release, Qt will think that it's a debug library and refuse to load.
This flag has other effects, such as removing
See Debugging Macros for more information.
In short, while the warning does have merit, it's entirely possible to build your library in release and still get the warning. Similarly, if your version of Qt Designer was built in debug and you accidentally build a release version of your plugin with the debug key set, things may break.
You'll also need to build your plugin so it's compatible with Qt Designer. If you're running Windows, and you're not building Qt Designer yourself, it's probably a 32bit release build.
The downloaded version of Qt Creator and Qt Designer on Windows can be built with different compilers, and won't load plugins that have not been built using the same compiler.
If Qt Designer is 32bit, make sure your plugin is 32bit too. If it's 64bit, make sure your plugin is 64bit. You also need to make sure the compiler used for building your plugin produces compatible output with the compiler used to build Qt Designer. Depending on the situation and how your plugin is used and distributed, it might be worth building your own version of Qt Designer or Qt Creator.
I'm currently playing a 5th edition D&D campaign with a group of friends that's been going strong for close to two years now. It's by far the longest running campaign I've been part of, by a wide margin!
For this campaign I decided to flesh out the backstory of my character through a series of short stories. Ix is a Kobold that my character encountered, and ended up traveling with as a child. Ix was abducted before the campaign started, and recently rescued by the party.
Since I haven't provided the group with a good description of what he looks like I decided to draw him in front of the party's stronghold!
This is probably the first piece of digital art I've finished in over a decade, experimental 3D stuff aside. Painted on a Surface Pro 2, using Ubuntu 17.10 and various betas and nightly builds of Krita 4.0 (which was released last week).
I've been meaning to use Krita for some actual art for a while now, but so far I've mostly used it to debug image data and create placeholder images. I also wanted to do something without a deadline attached to it for once.
In the end I think I spent north of 100 hours on this, trying to figure out workflows and the best way to achieve certain effects. I ended up redrawing the line art multiple times, and had similar issues with the shading because I did things in the "wrong" order. I really need to practice more.
For the most part I relied on four of the brushes in the default brush set, the color picker shortcut, and lots and lots of layers. I've also (ab)used the new text tool (for layouting), Filter Layers (non-destructive color balancing), and brush Blend Modes (to create glowing, hard lights).
I did try to use the new Colorize Mask feature, but since I like to work with large resolutions (source file is 4961x7016 pixels) it was too slow. For similar reasons I occasionally ran into issues where some of the brushes were too slow to be used properly on the canvas at the desired size. Other than that my biggest technical issue was that I eventually ran out of RAM on my Surface Pro, and that autosaving started freezing the application for tens of seconds at a time. While I did use a "large" number of layers in the final file (around 50), most of them were either disabled or did not contain much data, so this is probably something that can be vastly improved. On the flip side, I encountered zero crashes for the duration of the project!
All in all it was a pretty relaxing experience, and has made me seriously consider getting a Wacom Cintiq.
If you've got a recent AMD graphics card and are running Linux, there are two options available if you want to make full use of it:
- Use the Open Source drivers
- Use the proprietary drivers
In most cases there is no reason to go for the proprietary drivers, as the Open Source AMD drivers are better in almost every respect. Unfortunately the Open Source drivers that ship with current Ubuntu releases do not support AMD Vega.
The recently released Linux kernel 4.15 finally added support for these cards, and it looks like Ubuntu 18.04 will target this kernel. If that's the case, then Vega cards should be supported out of the box once Ubuntu 18.04 is out.
If you can't wait that long you're either going to be stuck with the proprietary driver and Ubuntu 16.04, or you can use Ubuntu 17.10 with a mainline 4.15 kernel and Open Source drivers.
Proprietary drivers and Ubuntu 16.04
If you stick with Ubuntu 16.04, then you can get the proprietary drivers here (install instructions here). The installation process is simple enough. Simply download and unpack the driver, then run the amdgpu-pro-install script:
cd ~/ wget https://www2.ati.com/drivers/linux/ubuntu/amdgpu-pro-17.50-511655.tar.xz tar tar -Jxvf amdgpu-pro-17.50-511655.tar.xz cd amdgpu-pro-17.50-511655 ./amdgpu-pro-install
Personally I've been using Ubuntu 17.04 since 16.04 is a bit too outdated for me. While 17.04 is not officially supported by the drivers, the kernel that comes with 17.04 is compatible. Unfortunately this is not the case for Ubuntu 17.10, and now Ubuntu 17.04 has been EOLed...
Open Source drivers, Ubuntu 17.10, and Linux Kernel 4.15
Fortunately Linux kernel 4.15 now supports AMD Vega cards out of the box, and as of 2018-02-01 this is available as a mainline .deb package here.
It should be noted that mainline kernels are intended for debugging and testing purposes, and are not officially supported. However, between downgrading to Ubuntu 16.04 and running with an unpatched system for three months I found this to be the better option. Getting this working is relatively simple:
- Uninstall any proprietary AMDGPU drivers you may have
- Download the appropriate .deb packages from here. Use the "generic" kernels if you aren't sure. For example:
- Verify checksums using e.g. sha256sum and the checksum file, available here
- You may also verify the CHECKSUMS file itself (instructions here)
- Install the .deb packages
cd ~/ mkdir temp cd temp wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.15/linux-headers-4.15.0-041500_4.15.0-041500.201802011154_all.deb wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.15/linux-headers-4.15.0-041500-generic_4.15.0-041500.201802011154_amd64.deb wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.15/linux-image-4.15.0-041500-generic_4.15.0-041500.201802011154_amd64.deb wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.15/CHECKSUMS sha256sum -c CHECKSUMS 2>&1 | grep 'OK$' sudo dpkg -i *.deb
If everything went well you can now reboot and enjoy working drivers. If not, please refer to this article.
Finally, it's worth noting that because the mainline kernels are not supported, you'll have to track and install updates as they become available yourself.
Update: You'll want to use Mesa 17.3 for better hardware acceleration. You can install them via The Ubuntu-X team PPA:
This year I decided rather belatedly to participate in the Inktober 2017 challenge. It's now been a little over 3 weeks since the challenge ended, so let's have a look at how it went.
Goals and rules
Since I started a bit late and my goals weren't strictly about improving my inking capabilities, I modified the rules slightly:
- Produce one inked drawing per day for the duration of October, on average
- November 1st is not a hard deadline
- Sketch a concept per day
- Ink when time allows
- Follow the official 2017 prompt list
- No theme; draw whatever
- Redoing a drawing before posting is only allowed if ruined beyond repair
- Rule 1 is a goal, not a criteria for success
The primary purpose of these rules was to force myself to complete things on a semi-regular basis, and make them public.
Most of these rules turned out to be good ideas. The first rule was worded a bit badly, and doesn't say much more than "produce 31 inked drawings". Although if I had worded it that way I might've decided to attempt drawing all of them during the last week.
The second rule was intended to relax the rules and reduce pressure. Although I managed to complete all 31 drawings before the end of October, I'm not sure I would've gotten very far without this rule, considering I started late and had to average two drawings per day. Especially considering that the first few drawings took the better part of a day to complete and post.
Similarly, rule 8 was designed to allow me to quit and still call it a success, as long as I had finished at least one drawing. A bit of a cop-out maybe, but considering I went from maybe one drawing per year to one per day, anything would've been an improvement.
Similarly, rule 3 and 4 were intended to make the process more flexible, so I wouldn't have to plan the entirety of October around drawing. Once I got into it however, I ended up inking at least one drawing per day fairly consistently. Next time I'll probably remove these type of rules, but I'd still like to allow some degree of flexibility. Maybe "seven drawings per week" would be a good compromise.
As for rule 5 and 6, I like brainstorming, so I added them as a way to kickstart ideas. Building concepts and scenes out of a single word is pretty fun, although some of the words were less interesting than others. Sometimes I just gave up and googled a bit. Screech was such an example.
Rule 7 turned out to be really important. It was designed to counter perfectionism and help focus on achieving the goals, which really had nothing to do with quality; just draw and post it!
I kind of broke this rule with day 7 (shy), but I had enough time to redo it once, so it wasn't a problem. This rule is also responsible for a bunch of the later entries. In particular half of the ones I posted during the last few days. For example day 28 (fall) would've been scrapped entirely if it wasn't for this rule.
It took me a long while before I managed to shake my perfectionist mindset. The first few drawings I made took half a day, and some blog posts took almost as long to write. In the end I don't know if the quality improved much by iterating on them. In some cases it might've even gotten worse. Towards the end some drawings took less than 30 minutes, and the blog post less than 10.
The drawings that turned out the best had the least amount of details in them. I would like to say that this was because less details meant more time and focus on what was there, but that would imply I would've reached the same result with some of the more complex drawings I spent more time on, which wasn't the case. Instead, it probably had more to do with providing a cleaner look, and that details often turned into noise due to the small paper size I drew on.
On the flip side, the worst images were the ones with lots of tricky perspective in it. I still don't know what my exact problem with perspective is. Drawing perspective lines help, but then the perspective lines themselves have to be near perfect. The exception might be day 22 (trail), which I somehow managed to draw without perspective references. One thing I did notice when drawing that was how big a difference a tiny change in a line makes. Maybe the problem is that I need some point of reference, so I subconsciously and incorrectly use the first lines I draw as a reference point. Eventually resulting in small errors that propagate until everything is slightly off.
Another potential problem is that most drawings lack any sort of shading or shadows. It was a deliberate attempt at risk mitigation, but in retrospect the lack of depth made things more difficult to draw, and without shading it can be hard to differentiate between bad proportions and something that is just angled towards or away from the viewer. Maybe that can be solved by varying the line width, but I never managed to do that reliably with a brush pen.
In closing, Inktober was super exhausting, but fun! I don't think I improved a lot in terms of final quality, but I learned a lot, and I got much faster near the end. More importantly, I managed to post everything online!
If I do this again next year it would be interesting to combine the drawings somehow. Maybe use a random word generator and do some storyboarding.
Drew this one surprisingly fast. Around 20 minutes? Did a really quick pencil outline, then sketched the entire drawing with a fineliner. Went way better than expected!
I originally intended this to be cartoony and goofy, though it turned out more realistic than not. Tried to find references of birds hitting windows, but that only made me sad. Ended up freehanding it. Not based on any anything specific, so I'm not even sure what type of bird this would be? A pidgeon maybe?
This is the final Inktober drawing for this year. I actually managed to finish everything on time, despite starting almost two weeks late! It's been pretty fun, though now I feel like I could sleep for a week.
I'll have to take a break for a few days, then maybe do a post-mortem of sorts.