Porting from Xenko 1.10 to Xenko 2.0 : Scene Renderers


#1

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


#2

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


#3

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();
}

#4

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


#5

You’re welcome. Glad to help.


#6

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?


#7

Are you then adding that camera to the scene?


#8

Well, no, how to do that?


#9

“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


#10

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.


#11

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