none
Problème de rafraîchissement d'affichage panel DirectX dans une ChildForm RRS feed

  • Question

  • Bonjour,

    Je m'exerce sur DirectX9.0c avec VC++ 2008 et j'ai réalisé un programme contenant une MainForm appelant une ChildForm dans laquelle se trouve un contrôle panel dans lequel j'affiche la visualisation en 3D d'un triangle qui tourne avec DirectX.

    Le prolème, c'est que le rafraîchissment du panel ne s'effectue que lorsque je déplace la ChildForm avec le curseur de la souris. Je pense que j'ai un problème avec ma fonction Composant_3D_Paint() car elle ne doit être appelée que larsque bouge ma fenêtre.

    Quelle focntion doit-on utiliser pour assurer un rafraîchissment en temps réel ? J'ai lu des des article sur la focntion PeekMessage() mais je ne sais pas si c'est réellment une solution et encore moins comment la mettre en oeuvre dans mon code.

    Connaissez-vous une solution pour assurer le rafraîchissement en temps réel?

    Je vous joins le code de ma ChildForm pour infformation :

    #pragma once
    
    namespace Archi_3D {
    
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    
    	using namespace Microsoft::DirectX;
    	using namespace Microsoft::DirectX::Direct3D;
    	using namespace Microsoft::DirectX::Diagnostics;
    
    
    	public ref class Composant_3D : public System::Windows::Forms::Form
    	{
    	
    	private: String ^Component_Name;
    
    	//Direct 3D device
    	private: Microsoft::DirectX::Direct3D::Device^ device;
    	
    	//
    	private: VertexBuffer ^vBuffer;
    
    	//Direct 3D Vertrices
    	private: array<CustomVertex::PositionColored, 1>^ Vertices;
    
    
    	private: System::Windows::Forms::Panel^  pnl_Visu_3D;
    	private: System::ComponentModel::IContainer^  components;
    
    			 
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			this->pnl_Visu_3D = (gcnew System::Windows::Forms::Panel());
    			this->SuspendLayout();
    			// 
    			// pnl_Visu_3D
    			// 
    			this->pnl_Visu_3D->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;
    			this->pnl_Visu_3D->Location = System::Drawing::Point(28, 41);
    			this->pnl_Visu_3D->Name = L"pnl_Visu_3D";
    			this->pnl_Visu_3D->Size = System::Drawing::Size(618, 437);
    			this->pnl_Visu_3D->TabIndex = 0;
    			// 
    			// Composant_3D
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->ClientSize = System::Drawing::Size(677, 522);
    			this->Controls->Add(this->pnl_Visu_3D);
    			this->Name = L"Composant_3D";
    			this->Text = L"Composant_3D";
    			this->ResumeLayout(false);
    
    		}
    
    #pragma endregion
    
    	public:
    		Composant_3D(String ^Nom_du_composant)
    		{
    			Component_Name = Nom_du_composant;
    
    			// Initialisation de la Windows Form
    			InitializeComponent();
    			this->Text = Component_Name;	//Renomme le titre dela fenêtre avec le nom du fichier
    			
    			InitializeGraphics();		//Initialisation de Direct 3D
    			
    			CreateTriangle();
    
    			Render();
    
    			this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &Composant_3D::Composant_3D_Paint);
    
    		}
    
    //Procédure d'initialisation du Device
    private : Void InitializeGraphics()
    		{
    			PresentParameters^ presentParams = gcnew PresentParameters();
    			presentParams->Windowed = true;
    			presentParams->SwapEffect = SwapEffect::Discard;
    			presentParams->EnableAutoDepthStencil = true;
    			presentParams->AutoDepthStencilFormat = DepthFormat::D16;
    			device = gcnew Device(0, DeviceType::Hardware, pnl_Visu_3D,	CreateFlags::SoftwareVertexProcessing, presentParams);
    		}
    
    // Procédure de création de notre triangle
    private :  Void CreateTriangle()
    		{
    			// On défini les vertices de notre triangle
    			Vertices = gcnew array<CustomVertex::PositionColored, 1>(3);
    			Vertices[0] = CustomVertex::PositionColored(0.0f, -1.0f, 0.0f, System::Drawing::Color::Red.ToArgb());
    			Vertices[1] = CustomVertex::PositionColored(-0.5f, 0.0f, 0.0f, System::Drawing::Color::Green.ToArgb());
    			Vertices[2] = CustomVertex::PositionColored(0.5f, 0.0f, 0.0f, System::Drawing::Color::Blue.ToArgb());
    	
    			// On crée le vertex buffer
    			vBuffer = gcnew VertexBuffer(CustomVertex::PositionColored::typeid, Vertices->Length, device, Usage::None, CustomVertex::PositionColored::Format, Pool::Default);
    	
    			// On stocke les vertices dans le vertex buffer
    			vBuffer->SetData(Vertices, 0, LockFlags::None);
    		}
    
    private: Void SetupMatrices()
    		{
    			float ^angle = gcnew float;
    			
    			Vector3 ^V3_CamPosition = gcnew Vector3(0.0f, 0.5f,-3.0f);
    			Vector3 ^V3_CamTarget = gcnew Vector3(0.0f, 0.5f,0.0f);
    			Vector3 ^V3_CamUpVector = gcnew Vector3(0.0f, 1.0f, 0.0f);
    
    			angle = Environment::TickCount / 500.0f;
    			device->Transform->World = Matrix::RotationY((float)angle);
    			device->Transform->View = Matrix::LookAtLH(*V3_CamPosition, *V3_CamTarget, *V3_CamUpVector);
    			device->Transform->Projection = Matrix::PerspectiveFovLH((float)Math::PI/4.0f, 1.0f, 1.0f, 5.0f);
    		}
    
    
    
    
    // La boucle de rendu
    private : Void Render()
    		{
    			// Effacement de la scène
    			device->Clear(ClearFlags::Target, Color::Bisque.ToArgb(), 1.0f, 0);
    			// Début de la scène
    			device->BeginScene();
    			// Configure les Matrices
    			SetupMatrices();
    			// On défini le vertex buffer à lire
    			device->SetStreamSource(0, vBuffer, 0);
    			// On défini le type des vertices stockées dans notre vertex buffer
    			device->VertexFormat = CustomVertex::PositionColored::Format;
    			// On dessine le vertex buffer
    			device->DrawPrimitives(PrimitiveType::TriangleList, 0, Vertices->Length / 3);
    	
    			// Fin de la scène
    			device->EndScene();
    			// Présentation de la scène à l'écran
    			device->Present();
    		}
    
    /// Clean up any resources being used.
    protected: ~Composant_3D()
    		{
    			if (components)delete components;
    			if(device) delete device;
    		}
    	private: System::Void Composant_3D_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e)
    			 {
    				 Render();
    			 }
    };
    }

    mercredi 22 février 2012 22:53

