Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 12:33

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Di Apr 15, 2008 13:28 
Offline
DGL Member

Registriert: Di Apr 01, 2008 11:05
Beiträge: 14
Hi, mein erster Versuch mit OpenGL ist ein mathematisches Pendel. Es soll die kinetische und potentielle Energie angezeigt werden.
Der "Faden" des Pendels bewegt sich schon mathematisch korrekt.
Mein erstes Problem ist, dass die Labels hinter der OpenGL Oberfläche verschwinden. Wie kann ich diese nach "vorne" bekommen?
Ich lasse die kinetische und potentielle Energie mit im Timer berechnen. Irgendwie springt der Manchmal auf unrealistische Werte ( während einer Schwingung). Habe ich nen Fehler bei der Formel gemacht, oder ist es unklug alles mit im Timer berechnen zu lassen?

l=Länge des Fadens m=Masse der Kugel alpha=Auslenkungswinkel alpham=maximaler Auslenkungswinkel

Code:
  1.  
  2. procedure TForm1.Render;  // Ausgabe
  3.   begin
  4.   // Farb- und Tiefenpuffer leeren
  5.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  6.   // Darstellungsmethoden festlegen(Standart)
  7.   glMatrixMode(GL_PROJECTION);
  8.   glLoadIdentity;
  9.   gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);
  10.  
  11.   glMatrixMode(GL_MODELVIEW);
  12.   glLoadIdentity;
  13.   // Kamere nach Hinten und Oben bewegen
  14.   glTranslatef(0, 1.5, -5);
  15.   // Drehwinkel um die Z-Achse
  16.   glrotatef(alpha,0,0,1);
  17.   glBegin(GL_QUADS);
  18.     glColor3f  (0,0,0);       // Den Faden erzeugen
  19.     glVertex3f(-0.005, 0, 0);
  20.     glVertex3f(0.005, 0, 0);
  21.     glVertex3f(0.005, -2, 0);
  22.     glVertex3f(-0.005, -2, 0);
  23.   glEnd;
  24.  
  25.   SwapBuffers(DC);
  26. end;
  27.  
  28.  
  29. procedure TForm1.Button1Click(Sender: TObject); // Pendel staten
  30.   begin
  31.   l:=strtofloat(edit2.text); // Pendellänge entnehmen
  32.   g:=strtofloat(edit1.text); // Gravitationsbeschleunigung entnehmen
  33.   m:=strtofloat(edit7.text); // Kugelmasse entnehmen
  34.   alpham:=strtofloat(edit3.text); // Maximaler Auslenkwinkel
  35.   if timer1.Enabled=false then timer1.Enabled:=true  //Timer starten/stoppen
  36.   else timer1.Enabled:=false;
  37.   WGes:=(l-l*cos(alpham))*m*g;  // Gesamtenergie ( Winkel maximal);
  38.   edit4.text:=floattostr(WGes);
  39. end;
  40.  
  41. procedure TForm1.Timer1Timer(Sender: TObject);   // Funktion
  42.                                                  // Render aufrufen
  43.   begin                                          // aktuelle Pendelposition
  44.  
  45.   // aktueller Winkel abhängig von der Systemzeit
  46.   alpha:=alpham*cos(sqrt(g/l)*GetTickcount/1000);
  47.  
  48.    Render;
  49.  
  50.  
  51.    WPot:=(l-l*cos(alpha))*m*g; // Potentielle Energie berechnen
  52.    WKin:=WGes-Wpot;  // Kinetische Energie folgt aus Gesamtenergie
  53.    Edit5.Text:=floattostr(WPot); // WPot ausgeben
  54.    Edit6.Text:=floattostr(WKin); // WKin ausgeben
  55.  
  56. end;
  57.  


Finde den Fehler nicht :-(
Würde mich freuen, wenn jemand einen Tipp weiß.
Als nächstes kommt noch die Kugel dran ;)

lg Florian


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 15, 2008 13:31 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Durch einen interessanten Zufall sitze ich auch gerade an einer Pendelanwendung :D

Was mir bei dir auffällt ist, dass du GetTickCount zur Abfrage der verstrichenen Zeit verwendest... GetTickCount gibt dir die Millisekunden nach dem Windowsstart zurück, du solltest dir also eine Methode anschauen, mit der du die verstrichene Zeit zwischen dem aktuellen und dem vorherigen Timeraufruf bekommst.

Was deine Labels betrifft: Die werden auf den Hintergrund des Fensters gezeichnet, und zwar nicht unbedingt nach deinem Rendern. Du könntest das Repaint der Labels nach dem Swap-Buffer aufrufen. Aber ich denke es wäre besser, wenn du dir mal ein paar Codes anschaust, um die Texte direkt in OpenGL anzeigen zu lassen, das ist besser für die Performance.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 15, 2008 13:36 
Offline
DGL Member

