Hy
Ist es möglich, XNA in ein Control zu rendern und nebenbei auch noch Controls auf meinem Formular zu haben? So, wie in dem angehängten Bild. Es soll in das blaue Panel gerendert werden.
sbertl
Hallo sbertl000
Mit Managed DirectX ist das auf jeden Fall möglich, auch mit XNA sollte das gehen.
Du benutzt dazu das Handle des Controls.
Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011
Und wo weiß ich das Handle zu? Und wo muss ich dann:
using (Game1 game = new Game1())
{
game.Run();
}
plazieren, damit auch Form Events geworfen werden und die GUI nicht einfriert?
sbertl
Medieval Fantasy Online - ORPG Projekt
.NET - Try and Error - Blog - Gemeinschaftsblog
MEt45's Dev Garage - Eigener Blog
Ok, so funktioniert das, aber dadurch muss ich doch wieder alles manuell machen. Das Game-Loop... Und ich hab auch dann keine Klasse mehr, die von Game erbt. Kann man das nicht anders realisieren?
sbertl
Ich hab auch noch eine andere Möglichkeit gefunden, so kann man direkt in ein Control rendern:
graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
private void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs eventargs)
{
eventargs.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = handle; //handle ist ein IntPtr Handle eines Controls
}
Allerdings ist die Performance mehr als grausig, so krieg ich gerade mal 20 fps zusammen mit einem einfachen Dreieck...
Es geht auch noch anders, indem man die Controls über das gerenderte Fenster legt. Im Konstruktor des Spiels z.B. folgendes hinzufügen:
System.Windows.Forms.Control gameWindow = System.Windows.Forms.Control.FromHandle(this.Window.Handle);
panel = new System.Windows.Forms.Panel();
panel.Bounds = new System.Drawing.Rectangle(700, 0, 100, 600);
panel.Parent = gameWindow;
Dann liegt das Panel allerdings wieder über dem zu zeichnenden Bereich, was auch nicht ideal ist.
sbertl
Hi sbertl,
vielleicht hab ich das Problem falsch verstanden oder stells mir auch zu einfach vor.. Aber ich hätte jetzt einfach gesagt, dass du beim Rendern am Schluss einfach sagst
device.Present(myControl);
dann rendert er nur in dem Control.. wenn du ein Label übergibst, dann eben in deinem Label.. das erscheint mir nu allerdings zu einfach, also hab ich wohl was falsch verstanden? 🤔
greetz..
I cna tpye 300 wrods pre mnuite!
Ja, das stimmt schon, aber das hat genau die selbe Auswirkung wie
eventargs.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = panel.Handle;
sbertl
Hallo zusammen
Ich benutze folgender Code, um mit Managed DirectX in eine Form zu zeichnen.
(Form ist auch ein Control):
this._device = new Device(0, DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing, pres);
Evt. http://www.zaknafein.hjcrusaders.com/?p=21
Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011
Du hast schon recht, aber würde ich das bei XNA so machen könnte ich den vorgefertigten GraphicsDeviceManager und ContentManager nicht mehr verwenden. Dein Link beschreibt eh das, was ich oben schon gepostet habe:
graphics.PreparingDeviceSettings Event abfangen und dann
eventargs.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = BeliebigesControl.Handle;
Wie gesagt, es funktioniert, allerdings verliere ich Performance und ganz besonders, was bei MDX nicht passiert: Meine FPS Anzeige von Fraps oder anderen wird sehr klein und passt sich der AspectRation nicht an.
sbertl
Ein Problem bleibt jedoch. Die Größe des Backbuffers muss ja auf die Größe des Forms eingestellt werden, sonst wird das Form kleiner. Mein Panel ist aber kleiner (z.B.: 320x240) doch der Backbuffer hat z.B.: 800x600...
sbertl
ich verweise ma auf meine andere antwort:
Medieval Fantasy Online - ORPG Projekt
.NET - Try and Error - Blog - Gemeinschaftsblog
MEt45's Dev Garage - Eigener Blog
Ok, das war mir klar, wie man die Größe des Forms verändert...
Aber: Ich habe ein Form mit 800x600, demnach muss auch der BackBuffer auf 800x600 eingestellt werden, sonst wird das Form kleiner.
Jetzt hab ich aber ein Panel mit z.B.: 320x240 in das ich rendere, allerdings hat der BackBuffer immer noch 800x600 und somit werden diese 800x600 in das 320x240 Panel gerendert
sbertl
Ist zwar schon etwas her, aber vielleicht wäre das etwas:
http://www.nuclex.org/downloads/developers/kits/xna-usercontrol
Gruß Robert
Du hast zwei Möglichkeiten. Entweder veränderst du die Größe des Backbuffers im Resize-Ereignishandler oder du benutzt eine eigene SwapChain.
Wenn du den Backbuffer vergrößerst, mußt du das Device resetten (das bezieht sich übrigens alles Managed DirectX, dürfte aber bei XNA zumindest ähnlich ablaufen).
Wenn du eine eigene SwapChain benutzt, kannst du jedesmal, wenn das Fenster vergrößert/verkleinert wird, die alte SwapChain einfach löschen und eine neue erstellen:
// SwapChain erstellen:
PresentParameters presentParams = device.PresentationParameters.Clone() as PresentParameters;
presentParams.DeviceWindow = this;
presentParams.BackBufferCount = 1;
presentParams.BackBufferWidth = this.Width;
presentParams.BackBufferHeight = this.Height;
presentParams.Windowed = true;
// ... (andere Einstellungen)
SwapChain swapChain = new SwapChain(device, presentParams);
// Löschen:
swapChain.Dispose();
// Anstatt device.Present(this)
swapChain.Present();
Die Backbuffer-Größe für das Device kannst du beim Erstellen einfach auf 1x1 setzen, um den Speicher zu sparen.
Schöne Grüße,
Christian
Weeks of programming can save you hours of planning