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

Aktuelle Zeit: Do Jul 10, 2025 20:57

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



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: "In die richtige Richtung" zoomen
BeitragVerfasst: So Apr 30, 2006 14:41 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Hi @ll

Der Titel ist vielleicht etwas ungenau, aber was besseres ist mir nicht eingefallen.

Ich schreibe momentan an einem Programm (später dann Spiel) wo erstmal eine Weltkarte zu sehen sein soll. Dort kann man reinzoomen. Jetzt würde ich aber gerne wissen, wie ich das so mache, dass beim Zoomen das Bild so verschoben wird, dass man die Position wo der Cursor hingezeigt hat als neues Zentrum hat. (hoffentlich war das jetzt verständlich)
Hier noch ein paar Codeschnipsel:

Zoomen und Scrollen:
Code:
  1. procedure TMainForm.FormMouseDown(Sender: TObject; Button: TMouseButton;
  2.   Shift: TShiftState; X, Y: Integer);
  3. begin
  4.   MouseCapture := True;
  5.   MouseX := X;
  6.   MouseY := Y
  7. end;
  8.  
  9. procedure TMainForm.FormMouseUp(Sender: TObject; Button: TMouseButton;
  10.   Shift: TShiftState; X, Y: Integer);
  11. begin
  12.   MouseCapture := False;
  13. end;
  14.  
  15. procedure TMainForm.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  16.   Y: Integer);
  17. begin
  18.   if MouseCapture then
  19.   begin
  20.     if ssLeft in Shift then
  21.     begin
  22.       OffsetX := OffsetX + (MouseX - X);
  23.       OffsetY := OffsetY + (MouseY - Y);
  24.       MouseX := X;
  25.       MouseY := Y;
  26.     end
  27.     else if ssMiddle in Shift then
  28.     begin
  29.       ZoomLevel := ZoomLevel + ((MouseY - Y) / 1000);      
  30.       MouseX := X;
  31.       MouseY := Y;
  32.     end;
  33.   end;
  34. end;


Zeichnen:
Code:
  1. procedure TMainForm.ApplicationEventsIdle(Sender: TObject;
  2.   var Done: Boolean);
  3. var
  4.   Error: LongInt;
  5.   CurrentUpdate: Int64;
  6.   ZoomDif: Double;
  7. begin
  8.   Done := False;
  9.   if not OpenGLInitialized then Exit;
  10.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  11.  
  12.   CurrentUpdate := GetTickCount;
  13.   RotTest := RotTest + (((CurrentUpdate - LastUpdate) / 1000) * RotSpeed);
  14.   ZoomDif := CurrentZoom - ZoomLevel;
  15.   if ZoomDif > 0 then
  16.   begin
  17.     if ZoomDif > 0.01 then
  18.       CurrentZoom := CurrentZoom - (((CurrentUpdate - LastUpdate) / 1000) * (ZoomDif*10))
  19.     else
  20.       CurrentZoom := ZoomLevel;
  21.   end
  22.   else if ZoomDif < 0 then
  23.   begin
  24.     if ZoomDif < -0.01 then
  25.       CurrentZoom := CurrentZoom + (((CurrentUpdate - LastUpdate) / 1000) * -(ZoomDif*10))
  26.     else
  27.       CurrentZoom := ZoomLevel;
  28.   end
  29.   else
  30.     CurrentZoom := ZoomLevel;
  31.  
  32.   if OffsetX < 0 then
  33.     OffsetX := 0;
  34.   if OffsetY < 0 then
  35.     OffsetY := 0;
  36.   if OffsetX + ClientWidth > (2048*CurrentZoom) then
  37.     OffsetX := Trunc(2048*CurrentZoom) - ClientWidth;
  38.   if OffsetY + ClientHeight > (976*CurrentZoom) then
  39.     OffsetY := Trunc(976*CurrentZoom) - ClientHeight;
  40.   LastUpdate := CurrentUpdate;
  41.  
  42.   glBlendFunc(GL_SRC_ALPHA,GL_ONE);
  43.   glColor3f(1, 1, 1);
  44.   glLoadIdentity;
  45.   glTranslatef(-OffsetX, -OffsetY, 0);
  46.   glPushMatrix;
  47.   glScalef(CurrentZoom, CurrentZoom, 1);
  48.   glTranslatef(0, 0, -1);
  49.  
  50.   WorldMap.Bind();
  51.   glBegin(GL_QUADS);
  52.     glTexCoord2f(0, 0);
  53.     glVertex2f(0, 0);
  54.     glTexCoord2f(0, 1);
  55.     glVertex2f(0, 976);
  56.     glTexCoord2f(1, 1);
  57.     glVertex2f(2048, 976);
  58.     glTexCoord2f(1, 0);
  59.     glVertex2f(2048, 0);
  60.   glEnd();
  61.   WorldMap.Unbind();                                      
  62.                                                            
  63.   glPopMatrix;                                          
  64.  
  65. //  glScalef(CurrentZoom, CurrentZoom, 1);
  66.   glTranslatef(200*CurrentZoom, 450*CurrentZoom, 0);
  67.   glRotatef(RotTest, 0, 0, 1);
  68. //  glScalef(1, 1, 1);
  69.   glBegin(GL_TRIANGLES);
  70.     glColor4f(1,1,1,1);
  71.     glVertex2f(0, 5);
  72.     //glColor4f(0,1,0, 0.5);
  73.     glVertex2f(-5, -5);
  74.     //glColor4f(0,0,1, 0.5);
  75.     glVertex2f(5, -5);
  76.   glEnd;
  77. {  glBegin(GL_LINES);
  78.     glVertex2f(0, 5);
  79.     glVertex2f(0, -5);
  80.   glEnd;   }
  81.   glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
  82.   glBeginText;
  83.     glColor3f(1, 1, 1);
  84.     glTextOut(0, 11, FntTahoma, Format('ZLvl: %f; CurrZ: %f', [ZoomLevel, CurrentZoom]));
  85.   glEndText;
  86.  
  87.   Error := glgetError;
  88.   if Error <> GL_NO_ERROR then
  89.   begin
  90.     Caption := gluErrorString(Error);
  91.     //Rendering kurz anhalten
  92.     Done := True;
  93.     FlashWindow(Handle, True)
  94.   end;
  95.  
  96.   SwapBuffers(DC);
  97. end;


