| Autor |
Beitrag |
F34r0fTh3D4rk
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: So 22.05.05 14:54
hallo, wie kann ich glRotateF so aufrufen, dass ich mit der maus ein 3d objekt drehen kann, zb bewege ich meine maus nach rechts und das objekt dreht sich nach rechts mit, genauso mit den anderen 3 richtungen, das objekt per drag beliebig aus jeder perspektive betrachten können, also in alle richtungen frei drehen, wie mache ich das ?
|
|
Phobeus
      
Beiträge: 1280
Linux (FC6), WinXP Pro (Box)
D6 Pers, D7 Pro, FPC 2.x
|
Verfasst: So 22.05.05 16:40
Wie ist den dein aktuelles Stand? Generell will glrotatef wissen, wie weit um welche Achse gedreht wurde. Wenn Du dort nun eine Variable einsetzt z.B. rotX und dann bei einer Mausbewegung diese Variable erhöhst bzw. erniedrigst, erreichst Du eine Rotation um diese Achse.
_________________ "Menschen sterben nicht wenn man sie zu Grabe trägt, sondern wenn sie ihre Träume verlieren..."
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: So 22.05.05 16:46
ja aber wie mache ich das, muss ich dazu nicht die alte mit der neuen mausposition vergleichen ? dann den unterschied irgendwie umrechnen ?
|
|
Phobeus
      
Beiträge: 1280
Linux (FC6), WinXP Pro (Box)
D6 Pers, D7 Pro, FPC 2.x
|
Verfasst: So 22.05.05 16:56
Kommt primär darauf an, was Du genau machen möchtest und welche Schnittstelle genommen wird. Wenn Du die VCL verwendest, wird es vermutlich am einfachsten sein die "alten Position" zu speichern und die Differenz zur neuen Position zu verwenden um die Variable zu manipulieren. Evtl. mit einem kleinen "Glättungsfaktor" rotx := rotx+(differenz*0.01); damit das ganze nicht ganz so hektisch ist.
_________________ "Menschen sterben nicht wenn man sie zu Grabe trägt, sondern wenn sie ihre Träume verlieren..."
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: So 22.05.05 16:58
funzt net:
onidle
Delphi-Quelltext 1:
| glRotatef(0.02, mx, my, 0); |
mousemove
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure TMainForm.Preview_ScreenMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var oldX, oldY: integer; tick: boolean; begin tick := false; if ssLeft in Shift then begin if not tick then begin oldX := X; oldY := Y; end; if tick then begin mx := x - oldx; my := y - oldy; end; tick := not tick; end; end; |
mx und my sind globale variablen vom typ glfloat
so gehts schon mal fast so wie ich mir das vorgestellt habe
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| procedure TMainForm.Preview_ScreenMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var oldX, oldY: integer; begin if ssLeft in Shift then begin if not tick then begin mx := 0; my := 0; oldX := X; oldY := Y; end; if tick then begin mx := x - oldx; my := y - oldy; end; tick := not tick; end else begin mx := 0; my := 0; end; end; |
aber auch nur in eine richtung, die rechnung ist noch nicht vollständig
scheint aber alles nicht wirklich zu stimmen
tick global als false definiert
|
|
NeoInDerMATRIX
      
