Mauskoordinaten

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
snapdragon
Beiträge: 28
Registriert: 24.09.2012, 14:49

Mauskoordinaten

Beitrag von snapdragon »

Hallo zusammen,

ich habe grade begonnen mich in die Grafikprogrammierung einzuarbeiten und gehe dabei die Tutorials auf codesampler durch. Mein erstes eigenes Fenster steht und er rendert auch die ersten primitiven. Nun wollte ich einmal mit der Windows API weiter rumspielen, dabei viel mir auf, dass die Koordinaten des Cursors bei einem fest definierten Fenster (600x400) nicht exakte Werte liefern.

D.h. verlasse ich das Fenster in der Tiefe, stoppt die Eventausgabe schon bei etwa 580-583 und in der Breite bei etwa 370. Wieso ist das so? Finde nirgens konkrete Informationen hierzu. Hat das mit dem Rand zu tun? Wie kann ich die tatsächlichen Werte bestimmen?

Render ich ein Quadrat mit dem Ursprung bei 25, 15, dann erhalte ich wenn ich mit dem Cursor den Ursprung ansteuer 25, 355, was den 370 -15 entspricht. Ich habe aber 400 angegeben?? Benute aktuell orthogonales mapping, hier brauche ich ja eigentlich nichts umrechnen da ich ja schon im screenspace bin oder?

Ich will ein einfaches drop down demo erstellen und das würde doch falsche Picking Werte ergeben?!
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Mauskoordinaten

Beitrag von dot »

snapdragon hat geschrieben:Hat das mit dem Rand zu tun?
Bingo!

Schau mal hier, hier und hier.
snapdragon
Beiträge: 28
Registriert: 24.09.2012, 14:49

Re: Mauskoordinaten

Beitrag von snapdragon »

Hmm, ich habe mir die Links mal angeschaut, aber irgendwie klappt das nicht. Ich erhalte als Client-Rect immer die Werte die ich hinein gesteckt habe (600x400) und nicht die um den Rand reduzierten Werte. Ich habe mir auch mal GetSystemMetrics angeschaut ob ich hier irgendwie die Randdaten bekomme, aber alle Werte die ich erhalte führen nicht zu den oben genannten reduzierten Pixelwerten.

Hier mal der Code, wie ich ein Fenster erzeuge:

Code: Alles auswählen

     dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;	//normal window which has an edge on it
     dwStyle = WS_CAPTION | WS_SYSMENU;	//a normal window's window

     int left = 0;
     int top  = 0;
     int width = 600;
     int height = 400;

     RECT windowrect;	//a rectangle that holds the size of the window
     windowrect.top	 = top;
     windowrect.bottom = height;
     windowrect.left	 = left;
     windowrect.right	 = width;

    AdjustWindowRectEx(&windowrect, dwStyle, false, dwExStyle);
   m_window=CreateWindowEx( dwExStyle ,m_name.c_str(),title.c_str(),
                                                dwStyle,	windowrect.left, windowrect.top,	
     		                                windowrect.right, windowrect.bottom,	
			                        NULL,NULL,
                                               GetModuleHandle(NULL),NULL);

    // Test ermitteln der realen Client-Rect Werte
    RECT rc;
    GetWindowRect(m_window, &rc);
   
    int w = GetSystemMetrics(SM_CXSIZEFRAME);
    int h = GetSystemMetrics(SM_CYSIZEFRAME);
   
    std::cout << "Window real width: " << rc.right << std::endl;
    std::cout << "Window real height: " << rc.bottom << std::endl;
Edit: Code korrigiert.
Zuletzt geändert von snapdragon am 25.09.2012, 08:30, insgesamt 1-mal geändert.
snapdragon
Beiträge: 28
Registriert: 24.09.2012, 14:49

Re: Mauskoordinaten

Beitrag von snapdragon »

Ok, Fehler gefunden, sollte auch das justierte Rect dann bei der Erzeugung des Fensters anwenden ;) Sieht schon mal besser aus, erhalte nun 600x378 als Werte zurück. Passt aber immer noch nicht ganz, da der Cursor bei 596x374 aufhört mir die Werte zurück zu geben??! D.h. irgendwo habe ich immer noch 4 Pixel die verschluckt werden.
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: Mauskoordinaten

Beitrag von antisteo »

Warum rechnest du auch mit globalen Cursorkoordinaten und fängst nicht einfach die Cursor-Events des Windows ab, die die korrekten Client-Koordinaten enthalten?
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
snapdragon
Beiträge: 28
Registriert: 24.09.2012, 14:49

Re: Mauskoordinaten

Beitrag von snapdragon »

Ich rechne ja mit den Event-Cursor Koordinaten. Dabei habe ich ja fest gestellt, dass die Koordinaten beim LEFT Event nicht den korrekten Werten entsprechen und die Koordinaten mit meinem Sprite (10x10) nicht übereinstimmen. Der Sprite Ursprung in der linken unteren Ecke (einfaches Quadrat) wird im Orhto Modus bei 25,15 gesetzt, der Cursor meldet aber Position 25,44. Eine einfache Kollisionsberechnung schlägt somit fehl.