Registriert: Di Apr 01, 2008 11:05
Beiträge: 14
GetTickCount hat den Vorteil, dass es harmonisch weiter läuft. Kannst du mir evtl. erklären, was eine andere Zeitzählung zum Vorteil hätte?
Bin noch ein ziemlicher Anfänger...
Wie kann ich das Repaint der Labels denn Aufrufen? refresh?
Mt der Schrift beschäftige ich mich im nächsten Projekt.
Würde jetzt gerne erst das Pendel fertig kriegen.
Dank dir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 15, 2008 13:59 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Repaint heißt die Methode.

Du solltest in einer privaten Variable vom Typ Cardinal in deiner Form Klasse die Zeit des letzten Frames speichern, so in der art:

Code:
  1.  
  2. type
  3.   TForm1 = class (TForm)
  4.   // ...
  5.   private
  6.     FLastUpdate: Cardinal;
  7.     FCurrentTime: Double;
  8.   // ...
  9.   end;
  10.  
  11. // ...
  12. implementation
  13. // ...
  14.  
  15. procedure TForm1.Timer1Timer(Sender: TObject);
  16. var
  17.   FThisUpdate: Cardinal;
  18. begin
  19.   FThisUpdate := GetTickCount;
  20.   FCurrentTime := FCurrentTime + (FThisUpdate - FLastUpdate) / 1000;
  21.   FLastUpdate := FThisUpdate;
  22.   // ...
  23. end;
  24.  


So hast du in FCurrentTime die aktuelle Zeit in Sekunden seit Anwendungsstart.
Du solltest FCurrentTime natürlich beim Initialisieren mit 0.0 und FLastUpdate mit GetTickCount initialisieren.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 15, 2008 14:19 
Offline
DGL Member

Registriert: Di Apr 01, 2008 11:05
Beiträge: 14
Das mit Repaint klappt schon mal. Macht aber nen häßlichen Effekt, da alle Labels von Zeit zu Zeit aufflackern. Kann ich die von Open GL verwendete Oberfläche verkleinern?
So das die Bedienelemente von Delphi gar nicht erst überschrieben werden?

Code:
  1. glViewport(80, 80, ClientWidth-80, ClientHeight-80);


z.b.?

Werde das mit der Zeit jetzt testen. Das hat immerhin den Vorteil, dass das Pendel nicht "springt" wenn ich es anhalte.


Edit: Das mit der Zeit klappt wunderbar.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 15, 2008 14:39 
Offline
DGL Member

Registriert: Di Apr 01, 2008 11:05
Beiträge: 14
Der Fehler bei der Energie lag daran, dass ich nicht im Bogenmaß gerechnet habe. Dachte Delphi rechnet nicht mit Radian. Lehrgeld bezahlt ;)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 16, 2008 10:43 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Das mischen von GDI und OpenGL innerhalb eines "Fensters"(Alle von TWinControl abgeleiteten komponenten sind Fenster) ist nicht zu empfehlen(Insbesondere unter Vista). Ich würde für die OpenGL Darstellung ein TPanel plazieren, und Panel1.Handle(oder wie immer das genau heißt) und Panel1.Canvas.Hande beim initialisieren verwenden.

Außerdem bewegt sich ein Pendel nur für infinitesimale Auslenkungen so wie du es berechnest. Das siehst du auch daran, dass bei großen Auslenkungen für eine harmonische Schwingung EGes=EKin+EPot nicht mehr konstant ist (sobald die näherung von cos(x)=1-0.5x^2 nicht mehr gilt).
Die korrekte Bewegung lässt sich leider nicht analytisch integrieren.
EKin=0.5*l^2*(dAlpha/dt)^2

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 17, 2008 11:55 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Zitat:
Außerdem bewegt sich ein Pendel nur für infinitesimale Auslenkungen so wie du es berechnest.


Das stimmt. Aber es sieht dennoch noch gut aus mit dieser Näherung :) Wenn man nicht sin(alpha) ~= alpha nähert, wird das schön hässlich. Dann hat man keine lineare DGL 2.ter Ordnung mehr und das ganze Konstrukt vom harmonischen Oszillator blättert dahin...


Was die Darstellung von Text angeht:

Wenn's mal eben schnell gehen soll, dann kannste ja einfach die Caption deiner Form nehmen (Form1.Caption z.B). Soll es schon irgendwie nach etwas aussehen, dann benutze vielleicht einfach die Textdarstellung, welche im Template der DGL implementiert ist!


Grüße,


Rüdiger


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Apr 28, 2008 13:45 
Offline
DGL Member

Registriert: Di Apr 01, 2008 11:05
Beiträge: 14
Hi, sorry dass ich mich nicht schneller gemeldet habe...Bis 8 ° geht das schon einigermaßen auch wenn es dann leichte Abweichungen gibt. Wichtiger ist für mich, dass es vernünftigt schwingt und das tut es.
Werde mich in Zukunft mit OpenGL Text beschäftigen. Eine Idee wäre auch gewesen mehrere Formblätter zu nehmen und die dann nur temporär zu zeigen bzw. zu verstecken.
Hab eben erstmal nen Sonnenystem gemacht (Nur Sonne,Erde,Merkur,Mond). Da müssen jezt noch Texturen drauf ;)
Das werde ich wohl noch vorm Text mir anschauen.
Vielen Dank für die Tipps!


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 14 Queries | GZIP : On ]