Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

GLFW ustawianie i odczytywanie pozycji kursora myszy

Ostatnio zmodyfikowano 2017-01-24 13:45
Autor Wiadomość
Nazgul
Temat założony przez niniejszego użytkownika
GLFW ustawianie i odczytywanie pozycji kursora myszy
» 2017-01-22 02:40:08
Z tego co widać w komentarzach zawartych w bibliotece GLFW3, funkcji 'GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);' nie powinno się używać do sterowania kamerą "__Do not use this function__ to implement things like camera controls." , dalej w komentarzu jest napisane, żeby  używać "glfwSetInputMode(GLFW_CURSOR, GLFW_CURSOR_DISABLED);" doczytałem, że ta funkcja ustawia kursor że jest niewidoczny, oraz że ma nielimitowane osie(sic!) i teraz mam pytanie, szukałem tego i nie mogę znaleźć w jaki sposób powinno się wtedy pobrać pozycje kursora.. glfwGetCursorPos ma ograniczenia jak zmienna double;/
Będę bardzo wdzięczny za odpowiedź(równie wdzięczny będę za odpowiedź, co się dzieje ze zmienną double po przeciążeniu)
P-156768
DejaVu
» 2017-01-22 10:14:28
Mieszasz dwie sprawy:
- pobieranie położenia myszy
- kontrolowanie kamery

A masz co najmniej kilka aspektów:
- pobieranie położenia myszy na scenie 2D
- pobieranie położenia myszy w świecie 3D (np. poprawne zaznaczanie obiektów z uwzględnieniem zastosowanej perspektywy)
- kontrolowanie kamery w świecie 2D (przesuwanie planszy)
- kontrolowanie kamery w świecie 3D (obracanie sceny względem aktualnego położenia gracza)

Coś o kamerze możesz poczytać tutaj: https://learnopengl.com/#!Getting-started/Camera

W zależności od celu jaki chcesz osiągnąć to musisz do sprawy podejść inaczej. W przypadku pobierania położenia myszy na scenie 2D funkcja, którą przytoczyłeś jest wystarczająca.

Może coś Ci jeszcze da ten temat: https://www.opengl.org​/discussion_boards​/showthread.php​/126440-Moving-the-camera-view-with-the-mouse

/edit:
Tu masz pełny przykład:
http://r3dux.org/2011/05​/simple-opengl-keyboard-and-mou​se-fps-controls​/

C/C++
// Function to deal with mouse position changes, called whenever the mouse cursorm moves
void handleMouseMove( int mouseX, int mouseY )
{
    GLfloat vertMouseSensitivity = 10.0f;
    GLfloat horizMouseSensitivity = 10.0f;
   
    //cout << "Mouse cursor is at position (" << mouseX << ", " << mouseY << endl;
   
    int horizMovement = mouseX - midWindowX;
    int vertMovement = mouseY - midWindowY;
   
    camXRot += vertMovement / vertMouseSensitivity;
    camYRot += horizMovement / horizMouseSensitivity;
   
    // Control looking up and down with the mouse forward/back movement
    // Limit loking up to vertically up
    if( camXRot < - 90.0f )
    {
        camXRot = - 90.0f;
    }
   
    // Limit looking down to vertically down
    if( camXRot > 90.0f )
    {
        camXRot = 90.0f;
    }
   
    // Looking left and right. Keep the angles in the range -180.0f (anticlockwise turn looking behind) to 180.0f (clockwise turn looking behind)
    if( camYRot < - 180.0f )
    {
        camYRot += 360.0f;
    }
   
    if( camYRot > 180.0f )
    {
        camYRot -= 360.0f;
    }
   
    // Reset the mouse position to the centre of the window each frame
    glfwSetMousePos( midWindowX, midWindowY );
}

C/C++
// Function to pass-through any mouse movements to our Camera class
void handleMouseMove( GLFWwindow * window, GLdouble mouseX, GLdouble mouseY )
{
    camera.handleMouseMove( window, mouseX, mouseY );
}

C/C++
glfwSetInputMode( window, GLFW_CURSOR_DISABLED, GL_TRUE );
glfwSetCursorPos( window, windowWidth / 2, windowHeight / 2 );
glfwSetCursorPosCallback( window, handleMouseMove );
P-156772
Nazgul
Temat założony przez niniejszego użytkownika
» 2017-01-22 16:28:22
Rozróżniam te dwie kwestie (położenie położenia myszy, sterowanie kamerą), operowałem analogicznymi funkcjami używając biblioteki GLUT i wszystko działało dobrze.
Ogólnie to co robię teraz pod GLFW również działa dobrze. Był tylko moment jak przekombinowałem i ustawiałem położenie myszy na środku ekranu, a dopiero potem pobierałem położenie myszy(funkcja nie reagowała na ruch myszy).. Wtedy podczas szukania błędu trafiłem na komentarz do funkcji glfwSetCursorPos(...) o dokładnej treści:
C/C++
/*! @brief Sets the position of the cursor, relative to the client area of the
*  window.
*
*  This function sets the position, in screen coordinates, of the cursor
*  relative to the upper-left corner of the client area of the specified
*  window.  The window must have input focus.  If the window does not have
*  input focus when this function is called, it fails silently.
*
*  __Do not use this function__ to implement things like camera controls.  GLFW
*  already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the
*  cursor, transparently re-centers it and provides unconstrained cursor
*  motion.  See @ref glfwSetInputMode for more information.
*
*  If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is
*  unconstrained and limited only by the minimum and maximum values of
*  a `double`.
*
*  @param[in] window The desired window.
*  @param[in] xpos The desired x-coordinate, relative to the left edge of the
*  client area.
*  @param[in] ypos The desired y-coordinate, relative to the top edge of the
*  client area.
*
*  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
*  GLFW_PLATFORM_ERROR.
*
*  @thread_safety This function must only be called from the main thread.
*
*  @sa @ref cursor_pos
*  @sa glfwGetCursorPos
*
*  @since Added in version 3.0.  Replaces `glfwSetMousePos`.
*
*  @ingroup input
*/
GLFWAPI void glfwSetCursorPos( GLFWwindow * window, double xpos, double ypos );

