I think I should have been more thorough in my initial reply here

The use of RenderEffect::performPreRenderFunctions is absolutely the right place to be doing any shader set up since it's called right before the geometry for the Window is sent for final rendering.
The basic algorithm is:
Code: Select all
for each pass in RenderEffect
call RenderEffect:: performPreRenderFunctions(pass)
render geometry buffer content
RenderEffect::performPostRenderFunctions
The issues with D3D10/11 come because the GeometryBuffer itself reset the shader in the 'render geometry buffer content' step.
The key to the rendering algorithm above is that when using the RenderEffect with a Window that has the AutoRenderingSurface property set, the default geometry drawn is two triangles, and the texture used is the texture holding the content of the window. This texture is always set up, and is set up
after the performPreRenderFunctions call in each pass - this is one point that could cause issues, not the setting of the texture, but perhaps the setting of some other states related to that. So, ideally, we could 'apply' some ogre material in the performPreRenderFunctions call and for most / many cases we would be done, however, the ogre interface is not friendly towards doing that at the level of Material (somewhat because Material/Technique/Pass is a similar - though much more advanced - abstraction as what the RenderEffect is supposed to be, except one is driven by Ogre at higher levels and the other is driven by CEGUI at higher levels).
So, the conclusion is that to use performPreRenderFunctions you need some way to activate appropriate render system settings from the Material. If this is possible, I think all will be well. If not, I think perhaps your existing solution may be the best that is possible given the current state of things (clearly you could bypass Material, and attack things from a lower level, but most people will not want to do this, and it's somewhat prone to break due to the use of low level / internal ogre calls).
is there any way to mitigate Downside 2) ? Perhaps be able to only instruct a particular window not to render to screen somehow? I mean only render to texture, not to screen.
I think probably the cleanest way is to override RenderEffect::realiseGeometry for the RenderEffect and simply return false. This will mean that no geometry is added for the window, so nothing should get drawn back to the owning cegui rendering surface.
Finally, I will mention that there has been a fair amount of discussion related to creating a new Ogre renderer module that operates at a higher level, and which would allow the use of Ogre Materials much more cleanly. However, this has not even entered a 'work in progress' stage, and whether it will ever happen is a matter of great debate.
CE