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

Aktuelle Zeit: Fr Jul 18, 2025 12:36

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



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Mo Okt 27, 2008 17:17 
Offline
DGL Member

Registriert: Sa Dez 30, 2006 17:01
Beiträge: 22
Wohnort: NRW/Fröndenberg
Hio!
Wie bekomme ich eine konstante Bewegung von Objekten (erstmal in 2D, d.h. Orthogonaler Modus) mit verschiedenen Geschwindigkeiten hin, die trotzdem noch schön flüssig wirken?
Also nehmen wir z.b. 2 Kreise auf dem Bildschirm. Kreis A hat eine Geschwindigkeit von 20, Kreis B von 10.
Mein naiver Ansatz dazu mit timebased movment sah so aus (pseudocode):
Code:
  1.  
  2. OnInit: TimerInterval(35ms)
  3. OnTimer:
  4. PositionKreisA = PositionKreisA + 20 (Position um 20 px verschieben)
  5. PositionKreisB = PositionKreisB + 10
  6. Render()
  7. Render: ZeichneA, ZeichneB


Problem: - Durch große Geschwindigkeiten (wobei ab 5 das schon bemerkbar ist) "springen" die Kreise
- Bei vielen Kreisen (>10) werden die Kreise auch merklich langsamer, weil 1. der Timer von wxWidgets relativ ungenau ist und 2. Schleifendurchläufe und Berechnung mit der Anzahl der Kreise natürlich zunehmen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Okt 27, 2008 20:14 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Darf ich fragen, warum mit der Anzahl der Kreise die Schleifendurchläufe zunehmen? Denn wenn ich Dein Beispiel ansehe, sieht es für mich so aus.

Routine OnTimer:

1. Für alle Kreise wird die Position berechnet
2. Alle Kreise werden gezeichnet

und das ist doch gleich, ob ich jetzt 10 Kreise bearbeite oder 20 Kreise - es bleibt immer nur eine einzige OnTimer-Routine. Oder versteh ich da etwas falsch?

Und wie genau zeichnest Du die Kreise? Kreise sind etwas aufwendig. Wenn Du glBegin/glEnd verwendest, wäre es sicher eine tolle Verbesserung, statt dessen eine Displayliste oder das etwas modernere Vertex Buffer Object zu nehmen. Du würdest nur einen einzigen Kreis mit Einheitsradius brauchen, dann mit glScale auf die richtige Größe skalieren.
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Okt 27, 2008 22:11 
Offline
DGL Member

