uniform-tagged shaders with gpipe
okay, two week projects
i didn't do something for february 1-14 since i was sick for that entire stretch (i was sick for like three weeks and it sucked), but i did get some stuff done for the 15-28 period.
gpipe has this enormous infrastructure for type-safe shaders, so that you can never write the wrong kind of vertex pipeline to a shader, or write the wrong thing to a buffer generally, and all of its weird internal types are instanced to a mess of typeclasses so that they get marshaled correctly automatically. it's real nice. but what they don't do for you is handle uniforms. or rather, they handle uniforms (you can write to them and use them just find) but they don't have any kind of construction for "this shader uses uniforms of type x y and z and so before you run the shader you have to provide x y and z values". basically they don't really surface the shader dependency on uniforms into the type system at all; a shader is just a shader and if you need to write uniforms for it then you need to manage that yourself.
in my existing code, the only uniform i really used was the camera, which was updated per-frame at the start of each frame, and while i had lots of ideas for useful shaders i could write, i basically had no way to store or structure them. my code ran using a list of
so already i was thinking this would have to be an existentially-quantified thing: have something like
so that the shader could vary based on the type of the chunks, but that would be hidden inside the type so that the overall type is still just
(i should also say that i put off working on this for a while since i only had a hazy idea of how this would work, and i figured it would be really complicated and involve a lot of weird type stuff.)
so with all that being said let's talk about the code i wrote.
( lots of code and code talk under the cut )
i didn't do something for february 1-14 since i was sick for that entire stretch (i was sick for like three weeks and it sucked), but i did get some stuff done for the 15-28 period.
gpipe has this enormous infrastructure for type-safe shaders, so that you can never write the wrong kind of vertex pipeline to a shader, or write the wrong thing to a buffer generally, and all of its weird internal types are instanced to a mess of typeclasses so that they get marshaled correctly automatically. it's real nice. but what they don't do for you is handle uniforms. or rather, they handle uniforms (you can write to them and use them just find) but they don't have any kind of construction for "this shader uses uniforms of type x y and z and so before you run the shader you have to provide x y and z values". basically they don't really surface the shader dependency on uniforms into the type system at all; a shader is just a shader and if you need to write uniforms for it then you need to manage that yourself.
in my existing code, the only uniform i really used was the camera, which was updated per-frame at the start of each frame, and while i had lots of ideas for useful shaders i could write, i basically had no way to store or structure them. my code ran using a list of
RenderUpdate os
values (where os
is a phantom type value that represents which rendering context the render event came from), and what that means is that if i wanted to keep that same basic infrastructure of having a render cache full of render actions, i would need to hide all the shader information, since haskell doesn't have heterogeneous lists -- i couldn't have a list of like, RenderUpdate os ShaderFoo
and RenderUpdate os ShaderBar
.so already i was thinking this would have to be an existentially-quantified thing: have something like
data RenderObject os = forall s. RenderObject
{ shader :: CompiledShader os s
, chunks :: [RenderChunk os s]
}
so that the shader could vary based on the type of the chunks, but that would be hidden inside the type so that the overall type is still just
RenderObject os
, so i could continue using a simple list of render updates. additionally, i'd need some way to attach uniforms to shaders, which would be an entire other step that would need to be done in a similar fashion -- stuff the uniform type in an existential somewhere, so that i could automatically set them in some fashion.(i should also say that i put off working on this for a while since i only had a hazy idea of how this would work, and i figured it would be really complicated and involve a lot of weird type stuff.)
so with all that being said let's talk about the code i wrote.
( lots of code and code talk under the cut )