-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|434|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
SoCoder -> Blogs Home -> Blogs

Created : 26 April 2013
Edited : 26 April 2013
System : PSP

Material Loading


So, right now it's 3 a.m., and I've just finished implementing the material loader in my engine -- this sounds like a small thing, but it requires two other things be in place: texture loading and shader loading. The former is simple, it's been in the engine for ages, never really posed any problems. The latter is not.

Due to some shaders using more uniforms and attributes than others, it becomes a bit difficult to say what all shaders conform to without simply defining some limits. And I don't like limits, so I decided that I would toss out a few named uniforms and attributes and otherwise leave it up to the shader definition to say what it was. So, you end up with a resource file like this:

There can be any number of materials or shaders in a resource file, the order is arbitrary, but the point is that they can all be defined using fairly simple text. So, for a shader, you've got the individual shaders that make up the program, the uniforms, the attributes, and the fragment outputs. In all three cases, it's basically "<binding type> <binding> <name>;".

For bindings, you have a choice of either a: a set of named bindings (like those used above) or b: an arbitrary integer. The integer can also be the same as what the named binding is (all named bindings start at 0). The name component of a binding statement is simply the name of the uniform or attrib or output in the source code. So, in the basic shader, the fragment output is called frag_color. It's using an arbitrary integer in this case because I didn't add out0-4 as named bindings for frag_out until later.

This basically means that the engine can load whatever shader it wants and it's a non-issue as to how it's structured, either in source or otherwise. If for some reason something needs an extra uniform or vertex attribute or frag output, then it's easy enough to define (though materials themselves only use the three uniforms above right now).

All of this is doable just because of the lexer I adapted previously. Parsing is fairly simple, since it's just a matter of reading in the tokens. The upside is that I can easily pick out strings, numbers, etc. as needed without trying to figure out while parsing what it is by inspecting the text since the lexer did that ahead of time. The loading process itself is also sort of smart, but I already went over that in the "What Have You Done" thread, so I won't repeat that. At any rate, the lexer's invaluable to getting stuff like this working.

At any rate, this rounded out the material loading code and finally lets me just do this in my code, and get shaders, textures, etc. loaded: