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

Aktuelle Zeit: Di Mai 14, 2024 22:55

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: ZLevel ermitteln
BeitragVerfasst: Fr Jun 08, 2012 19:27 
Offline
DGL Member

Registriert: Mi Mai 23, 2012 08:09
Beiträge: 32
Wohnort: Karlsruhe
Programmiersprache: FreeBASIC
Dieser Codesnipped funktioniert bestens um in einer 3D Welt die position eines Mausklicks zu ermitteln und um damit zu berechnen welches Objekt oder Fläche angeklickt wurde...

Nun bräuchte ich das gleiche lediglich zum ermitteln des ZLevels im Orthogonalen modus:
Das ganze soll für eine kleine GUI sein und wollte so ermitteln auf welches Fenster, die
nach ZLevel sortiert vorliegen, geklickt wurde...

In den Ortho modus wechsel ich recht einfach so
Code:
  1.  
  2.     glMatrixMode GL_PROJECTION                
  3.     glPushMatrix()
  4.     glLoadIdentity()
  5.    
  6.     glMatrixMode GL_MODELVIEW                
  7.     glPushMatrix()
  8.    
  9.     glLoadIdentity()
  10.    
  11.     glOrtho(0,WWidth,WHeight,0,-128,128)    
  12.  


und zurück dann wieder so

Code:
  1.  
  2.     glMatrixMode GL_PROJECTION                          
  3.     glPopMatrix()
  4.    
  5.     glMatrixMode GL_MODELVIEW
  6.     glPopMatrix()
  7.  


Sollte alles seine richtigkeit haben ^^

hier dann der Codeteil zum ermitteln des ZLevel, ist 'Fremdsprache' aber der wesentliche GL-Teil
sollte ersichtlich sein:
Code:
  1.  
  2.             'Wurde 'irgendeine' Maustaste gedrückt den ZLevel ermitteln (nur OpenGL)
  3.             If anyButton Then
  4.                 SCREENINFO , , , , , , Driver
  5.                 If lcase(Driver) = "opengl" Then
  6.  
  7.                     Dim as Integer Viewport (0 to  3)
  8.                     Dim as Double  Modelview(0 to 16), Projection(0 to 16), tmpZ, RX, RY, RZ
  9.  
  10.                     Dim tmpY as Integer
  11.  
  12.                     glGetDoublev (GL_MODELVIEW_MATRIX , @Modelview (0) )' Aktuelle Modelview Matrix speichern
  13.                     glGetDoublev (GL_PROJECTION_MATRIX, @Projection(0) )' Aktuelle Projectiona Matrix speichern
  14.                     glGetIntegerv(GL_VIEWPORT         , @Viewport  (0) )' Aktuellen Viewport speichern
  15.                    
  16.                     tmpY = Viewport(3) - .PositionY                     ' In OpenGL steigt Y von unten (0) nach oben
  17.  
  18.                     ' Auslesen des Tiefenpuffers an der Position (X/tmpY)
  19.                     glReadPixels(.PositionX, tmpY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, @tmpZ )
  20.  
  21.                     ' Errechnen des Punktes, welcher mit den beiden Matrizen multipliziert (X/tmpY/tmpZ) ergibt:
  22.                     gluUnProject(.PositionX, tmpY, tmpZ, @modelview(0), @projection(0), @viewport(0), @RX, @RY, @RZ)
  23.                    
  24.                     .ZLevel = RZ
  25.                     .tmpX = RX
  26.                     .tmpY = RY
  27.                 End If
  28.             Else
  29.                 .ZLevel = 0
  30.             End If
  31.  


Leider gibt mir das ganze, egal wo ich klicke und ob sich dort etwas befindet, immer 128 aus

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: ZLevel ermitteln
BeitragVerfasst: Fr Jun 08, 2012 22:03 
Offline
DGL Member

Registriert: Sa Mär 31, 2012 23:14
Beiträge: 26
Programmiersprache: PASCAL
Du speicherst glOrtho() in der Modelview, obwohl es in die Projection müsste. Die ist dafür die Einheitsmatrix und dementsprechend gibt das auslesen der Projection-Matrix auch nur die Einheitsmatrix zurück.
Mit glOrtho() in der Projectionmatrix könnte es gehen (keine Garantie).

PS
Nicht relevant für das Problem, aber die Variablen 'Modelview' und 'Projection' müssen nur 16 und nicht 17 Werte halten,
also sollte (0 to 15) statt (0 to 16) eig reichen

_________________
The force, strong it is in OpenGL.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: ZLevel ermitteln
BeitragVerfasst: Fr Jun 08, 2012 22:40 
Offline
DGL Member

Registriert: Mi Mai 23, 2012 08:09
Beiträge: 32
Wohnort: Karlsruhe
Programmiersprache: FreeBASIC
Das mit der Matrix war mir so gar nicht aufgefallen da es beim bisherigen testen gant gut funktionierte
habs aber mal geändert, scheint auf den ersten blick aber keine veränderung zu bringen...

das eigentliche Problem aber konnte ich inzwischen lösen...
Aus irgendeinem Grund gibt glReadPixels der tmpZ als Double deklariert ganz andere
Werte zurück als wenn sie 'nur' als Single deklariert ist...

geändert, funzt!

