well I've prety much finalised the syntax o the materials table, and I have a working parser for it (and the structs needed to store the data)
you will have to/be able too (depending on how you look at it) define materials that will have diferent properties based on the environment and define multi-pass lighting behavior (usualy this is little more than telling it to use additiive alpha on the aditive lighting passes)
this is the current state of my materials table, keep in mind that if you don't want to take advantage of this you won't have to mess with it at all. and once I get materials working it won't be much longer till I get shaders working, and with the way this is set up it will be almost the most versitile shader/material system posable.
$Material: fullbright
#Instance_set{
#Instance{
$Format: ("pos" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: yes
+opp: lessequal
$Alpha: +preset:none
$Cull: 1
$Lighting: no
$Render_Step:
+Opp: arg1
+Arg1:
+type: texture
+value: 0
}Pass
}Instance
}Instance_set
$Material: diffuse
#Instance_set{
#Instance{
$Format: ("pos" "norm" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: #FLP{yes}FLP #ALP{no}ALP
+opp: lessequal
$Alpha: +preset: #FLP{none}FLP #ALP{add}ALP
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
}Pass
}Instance
}Instance_set
$Material: glowmapped_diffuse
#Instance_set{
#Instance{
$Format: ("pos" "norm" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: #FLP{yes}FLP #ALP{no}ALP
+opp: lessequal
$Alpha: +preset: #FLP{none}FLP #ALP{add}ALP
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
#FLP{
$Render_Step:
+Opp: add
+Arg2:
+type: texture
+value: 1
}FLP
}Pass
}Instance
}Instance_set
$Material: glowmapped_shinemapped
#Instance_set{
#Instance{
$Format: ("pos" "norm" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: #FLP{yes}FLP #ALP{no}ALP
+opp: lessequal
$Alpha: +preset: #FLP{none}FLP #ALP{add}ALP
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult*4
+Arg1:
+type: specular
+Arg2:
+type: texture
+value: 2
$Render_Step:
+Opp: mult_add
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
#FLP{
$Render_Step:
+Opp: add
+Arg2:
+type: texture
+value: 1
}FLP
}Pass
}Instance
#Instance{
$Format: ("pos" "norm" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: #FLP{yes}FLP #ALP{no}ALP
+opp: lessequal
$Alpha: +preset: #FLP{none}FLP #ALP{add}ALP
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
#FLP{
$Render_Step:
+Opp: add
+Arg2:
+type: texture
+value: 1
}FLP
}Pass
#Pass{
$Z_Buffer:
+read: yes
+Write: no
+opp: lessequal
$Alpha: +preset:add
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult*4
+Arg1:
+type: specular
+Arg2:
+type: texture
+value: 2
}Pass
}Instance
}Instance_set
$Material: shinemapped
#Instance_set{
#Instance{
$Format: ("pos" "norm" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: #FLP{yes}FLP #ALP{no}ALP
+opp: lessequal
$Alpha: +preset: #FLP{none}FLP #ALP{add}ALP
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
}Pass
#Pass{
$Z_Buffer:
+read: yes
+Write: no
+opp: lessequal
$Alpha: +preset:add
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult*4
+Arg1:
+type: specular
+Arg2:
+type: texture
+value: 2
$Render_Step:
+Opp: mult_add
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
}Pass
}Instance
#Instance{
$Format: ("pos" "norm" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: #FLP{yes}FLP #ALP{no}ALP
+opp: lessequal
$Alpha: +preset: #FLP{none}FLP #ALP{add}ALP
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
}Pass
#Pass{
$Z_Buffer:
+read: yes
+Write: no
+opp: lessequal
$Alpha: +preset:add
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult*4
+Arg1:
+type: specular
+Arg2:
+type: texture
+value: 2
}Pass
}Instance
}Instance_set
$Material: multi_pass_shinemapped ;;sometimes you want to force this, like glass
#Instance_set{
#Instance{
$Format: ("pos" "norm" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: #FLP{yes}FLP #ALP{no}ALP
+opp: lessequal
$Alpha: +preset: #FLP{none}FLP #ALP{add}ALP
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
}Pass
#Pass{
$Z_Buffer:
+read: yes
+Write: no
+opp: lessequal
$Alpha: +preset:add
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult*4
+Arg1:
+type: specular
+Arg2:
+type: texture
+value: 2
}Pass
}Instance
}Instance_set
$Material: same_texture_shinemapped ;;uses the defuse texture as the shine texture as well
#Instance_set{
#Instance{
$Format: ("pos" "norm" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: #FLP{yes}FLP #ALP{no}ALP
+opp: lessequal
$Alpha: +preset: #FLP{none}FLP #ALP{add}ALP
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
}Pass
#Pass{
$Z_Buffer:
+read: yes
+Write: no
+opp: lessequal
$Alpha: +preset:add
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult*4
+Arg1:
+type: specular
+Arg2:
+type: texture
+value: 0
}Pass
}Instance
}Instance_set
$Material: 1_texture_glow/shinemapped ;;uses the defuse texture as the shine texture as well
#Instance_set{
#Instance{
$Format: ("pos" "norm" "uv_1")
#Pass{
$Z_Buffer:
+read: yes
+Write: #FLP{yes}FLP #ALP{no}ALP
+opp: lessequal
$Alpha: +preset: #FLP{none}FLP #ALP{add}ALP
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult
+Arg1:
+type: diffuse
+Arg2:
+type: texture
+value: 0
$Render_Step:
+Opp: add
+Arg2:
+type: texture
+value: 1
}Pass
#Pass{
$Z_Buffer:
+read: yes
+Write: no
+opp: lessequal
$Alpha: +preset:add
$Cull: 1
$Lighting: yes
$Render_Step:
+Opp: mult*4
+Arg1:
+type: specular
+Arg2:
+type: texture
+value: 0
}Pass
}Instance
}Instance_set
each material consists of a name and a number of instinces held within an instince set, each instance is one posable implementation of the material. the instances should be ordered from best implementation to simplest. the first instance that the user's hardware is capable of suporting is the one that is used, all others are ignored.
within the instance, you must declaire what vertex data this instance of the material will use, generaly this will involve position, normal, and one uv coordanant (I have an idea for upgradeing the model format (so that, for example, more than one UV coord can be used) that won't requier rebuilding all exsisting models) ["pos" "norm" "uv_1"], (if you don't need lighting don't includ norm, if you don't need textures don't include uv_1).
after vertex format has been specified, you must define one or more rendering passes, the fewer passes you use the better.
each pass consists of a number of render states (zbuffer, alpha blending, ect...) and up to eight render steps (you must define at least one) were you can define all sorts of behavior such as render arguments, how they will be combind, were they will be output to (current or temp, this is not render target, though I intend to add that functionality eventualy),wich UV coord set to use, and texture wrapping behavior (for example, you could have the texture mirror rather than repete)
one of the unfortunate complexities, is that you will need to define diferent behaviors for diferent environments and lighting modes. this is done via blocks, a block is a section of table that is started by #a_label{ and ended with }a_label. the only two blocks that I currently have in the table are FLP and ALP. FLP is the first lighting pass, generaly this will be the only thing you see, but when more than the maximum lights are needed an additive lighting pass is used to draw the additional data, because you have controle over how the first lighting pass is blended, there is no way to determine how the additional passes are to be drawen, so you will have to define them. generaly anything constant should be only used in the first lighting pass, for example glow mapps should only be drawen once (and my tables reflect this), in most cases you are going to want to use no blending on the first lighting pass, and additive blending one the additive ones (as my tables reflect) if you however should use a subtractive alpha blend you won't want to use addtive blending here, further, you have full access to all alpha blending options (not showen in the table but it's there) so you will need to figure out how your alpha mode should be added.
in addition to lighting modes you will also be able to specify diferent behavior for nebula, normal space, and subspace (and anything else I eventualy think of) useing a similar method.
anything between the brackets of the labels will only be parsed when that option is active, text between the bracets is erased when the option is not present so for anyone with any programming experience it's sort of like an #ifdef #endif block.
now any questions?
this might seem confuseing, but once you get the hang of it it's unbeleiveably easy and super powerful, you will no longer have to rely upon us programmers to develop new rendering modes, (multi-textureing, for example, would be a peice of cake to implement).