Beiträge: 245
Win95, Win98(+se), WinNT, Win2000, WinME, WinXP(+pro), VISTA, Linux(SuSe), DOS [MultiMon(3)], Vista
D6 PeE + (FP 2.0l) + D3 Pe + D2005+ D2006 Arch
|
Verfasst: Mo 23.05.05 01:14
Hi,
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| Var RotX, RotY, RotZ: Float; OldX, OldY: Integer;
procedure tMainForm.myDraw; Begin ... glRotateF(0.02, RotX, RotY, RotZ); End;
procedure TMainForm.Preview_ScreenMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); Begin OldX:=X; OldY:=Y; RotX:=RotX + (OldX - X); RotY:=RotY + (OldY - Y); End; |
So sollte es eigentlich gehen! Evtl. noch ne Bereichs Prüfung.
@Phobeus: Hoffe das ich mich jetzt nicht zu sehr vertan habe. Aber wenn dann Korigierst du mich sicher.
Cu
Neo
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mo 23.05.05 05:27
Also ich habe es bei meinem Programm so gelöst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TForm1.WMMouseMove(var Msg: TWMMouseMove); var NewCursorPos: TSmallPoint; begin NewCursorPos:=Msg.Pos; RotateY:=RotateY-(CursorPos.x-NewCursorPos.x)/20*Mausempfindlichleit; RotateX:=RotateX-(CursorPos.y-NewCursorPos.y)/20*Mausempfindlichleit; if (NewCursorPos.x<100) or (NewCursorPos.x>Screen.Width-100) then begin SetCursorPos(Screen.Width div 2, NewCursorPos.y); NewCursorPos.x:=Screen.Width div 2; end; CursorPos:=NewCursorPos; if (NewCursorPos.y<100) or (NewCursorPos.y>Screen.Height-100) then begin SetCursorPos(NewCursorPos.x, Screen.Height div 2); NewCursorPos.y:=Screen.Height div 2 end; CursorPos:=NewCursorPos; if RotateY<=0 then RotateY:=RotateY+360; if RotateY>360 then RotateY:=RotateY-360; if RotateX<-90 then RotateX:=-90; if RotateX>90 then RotateX:=90; end; |
Mausempfindlichkeit ist bei mir noch eine Kostante, die die Empfinglichkeit der Maus bestimmt.
Des weiteren kannst du mit der Maus kein Kopfüberpsrung machen, da ich es unterbunden habe, in dem man maximal 90° nach oben oder unten schauen kann.
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 23.05.05 13:43
wieso sieht die prozedur bei dir so aus ?
Delphi-Quelltext 1:
| procedure TForm1.WMMouseMove(var Msg: TWMMouseMove); |
bei mir ist das so:
Delphi-Quelltext 1: 2:
| procedure TMainForm.Preview_ScreenMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); |
liegt das an mir oder an der delphi version ?
so ist das wie bei mir, lässt sich nur nach rechts bewegen, nicht nach links, oben und unten gehen auch nicht, sieht auch sehr ruckelig aus:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
| procedure TMainForm.Preview_ScreenMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var NewCursorPos: TSmallPoint; Msg: TWMMouseMove; sens: glfloat; begin sens := 1; if ssleft in shift then begin NewCursorPos := Msg.Pos; RotateY := RotateY - (y - NewCursorPos.y) / 20 * sens; RotateX := RotateX - (x - NewCursorPos.x) / 20 * sens; if (NewCursorPos.x < 100) or (NewCursorPos.x > preview_Screen.Width - 100) then begin x := NewCursorPos.x; y := preview_screen.Height div 2; NewCursorPos.x := preview_Screen.Width div 2; end; x := NewCursorPos.x; y := NewCursorPos.y; if (NewCursorPos.y < 100) or (NewCursorPos.y > preview_screen.Height - 100) then begin x := NewCursorPos.x; y := preview_screen.Height div 2; NewCursorPos.y := preview_Screen.Height div 2; end; x := NewCursorPos.x; y := NewCursorPos.y;
if RotateY <= 0 then RotateY := RotateY + 360;
if RotateY > 360 then RotateY := RotateY - 360;
if RotateX < -90 then RotateX := -90;
if RotateX > 90 then RotateX := 90;
rotatex := rotatex / 50; rotatey := rotatey / 50; glrotatef(rotatex, 1, 0, 0); glrotatef(rotatey, 0, 1, 0); end; end; |
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Mo 23.05.05 14:32
@Fear: Damit machst du mir jetzt aber wirklich Angst! Das glRotate hat nichts im MouseMove zu suchen. Die Rotation musst du immer beim Rendern setzen, da du dort normal die ModelView Matrix zurücksetzt. Und entsprechend musst du als nächsten Schritt deine Rotation setzen.
Ein kleines Extrakt aus einer meiner Anwendungen. Der Code beinhält also nur interessante Codefragmente. Nichts weiter. Wollte das nur noch mal sagen.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126:
| TForm1 = class(TForm) procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private FMouseMove: Boolean; FMousePos: TPoint;
FRotateX: Single; FRotateY: Single; FZoom: Single; end;
implementation
procedure TForm1.DrawScene; var TempRotateY: Single; Error: Cardinal; quad: PGLUQuadric; begin glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glTranslatef(0, 0, -7.5);
if (FMouseMove) then begin if (FRotateY > 90) then FRotateY := 90 else if (FRotateY < -90) then FRotateY := -90;
if (FRotateX < -85) then FRotateX := -85 else if (FRotateX > 0) then FRotateX := 0;
if FZoom < 0.1 then FZoom := 0.1 else
if FZoom > 3 then FZoom := 3; end;
if (FRotateY > -10) and (FRotateY < 10) then begin if (not FMouseMove) then FRotateY := 0; TempRotateY := 0 end else TempRotateY := FRotateY;
glScalef(FZoom, FZoom, FZoom); glRotatef(FRotateX, 1, 0, 0); glRotatef(TempRotateY, 0, 0, 1);
glPopMatrix;
Error := glGetError; if Error <> 0 then Caption := gluErrorString(Error); end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if ((Button = mbLeft) or (Button = mbRight)) then begin FMouseMove := True; FMousePos.X := X; FMousePos.Y := Y;
Mouse.Capture := Handle; end; end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin FMouseMove := False; Mouse.Capture := 0; end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if FMouseMove then begin if GetAsyncKeyState(VK_LBUTTON) <> 0 then begin FRotateX := FRotateX + ((Y - FMousePos.Y) / 5); FRotateY := FRotateY + ((X - FMousePos.X) / 5); end;
if GetAsyncKeyState(VK_RBUTTON) <> 0 then begin FZoom := FZoom + (((Y - FMousePos.Y) + (X - FMousePos.X)) / 100); end;
FMousePos.X := X; FMousePos.Y := Y; end; end; |
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 23.05.05 15:19
ich hab das jetzt so, finde es aber immer noch recht unkompfortabel:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, opengl, ExtCtrls, AppEvnts, StdCtrls;
type TMainForm = class(TForm) Preview_Screen: TPanel; ApplicationEvents1: TApplicationEvents; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean); procedure Preview_ScreenMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Preview_ScreenMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Preview_ScreenMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private
public
end;
var MainForm: TMainForm; DC: HDC; RC: HGLRC; oldx, oldy, difx, dify: integer; mmove: boolean = false; tick: boolean = false; RotateX, RotateY: glfloat;
implementation
{$R *.dfm}
procedure TMainForm.FormCreate(Sender: TObject); var pfd: TPixelFormatDescriptor; p: integer; begin fillchar(pfd, sizeof(pfd), 0); DC := getDC(Preview_Screen.Handle); pfd.cDepthBits := 16; pfd.cColorBits := 16; pfd.DWflags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER; p := choosepixelformat(DC, @pfd); setpixelformat(DC, p, @pfd); RC := wglCreateContext(DC); wglMakeCurrent(DC, RC);
glViewPort(0, 0, Preview_Screen.width, Preview_Screen.height); glMatrixMode(GL_PROJECTION); glLoadIdentity; gluPerspective(45, Preview_Screen.width / Preview_Screen.height, 0.1, 100); glMatrixMode(GL_MODELVIEW);
glClearColor(1, 1, 1, 0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); glTranslatef(0, 0, -4); glRotatef(-25, 0, 1, 0); end;
procedure TMainForm.FormDestroy(Sender: TObject); begin wglMakeCurrent(DC, 0); wglDeleteContext(RC); releaseDC(0, DC); end;
procedure DrawQuad(x, y, z: glfloat); begin glBegin(GL_QUADS); glTexCoord2f(1, 0); glVertex3f(-x, -y, z); glTexCoord2f(1, 1); glVertex3f(x, -y, z); glTexCoord2f(0, 1); glVertex3f(x, y, z); glTexCoord2f(0, 0); glVertex3f(-x, y, z);
glTexCoord2f(1, 0); glVertex3f(-x, -y, -z); glTexCoord2f(1, 1); glVertex3f(-x, y, -z); glTexCoord2f(0, 1); glVertex3f(x, y, -z); glTexCoord2f(0, 0); glVertex3f(x, -y, -z);
glTexCoord2f(1, 0); glVertex3f(-x, y, -z); glTexCoord2f(1, 1); glVertex3f(-x, y, z); glTexCoord2f(0, 1); glVertex3f(x, y, z); glTexCoord2f(0, 0); glVertex3f(x, y, -z);
glTexCoord2f(1, 0); glVertex3f(-x, -y, -z); glTexCoord2f(1, 1); glVertex3f(x, -y, -z); glTexCoord2f(0, 1); glVertex3f(x, -y, z); glTexCoord2f(0, 0); glVertex3f(-x,-y, z);
glTexCoord2f(1, 0); glVertex3f(x, -y, -z); glTexCoord2f(1, 1); glVertex3f(x, y, -z); glTexCoord2f(0, 1); glVertex3f(x, y, z); glTexCoord2f(0, 0); glVertex3f(x, -y, z);
glTexCoord2f(1, 0); glVertex3f(-x, -y, -z); glTexCoord2f(1, 1); glVertex3f(-x, -y, z); glTexCoord2f(0, 1); glVertex3f(-x, y, z); glTexCoord2f(0, 0); glVertex3f(-x, y, -z); glEnd; end;
procedure TMainForm.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean); begin Done := false;
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
if mmove = true then begin if (difx <= -1) or (difx >= 1) then glrotatef(0.75, difx, 0, 0); if (dify <= -1) or (dify >= 1) then glrotatef(0.75, 0, dify, 0); end;
mmove := false;
glColor3f(0, 0, 0); glLineWidth(2); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); DrawQuad(0.75, 1, 0.2);
SwapBuffers(DC); end;
procedure TMainForm.Preview_ScreenMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin oldx := x; oldy := y; end;
procedure TMainForm.Preview_ScreenMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if tick then begin oldx := x; oldy := y; end; if not tick then if ssleft in shift then begin mmove := true; difx := difx + (x - oldx); dify := difx + (oldy - y); end; tick := not tick; end;
procedure TMainForm.Preview_ScreenMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin difx := 0; dify := 0; end;
end. |
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mo 23.05.05 16:11
Schau dir hier mal den Quelltext an. Ist ein OpenGl-Programm von mir, was auch funktioniert.
F34r0fTh3D4rk hat folgendes geschrieben: | wieso sieht die prozedur bei dir so aus ?
Delphi-Quelltext 1:
| procedure TForm1.WMMouseMove(var Msg: TWMMouseMove); |
bei mir ist das so:
Delphi-Quelltext 1: 2:
| procedure TMainForm.Preview_ScreenMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); |
liegt das an mir oder an der delphi version ?[/delphi] |
Es liegt an dir  . Du nimmst ein Ereignis von einer Komponenten (das Formular bei dir) und ich fange dagegen die Windowsmessage ab, die von Windows an das Programm  Formular gesendet wird.
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 23.05.05 16:29
dachte ich mir doch  ok werde versuchen das bei mir einzubauen, danke !
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mo 23.05.05 16:34
Hättest du aber auch aus dem Prozedurenkopf erkennen können  .
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 23.05.05 17:51
hab ich ja, deshalb auch das WM ich dachte so heißt deine komponente
Moderiert: Sinn hinzugefügt
Zuletzt bearbeitet von F34r0fTh3D4rk am Di 24.05.05 12:56, insgesamt 1-mal bearbeitet
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mo 23.05.05 18:36
Kann ja nicht vom Formular sein. Sonst würde es ja nicht
procedure TForm1.WMMouseMove(var Msg: TWMMouseMove);heißen (ich meine das TForm1. hätte sonst nicht da gestanden).
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Di 24.05.05 12:56
habs oben editiert 
|
|
|