Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple GameWindow support for Windows/DirectX #1465

Merged
merged 17 commits into from
May 1, 2013

Conversation

jamesford42
Copy link

Adding support for multiple GameWindow(s) within a single game.

This is only implemented for WINDOWS && DIRECTX

Non-primary windows do not handle any input and for input events to reach the users game the primary window must be active. This can be improved at a later time when it is a needed feature.

The existing Game / Platform / GraphicsDevice code is largely unchanged and only deals directly with the standard, primary window which it also creates.

Example:

// In Game.Initialize()
window = GameWindow.CreateWindow(this, 640, 480);
window.Title = "Second Game Window";
swapChain = new SwapChainRenderTarget(GraphicsDevice, window.Handle, 640, 480);

// In Game.Draw()
GraphicsDevice.SetRenderTarget(swapChain);
GraphicsDevice.Clear(Color.Red);
GraphicsDevice.Present();
GraphicsDevice.SetRenderTarget(null);

@mgbot
Copy link
Member

mgbot commented Feb 26, 2013

Can one of the admins verify this patch?

@jamesford42 jamesford42 mentioned this pull request Feb 26, 2013
@tomspilman
Copy link
Member

@mgbot test

@mgbot
Copy link
Member

mgbot commented Feb 26, 2013

Build results will soon be (or already are) available at: http://build.monogame.net/job/BuildPR/41/

@tomspilman
Copy link
Member

@mgbot test

@mgbot
Copy link
Member

mgbot commented Feb 26, 2013

Build results will soon be (or already are) available at: http://build.monogame.net/job/BuildPR/42/

@tomspilman
Copy link
Member

@mgbot test

@mgbot
Copy link
Member

mgbot commented Feb 27, 2013

Build results will soon be (or already are) available at: http://build.monogame.net/job/BuildPR/44/

@mgbot
Copy link
Member

mgbot commented Mar 5, 2013

Can one of the admins verify this patch?

@dellis1972
Copy link
Contributor

@mgbot test

On 5 March 2013 22:59, MonoGame Build Bot notifications@github.com wrote:

Can one of the admins verify this patch?

Reply to this email directly or view it on GitHubhttps://github.com//pull/1465#issuecomment-14471385
.

@tomspilman
Copy link
Member

@mgbot test

@mgbot
Copy link
Member

mgbot commented Mar 9, 2013

Build results will soon be (or already are) available at: http://build.monogame.net/job/BuildPR/88/

@tomspilman
Copy link
Member

Can someone else give this PR a test?

Are there any concerns with adding this feature?

@xanather
Copy link
Contributor

xanather commented Mar 9, 2013

I can give this a test later tonight/tomorrow, but how do I function it? create another GameWindow from within the main Game1.cs constructor? then to draw set RenderTarget to that window?

@tomspilman
Copy link
Member

Well first make sure it doesn't break any existing functionality in your game.

If you want to then test the new features just create the second window in Game.Initialize:

_altwindow = GameWindow.CreateWindow(this, 640, 480);
_altwindow.Title = "Second Game Window";

_altSwapChain = new SwapChainRenderTarget( GraphicsDevice, 
                                            _altwindow.Handle,
                                            640,
                                            480,
                                            false,
                                            PresentInterval.Default,
                                            SurfaceFormat.Color,
                                            DepthFormat.Depth24Stencil8,
                                            0,
                                            RenderTargetUsage.DiscardContents);

Then in your Game.Draw do this:

// Set the alt windows/swapcain and render to it.
GraphicsDevice.SetRenderTarget(_altSwapChain);
GraphicsDevice.Clear(Color.Red);
GraphicsDevice.Present();

// Return to the default window/swapchain.
GraphicsDevice.SetRenderTarget(null);

// Do your normal rendering.

base.Draw();

It is pretty simple and you can create as many windows as you need.

Also in theory you could pass a IntPtr handle to a non-GameWindow window as well... but we've not tried that.

@xanather
Copy link
Contributor

Well, I can make the other window show. However I cant render to it (its not displaying the correct color from GraphicsDevice.Clear()).

This is my draw method:

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.SetRenderTarget(swapChain);
        GraphicsDevice.Clear(Color.Black);
        GraphicsDevice.Present();
        GraphicsDevice.SetRenderTarget(null);
        GraphicsDevice.Clear(Color.Black);
        base.Draw(gameTime);
    }

The other window just has the default creamy-colored background.

Also can I suggest that SwapChainRenderTarget gets a new constructor that is much more simple and automatically sets all the other settings (default settings)?

new SwapChainRenderTarget(GraphicsDevice, gameWindow.Handle, 1000, 1000);?

If people want the more customizable constructor they can use it aswell

@tomspilman
Copy link
Member

@xanather

However I cant render to it

Are you sure you are building against MonoGame for Windows DX? It does not work under OpenGL yet.

Also can I suggest that SwapChainRenderTarget gets a new constructor