Muss meine Aussage das es klappt revidieren. wenn ich wie oben im Code angegeben die Top/Left Position aus meinem Adjusted Rect setze, wird der Ursprung der Client-Area in den Ursprung des Fensters gesetzt, so dass der obere Rand fehlt, wie beim Fullscreen. Setze ich mein top/left mit 0,0, dann sind die zurückgegebenen Werte sogar größer als die gesetzten (603x403). D.h. das Delta ist sogar noch größer!

Irgendwie verstehe ich das ganze nicht ...
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Mauskoordinaten

Beitrag von Schrompf »

Wie groß ist denn Dein Sprite? Und weißt auch pixelgenau, wo der Klickpunkt bei Deinem Mauszeiger ist?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
snapdragon
Beiträge: 28
Registriert: 24.09.2012, 14:49

Re: Mauskoordinaten

Beitrag von snapdragon »

Mein Sprite ist 10x10 groß, d.h. die Rect (x,y,w,h) Daten lauten 25, 15, 35, 25. Und dagegen teste ich aktuell die Cursor position,
die ich aus dem Event erhalte:

Code: Alles auswählen

case WM_MOUSEMOVE :
{
       cursor_x = LOWORD(lparam);
       cursor_y = HIWORD(lparam); 
} 
case WM_MOUSELEAVE :
{
       cursor_x = LOWORD(lparam);
       cursor_y = HIWORD(lparam); 

       std::cout << "EXIT WITH: " << cursor_x << ", << cursor_y << std::endl;   // Liefert für linke untere Ecke 0,374
}

Da der Ursprung des Fensters ja leider in der linken oberen Ecke ist, ich aber als OpenGL Ursprung die linke untere Ecke
verwende, rechne ich den Cursor für den folgenden check um (cursor_x, RES_HEIGHT-cursor_y):

Code: Alles auswählen

bool Rect::contains(int pX, int pY)
{
   return m_x <= pX && m_x + m_width >= pX && m_y <= pY && m_y + m_height >= pY;
}
Und da liegt der Fehler, weil 400 != 373 und ich somit ein Delta habe.
Psycho
Establishment
Beiträge: 156
Registriert: 16.09.2002, 14:23

Re: Mauskoordinaten

Beitrag von Psycho »

Code: Alles auswählen

std::cout << "Window real width: " << rc.right << std::endl;
std::cout << "Window real height: " << rc.bottom << std::endl;
Was steht denn in rc.left und rc.top, sicher dass die null sind?

Andere stellen wo es wichtig sein könnte:

Code: Alles auswählen

m_window=CreateWindowEx( dwExStyle ,m_name.c_str(),title.c_str(),
dwStyle, windowrect.left, windowrect.top,
windowrect.right, windowrect.bottom,
NULL,NULL,
GetModuleHandle(NULL),NULL);
Schreib lieber:

Code: Alles auswählen

m_window=CreateWindowEx( dwExStyle ,m_name.c_str(),title.c_str(),
dwStyle, windowrect.left, windowrect.top,
windowrect.right - windowrect.left, windowrect.bottom - windowrect.top,
NULL,NULL,
GetModuleHandle(NULL),NULL);
Und oben (wobei das in Deinem Fall egal sein sollte, weil dein Left/Top null ist):

Code: Alles auswählen

RECT windowrect; //a rectangle that holds the size of the window
windowrect.top = top;
windowrect.bottom = height;
windowrect.left = left;
windowrect.right = width;

Code: Alles auswählen

RECT windowrect; //a rectangle that holds the size of the window
windowrect.top = top;
windowrect.bottom = top + height;
windowrect.left = left;
windowrect.right = left + width;
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Mauskoordinaten

Beitrag von dot »

Exakt, da oben verwendest du windowrect.right als Breite und windowrect.bottom als Höhe, was aber eben nicht unbedingt richtig ist. Schau dir mal im Debugger an, was für Werte in deinem windowrect so stehen... ;)
snapdragon
Beiträge: 28
Registriert: 24.09.2012, 14:49

Re: Mauskoordinaten

Beitrag von snapdragon »

Ok, da liegt der Hund begraben. Warum auch immer, im rc.top und rc.left stehen nach dem Adjust -25 und -3. Damit erklärt sich dann auch das Delta, denn meine Dimension + diese Werte ergeben dann die korrekten Ausstiegswerte.

Aber warum ist das so? Ich kann übrigens wie beschrieben das left und top des Adjustments nicht verwenden, da sonst wie beschrieben das Fenster so verschoben wird, dass die Kopfleiste nicht mehr zu sehen ist. Bei diesen Werten ja auch nicht anders zu erwarten.

Rechnet Ihr das alle so um? Habe kein Tutorial Code oder Sample gefunden, dass dies so umrechnet.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Mauskoordinaten

Beitrag von dot »

Ist doch klar, das Rechteck, das in AdjustWindowRect() reingeht, ist dein gewünschter Clientbereich. AdjustWindowRect() baut das Fenster um diesen herum auf. Damit die linke obere Eckte des Clientbereichs bei (0 0) zu liegen kommt, muss die linke obere Ecke des Fensters negative Koordinaten haben...

Wofür brauchst du left und top denn? Du willst doch nur die richtige Höhe und Breite des Fensters bestimmen!?
snapdragon
Beiträge: 28
Registriert: 24.09.2012, 14:49

Re: Mauskoordinaten

Beitrag von snapdragon »

Logisch! Danke für Eure Hilfe.
Antworten