Bonjour,

J'ai en projet d'écrire un petit jeu histoire d'élargir mes connaissances en C#.

Après avoir tenté d'écrire un petit moteur graphique avec GDI et tombé à moins de 10 fps dès que j'ai voulu commencer à dessiner quelques formes simples, je me suis tourné vers SharpDX, en utilisant la partie 2D.

J'ai "à peu près" compris comment ça marchait d'un point de vue dessin. J'ai pas trop de souci pour dessiner une scène, et avec quelques mini-optimisations, je suis à 1500fps (pour une scène vide et statique, certes), mais tout de même plus complèxe que celle de GDI qui m'avait fait tomber à moins de 15fps... De ce côté, pour le moment "tout va bien".

En revanche, c'est pour le reste.

En effet, avec le tuto GDI que j'avais trouvé, j'avais bien cerné l'endroit et la manière de déclencher deux thread séparés : un pour le moteur graphique, et un pour le moteur du jeu lui-même.

Seulement, avec les tutos que j'ai pu trouver sur SharpDX, j'ai du tout casser, et je n'arrive pas à comprendre :
- où créer mon thread du moteur de jeu
- comment accéder depuis le moteur graphique aux données du moteur de jeu
- comment renvoyer au moteur de jeu les actions utilisateur (clic souris, etc.)

Voici mon fichier "program.cs" :

Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
 
using System;
using System.Windows.Forms;
 
using SharpDX;
using SharpDX.DXGI;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.Direct2D1;
using SharpDX.Windows;
using Device = SharpDX.Direct3D11.Device;
using FactoryD2D = SharpDX.Direct2D1.Factory;
using FactoryDXGI = SharpDX.DXGI.Factory1;
 
namespace MyGame
{
    static class Program
    {
        static void Main()
        {
            // Create render target window
            var form = new RenderForm("MyGame");
 
            // Create swap chain description
            var swapChainDesc = new SwapChainDescription()
            {
                BufferCount = 2,
                Usage = Usage.RenderTargetOutput,
                OutputHandle = form.Handle,
                IsWindowed = false,
                ModeDescription = new ModeDescription(System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width,System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                SampleDescription = new SampleDescription(1, 0),
                Flags = SwapChainFlags.AllowModeSwitch,
                SwapEffect = SwapEffect.Discard
            };
 
            // Create swap chain and Direct3D device
            // The BgraSupport flag is needed for Direct2D compatibility otherwise new RenderTarget() will fail!
            Device device;
            SwapChain swapChain;
            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.BgraSupport, swapChainDesc, out device, out swapChain);
 
            // Get back buffer in a Direct2D-compatible format (DXGI surface)
            Surface backBuffer = Surface.FromSwapChain(swapChain, 0);
            RenderTarget renderTarget;
 
            // Create Direct2D factory
            using (var factory = new FactoryD2D())
            {
                // Get desktop DPI
                var dpi = factory.DesktopDpi;
 
                // Create bitmap render target from DXGI surface
                renderTarget = new RenderTarget(factory, backBuffer, new RenderTargetProperties()
                {
                    DpiX = dpi.Width,
                    DpiY = dpi.Height,
                    MinLevel = SharpDX.Direct2D1.FeatureLevel.Level_DEFAULT,
                    PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Ignore),
                    Type = RenderTargetType.Default,
                    Usage = RenderTargetUsage.None
                });
            }
 
            // Disable automatic ALT+Enter processing because it doesn't work properly with WinForms
            using (var factory = swapChain.GetParent<FactoryDXGI>())   // Factory or Factory1?
            {
                factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAltEnter);
            }
 
            renderTarget.Transform = Matrix3x2.Identity;
            GraphicEngine ge = new GraphicEngine(renderTarget);
 
            // Rendering function
            RenderLoop.Run(form, () =>
            {
                renderTarget.BeginDraw();
 
                ge.DrawScene();
 
                renderTarget.EndDraw();
 
                swapChain.Present(0, PresentFlags.None);
            });
 
            renderTarget.Dispose();
            swapChain.Dispose();
            device.Dispose();
        }
    }
}

J'ai bien compris que mon "RenderLoop.Run" correspondait à la boucle qui lançait le moteur graphique.

Mais je ne suis pas habitué à cette syntaxe. Du coup je vois pas comment je peux lancer un thread en parallèle et interagir avec le contenu de mon Run()...