Précédent   Forum des professionnels en informatique > Applications > Développement 2D, 3D et Jeux > API graphiques > DirectX
DirectX Forum d'entraide sur le développement avec DirectX. Avant de poster -> FAQ DirectX
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 02/06/2011, 15h53   #1
Invité régulier
 
Homme Quentin Ventura
Inscription : juin 2011
Messages : 30
Détails du profil
Informations personnelles :
Nom : Homme Quentin Ventura
Localisation : Canada

Informations professionnelles :
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2011
Messages : 30
Points : 8
Points : 8
Par défaut Optimisation de multi-view

(Petites précisions, c'est du C# couplé avec SlimDX)

Bonjour à tous,
Je développe actuellement une interface graphique qui doit afficher plusieurs données différentes à l'écran (un screenshot suit pour mieux comprendre)

J'aurai plusieurs types de vu à afficher, certaines ou j'affiche des plans avec déplacement de cibles et trajectoires, d'autre ou j'affiche des graphiques a 3 dimensions. Les "plans" seront totalement en 2 dimensions. (sur le screen, seuls les plans sont affichés)

http://imageshack.us/photo/my-images...enshot1an.png/

Donc voila la manière dont j'ai développé le bazar:
J'ai une classe static GPIUDevice qui instancie un device sans swapchain, et qui a en attribut une liste de panels
Ensuite, j'ai (pour le moment) deux types de panel, les plans, et les miniatures, qui sont tous deux des panels dans lesquels je dessine avec directX. Donc par exemple sur le screen, j'ai 2 grands plans, et 16 miniatures (8 sont cachés) ce qui fait 18 panels utilisants directX pour l'affichage.
Pour chacun de ses panels, je créé donc une swapChain, un renderTarget, etc. pour chacun des panels. En gros j'me retrouve avec 18 swapChain donc.

Quand je lance mon appli, j'utilise comme 260 000k de mémoire, ce qui me semble assez énorme, donc j'en déduis que la manière dont je fais ça est vraiment pas optimisée !

Ma classe qui instancie le device

Code :
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlimDX;
using SlimDX.Direct3D10;
 
using Device = SlimDX.Direct3D10.Device;
 
namespace PrototypeV4.GraphicEngine
{
 
    static class GPUDevice
    {
        private static SlimDX.Direct3D10.Device gpuDevice;
        private static List<PrototypeV4.GUI.ViewPanel> listOfPanels;
        static GPUDevice()
        {
            gpuDevice = new SlimDX.Direct3D10.Device(DriverType.Hardware, DeviceCreationFlags.Debug);
            listOfPanels = new List<GUI.ViewPanel>();
        }
 
        public static SlimDX.Direct3D10.Device GpuDevice
        {
            get
            {
                return gpuDevice;
            }
        }
 
        public static List<GUI.ViewPanel> ListOfPanelsToRender
        {
            get
            {
                return listOfPanels;
            }
        }
 
        public static void addPanelToRender(GUI.ViewPanel vp)
        {
            listOfPanels.Add(vp);
        }
 
 
        public static void clear()
        {
            gpuDevice.Dispose();
        }
    }
}
Et l'une de mes classe panel (j'ai viré deux trois trucs pas utile pour alléger)

Code :
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlimDX;
using SlimDX.Direct3D10;
using SlimDX.DXGI;
using SlimDX.Windows;
using SlimDX.D3DCompiler;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
namespace PrototypeV4.GUI
{
    [StructLayout(LayoutKind.Sequential)]
    struct Vertex
    {
        public Vector4 PositionRhw;
        public Vector4 Color;
        public Vector2 UV;
    }
 
    class MapView : ViewPanel
    {
        SlimDX.Direct3D10.Device gpuDevice;
 
        private SwapChain swapChain;
        private RenderTargetView renderTarget;
        private Factory factory;
        private Viewport viewport;
        private SlimDX.Direct3D10.Resource resource;
        private Effect effect;
        private EffectTechnique technique;
        private EffectPass pass;
        private List<Vector4> vertexPositions;
        private List<Vector2> textureCoords;
        private List<Vector4> vertexColors;
        private SlimDX.Direct3D10.Buffer vertices;
        private InputLayout layout;
 
        private float mapWidth;
        private float mapHeight;
        private Modele.M_Map map;
        private MapViewContainer parent;
 
        public MapView(MapViewContainer parent)
            : base()
        {
 
            this.parent = parent;
            map = parent.CurrentMap;
            mapWidth = map.Width;
            mapHeight = map.Height;
 
            this.Dock = System.Windows.Forms.DockStyle.Fill;
            gpuDevice = GraphicEngine.GPUDevice.GpuDevice;
 
            initView();  
 
        }
 
