4 Hugues Ross - Blog: 03/01/2017 - 04/01/2017
Hugues Ross

3/27/17

DFGame - Rendering Improvements

One of my main goals for DFGame is to make development fast and convenient. Some people might consider something like this to be impossible with a low-level language like C. However, there are a number of tricks that I've been using to improve the simplicity of DFGame. To see how this works, I'm going to compare and contrast the graphics code from before I started working to now.

Friendly warning: The contents of this post are going to get a bit technical. If you aren't fascinated by APIs, you may not be interested.

Shaders and Meshes

The first thing that we'll compare is how to create shaders and meshes.
The old method is simple, but not great. Both asset types can be loaded from files, but if you want to include any shaders in your code then you need to write them as strings. To help you visualize, here's an example from the old version of the code:

static const char* quad_fs[] =
{
    "#version 330\n"
    "uniform sampler2D texture;\n"
    "uniform vec4 color;\n"
    "in  vec2 v_uv;\n"
    "layout(location = 0) out vec4 f_color;\n"
    "void main() {\n"
    "f_color = texture2D(texture, v_uv) * color;\n"
    "}\n"
};
That's more or less how it looks. There's no syntax highlighting, and every line has to be quoted and end with a "\n".
To create a new mesh from code, you specify the number of vertices and the type of data that you intend to store. The result looks a little like this:
create_mesh(vertex_count, VT_POSITION | VT_TEXTURE);
Not too shabby, but we can do better.

Next, let's see how it's handled now!
The first big difference is that I no longer need to put shaders in my code in order to compile them in. After discovering a code generation feature in Meson, I wrote a small program to generate C headers from shaders. The resulting headers go to the trouble of embedding the code for me, and I can simply include them in the code wherever I wish. I also made the generator write macros so that I can make a single call to get the compiled shader, ready for use.
Mesh creation has changed a little as well. Instead of initializing a buffer with the components that I specify, I've made a simple generic macro (another very neat thing that I learned a few months ago) that can infer what components you want based on the data that you pass in. To extend this I'm planning on making it possible to add/replace data in the mesh even if the data is in the wrong format, since I can figure out what's inside at compile-time. As you can see below, the result is a little more readable.

mesh_new(vertex_count, data);
As you can see, I've taken some decent code and made it even quicker and easier to work with. Changes like these are happening all over the codebase, so I have high hopes for the resulting framework.

One unfortunate thing to mention is that the updated version of dfgame can't load resources from files yet. In many cases, I'd load my meshes and shaders from elsewhere, but I can't compare how that will look until I get to it later down the line...

Binding Data

Now that we've looked at how meshes and shaders are created, let's look at how binding data to shaders works. In order to render a mesh, we need to bind the mesh being rendered as well as any additional data (textures, transformations, etc). Generally, making binding simpler also simplifies drawing code in general.

In the old version, there was a bind function for each type. Aside from textures, every function was more or less the same-it just called a different OpenGL function to bind the data. To try and get around this, I wrote a bunch of rendering functions that would bind things for the user. These would always bind to the same variable names, however.

When deciding how to update this part of the code, I decided to try and give a decent balance of simplicity and control. The rendering functions are no longer present (for now) but I've wrapped the binding functions in another generic macro. Now, I can bind almost anything I want with the same call instead of having to specify the type.

There remains one problem with this approach, however: Since meshes can have multiple types of data in their vertices, they need to potentially be bound to multiple different shader inputs. This wasn't an issue before, since variable names were assumed when binding. To get around this, I made my mesh binding function variadic (that is, I allow a variable number of arguments). The user can simply pass all of the names and data types that they care about in a single function call, resulting in something like this:

shader_bind_attribute_mesh(shader, mesh, "position", VT_POSITION, "color", VT_COLOR);
This is pretty simple, and if I wanted to I could make a name-less version that used the old assumed names.

Conclusion

There are still many parts of dfgame to review, and I'm certain that there are many other places where the API could use a helping hand. The few parts that I've touched have already benefited immensely, and I'm excited to see where things go from here! These posts will hopefully be a little less dry once I get out of the graphics code, but until then hang in there!