Réponses

Toutes les réponses

  • Il n'y que WindowsCE et ces héritier qui est un OS ayant des possibilités de temps réel.

    Donc temps réel veux dire que vous oubliez Windows.

    Je pense que vous utilisez le mauvais terme. ;-)

    Windows ne demande pas en permanence aux fenêtres de se réafficher, et heureusement.

    Il faut signaler à Windows que le contenu des fenêtres doit être rafraichi, par exemple avec un timer qui invalide l'affichage de tout ou partie d'un formulaire.

    http://msdn.microsoft.com/en-us/library/system.windows.forms.form.invalidate.aspx


    Paul Bacelar, Ex - MVP VC++

    jeudi 23 février 2012 10:28
    Modérateur
  • Paul,

    Effectivement, il s'agit certainement d'un emploi abusif de "temps réel".

    Ce que j'aurais voulu faire, c'est une boucle while dans une fonction main qui permettrait une remise à jour de l'affichage du Panel de ma MDIChild. Le problème, c'est que je n'ai pas de fonction main dans ma MDIChlid. La seule qui existe est dans ma Main form dont voici le code:

    Architeture_3D.cpp

    #include "stdafx.h"
    #include "Architecture_3D.h"
    
    
    using namespace Archi_3D;
    
    [STAThreadAttribute]
    int main(array<System::String ^> ^args)
    {
    	// Enabling Windows XP visual effects before any controls are created
    	Application::EnableVisualStyles();
    	Application::SetCompatibleTextRenderingDefault(false); 
    
    	// Create the main window and run it
    	Application::Run(gcnew Architecture_3D());
    
    	return 0;
    }

    Architetcure_3D.h

    #pragma once
    
    #include "Composant_3D.h"
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    
    
    namespace Archi_3D {
    
    	/// <summary>
    	/// Description résumée de Fenetre_Principale
    	///
    	/// AVERTISSEMENT : si vous modifiez le nom de cette classe, vous devrez modifier la
    	///          propriété 'Nom du fichier de ressources' de l'outil de compilation de ressource managée
    	///          pour tous les fichiers .resx dont dépend cette classe. Dans le cas contraire,
    	///          les concepteurs ne pourront pas interagir correctement avec les ressources
    	///          localisées associées à ce formulaire.
    	/// </summary>
    	public ref class Architecture_3D : public System::Windows::Forms::Form
    	{
    	public:
    		Architecture_3D(void)
    		{
    			InitializeComponent();
    			//
    			//TODO : ajoutez ici le code du constructeur
    			//
    		}
    
    	protected:
    		/// <summary>
    		/// Nettoyage des ressources utilisées.
    		/// </summary>
    		~Architecture_3D()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    	private: System::Windows::Forms::MenuStrip^  menuStrip1;
    	protected: 
    	private: System::Windows::Forms::ToolStripMenuItem^  fichierToolStripMenuItem;
    	private: System::Windows::Forms::ToolStripMenuItem^  ouvrirToolStripMenuItem;
    	private: System::Windows::Forms::OpenFileDialog^  Dlg0penComponent;
    	private: System::Windows::Forms::ToolStripMenuItem^  fenêtresToolStripMenuItem;
    
    	private:
    		/// <summary>
    		/// Variable nécessaire au concepteur.
    		/// </summary>
    		System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
    		/// le contenu de cette méthode avec l'éditeur de code.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			this->menuStrip1 = (gcnew System::Windows::Forms::MenuStrip());
    			this->fichierToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
    			this->ouvrirToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
    			this->Dlg0penComponent = (gcnew System::Windows::Forms::OpenFileDialog());
    			this->fenêtresToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
    			this->menuStrip1->SuspendLayout();
    			this->SuspendLayout();
    			// 
    			// menuStrip1
    			// 
    			this->menuStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(2) {this->fichierToolStripMenuItem, 
    				this->fenêtresToolStripMenuItem});
    			this->menuStrip1->Location = System::Drawing::Point(0, 0);
    			this->menuStrip1->MdiWindowListItem = this->fenêtresToolStripMenuItem;
    			this->menuStrip1->Name = L"menuStrip1";
    			this->menuStrip1->Size = System::Drawing::Size(1099, 24);
    			this->menuStrip1->TabIndex = 0;
    			this->menuStrip1->Text = L"menuStrip1";
    			// 
    			// fichierToolStripMenuItem
    			// 
    			this->fichierToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(1) {this->ouvrirToolStripMenuItem});
    			this->fichierToolStripMenuItem->Name = L"fichierToolStripMenuItem";
    			this->fichierToolStripMenuItem->Size = System::Drawing::Size(50, 20);
    			this->fichierToolStripMenuItem->Text = L"&Fichier";
    			// 
    			// ouvrirToolStripMenuItem
    			// 
    			this->ouvrirToolStripMenuItem->Name = L"ouvrirToolStripMenuItem";
    			this->ouvrirToolStripMenuItem->Size = System::Drawing::Size(115, 22);
    			this->ouvrirToolStripMenuItem->Text = L"&Ouvrir";
    			this->ouvrirToolStripMenuItem->Click += gcnew System::EventHandler(this, &Architecture_3D::ouvrirToolStripMenuItem_Click);
    			// 
    			// Dlg0penComponent
    			// 
    			this->Dlg0penComponent->Filter = L"Fichier Points (*.txt)|*.txt|Tous les fichiers (*.*)|*.*";
    			this->Dlg0penComponent->InitialDirectory = L"D:\\Dossier système\\Mes Documents\\Visual Studio 2008\\Projects";
    			// 
    			// fenêtresToolStripMenuItem
    			// 
    			this->fenêtresToolStripMenuItem->Name = L"fenêtresToolStripMenuItem";
    			this->fenêtresToolStripMenuItem->Size = System::Drawing::Size(62, 20);
    			this->fenêtresToolStripMenuItem->Text = L"Fenêtres";
    			// 
    			// Architecture_3D
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->ClientSize = System::Drawing::Size(1099, 579);
    			this->Controls->Add(this->menuStrip1);
    			this->IsMdiContainer = true;
    			this->MainMenuStrip = this->menuStrip1;
    			this->Name = L"Architecture_3D";
    			this->Text = L"Architecture_3D";
    			this->menuStrip1->ResumeLayout(false);
    			this->menuStrip1->PerformLayout();
    			this->ResumeLayout(false);
    			this->PerformLayout();
    
    		}
    #pragma endregion
    	private: System::Void ouvrirToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
    	{
    		if (Dlg0penComponent->ShowDialog() == ::DialogResult::OK)
    		{
    			if (Dlg0penComponent->SafeFileName != nullptr)
    			{
    				//Ouverture d'une fenêtre composant				
    				Composant_3D ^New_Composant_3D = gcnew Composant_3D(Dlg0penComponent->SafeFileName);
    
    				// Attribut la feuille parent à la fenêtre composant
    				New_Composant_3D->MdiParent = this;
    
    				// Affiche la fenêtre composant
    				New_Composant_3D->Show();
    			}
    		}
    
    			 }
      };
    }

    Je ne vois où je peux insérer ma boucle while, Avez-vous une idée?

    • Modifié CAO_JIM53 jeudi 23 février 2012 20:09
    jeudi 23 février 2012 20:03
  •  

    Bonjour,

    Je crois que vous avez mal compris ce que Paul vous a dit. La méthode Invalidate doit être appelée quand vous faites une modification dans votre Panel ou un de ses contrôles enfants. Vous pouvez aussi utiliser la méthode Refresh.

    Je ne comprends pas qu’est-ce que vous voulez faire dans votre boucle. Vous voulez faire une animation?

    Bonne journée,

    Cipri


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    lundi 27 février 2012 10:01