Sure... no problem. I'll add that right now in fact.

@tomspilman
Copy link
Member

Note I came across the old Windows Mobile C# wrapper for DirectX and it too has a SwapChain class:

http://msdn.microsoft.com/en-us/library/microsoft.windowsmobile.directx.direct3d.swapchain_members.aspx

Just noting the precedent for having this class in MonoGame.

Rearraged the construtor parameters to match RenderTarget better.
Resharper cleanups.
Added some TODOs.
Fixed some of the docs.
@tomspilman
Copy link
Member

@xanather - Updated with the simpler constructor.

@xanather
Copy link
Contributor

It is a windows DirectX project.

Code:

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace MonoGameTest
{
    class Engine : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        GameWindow gameWindow;
        SwapChainRenderTarget swapChain;
        public Engine()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
        protected override void Initialize()
        {
            gameWindow = GameWindow.Create(this, 640, 480);
            gameWindow.Title = "Second Game Window Test";
            swapChain = new SwapChainRenderTarget(GraphicsDevice, gameWindow.Handle, 640, 480, false, PresentInterval.Default, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents);
            base.Initialize();
        }
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
        }
        protected override void UnloadContent()
        {
        }
        protected override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.SetRenderTarget(swapChain);
            GraphicsDevice.Clear(Color.Black);
            GraphicsDevice.Present();
            GraphicsDevice.SetRenderTarget(null);
            GraphicsDevice.Clear(Color.Black);
            base.Draw(gameTime);
        }
    }
}

Edit: that didnt come out too well : /
Should be still readable though, I can't see anything wrong with it?

@tomspilman
Copy link
Member

@xanather

I edited your post to use code block formatting... take a look.

Maybe try calling base.Initialize(); before everything else in that method?

@xanather
Copy link
Contributor

no difference, do you want me to upload the project?

@tomspilman
Copy link
Member

Hum. I have an idea... i'll test it over here first. I think there might be an error if you try to create the swap chain too early. Looking at our use we are creating the swap chain on first GameWindow.ClientSizeChanged event.

@xanather
Copy link
Contributor

Oh I see. I just tried after a 1 second timer, still doesn't work.

@KonajuGames
Copy link
Contributor

I've been trying to test this, but I get E_FAIL (0x80004005) when trying to create the Direct3D11 device. No idea why.

@tomspilman
Copy link
Member

Hum.... i'll make sure I test a clean pull of this and verify some of the issues brought up here.

@tomspilman
Copy link
Member

@xanather - I went and tested your case... you just misinterpreted how to use the API. You had this:

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.SetRenderTarget(swapChain);
            GraphicsDevice.Clear(Color.Black);
            GraphicsDevice.Present(); // WRONG!

            GraphicsDevice.SetRenderTarget(null);
            GraphicsDevice.Clear(Color.Black);
            base.Draw(gameTime);
        }

... it should have been this...

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.SetRenderTarget(swapChain);
            GraphicsDevice.Clear(Color.Black);
            swapChain.Present(); // Correct!

            GraphicsDevice.SetRenderTarget(null);
            GraphicsDevice.Clear(Color.Black);
            base.Draw(gameTime);
        }

So this it would be good if you can verify, but this PR does work.

@tomspilman
Copy link
Member

@slygamer @dellis1972

Are you guys good with this?

Note that the high level plan is simplify swapchain/framebuffer management code in GraphicsDevice.

I next want to add OpenGL support (not sure if GLES can support it). Also need to add resize support as that is missing right now.

Then we can replace the existing swap chain creation/resizing code which makes up a ton of GraphicsDevice (and scattered about on OpenGL) with this class.

@tomspilman
Copy link
Member

@mgbot test

@mgbot
Copy link
Member

mgbot commented Apr 5, 2013

Build results will soon be (or already are) available at: http://build.monogame.net/job/PullRequestTester/86/

@dellis1972
Copy link
Contributor

ok by me

On 5 April 2013 19:51, MonoGame Build Bot notifications@github.com wrote:

Build results will soon be (or already are) available at:
http://build.monogame.net/job/PullRequestTester/86/


Reply to this email directly or view it on GitHubhttps://github.com//pull/1465#issuecomment-15973815
.

@xanather
Copy link
Contributor

xanather commented Apr 6, 2013

Oh cool, I will verify it soon

@xanather
Copy link
Contributor

xanather commented Apr 7, 2013

yep with the change it works :)

@xanather xanather mentioned this pull request Apr 23, 2013
KonajuGames added a commit that referenced this pull request May 1, 2013
Multiple GameWindow support for Windows/DirectX
@KonajuGames KonajuGames merged commit 7da4118 into MonoGame:develop May 1, 2013
@tomspilman tomspilman deleted the multiwin branch January 20, 2014 09:17
alxwest pushed a commit to alxwest/MonoGame that referenced this pull request May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants