| Autor |
Beitrag |
t/f
      
Beiträge: 70
|
Verfasst: Sa 19.04.03 23:53
Hallo Board!
Wie finde ich via OpenGL heraus, wo ich mit meiner Maus hinklicke?
Ich krieg zwar die Pixel von Form1 über das OnMouseDown-Ereignis, doch wenn ich nun in OpenGL etwas in meiner Scene verändern möchte, ( beispielsweisie, die "Kamera" an diese Stelle bewegen oder dort ein Objekt erscheinen lassen ), helfen mir die Pixel nun gar nicht weiter, da ich erstens ein zwedimensionales Koordinatensystem mit dem Urprung in der oberen linken Ecke habe, dass zweitens mit ganz anderen Maßstäben rechnet als mein OpenGL-Fenster.
nungut, die Frage nach den Maßstäben ließe sich mit Müh und not durch geschicktes Zoomen durch glTranslate und dann?
Um euch zu erklären worum es mit im Detail geht:
ich habe ein Quad, dass in eine bestimmte Lage gedreht wurde und durch einfaches Kacheln eine Map darstellen soll.
Nun klicke ich irgendwo mit der Maus hin... meine Kamera soll dabei zu diesem Ort "hinfahren".
Es wäre toll, wenn ich wenigstens für zwei Dimensionen des Koordinatensystems meine Mauskoordinaten umsetzen könnte, da die dritte ja eh nicht veränderbar sein brauch, oder?
Hier mein Quellcode (wird euch sicher aus den Tutorials bekannt vorommen  ):
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: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OpenGL12, Textures, StdCtrls, ExtCtrls;
type TForm1 = class(TForm) Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure InitGL; procedure DrawScene; procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean); procedure Button1Click(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure CheckKeys; procedure Timer1Timer(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end;
procedure SetDCPixelFormat(Handle: HDC);
var Form1: TForm1; h_DC: hDC; hRC: HGLRC; Rotate,RotateX,PosX,PosZ,CamX,CamY: Single; MyTex: TTextur; Keys: Array[0..255] of Boolean; RealFPS: Integer = 100; FPS: Integer;
implementation
{$R *.dfm}
procedure TForm1.CheckKeys; begin if Keys[VK_LEFT] then begin Rotate:=Rotate - 2 * (100 / RealFPS); if Rotate<0 then Rotate:=Rotate + 360; end; if Keys[VK_RIGHT] then begin Rotate:=Rotate + 2 * (100 / RealFPS); if Rotate>360 then Rotate:=Rotate - 360; end; if Keys[VK_UP] then begin PosX:=PosX + Sin(-Rotate * (PI / 180)) * (0.1); PosZ:=PosZ + Cos(-Rotate * (PI / 180)) * (0.1); end; if Keys[VK_DOWN] then begin PosX:=PosX - Sin(-Rotate * (PI / 180)) * (0.1); PosZ:=PosZ - Cos(-Rotate * (PI / 180)) * (0.1); end; end;
procedure TForm1.FormCreate(Sender: TObject); begin Form1.Left := 0; Form1.Top := 0; Form1.Width := Screen.Width; Form1.Height := Screen.Height; InitOpenGL; h_DC:=GetDC(Handle); SetDCPixelFormat(h_DC); hRC:=wglCreateContext(h_DC); wglMakeCurrent(h_DC,hRC); InitGL; Application.OnIdle := ApplicationEvents1Idle; glEnable(GL_TEXTURE_2D); MyTex:=TTextur.Create('terrain1.jpg'); end;
procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean); begin DrawScene; Done:=False; end;
procedure TForm1.DrawScene; begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glLoadIdentity;
//CheckKeys;
glColor3f(1.0, 1.0, 1.0); glTranslate(CamX,CamY,-2); //glRotate(45,0,1,0); glRotate(-45,1,0,0); MyTex.Bind; glBegin(GL_QUADS); glTexCoord2f(50,0); glVertex3f(5,-5,0); glTexCoord2f(50,50); glVertex3f(5,5,0); glTexCoord2f(0,50); glVertex3f(-5,5,0); glTexCoord2f(0,0); glVertex3f(-5,-5,0); glEnd;
SwapBuffers(h_DC);
RotateX:=RotateX + 1; if RotateX>360 then RotateX:=RotateX - 360;
FPS := FPS + 1; end;
procedure TForm1.InitGL; begin glClearColor(0,0,0,0); glClearDepth(1); glDepthFunc(GL_LESS); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST);
glViewport(0,0,Screen.Width,Screen.Height); glMatrixMode(GL_PROJECTION); glLoadIdentity; gluPerspective(45,Screen.Width/Screen.Height,1,100); glMatrixMode(GL_MODELVIEW); end;
procedure SetDCPixelFormat(Handle: HDC); var nPixelFormat: GLUint; const pfd: PIXELFORMATDESCRIPTOR = ( nSize: sizeof( PIXELFORMATDESCRIPTOR ); nVersion: 1; dwFlags: PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER; iPixelType: PFD_TYPE_RGBA; cColorBits: 16; cRedBits: 0; cRedShift: 0; cGreenBits: 0; cBlueBits: 0; cBlueShift: 0; cAlphaBits: 0; cAlphaShift: 0; cAccumBits: 0; cAccumRedBits: 0; cAccumGreenBits: 0; cAccumBlueBits: 0; cAccumAlphaBits: 0; cDepthBits: 16; cStencilBits: 0; cAuxBuffers: 0; iLayerType: PFD_MAIN_PLANE; bReserved: 0; dwLayerMask: 0; dwVisibleMask: 0; dwDamageMask: 0 ); begin nPixelFormat:=ChoosePixelFormat(h_DC, @pfd); SetPixelFormat(h_DC,nPixelFormat,@pfd); end;
procedure TForm1.Button1Click(Sender: TObject); begin close; end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin Keys[Key]:=true; if(Key = vk_escape)then close; end;
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin Keys[Key]:=false; end;
procedure TForm1.Timer1Timer(Sender: TObject); begin RealFPS:=FPS; FPS:=0; end;
end. |
Wäre echt genial, wenn jemand mir helfen könnte
greetz
//me
Zuletzt bearbeitet von t/f am So 20.04.03 22:49, insgesamt 1-mal bearbeitet
|
|
Raphael O.
      
