While creating 64kb intros everything is focused on optimizations to reduce the final executable size. When it comes to textures, it is not feasible to store the image files on the project. For example, a 512x512 RGBA texture weights 1024Kb on raw format, and typically will compress to ~100Kb on JPG.
To accomplish beautiful and complex texture patterns, the approach for these productions is to generate procedurally every texture on code, storing only the algorithms and the steps used to generate them on runtime.
As I've always loved to create tools, find here a glimpse of my texture generators in different iterations.
One of the first articles, and probably the only one, I read about texture generation was the one by Ile/Aardbei on the diskmag Hugi 18. Ile explained the approach he uses in his texture generator, and I tried to recreate the same idea.
The basic concept of the tool is that you've four buffers that you use as temporary steps to generate your texture. There is a set of operations to apply to those buffers, divided on three categories:
- Generators: Used to generate base images to work with. For example: lens flares, perlin noise, checkers, plasma, ...
- Filters: Modify an image. For example: blur, emboss, colorize, ...
- Layers operations: Operations between layers like mixing two of them for example.
This version was done using Borland C++ Builder as it was much easier to create UI with it than with Microsoft's MFC.
This was an improved version from the previous one. It was also done in C++ Builder using the same 4-buffers system but including more features:
Texture pack to allow working in the same interface with multiple textures.
Estimate file size for the final compressed file.
Plenty of new generators and filters
Choose which channel to apply filters
Export textures to TGA
Load image file: It lets you to convert an image file to a format to generate a smaller size image:
- B/W: 1 bit per pixel black and white
- Greyscale: 1 byte per pixel
- Color 256: 1 byte per pixel with 256 colours palette
- RGB: 3 bytes per pixel (Non recommended because of the huge file size)
KTexGen (Node based)
This version was a huge change in the application that was completely rewritten and I just reused some generators and filters. The 4-buffers system was replaced with a modular node system. This change made the UI more accessible for non-technical users. When I was designing the UI of this release, a friend suggested me to take a look to the Darksim's Darktree modular node based texture editor. I took many ideas from it and as you can see the UI is heavily inspired by it.
The application also included a vectorial designer to create 2D layers. Following the same techniques used with the textures, only the steps to generate the 2D layers were stored, keeping the output file small.
This was the release used to create the textures from This Way 64Kb Intro which justified the need of the vectorial designer to recreate the vector graphics the original demo had. The following example shows the original photoshopped layer and the ktexgen version:
Due to the node system and the vectorial editor the complexity increased quite a lot compared with the previous releases. The UI was done in C++ Builder as the previous releases, but the machines (generators and filters) were created in VC++ 6.0 compiled to both static (LIB) and dynamic library (DLL). That DLL is included as a plugin in the TexGen UI allowing to rewrite the machines in VC++ without needing to recompile the UI.
This version also was a huge rewrite from the core to the UI. It's quite similar to the previous version but I removed the vectorial module. This module was quite fun to develop but very hard to compete UX wise against the industry standard tools a designer is used to like Illustrator or Photoshop.
What I did this time was to create a SVG parser to convert those files into a tiny binary file format readable by the 64k introsystem.
The following gallery shows the progress of loading the custom vectorial binary format exported from SVG in Adobe Illustrator or Inkscape:
After all I was able to load a vector graphic from Illustrator in SVG directly on the editor and link it to any node.
I also refined the UI with new custom controls and options.
I also added a GIF loader, focused on loading greyscale (8 bits per pixel) and black and white (1 bit per pixel) images:
At the time when I started developing this version I was designing the API of my softsynthetizer so I used the same approach for the plugin interface.