3/20/17

Let's Make a Roguelike: Schedule Change

Today, I have a not-so-good announcement. After much consideration, I've decided to drop the schedule for my tutorials, and post segments on a "when it's done" basis.

If you look at my track record, you'll find that I haven't hit my schedule on a very consistent basis. However, I probably wouldn't drop the schedule if this was the only issue. The real problem is how this schedule has been affecting my ability to work on other things.
My typical schedule for the past few months was something like this:

Pre-Tutorial Weeks
On weeks before a tutorial is due, I usually commit most of the week to working on the tutorial. However, I usually end up delaying things and as a result, I don't get a whole ton finished. This also means that I don't get anything done on my other projects. After that, I need to spend the weekend working on the tutorial so that it can be ready on Monday.

Post-Tutorial Weeks
Following the Monday tutorial post, I have about four days to work on other things before the weekend rolls around. I don't necessarily have to work on the tutorial during these weekends, but if I want to ensure that the tutorial will be done in time then it's a good idea.

Because of the circumstances, the tutorial is currently eating about 2/3rds of my development time. This makes it really tough to work on more than one other project at any moment. I'm not going to stop working on tutorials or anything, but after this one's done I'm going to move to a "prepare everything before posting" strategy.

Wrapping up
Despite these issues I'm still working on this series. After scrapping it twice, I want to see this thing done no matter what. However, I won't sacrifice my other projects to see that happen. To avoid that, I'm dropping the schedule.

3/18/17

DFGame - The road to 1.0

I haven't written much about DFGame in a while. At the end of last year, I gave the project two small paragraphs but didn't get into any specifics. In this post, I'll be getting you back up to speed on the project's status and where things will go from here.

The plan

When I started going back over DFGame, there were a few outstanding problems:

The build system

DFGame was started before I learned about Meson. As a result, the library was being compiled with a makefile. In order to make the project fall in line with others (and hopefully organize it better) I needed to ditch the makefiles and switch over to Meson.

Changing the way that your code compiles can be a bit drastic, especially if the two systems aren't very compatible. In order to simplify things, I decided to try and build each module of the framework as I got to it.

The modules

DFGame was started not long after I started breaking my code up into modules. For the uninitiated, modules are pieces of the codebase that are separated from the rest, and typically compile separately. This allows programmers to use their code in multiple projects, or have multiple applications in their project that share the same code in the backend. As you can imagine, this is a good thing.

The problem with DFGame was that I didn't make enough modules. I broke my code up into five parts, based on whether it was editor or game code and frontend vs backend (plus one for common code). The result is that the common module was a gigantic mess, with 46 code files spanning subjects from audio to rendering to error logging, and everything in-between.

At the tail-end of last year, I decided to try and separate things further. Now, I have 7 modules: Application (game frontend), Audio, Core (logging, memory, etc.), Editor, Graphics, Math, and Resource (asset loading/management). This keeps the different aspects of my framework separated in a more logical fashion, and makes it easier for me to find what I'm looking for.

Inexperience

I don't claim to be an expert, especially not at C. I spend a lot of time programming and practicing, but I still learn new things every day. As a result, there are many small lessons that I've learned since I started working on DFGame. As my knowledge of programming has improved, I've found better ways to do the things that I've already done, so the temptation to rewrite things follows.

With that said, I'm trying to preserve as much as possible. I'm keenly aware (from experience, of course) that rewrites can seriously slow things down, and I want to try and get things sorted out at a decent pace. To that end, I'm going over each file individually to try and improve what I have without scrapping it. I hope that this methodical approach will save some time over a simple redo.

Where are we now?

I've finished going through the core, math, and application modules, and now I'm working on the graphics module. Unfortunately, that means that I don't have much to show for my work yet. I do have this stylish hot-pink triangle though:

Thrilling, I know!
Now that things are showing up on-screen, I expect to have more to show in the coming weeks.

Coming up