        public override void run()
        {
            gpuDevice.ClearRenderTargetView(renderTarget, this.BackColor);
            gpuDevice.OutputMerger.SetTargets(renderTarget);
 
            for (int p = 0; p < technique.Description.PassCount; p++)
            {
                pass.Apply();
                gpuDevice.Draw(4, 0);
            }
 
            swapChain.Present(0, PresentFlags.None);
        }
 
         public void initView()
        {
            vertexPositions = new List<Vector4>();
            textureCoords = new List<Vector2>();
            vertexColors = new List<Vector4>();
 
            var description = new SwapChainDescription()
            {
                BufferCount = 2,
                Usage = Usage.RenderTargetOutput,
                OutputHandle = Handle,
                IsWindowed = true,
                ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                SampleDescription = new SampleDescription(1, 0),
                Flags = SwapChainFlags.AllowModeSwitch,
                SwapEffect = SwapEffect.Discard
            };
 
 
            factory = new Factory();
            factory.SetWindowAssociation(Handle, WindowAssociationFlags.IgnoreAltEnter);
 
            swapChain = new SwapChain(factory, gpuDevice, description);
 
            resource = SlimDX.Direct3D10.Resource.FromSwapChain<Texture2D>(swapChain, 0);
            renderTarget = new RenderTargetView(gpuDevice, resource);
 
            viewport = new Viewport(0, 0, this.Width, this.Height);
            gpuDevice.OutputMerger.SetTargets(renderTarget);
            gpuDevice.Rasterizer.SetViewports(viewport);
 
            effect = Effect.FromFile(gpuDevice, "PrototypeV4.fx", "fx_4_0", ShaderFlags.None, EffectFlags.None, null, null);
            technique = effect.GetTechniqueByIndex(0);
            pass = technique.GetPassByIndex(0);
 
 
            Texture2D texture = Texture2D.FromFile(gpuDevice, map.Path);
            EffectResourceVariable shaderTexture = effect.GetVariableByName("texture2d").AsResource();
            ShaderResourceView textureView = new ShaderResourceView(gpuDevice, texture);
            shaderTexture.SetResource(textureView);
 
            InputElement[] inputElements = new InputElement[]
					{
						new InputElement("POSITION", 0, SlimDX.DXGI.Format.R32G32B32A32_Float, 0, 0),
						new InputElement("COLOR", 0, SlimDX.DXGI.Format.R32G32B32A32_Float, 16, 0),
                        new InputElement("TEXCOORD", 0, SlimDX.DXGI.Format.R32G32_Float, 32, 0)
					};
            layout = new InputLayout(gpuDevice, pass.Description.Signature, inputElements);
 
            float ratio = 1 / (mapHeight / mapWidth);
 
            vertexPositions.Add(new Vector4(-1.0f * ratio, -1.0f, 0.5f, 1.0f));
            vertexPositions.Add(new Vector4(-1.0f * ratio, 1.0f, 0.5f, 1.0f));
            vertexPositions.Add(new Vector4(1.0f * ratio, -1.0f, 0.5f, 1.0f));
            vertexPositions.Add(new Vector4(1.0f * ratio, 1.0f, 0.5f, 1.0f));
 
            textureCoords.Add(new Vector2(0.0f, 1.0f));
            textureCoords.Add(new Vector2(0.0f, 0.0f));
            textureCoords.Add(new Vector2(1.0f, 1.0f));
            textureCoords.Add(new Vector2(1.0f, 0.0f));
 
            vertexColors.Add(new Vector4(1.0f, 0.0f, 0.0f, 1.0f));
            vertexColors.Add(new Vector4(0.0f, 1.0f, 0.0f, 1.0f));
            vertexColors.Add(new Vector4(0.0f, 0.0f, 1.0f, 1.0f));
            vertexColors.Add(new Vector4(1.0f, 0.0f, 1.0f, 1.0f));   
 
            DataStream stream = new DataStream(vertexPositions.Count * Marshal.SizeOf(typeof(Vertex)), true, true);
            for (int i = 0; i < vertexPositions.Count; i++)
            {
                stream.Write(vertexPositions[i]);
                stream.Write(vertexColors[i]);
                stream.Write(textureCoords[i]);             
            }
 
            stream.Position = 0;
 
            BufferDescription bufferDescription = new BufferDescription();
            bufferDescription.BindFlags = BindFlags.VertexBuffer;
            bufferDescription.CpuAccessFlags = CpuAccessFlags.None;
            bufferDescription.OptionFlags = ResourceOptionFlags.None;
            bufferDescription.SizeInBytes = vertexPositions.Count * Marshal.SizeOf(typeof(Vertex));
            bufferDescription.Usage = ResourceUsage.Default;
 
            vertices = new SlimDX.Direct3D10.Buffer(gpuDevice, stream, bufferDescription);
 
            stream.Close();
 
            // create the vertex layout and buffer
            // configure the Input Assembler portion of the pipeline with the vertex data
 
            gpuDevice.InputAssembler.SetInputLayout(layout);
            gpuDevice.InputAssembler.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
            gpuDevice.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Marshal.SizeOf(typeof(Vertex)), 0));
 
        }
 
    }
}
Et enfin la manière donc j'utilise le tout dans mon form:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
            MessagePump.Run(this, () =>
            {
                foreach(GUI.ViewPanel vp in GraphicEngine.GPUDevice.ListOfPanelsToRender)
                {
                    vp.run();
                }
            });
            foreach (GUI.ViewPanel vp in GraphicEngine.GPUDevice.ListOfPanelsToRender)
            {
                vp.clear();
            }