Registriert: Sa Dez 30, 2006 17:01
Beiträge: 22
Wohnort: NRW/Fröndenberg
Also die Kreise waren nur ein Beispiel, ich benutze derzeit Dreiecke und die gehen doch sehr schnell zu zeichnen oder?
Ich gehe beim Zeichnen in der Renderfunktion so vor(ist in c++ geschrieben):
Code:
  1.  
  2. void Render() {
  3.     glClearColor(255, 255, 255, 0);
  4.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  5.  
  6.     glMatrixMode(GL_PROJECTION);
  7.     glLoadIdentity();
  8.     glViewport(0,0,GetWidth(),GetHeight());
  9.     glOrtho(0,GetWidth(),0,GetHeight(),0,1);
  10.     glMatrixMode(GL_MODELVIEW);
  11.     glLoadIdentity();
  12.  
  13.     //Hier aufjedenfall optimierbar
  14.     for (int i = 0; i < ANZAHL_OBJEKTE; ++i) {
  15.       glPushMatrix();
  16.       objekt[i].draw();
  17.       glPopMatrix();
  18.     }
  19.  
  20.     glFlush();
  21.     SwapBuffers();
  22. }
  23.  
  24. void Objekt::draw() {
  25.     double angle = atan2(GetDirectionVector().GetYKoord(),GetDirectionVector().GetXKoord())*180/M_PI;
  26.  
  27.     glColor3d(255,0,0);
  28.     glTranslated(xKoord, yKoord, 0); //optimierbar
  29.     glRotated(angle, 0,0,1);
  30.     glScaled(size,size,0);
  31.  
  32.     glBegin(GL_TRIANGLES);
  33.         glVertex2d(-1,-1);
  34.         glVertex2d(2,0);
  35.         glVertex2d(-1,1);
  36.     glEnd();
  37.  


Wie ihr seht ist da aufjedenfall Spielraum zum optimieren. Aber auch wenn das vielleicht mein Problem mit einer großen Anzahl an Objekten klären würde, wüsste ich immer noch nicht wie ich eine gleichmäßige Bewegung hinbekomme


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 28, 2008 10:52 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Zwei Änderungen würde ich vorschlagen:

1. Alle Dreiecke auf einmal zeichnen, dh glBegin/glEnd jeweils nur einmal aufrufen und dazwischen alle Dreiecke zeichnen. Das sollte schon eine ganze Menge helfen.

2. Das Timer-Setting in Relation zur Geschwindigkeit ändern. Soll heißen, öfter zeichnen bei gleicher Geschwindigkeit.

Ein Timer-Setting von 35 ms sind 1000/35 = rund 29 Frames pro Sekunde (FpS). Filme haben 24 Frames(Bilder) pro Sekunde und die sind eher an der unteren Grenze angesiedelt, was menschliche Augen noch als flüssig bezeichnen. Ein FpS von 50 ist auch noch nicht wirklich so toll, kann aber schon hingehen. Das ware dan ein Timer-Setting von 1000/50=20 ms. Ich habe jetzt keine Ahnung, ob das Dein Timer schafft.

Und jetzt müsstest Du Deine Geschwindikeit anpassen. 20/35= 0,57. Enn Du also vorher Deine Dreiecks-Position um 10 verschoben hast, dann verschiebe sie jetzt um 10*0,57 =5,7. Oder Wenn Du sie vorher um 20 verschoben hast, dann verschieb sie jetzt um 20*0,57=11,4.

Die Objekte sind genauso schnell wie vorher, nur werden sie öfter gezeichnet und legen zwischen den Frames geringere Strecken zurück.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 28, 2008 12:50 
Offline
DGL Member

Registriert: Sa Dez 30, 2006 17:01
Beiträge: 22
Wohnort: NRW/Fröndenberg
Wie soll ich alle Dreiecke in einem glBegin/glEnd Block zeichnen? Ich darf ja nicht innerhalb eines Blockes glPop/glPush anwenden oder? Also müsste ich das noch irgendwie (schlau) ändern..?

Zum anderen: Wie meinst du es das Timersetting in Relation zur Geschwindigkeit zu ändern?
Ich kann ja 10 verschiedene Objekte mit 10 verschiedenen Geschwindigkeiten (sagen wir mal zwischen 0 und 20) haben.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 28, 2008 14:32 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Zitat:
Also müsste ich das noch irgendwie (schlau) ändern..?

Nein, denn ich habe übersehen, dass Du offenbar immer das gleiche Dreieck verwendest und es nur verschieden verschiebst/rotierst/skalierst. Also kann man es ga rnicht anders machen.

Zitat:
Wie meinst du es das Timersetting in Relation zur Geschwindigkeit zu ändern?

1. Neue Timerzeit:= 20ms (alte Timerzeit war 35 ms)
2. jede einzelne neue Geschwindigkeit ist nur mehr 57% der jeweils alten einzelnen Geschwindigkeit.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 28, 2008 19:08 
Offline
DGL Member

Registriert: Sa Dez 30, 2006 17:01
Beiträge: 22
Wohnort: NRW/Fröndenberg
Ja unter welchen Kriterium soll ich denn die Timerzeit ändern?
Bei einer größeren Anzahl an Dreiecken oder wie?

Zum zeichnen: Die Zeichenfunktion ist zwar immer die selbe, aber es gibt ja z.b. 5 verschiedene Dreiecke, die unterschiedlich groß sind, unterschiedlich schnell etc. die alle gleichzeitig zu sehen sind.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 28, 2008 20:30 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Zitat:
Ja unter welchen Kriterium soll ich denn die Timerzeit ändern?

Kein Kriterium. Einfach Timerzeit ändern. Du renderst jetzt einfach öfter als früher. Dadurch wirkt die Bewegung flüssiger.

Zitat:
Zum zeichnen: Die Zeichenfunktion ist zwar immer die selbe, aber es gibt ja z.b. 5 verschiedene Dreiecke, die unterschiedlich groß sind, unterschiedlich schnell etc. die alle gleichzeitig zu sehen sind.

Ja. Und bei einer Timerzeit von 35 ms war die Verschiebung 10 Pixel (das meine ich mit Geschwindigkeit) aber bei der verkürzten Timerzeit sind es nur 57 Prozent von 10 Pixel. Wenn es da ein Problem gibt, dann sehe ich es nicht.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 29, 2008 12:23 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
also wenn du eine Bewegung hast, dann hast du einen bewegungs vektor. für eine 2d anwendung hast du dann natürlich eine bewegung auf x und y achse. Für die 3itte dimension kommt dann natürlich eine achse hinzu.
Wenn du ein Objekt bewegen willst, dann rechnest du auf die aktuelle position die geschwindigkeit drauf. Da du das bei jedem Frame machst, also immer wenn du dein Bild neu erstellst, musst du die Geschwindigkeit der Objekte an die Renderzeit anpassen. Dafür misst du die Zeit, die du brauchst um ein Frame zu zeichnen. Am besten funktioniert das mit dem onidle event als render routine und der Systemzeit-millisekunden. Anschließend bildest du den kehrwert der gemessenen zeit. Dieser wert gibt die dann an wie viel Zeit das zeichnen eines Bildes beansprucht. Um deine Bewegung jetzt an diese Renderzeit anzupassen reicht es die x und y bewegung des Objektes mit dem gemessenen Zeitfaktor zu multiplizieren. Mal eine schmatische Darstellung.

1.Zeitmessung starten (aktuelle Zeit speichern)
2.bewegung aller objekte (x&y geschwindigkeit mit zeitfaktor multiplizieren und auf aktuelle position addieren)
3.zeichnen aller objekte
4.Zeitmessung beenden (aktuelle Zeit speichern)
5.differenz der beiden Zeiten berechnen und in millisekunden umrechnen
6.den kehrwert daraus bilden und als zeitfaktor speichern

P.S.: wenn du eine rotation hast, empfiehlt es sich auch diese mit dem zeitfaktor zu multiplizieren, da sich die dreiecke sonst je nach Rechner unterschiedlich schnell bewegen. Ich kann die auch später zeigen, wie ich die Zeitmessung bei mir durchführe, habe damit bisher immer sehr gut arbeiten können. Bin nur leider in der Uni gerade und tue mir Algos an.

grüße

_________________
Klar Soweit?


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 5 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.007s | 16 Queries | GZIP : On ]