Jest tutaj bardzo wyraźnie napisane, żeby nie używać tej funkcji do implementacji sterowania kamerą.
Stąd moje pytanie (teraz trochę inaczej je sformułuję), w jaki sposób powinno się odczytywać położenie kursora myszy, które wpływa na sterowanie kamerą, skoro w dokumentacji jest napisane, żeby nie robić tego przy pomocy tej funkcji? ;)

W komentarzu do funkcji(powyżej) jest również napisane, żeby posłużyć się funkcją:
C/C++
glfwSetInputMode( GLFW_CURSOR, GLFW_CURSOR_DISABLED );
//... dalej domyśliłem się, że do pobrania samego położenia myszy trzeba użyć:
glfwGetCursorPos( window, & xpos, & ypos );

..,tylko że mam wątpliwości co do ustawienia tego trybu myszy i pobierania współrzędnych za pomocą tej funkcji, ponieważ to rozwiązanie nie ma zabezpieczenia przed przeciążeniem zmiennych typu double (xpos, ypos).

Dlatego kontynuuję pytanie. Zależy mi żeby funkcje które piszę, były bezpieczne;)

P.S. używam biblioteki GLFW w wersji 3.2, dlatego nie wiem jak działa glfwSetMousePos(midWindowX, midWindowY); i nie wiem jaka jest różnica z funkcją glfwSetCursorPos(window, windowWidth / 2, windowHeight / 2);. W dokumentacji znalazłem jedynie wzmiankę, że pierwsza funkcja została usunięta i że zastąpiono ją tą drugą(tym bardziej mnie dziwi że w przykładzie, który Pan podał są zastosowane obie)
P-156780
Lora
» 2017-01-22 17:41:12
Możesz spróbować użyć funkcji reagującej na ruch myszy:

C/C++
void mousePos_callback( GLFWwindow * win, double x, double y )
{
    events.push( Event() );
    events.back().type = Event::EventType::MouseMoved; //Statyczny wektor przechowujący eventy, można to pominąć
    Mouse::position = glm::vec2( static_cast < float >( x ), static_cast < float >( y ) ); // to jest jakaś twoja zmienna statyczna
}

Przy inicjalizacji okna użyj tej funkcji:
C/C++
glfwSetCursorPosCallback( window, mousePos_callback );

glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );

Przykładowe sterowanie kamerą:
C/C++
glm::vec2 mouse = Mouse::position;
rX =( prevMouse.x - mouse.x );
rY =( - mouse.y + prevMouse.y );
camera.rotate( rX, rY );
prevMouse = mouse;

Edit:
Właściwie to to samo o czym pisał Deja Vu, w każdym razie powinieneś używać callbacka do ruchu myszą, a nie funkcji glfwGetCursorPos.
P-156782
Nazgul
Temat założony przez niniejszego użytkownika
» 2017-01-23 04:45:52
mmm kurczę, to dalej nie jest odpowiedź której oczekuję;)

znam tę funkcję, ona podobnie do glfwGetCursorPos(...) nie jest zabezpieczona przed przeciążeniem zmiennych;/

zabezpieczeniem przeciążenia tych zmiennych byłoby właśnie glfwSetCursorPos(..), tyle że w dokumentacji jest napisane, żeby nie używać tej funkcji do implementacji sterowania kamerą (co właśnie chcę zrobić).

Także, mam się nie przejmować tym przeciążeniem, bo to praktycznie niemożliwe, że ktoś(użytkownik programu) to przeciąży,
czy mam się nie przejmować informacją w dokumentacji i ją zignorować?
Czy jest 3 opcja?;)
P-156813
DejaVu
» 2017-01-23 15:10:18
Jeżeli ktoś Ci pisze 'nie rób tego' to niech napisze również 'czym to zrobić'.
P-156832
Nazgul
Temat założony przez niniejszego użytkownika
» 2017-01-24 13:45:30
No trudno, zdecydowałem się na zignorowanie komentarza w bibliotece(będę używał funkcji glfwSetCursorPos w implementacji funkcji kamery) i jeżeli faktycznie będą problemy, to wznowię temat;)
dziękuję za ciekawe artykuły oraz chęci
P-156855
« 1 »
  Strona 1 z 1