Donc déjà je pense que pour alléger le tout, j'peux regarder du côté des "dispose". Pour le moment, dans ma classe PanelView, je passe tout en attribut de classe, que ce soit les factory, les ressource, texture2d, etc. Je devrais je pense alléger le tout. Qu'est ce que je peux créer localement dans la fontion init, et de quoi ai-je besoin en attribut de classe?
J'aurai bien envie de passer uniquement : renderTarget, technique (EffectTechnique), pass (EffectPass) et swapChain en attribut de classe et le reste en local, mais est ce la bonne solution ?
qventura est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/06/2011, 16h35   #2
Membre Expert
 
Inscription : février 2006
Messages : 1 391
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 1 391
Points : 2 053
Points : 2 053
bonjour,

est ce que tous tes affichages ont besoin de dx?

les miniatures, tel que je le vois, sont juste des bitmaps plus ou moins statiques, donc quand il y a une mise à jour, récupération du front buffer, conversion en bitmap et affichage dans une miniature.
stardeath est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/06/2011, 16h49   #3
Invité régulier
 
Homme Quentin Ventura
Inscription : juin 2011
Messages : 30
Détails du profil
Informations personnelles :
Nom : Homme Quentin Ventura
Localisation : Canada

Informations professionnelles :
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2011
Messages : 30
Points : 8
Points : 8
En fait pour le moment tout est statique. Mais sur chacun de ces panel je vais placer des "Cibles" et les faire se déplacer. Sur les miniatures ont verra juste le déplacement par internat de x secondes, sur les plan en eux même, les déplacement temps réel avec l'affichage des trajectoires.

Donc même pour les miniatures, il ne s'agit pas juste d'image statiques.

Par contre je sais pas ... Je peux peut être mettre l'image en background du panel et dessiner par dessus les cibles avec un backbuffer transparant ? Mais dans ce cas je perds l'accélération matérielle pour l'affichage des plans. (Qui sont ici d'une qualité pourrie, mais qui pourrait être en haute définition et donc avoir un certain poids)

En tout cas merci de t'intéresser au sujet !
qventura est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/06/2011, 18h50   #4
Membre Expert
 
Inscription : février 2006
Messages : 1 391
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 1 391
Points : 2 053
Points : 2 053
en fait je ne comprends pas tes besoins.

si tu ne fais que de la 2d, direct3d ne sert à rien, même pour l'accélération matérielle, si tu ne fais pas d'action utilisant le gpu, c'est plus du gâchi qu'autre chose.

dans ce cas autant faire du direct2d, en plus c'est fait exprès, garde plutôt direct3d pour la 3d.
stardeath est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/06/2011, 02h35   #5
Invité régulier
 
Homme Quentin Ventura
Inscription : juin 2011
Messages : 30
Détails du profil
Informations personnelles :
Nom : Homme Quentin Ventura
Localisation : Canada

Informations professionnelles :
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2011
Messages : 30
Points : 8
Points : 8
Réponse tardive, je m'étais attaqué à un autre gros morceaux

Direct2D n'est pas uniquement inclut dans DirectX11 et donc uniquement pour Vista / Seven ?
qventura est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/06/2011, 12h56   #6
Membre Expert
 
Inscription : février 2006
Messages : 1 391
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 1 391
Points : 2 053
Points : 2 053
il utilise déjà de base directx 10, donc déjà contraint à vista minimum.
stardeath est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/06/2011, 20h33   #7
Invité régulier
 
Homme Quentin Ventura
Inscription : juin 2011
Messages : 30
Détails du profil
Informations personnelles :
Nom : Homme Quentin Ventura
Localisation : Canada

Informations professionnelles :
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2011
Messages : 30
Points : 8
Points : 8
WTF ... J'aurai du me renseigner avant, j'étais persuadé que directX 10 était compatible XP !
En plus à vu de nez la manière de programmer diffère pas mal entre les deux ... Bon bah je vais rester sur DX10 pour mon prototype ...

Mais du coup je vais devoir faire une version qui tournera sur XP dans un future plus ou moins proche. C'est peut être plus simple dans ce cas de continuer a ne pas utiliser Direct2D, comme ça le travail sera en grande partie réutilisable ... Et je pense qu'il sera plus simple ensuite de développer des classes utilisant Direct2D pour avoir un prototype multiversion ...
qventura est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h20.


 
 
 
 
Partenaires

Hébergement Web