Beiträge: 1596
VS 2013
|
Verfasst: So 20.04.03 00:12
geh mal auf delphigl.de dann auf OpenGL und dann in den Tutorials nimmste "Objektauswahl"...
das ist IMO das was du meinst/willst...
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: So 20.04.03 00:15
huhu,
nicht verzagen, Aya frange
Diese procedure sollte dir weiterhelfen:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure GetMousePos(MouseX, MouseY, MouseZ: Double); var ModelView, Projection: TMatrix4d; Viewport: TVector4i; ObjX, ObjY, ObjZ: GLDouble; begin glGetDoublev(GL_MODELVIEW_MATRIX,@ModelView); glGetDoublev(GL_PROJECTION_MATRIX,@Projection); glGetIntegerv(GL_VIEWPORT,@Viewport); gluUnProject(MouseX,Viewport[3] - MouseY - 1,MouseZ,ModelView,Projection,Viewport,@ObjX,@ObjY,@ObjZ); MX:=ObjX; MY:=ObjY; MZ:=ObjZ; end; |
MX, MY und MZ ist die Position auf dein OpenGL Fenster umgerechnet.
MouseX, MouseY sind die MausKoordinaten (vom Fenster, also z.B. vom OnMouseDown das X und Y)
MouseZ ist die tiefe der Maus.. sozusagen...  Also in welcher tiefe du klickst...
Au'revoir,
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
Zuletzt bearbeitet von Aya am So 20.04.03 00:23, insgesamt 1-mal bearbeitet
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 00:20
jo besten Dank ihr 2  ...
kleine Frage an Aya... sieht ja furchtbar aus der Quellcode... was passiertn da eigentlich?
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: So 20.04.03 00:25
huhu,
Quelltext 1:
| glGetDoublev(GL_MODELVIEW_MATRIX,@ModelView); |
Speichert die aktuelle ModelMatrix nach ModelView.
Quelltext 1:
| glGetDoublev(GL_PROJECTION_MATRIX,@Projection); |
Dasselbe nur mit der ProjektionsMatrix -> Projection
Quelltext 1:
| glGetIntegerv(GL_VIEWPORT,@Viewport); |
Den Viewport speichern...
Quelltext 1: 2:
| gluUnProject(MouseX,Viewport[3] - MouseY - 1,MouseZ,ModelView,Projection,Viewport,@ObjX,@ObjY,@ObjZ); |
Die eigentliche funktion, mit gluUnProject werden WindowsKoordinaten in OpenGL Koordinaten umgewandelt.. mit gluProject genau andersrum, OpenGL -> Windows Koordinaten
Au'revoir,
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 00:25
hö? jetzt mal im Nachhinein..... wie was für 'ne Tiefe denn  ... mein Form1 ist platt wie ne Briefmarke *g ...
Ich möcht ja 2 Koordinaten eingeben und drei wieder 'rauskriegen  ...
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 00:28
und nocheins.... MX, MY, und MZ müssen als GLDouble deklariert werden, seh' ich das richtig?
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: So 20.04.03 00:31
Na ja, dein Fenster ist 2D, klar... aber OpenGL ist 3D
Wenn du einfach nur exakt die stelle willst wo du hinklickst, nimm für MouseZ 0..
MX etc muß GLDouble sein, ja
Au'revoir,
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 00:49
Wenn ich in meinem Proggi nun schreibe glTranslate(MX,MY,-10);
müsste ich dann mit meiner "Kamera" jetzt nicht dort landen, wohin ich mit der Maus gezeigt habe?
Irgendwie haut das nicht hin. Der Punkt, der mit der Maus angeklickt wird, soll ja nun in der Mitte meines bildschirms sein. funzt nich 
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: So 20.04.03 00:52
mach es mal so:
Quelltext 1: 2: 3:
| glTranslate(0,0,-10); GetMousePos; glTranslate(MX,MY,0); |
Au'revoir,
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 00:56
hm... will mein compiler nicht ([Fehler] Unit1.pas(105): Nicht genügend wirkliche Parameter), weil ich die mauskoordninaten übergeben soll (hab ich vorher im im OnMouseDown-Ereignis geholt) ... und noch ne kleine Frage... wieso gehe ich eigentlich zum Ursprung zurück? Kann ich mir das erste glTranlate nicht sparen?
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: So 20.04.03 01:02
huhu,
sorry.. mein fehler
änder die Procedure GetMousePos mal so um das keine parameter gebraucht werden.
jetzt machste drei globale Variablen:
Quelltext 1: 2: 3: 4:
| var MouseX: Integer = 0; MouseY: Integer = 0; MouseZ: Integer = 0; |
und im OnMouseDown machste dann:
Quelltext 1: 2:
| MouseX:=X; MouseY:=Y; |
so sollte es klappen..
und zum glTranslate.. wenn du glTranslate(MX,MY,0) machst heißt das das es in z-Richtung um 0 Einheiten verschoben wird, nicht das es wieder zum 0 punkt zurückgeht
Au'revoir,
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 01:12
... und es will immernoch nicht. Es ruckelt zwar etwas hin und her, aber ich kann hinklicken wo ich will. So wirklich ändert sich meine Position nicht.

|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: So 20.04.03 01:19
huhu,
hier mal nen beispiel..
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:
| var MX, MY, MZ: Single; MouseX, MouseY: Integer;
procedure TForm1.GetMousePos; var ModelView, Projection: TMatrix4d; Viewport: TVector4i; ObjX, ObjY, ObjZ: GLDouble; begin glGetDoublev(GL_MODELVIEW_MATRIX,@ModelView); glGetDoublev(GL_PROJECTION_MATRIX,@Projection); glGetIntegerv(GL_VIEWPORT,@Viewport); gluUnProject(MouseX,Viewport[3] - MouseY - 1,0,ModelView,Projection,Viewport,@ObjX,@ObjY,@ObjZ); MX:=ObjX; MY:=ObjY; MZ:=ObjZ; end;
procedure TForm1.OGLDrawScene(Sender: TObject; hDC: HDC; hRC: Cardinal); begin glTranslate(0,0,-2); glRotate(45,0,1,0); GetMousePos; glTranslate(MX,0,MZ); glBegin(GL_QUADS); glColor3f(1,0,0); glVertex3f(-0.3,-0.3,0); glVertex3f(0.3,-0.3,0); glColor3f(1,1,0); glVertex3f(0.3,0.3,0); glVertex3f(-0.3,0.3,0); glEnd; end;
procedure TForm1.OGLMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin MouseX:=X; MouseY:=Y; end; |
da funktioniert alles wunderbar, vieleicht hilft dir das deinen fehler zu finden
Muß jetzt leider erstmal weg, aber wenn das Problem morgen immernoch da ist, dann schick mir doch morgen mal deinen Code und ich schau mal durch
Au'revoir,
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 01:31
also da erkenn ich grad noch eine grundlegende Frage:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| X | | Z | / | / | / | / | / | / |/ +-------------------Y |
Sieht so das Koordinatensystem in OpenGl aus? Sind die Achsen etwa anders belegt?
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 01:52
hm.... ich glaub, jetz weiß ich, wo das probem liegt  ...
wir reden nicht über das gleich problem.
Ich befinde mich auf einem Punkt meiner Map und klicke mit der Maus auf einen anderen. Nun soll die Kamera, die ich im Bild gekennzeichnet habe, den Ort, an dem die Maus geklickt wurde, zentrieren. D.h. mann hat als Benutzer das Gefühl, sich auf der Map zu bewegen.
Das mit dem Koordinatensystem ha6t sich soweit erstmal erledigt. Ich denk mal daran liegts nicht.
greetz
//me
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: So 20.04.03 04:07
huhu,
also erstmal das Koordinaten System in OpenGL ist:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| Y | | Z | / | / | / | / | / | / |/ +-------------------X |
X: Breite
Y: Höhe
Z: Tiefe
wegen deinem Problem... ich hab da leider auch nich direkt ne ahnung woran das liegt... hab den gluUnProject befehl erst einmal benutzt...
Aber wie gesagt, schick mir doch morgen mal dein Programm und ich schau mal ob ich den fehler finde  (oder spiel einfach mal ein wenig mit dem MouseZ rum.. veränder da mal die werte auf z.B. -10  )
Au'revoir,
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 11:49
Wahnsinn, schläfst du nie?
Nuja  ... *g ... hast mein letztes Posting übersehen glaub ich
Ich hab' nu gedacht, wenn ich glTranslate hinter dem Quad einsetz bewegt sich was... aber nö. 
|
|
t/f 
      
