loading images
Hi! love the simplicity of this - will recommend for newbies that want to see something on the screen!
Perhaps the only missing thing is image loading - LoadImage() from windows.h can load bitmaps and I hear jpegs can be read with gdiplus.h (or maybe some other headers).
GDI+ will definitely do the trick. It supports lots of formats all the way to handling the frame timing automatically in animated GIFs!
I worry it might be tricky to keep the drawing.h header as simple for beginners though. Images could be stored in an opaque handle (a little like Color) but to load one you have to give a path. Now their teacher has to explain what the funny-looking :: is in std::string or what the funny-looking * means in const char *. (This is why SaveImage sidesteps the problem by choosing your desktop automatically and only allowing for an integer suffix.) Although, granted, these aren't very tall hurdles and the teacher could always say "don't worry about it for now..."
Beyond that, there is always the frustration of "where do my images go in the filesystem? Is it the solution folder? The project folder? I keep getting 'image not found' errors. The Debug folder? I changed the dropdown to 'Release' and now my program crashes!"
One solution might be to have the framework do a lot of extra work so the user doesn't have to: it could keep climbing up from the current path looking for images with the given name (and maybe try to drill down into any "images" sub-folders that may or may not be present). That might eliminate some of the confusion and get things back to the point of "just work"ing.
It would also be the first Immediate2D API call that could possibly "fail" in an interesting way. The other draw calls simply don't draw anything if you give bad coordinates or whatever, but if an image couldn't be found or couldn't be loaded, is the returned handle a nullptr? I suppose it's not unreasonable to have the new student check for errors. I mean, they already have to check cin.good() all the time. Hmm.
I do agree that images would raise the ceiling on the sort of fun that could be had with the library by a substantial margin. Perhaps they're a good candidate to go in with the rest of the "secret" functions in drawing.cpp.
This is a pretty good start, but there is still a lot of work to go. Notably, like I mentioned in my previous (2017!) post, the LoadImage() documentation in the header says it will check a bunch of different places until it finds the file. Right now it just checks the file system, so it will only work for local (to the current working directory) or absolute paths.
Instead of nullptr, the API handles the "we couldn't load the image" situation by returning a special InvalidImage constant handle. Even if you don't check your return values, all of the Image functions will happily ignore (or return default values for) any calls made with InvalidImage. So beginners continue to be able to live in this exception-free, happy place where you can get away with exactly zero error handling code.
I wanted to avoid naked string pointers for the image name parameter, but I still feel like it's more important to keep the top of immediate2d.h free of any #includes whatsoever. Reading that file is already daunting enough for beginners. So the parameters are const char * for now.
Otherwise, so much for GDI+ handling animated GIF frame timing automatically! System.Drawing.ImageAnimator is .NET Framework-only and it spins up a thread(!) that sleeps for 50ms at a time between checking if it's time to change frames. 😬 (The Immediate2D implementation in the commit above doesn't do this.)
Here's a quick example to get started. To have an animated GIF's timing handled completely automatically, you just need to draw your image periodically. Here, the 16ms wait is arbitrary and picked for smoothness:
#define IMM2D_IMPLEMENTATION
#include "immediate2d.h"
void run()
{
Image something = LoadImage("myCoolAnimation.gif");
while (LastKey() != Esc)
{
DrawImage(10, 10, something);
Wait(16);
}
CloseWindow();
}
Alright, the new v2 release has all the image APIs properly documented and it includes a couple examples demonstrating their use.