GSoC 2020

Coding starts, what has happened so far?

The coding phase of this year’s GSoC will begin this week. What has happened so far on the porting of Wintermute3D into ResidualVM. Well, first I started learning a little about OpenGL 2.1.Having done some Direct3D 9 in the past, a lot of the concepts were familiar to me, but nevertheless a different API is a different API. I tried out some loading of .X files as well via the assimp library, just to get a feeling for what would expect me since .X files are a big part of the project.

One aspect of the project is to load in data from an .X file. My first plan was to base a parser on assimp, taking out the code and reusing parts of it. But I realized after starting to write a lexer for the .X format that writing a recursive descent parser myself as well is not that difficult and might be even more straight forward. At the moment I am more concerned about displaying and animating the data, which has a lot of room for little, hard to find, errors, although I can reuse a lot of code here from the original code base.

As an additional exercise, I took the existing renderer for the Wintermute port of ScummVM, after importing the code into my ResidualVM fork and implemented a simple texture renderer based on it.

After that, I got a little bit more ambitious and decided to go for an actual OpenGL based renderer for the 2d graphics part, which would also be the foundation for the rest of the project. In the beginning things were buggy, partly due to miscalculations of coordinates but also due to the fact that Direct3D offers something called transformed vertices, which bypass the transformation pipeline. It took me some time to realize this as I was searching the Wintermute code base for the part where actual 2d rendering to the viewport is activated. The catch is that this is done by setting a specific vertex format. Now OpenGL has no direct equivalent for this but one can set an orthographic projection via glOrtho to archieve the same effect.

Here is a screenshot showing a temporary state (this is from the Wintermute 2d demo). It was taken after I discovered how to setup 2d rendering onto the viewport. As one can see, the color key is still there and the sprites are somewhat displaced, which is due to the fact the Direct3D and OpenGL differ in what corner of the viewport has coordinates (0, 0). These things have been fixed since then. What is still missing on the picture above are two more sprites displaying two people. This is because I didn’t yet implement the necessary functions and I might postpone this until much later since complete support for 2d graphics is not the goal of this project.

I also wanted to do some 3d rendering, so I took some of the Wintermute3D code for the scene geometry and reintegrated it into the ScummVM Wintermute port. To display the scene geometry (which is actually supposed to be invisible and only the for lightning and shadows as well as path finding), I needed to implemented a .3ds loader. Now fortunately the .3ds format is not so complicated and Wintermute3D even has a .3ds loader which I used for comparison. On the other hand, I still had enough pointer arithmetic bugs in the beginning but I like this kind of stuff, so it was fine. Displaying the data correctly was again another story, I had some fights with camera and projections matrices and had to find out the hard way, that the .3ds format is using a right-handed coordinate system where the z axis is pointing upwards. Wintermute3D is just exchanging the the y and x coordinates, but this also changes handedness (a great illustration that switching rows in a matrix negates the sign of the determinant!) and thus does not work for OpenGL, one has also to negate the z coordinate (or y coordinate, from the .3ds perspective). After taking this into account, I got the following result:

This is from the Wintermute 3D demo. The background is just a two-dimensional texture, the (again, usually hidden) geometry (here visible) is actually 3d though, as one can see.

So this is essentially the current state. Simple 2d and 3d rendering (with the necessary state switching) as well as loading of simple .3ds files. There are plenty of details missing here, though, for example text is not rendered correctly yet. Nevertheless, I will postpone this somewhat later and instead spent the next two weeks or so on getting rudimentary loading and displaying of .X models done. This is mainly due to the fact that this is a big chunk of work which I would like to get done quickly so that I am left with smaller, more manageable pieces. If possible, I would like to add animations as well to this during this time, but after my experience with the .3ds models I am very concerned about potential coordinate system bugs and expect a lot of debugging time for this.

Leave a Reply

Your email address will not be published. Required fields are marked *