Beiträge: 70
|
Verfasst: So 20.04.03 22:52
hm... also wenn die Achsen nun so verschoben sind, muss ich das bei meiner Auswertung von MX, MZ etc beachten oder macht die Funktion das alles für mich?
|
|
Andreas Pfau
      
Beiträge: 997
|
Verfasst: Mo 21.04.03 11:47
Hallo,
ich bin begeistert vom diesem Code, weil ich auch schon nach so was gesucht habe. Aber nu is' nix: Wenn ich das ganze mit einer 2D-Projektion mache (gluOrtho2D()), alles OK. Wenn ich mit glFrustum() eine 3D-Projektion erstelle, klappt auch. Aber ich will gluPerspective verwenden. Und dann liefert gluUnProject einen Fehler:
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: 27: 28: 29: 30:
| procedure MainLoop; var X, Y, Z: Double; S1, S2: String; Modelview, Projection: Array[0..15] Of Double; Viewport: Array[0..3] Of Integer; begin glMatrixMode(GL_Projection); glLoadIdentity; gluPerspective(45, WinX / WinY, 0, 100); // glFrustum(-1,1,-1,1,0.1,100); glMatrixMode(GL_ModelView);
glGetDoublev(GL_Modelview_Matrix, @Modelview); glGetDoublev(GL_Projection_Matrix, @Projection); glGetIntegerv(GL_Viewport, @Viewport); gluUnProject(MouseX, MouseY, MouseWheel, @Modelview, @Projection, @Viewport, X, Y, Z); S1 := 'X=' + IntToStr(MouseX) + ' Y=' + IntToStr(MouseY) + ' Z=' + ValToStr(MouseWheel, 0, 0); S2 := 'X=' + ValToStr(X, 0, 2) + ' Y=' + ValToStr(Y, 0, 2) + ' Z=' + ValToStr(Z, 0, 2);
glMatrixMode(GL_Projection); glLoadIdentity; gluOrtho2D(0, WinX, 0, WinY); glMatrixMode(GL_ModelView);
glColor4f(1.0, 1.0, 1.0, 1.0); CallText(Font_Digital, WinX * 0.700, WinY * 0.130, WinY * 0.025, S1); CallText(Font_Digital, WinX * 0.700, WinY * 0.100, WinY * 0.025, S2); |
MouseX, MouseY und MouseWheel ist klar. WinX und WinY ist die Fenstergröße. CallText() rendert halt den Text. So wie der Code jetzt ist, kommt ein Fehler, d.h. alle Werte (X, Y, Z) sind 0, und wenn man's nachprüft, liefert gluUnProject 0 zurück, d.h. einen Fehler. Schalte ich oben um auf glFrustum, klappt alles.
Woran liegt das? Sag bloß, gluUnProject arbeitet nicht mit 3D-Projektionen???
_________________ Life is a bad adventure, but the graphic is really good!
|
|
|