Now that I've caught you up to speed, you might be wondering what I'm planning on in the long term. I'm not the best at keeping to my plans, but I do have a goal that I'm aiming for. In about 4 months, it will have been 3 years since I last participated in a Game Jam (aside from 7DRL, of course). That makes me sad, as I really enjoy doing them. Looking at the games page on my site, it seems like when I started DFEngine and AMAZE I mostly much stopped doing game jams altogether.

This year, I want to turn that around. To accomplish this, I'm setting myself a deadline now: I will have DFGame ready for an initial release by August, and I'll compete in Ludum Dare around that time. From my experience, the Ludum Dare game jam usually falls smack dab in the middle of something important and college-related, either the beginning of a semester, finals week, or the move back home. In other words, it wasn't really convenient for me to compete back in college. Now that I don't have a weird seasonal schedule to work around, it seems like a good way to get back into the rhythm of Game Jams. I think that the timeframe I have between then and now is pretty reasonable, and I expect to be finished well before my deadline. Any leftover time that I have can be spent trying things out and building tools.

Conclusion

So that's it! I'm hard at work fixing up DFGame for a release later this year, and hopefully once the dust settles I'll be able to make games again like I used to. I played around with DFGame last fall, and even though I didn't post the results were promising. Whether those results will be replicated with future projects has yet to be seen.

3/13/17

No tutorial this week

This week's tutorial has been delayed to next week. This is mostly because I fell ill recently, and wasn't really in the best shape to do anything serious like preparing tutorial content until a few days ago. I did get a few mindless tasks done on my website, but besides that I didn't accomplish much.

Not to worry, though! I'll have a new post up later this week.

3/11/17

Site Update: Updated software page and more

Last week, I mentioned that I would start posting content on non-tutorial weeks. Now, it's time to make good on that.

I was stuck home sick this week, so I took the opportunity to make some improvements to my site. Some of the changes are obvious, but others are much more subtle so let's take a closer look. Generally, the changes can be broken up into three categories:

Accessibility Improvements

When building my site, I didn't really put too much thought into it beyond how it looked. On a whim, I decided to toss my site's HTML into the W3C Markup Validator, and found its structure lacking.

The two main issues were the misuse of headings and missing alt text on images. In a few places, such as the notes in my tutorials, I was using <h1> tags. <h#> tags have a number that indicates their "level" in the document, like so:

Heading

Heading

Heading

...and so on. The numbers in these tags are used by screen readers and other applications, so it's good practice to ensure that the headings reflect the structure of the page. In my case the stray <h1> tags were breaking the structure, so I changed/removed the offending tags.

Alt text on images is the text that is displayed if the image doesn't load or you're viewing a page in a program that doesn't handle images, the alt text is displayed. Since the images on my site had no alt text, they would effectively be missing if my site were put through a screen reader. Fixing this was pretty simple, since it was just a matter of going through and adding some simple descriptions where applicable.

For the average visitor, these changes are essentially invisible. However, if I ever get any visits from someone who's visually impaired then these changes will hopefully make their life a little bit easier.


Updated Software Page

This change was a long time coming. Ever since I gave the Games Page a fresh coat of paint back in September, I've been meaning to do the same for the Software Page. I've replaced the old design with the one currently used for the Games Page and I've also added some more entries, for a new count of 5.

Right now, there isn't too much content in each entry. I'm still trying to decide what I want to put there, and I also need to get some screenshots/logos for my software. In the meantime, it's still a step up from how things looked before:
The software page (before)
The software page (after)

Mobile-Friendly Styling

Another thing that I'd been meaning to do for a while was making the site responsive. For the uninitiated, responsive websites are sites that can adapt their design to different screen sizes and orientations. Obviously, this is quite important for any site that receives mobile traffic.

A before and after comparison of the site's responsive CSS.
Now, almost all of the content on the site is responsive (there are still one or two exceptions).

Along with the above changes, I've also tried to make the site's text a little more readable by increasing the font size and line spacing. It's a small change, but from my experience it makes reading the content easier on the eyes.

If you have any feedback regarding the changes, feel free to email me or leave a comment below.