Hab das ganze dann noch etwas abgekürzt:
Code:
  1.  
  2.                     Dim as Integer Viewport (0 to  3)
  3.                     Dim as Double  Modelview(0 to 15), Projection(0 to 15)
  4.                    
  5.                     Dim as Single  tmpY, tmpZ
  6.                    
  7.                     glGetDoublev (GL_MODELVIEW_MATRIX , @Modelview (0) )' Aktuelle Modelview Matrix speichern
  8.                     glGetDoublev (GL_PROJECTION_MATRIX, @Projection(0) )' Aktuelle Projections Matrix speichern
  9.                     glGetIntegerv(GL_VIEWPORT         , @Viewport  (0) )' Aktuellen Viewport speichern
  10.                    
  11.                     tmpY = Viewport(3) - .PositionY                     ' In OpenGL steigt Y von unten (0) nach oben
  12.  
  13.                     ' Auslesen des Tiefenpuffers an der Position (X/tmpY)
  14.                     glReadPixels(.PositionX, tmpY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, @tmpZ )
  15.  
  16.                     .ZLevel = CInt(128-(tmpZ*256))
  17.  


Danke für den Dimensionshinweis, hab ich mal wieder geschlafen
Array[16] ist eben nur 0-15 und nicht 0 bis 16 ^^

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: ZLevel ermitteln
BeitragVerfasst: Sa Jun 09, 2012 08:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
EternalPain hat geschrieben:
Aus irgendeinem Grund gibt glReadPixels der tmpZ als Double deklariert ganz andere Werte zurück als wenn sie 'nur' als Single deklariert ist...
Das ist auch logisch, wenn man sich anschaut, was da hinter den Kulissen passiert. Du übergibst mit @tmpZ einen Pointer auf deine Variable (nebenbei ist es unverantwortlich von welcher-sprache-auch-immer-du-verwendest, dass da keine Fehlermeldung geflogen ist, weil die Typen die da rauskommen inkompatibel sind). Falls du das nicht weißt, ein Pointer ist ein Verweis auf einen Speicherbereich. Du übergibts also einen Verweis auf den Bereich, wo dein Double liegt.
glReadPixels interpretiert den aber als Single (siehe Referenz). Nun wird also der Single-Wert in den Bereich für den Double geschrieben. Das hat zweierlei implikationen: Erstens ist ein Single nur halb so lang, also werden die oberen vier Bytes des Doubles garnicht gesetzt (sind also undefiniert, da deine Variable auch noch nicht initialisiert ist; ein Punkt wo der Kompiler übrigens hätte warnen sollen, da er nicht wissen kann, was in glReadPixels mit der Variable angestellt wird; könnte ja auch von gelesen werden) und zweitens haben Double und Single aufgrund ihrer unterschiedlichen Größe auch jeweils ein anderes internes Format. Siehe Gleitkommazahl#Interne Darstellung.

grüße.

_________________
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: Re: ZLevel ermitteln
BeitragVerfasst: Sa Jun 09, 2012 10:12 
Offline
DGL Member

Registriert: Mi Mai 23, 2012 08:09
Beiträge: 32
Wohnort: Karlsruhe
Programmiersprache: FreeBASIC
Eigentlich wollte ich nun gerade argumentieren, (ohne weiteres wissen auf die interne verarbeitung von fliesskommazahlen) das ich doch problemlos kleine werte in einem grösser dimensionierten bereich übergeben kann, dann wird eben ein teil des bereichs nicht genutzt... aber nochmal darüber nachgedacht und getestet völliger blödsinn :D Da ich ja keinen Wert sondern eine Adresse übergebe und somit mit einem grösser dimensionierten bereich dann über die Adresse auch über den von der Funktion dafür reservierten Speicher somit über den speicher hinaus 'lese'

Jetzt im nachhinein hätte hier tatsächlich eine Fehler bzw Warnmeldung kommen müssen...

Ähnliches Beispiel
Code:
  1.  
  2. Dim test as UInteger ptr
  3. Dim wert as ubyte
  4.  
  5. wert= 100
  6. test=@wert
  7.  
  8. ?test
  9.  


Ergibt auch völlig falsche Werte, aber mit dazu gehöriger Warnmeldung
Zitat:
Suspicious pointer assignment


Diese allerdings bekam ich bei dem glReadPixel problem leider nicht, wäre sonst ein Hinweis auf das Problem gewesen...

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: ZLevel ermitteln
BeitragVerfasst: Sa Jun 09, 2012 10:43 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Das sollte nicht nur eine Warnung sondern eigentlich ein Fehler sein und einen expliziten Typecast erfordern, aber gut ;).

EternalPain hat geschrieben:
Da ich ja keinen Wert sondern eine Adresse übergebe und somit mit einem grösser dimensionierten bereich dann über die Adresse auch über den von der Funktion dafür reservierten Speicher somit über den speicher hinaus 'lese'
Nicht vollständig korrekt, da die Funktion keinen Speicher reserviert. Den Speicher hast du reserviert, die Funktion schreibt nur rein (aber nicht in den ganzen Bereich).

Und Fließkommazahlen sind nicht so gebaut, dass sie untereinander binärkompatibel sind (anders als ganzzahlige Typen, zumindest auf Little Endian Architekturen), siehe auch link von oben.

grüße

_________________
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  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 11 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.031s | 20 Queries | GZIP : On ]