Prototype stage

I’m still focusing squarely on finishing a fully functional first iteration of the new Home UI, and it is coming along nicely. Here’s a brief glimpse of how things are looking currently (click for an animated gif):

home_columns

Basic tasks like selecting a game or a saved game are working, and I have a list of the multiplayer games up as well. Main focus is now on the Packages tab, where I’ve revamped the list’s appearance. The next step is to implement some additional features for managing packages, like sorting, filtering and searching. After that the only thing that’s needed is a little of bit of performance tuning in the widgets framework to iron out the worst bottlenecks — this is the most complicated UI so far running on the new widgets and it is revealing some previously unseen issues.

Home improvement

Work continues on implementing a functional prototype of the new Home design. The current status is that it is possible to select and start a game, and load saved games. The Multiplayer browser and package management UIs are still missing.

As expected, the planned ideas didn’t feel quite right when I got to try them out in practice. For instance, I was envisioning that when one selects a game (say, “Doom II”), a list of saved games would expand below it. The rationale was that it would save space to not show all the savegames all the time. However, in practice it was extremely distracting that the game items would keep moving up and down in the list due to saves being shown and hidden above them. I ended up just keeping the save lists visible all the time.

Next I will focus on the multiplayer browser. The basic idea is to use widgets similar to the ones used in game selection, but of course show information relevant to multiplayer. When it comes to the package manager, it will be based on the existing (preliminary) Packages dialog, with a couple of additions and improvements.

Homeward

With the 3D model renderer in reasonably good shape so that new models can be worked on, I’m now pushing toward building the front-end’s central features into the Home screen: selecting PWADs and other resources to use when playing a game.

The main feature I was working on last week was a new way of handling classic data files such as WADs, PK3s, DEDs, and DEHs. The engine is now able to recognize these files and treat them as Doomsday 2 packages internally. Additionally, I’ve added a small database of known files (such as the vanilla IWADs) that are further identified as packages with very specific IDs and versions.
Continue reading Homeward

Getting started on data file packages

This week I decided to switch gears and start work on support for data files in the Doomsday 2 package loader.

As planned, the idea is that the various supported data files are each seen by Doomsday as packages. This makes it possible to identify the data files uniquely, save the list of used files in savegames, share the file list in multiplayer games, and also set up game configurations via the Home screen.

In practice, I’ve begun by making the Doomsday 2 file system aware of what these data files (like WADs and PK3s) are and what kind of data they contain. I’m also planning to set up a new way to identify data files based on a set of criteria read from a configuration file. Continue reading Getting started on data file packages

3D model editor

The final week of 2015 turned out to be quite prolific.

There was a new stable build on Friday: 1.15.7.

I made a little bit of progress with animating player weapons by introducing the vanilla-style walk bobbing for the new model renderer. The final missing detail now is to improve how the weapon is positioned, so that FOV and viewport size changes don’t so easily move the weapon out of view. This has always been a bit of a problem with the old model renderer, so doing it better this time around is important.

I continued last week’s work on reflections by incorporating cubemaps to each of the default shaders. Cubemaps can now be put in packages and loaded as assets: there is a new asset type for environment cubemaps (texture.reflect).

It turned out part of the confusion last week was due to some mistakes I had made earlier in how light directions were being passed to and calculated in the shaders. This was causing artifacts such as specular highlights in the wrong places on the model. While fixing the shaders, I also managed to streamline them a little and remove excessive texture lookups.

Overall, we are now getting closer to calling the shaders feature complete. The next step is to apply some final adjustments so that lighting on 3D models will appear natural yet distinctive. However, a big part of making models look good is tuning all the shader and material parameters correctly for each model asset. It is quite challenging to do this if one only has a text file and the appropriate values have to be found via trial and error. Therefore, I added a new editor sidebar for making adjustments to 3D models. I got a nice head start on this by reusing a bunch of code from the Renderer Appearance editor.

The model asset editor should provide all the tools for perfecting how a 3D model appears in Doomsday. It shows basic information about the model file and allows interactively adjusting shader variables, enabling and disabling rendering passes, changing materials, and trying out animations. The editor will not write definition files, though, it just allows finding the best parameters. This is partly because the definitions may incorporate Doomsday Script, and partly to ensure that one can’t accidentally mess up the parameters of a model.

Reflections

This week’s festive screenshot shows a bunch of test models that I’ve been using for developing environment mapping for 3D model reflections. While the current map renderer is not efficient enough for rendering cube maps on the fly, 3D models will be able to benefit from manually prepared cube maps.

This has been an interesting implementation challenge. It turned out the code I had previously written for transforming objects was not quite compatible with how cube maps needed to be rendered. I thought I was being clever by setting up player weapon models directly in view space, since they are affixed to the camera. For a while I was getting confused by all the different transformations needed for moving between tangent, model, world, and view space coordinates (cube maps are defined in world space). Models already in view space needed to be handled differently than objects in world space.

Eventually I decided to scrap that approach and wrote some new code that positions all models in world space, so their lighting and reflections can be done in the same way. This was much easier to get working correctly. K.I.S.S. wins again!

I’ve also been making some bug fixes for the upcoming 1.15.7 patch. Noteworthy fixes include support for Freedoom’s FreeDM multiplayer IWAD as a recognized game, and correct handling of command line options in the Shell app. The same fixes are already available in the 2.0 unstable builds.

Wand update and custom shaders

This week’s screenshot shows a work-in-progress version of veirdo’s beautiful new Sapphire Wand model for Hexen. It takes advantage of the new model rendering features such as random alternative animation sequences, animated shader variables, and custom GL parameters for drawing layered effects.

On the topic of weapon models, the new renderer still lacks the vanilla-style walk bobbing. That shouldn’t be a lot of work to implement, though. After some additional weapon position fine-tuning this should be ready for prime time, and we can start preparing some models for distribution and use with the 2.0 builds.

As planned, last week I was working on a better way to load shaders from packages. I managed to complete the improved functionality as planned: when any package is loaded, it is checked for shader definitions; if found, the shaders are added to the runtime shader bank. Similarly when a package is unloaded, its shaders are removed from the the shader bank. Now there is no longer any special case logic needed for the net.dengine.client packages, as their shaders are loaded the same way as shaders from any other package.

I then proceeded to add a way to customize shaders using macros. Like C, GLSL allows defining macros for the preprocessor. This enables injecting custom code at compile time. For example, let’s say a model wants to continuously scroll its texture. This could be done using Doomsday Script, however one would need to keep restarting the script at regular intervals to keep the animation going — not the most efficient way to do things if you have a lot of objects using the model. However, if the model injects a line of code into the model shader for modifying its UV coordinates on every frame, all the work is done cheaply by the GPU. And even better, if the shader is later updated (for example when the user installs a new version of the engine), the model has a much better chance of continuing to work correctly.

Click the screenshot below for a short animation:

UV scrolling shader

Naturally model packages can also provide their completely custom shaders that do not depend on the net.dengine.client shaders in any way.

I was also briefly obsessed with improving the formatting of log entries. There is something about formatting text that manages to hook me every time. The most visible changes are that the so-called “log sections” that contain contextual information about where a log entry was created are now placed within square brackets. This should improve readability. In the doomsday.out/runtime debug output, the content now uses better alignment to visually indicate which entries belong together.

#1815 200.594 I  (v) [BindContext] 'global' cleared
#1815 200.594 I  (v)               'deui' cleared
#1815 200.594 I  (v)               'console' cleared
#1815 200.594 I  (v)               'message' cleared
#1815 200.594 I  (v)               'chat' cleared