Meilleur auteur de réponses
Problème de rafraîchissement d'affichage panel DirectX dans une ChildForm

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(); } }; }
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++
- Proposé comme réponse Ciprian Duduiala jeudi 23 février 2012 11:49
- Marqué comme réponse Ciprian Duduiala mercredi 29 février 2012 07:28
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++
- Proposé comme réponse Ciprian Duduiala jeudi 23 février 2012 11:49
- Marqué comme réponse Ciprian Duduiala mercredi 29 février 2012 07:28
-
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
-
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
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.