Monday, January 21, 2008

CG Shaders and FBO

After getting textures working I wanted to have my test application run using nebula3's application framework. The only way to have this working was to implement shaders and render targets.

Nebula3 makes use of effect states and glsl does not have an effect framework so it was a natural choice to use Nvidia's CG. Nvidia just released CG 2.0 so I decided to give it a try. I have to say, CG's API is pretty straight forward and easy to work with.

According to the CG specification, semantic names are case-insensitive and CG returns semantics in uppercase so if e.g. I define a semantic as ModelViewProjection in my shader, CG returns it as MODELVIEWPROJECTION . This is what I feed into nebula as a the shader variable's semantic when its created. The problem comes in when a semantic is hard coded into the application as ModelViewProjection. This throws an error since the variable ModelViewProjection cant be found. As a temporary solution, I've changed all references to shader variable semantics in the source code to upper case.

Whever a ShaderInstance is created, a clone of the effect should be created, as of this writing, CG's cgCloneEffect function is not working, as a temporary solution, whenever a shader is loaded from file, I keep a copy of the source in the shader. Whenever a shader instance is created I re-create the effect using the source in the shader.

Apart from that, I'm generally happy with CG 2.0.

As a render target implementation, I've used Frame Buffer Objects(FBO), it was pretty straight foward to set it up but there are still issues I need to fix here and there. e.g. I'm testing it on a Radeon x1650 that does not have the None Power of Two(NPOT) extension which makes rendering to a 1024 x 768 texture very, very slow. The card however supports the texture rectangle extension so when I bind a rectangular texture as a render target the rendering works fine. But another issue rears its ugly head, rectangular texture coordinates are addressed using the textures pixel dimensions not the usual 0...1 range.

Still pondering on this one but I think Ill set it up such that if the hardware supports NPOT, setup will be done normally, if the hardware has the rectangular texture extension but not the NPOT extension, a rectangular texture will be used and if the hardware supports neither of the two, some sort of pixel padding could be used to make the texture a power of two (have to research on how to do this).

Finally here is a screenshot of the testviewer application running on CG shaders.

No comments: