Porting from Xenko 1.10 to Xenko 2.0 : Scene Renderers

Hello everybody,

I am porting my app from Xenko 1.10 to Xenko 2.0.
There is a breaking change between Xenko 1.10 and Xenko 2.0 about Scene Renderer & new Graphic compositor that break my code.
I have in my code several custom renderes that were added “by hand” that way with Xenko 1.10:

public abstract class MyRendererScript : SyncScript
{
	public override void Start()
	{
		var compositor = (SceneGraphicsCompositorLayers)SceneSystem.SceneInstance.Scene.Settings.GraphicsCompositor;

		int nbRenderers = compositor.Master.Renderers.Count;
		compositor.Master.Renderers.Insert(nbRenderers - 1, new SceneDelegateRenderer(Render));
	}

	public abstract void Render(RenderDrawContext renderDrawContext, RenderFrame renderFrame);
}

How to adapt this code to Xenko 2.0?
I found I have to create a BaseSceneRenderer an implement RenderCore instead of using a delegate, but not sure, and does not know how to insert it into the system’s renderer list.
Thank you for providing a code, pseudo code or just explanation.

Thanks

1 Like

Thanks for the feedback. We will try to improve the documentation on this subject.

It still has a delegate renderer but it is now called DelegateSceneRenderer and the callback signature has changed to void Draw(RenderDrawContext renderContext). (I have created a pull request to update the doco http://doc.xenko.com/latest/en/manual/graphics/graphics-compositor/custom-scene-renderers.html#use-a-delegate updated. Though I probably should have added the below information…

Adding a DelegateSceneRenderer will depend entirely on how your composition is setup. Have a look at the properties of your Entry Point. If you have a basic out of the box setup like:

You can do something like:

private DelegateSceneRenderer delegateRenderer;
private SpriteBatch spriteBatch;

private SceneRendererCollection GetSceneRendererCollection()
{
    var cameraRenderer = this.SceneSystem.GraphicsCompositor.Game as SceneCameraRenderer;
    var rendererCollection = cameraRenderer?.Child as SceneRendererCollection;
    return rendererCollection;
}

public override void Start()
{
    base.Start();

    var virtualResolution = new Vector3(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height, 1);
    spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = virtualResolution };

    GetSceneRendererCollection()?.Children.Add(delegateRenderer = new DelegateSceneRenderer(Draw));

}

public override void Cancel()
{
    // Remove the delegate renderer from the pipeline

    SceneRendererCollection rendererCollection = GetSceneRendererCollection();
    rendererCollection?.Children.Remove(delegateRenderer);

    // destroy graphic objects
    spriteBatch.Dispose();
}

Thank you, looks good. It compiles now. But I still can’t launch due to another problem, I’m opening another thread for this.

You’re welcome. Glad to help.

Still in the Xenko 2.0 porting subject.

Xenko doc says that a camera need to be set; I use following code to do this.
It is called in Script’s Start()

var camera = new CameraComponent();
camera.Slot = SceneSystem.GraphicsCompositor.Cameras[0].ToSlotId();
camera.Enabled = true;

I still get following error:
System.InvalidOperationException: 'A SceneCameraRenderer in use has no camera set. Make sure the camera component to use is enabled and has its [Slot] property correctly set.'
Not sure if I set my camera wrongly, or if there is some hidden SceneCameraRenderer somewhere.
How to investigate?

Are you then adding that camera to the scene?

Well, no, how to do that?

“Adding camera to scene”:
To get the scene instance, I use this.SceneSystem.SceneInstance.RootScene
but then how to add my camera which is from type CameraComponent?

For example, I tried:
this.SceneSystem.SceneInstance.RootScene.Entities.Add(cam);
this.SceneSystem.SceneInstance.RootScene.Children.Add(cam);
Does not compile of course, wrong types.

Son how to add my camera to the scene? Thanks in advance

Well you can’t just add a component to the scene you have to add the component to an entity and add the entity to the scene. so you could do like:

SceneSystem.SceneInstance.RootScene.Entities.Add(new Entity{cam});

or

var cameraEntity = new Entity();
cameraEntity.Add(cam);
SceneSystem.SceneInstance.RootScene.Entities.Add(cameraEntity );

But I have been thinking about it. If you are not going to use any of the built in render features i.e. models, sprites, ui, particles etc. you might not even need a camera. You may just need to change your composition. i.e. delete all the unwanted features.stages and camera slots. I have not tried this though.

This solution worked for me.
As you say it is not clean because it is a fake camera that is not used, but it works so that’s fine
Thanks