Dieses gewirr von CurrentZoom und ZoomLevel hab ich für einen fließenderen Übergang eingebaut.

Gruß Lord Horazont[/pascal]

_________________
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: Do Mai 04, 2006 10:10 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Du brauchst erstmal den punkt des cursors in der opengl welt.
Den kannst du z.B. durch Raycast Intersection(Linien-Ebenen kollision) bekommen, es gibt aber auch OpenGL basierte Möglichkeiten.
Wenn du den Punkt hast, kannst du dann über eine Funktion egal ob Linear,Sinus,Kubisch oder was es noch alles gibt die Animationspunkte zwischen Startpunkt und Endpunkt berechnen. Wenn ich es recht gesehen hab nutzt du eine Lineare gleichung.
Zu dem Thema könntest du bei Nehe fündig werden.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 04, 2006 12:54 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Diese Position bekommst du, indem du mittels glUnProject die 3D-Koordinaten des 2D-Cursors berechnest. Dadurch erhältst du den 3D-Punkt zurück, auf den der Cursor gerade zeigt.

Dadurch kannst du dann deine neue Kamera-Position berechnen. Da es ja ne Kugel ist, würde ich einfach den Vektor vom Kugelmittelpunkt zu diesem anvisierten Punkt nehmen und verlängern. Dorthin bewegst du dann die Kamera. (Ich hoffe, ich muss hier nicht erwähnen, dass es in OpenGL keine Kamera gibt *g*). Nen fließenden Übergang kannst du ganz easy mit linearer Interpolation oder mit Kosinus-Interpolation erzeugen.

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 06, 2006 17:13 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Öhhmm... Das ganze ist in einer 2D welt, womit ich mir (rein theoretisch) das UnProjecten sparen kann...
So ganz kapiert hab ich das jetzt sowieso nicht, also bitte etwas genauer... (bin heute schwer von begriff)

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: Sa Mai 06, 2006 17:37 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
TAK2004 hat geschrieben:
Du brauchst erstmal den punkt des cursors in der opengl welt.

Ist für dich die wichtigste Aussage. Wenn du den Punkt hast, was ja bei 2D wie du schon gesagt hast sehr leicht ist.
Dann berechnest du dir den Vektor der den alten Punkt mit den neuem verbindet. Den spaltest du am besten in Zoom und Bewegung auf.
Dann suchst du dir einfach ein Verfahren wie du diese Bewegung möglichst glatt vonstatten gehen lässt.
Das einfachste wäre hier ne lineare Funktion, so dass du für x Sekunden immer y zum alten Punkt hinzuaddierst, sodass dies dein neuer ist.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 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.009s | 16 Queries | GZIP : On ]