Menjebak mouse di dalam jendela di OpenGL dengan GLUT?

8

Saya sangat mengerti bahwa GLUT terbatas dan masalah berikut mungkin tidak dapat diselesaikan dengan OpenGL / GLUT, tetapi karena saya tidak tahu persis apakah itu bisa atau tidak, saya lebih baik bertanya. Mungkin saya melakukan sesuatu yang salah atau melupakan sesuatu yang penting. Atau mungkin tidak dan GLUT tidak lebih baik dari ini.

Masalah saya adalah saya tidak bisa menjebak mouse di dalam jendela. Sebenarnya saya bisa, kode di bawah tidak hanya itu. Saya menjebak mouse di dalam jendela dan saya dapat menggunakan mouse secara bebas untuk memutar dunia. Masalah? Jika saya menggerakkan mouse terlalu cepat saya bisa mendapatkan jalan dari penjara jendela.

Apakah ada cara untuk mengatasi hal ini dengan OpenGL / GLUT atau satu-satunya pilihan adalah pustaka lain atau langsung melakukan panggilan ke API Windows? Cukup kata-kata, ini kode saya saat ini:

void processPassiveMouseMotion(int x, int y) {
    static int centerX = glutGet(GLUT_WINDOW_WIDTH) / 2;
    static int centerY = glutGet(GLUT_WINDOW_HEIGHT) / 2;

    CameraAngle.x = -1.0f * (y - centerY);
    CameraAngle.y = -1.0f * (x - centerX);

    if(CameraAngle.x != 0.0f || CameraAngle.y != 0.0f) {
        SceneCamera.Rotate(CameraAngle);
        glutPostRedisplay();

        glutWarpPointer(centerX, centerY);
    }
}

glutPassiveMotionFunc(processPassiveMouseMotion);
rfgamaral
sumber

Jawaban:

7

Sepengetahuan saya ini adalah Windows-API khusus - fungsi ini bahkan tidak ada di semua platform. Jika Anda ingin menggali melalui kode saya, Anda dapat menemukan implementasi Windows yang berfungsi (LockMouseCursor adalah titik masuk ke dalam modul OS, ClipCursor adalah fungsi Windows sebenarnya yang melakukan trapping, tetapi ada beberapa sifat di sekitar fungsi itu - seharusnya tidak boleh terlalu sulit untuk diuraikan.)

Saya juga memiliki implementasi Linux di X murni (sekali lagi, mulai dengan LockMouseCursor) tapi saya belum pernah menemukan API OSX yang dapat digunakan untuk itu. Jika Anda akhirnya membutuhkan satu atau datang dengan satu, periksa pertanyaan Stackoverflow saya tentang masalah ini :)

ZorbaTHut
sumber
Terima kasih, saya akan mengingat posting ini sebagai referensi. Anda sedang berurusan dengan Windows API karena saya curiga menjadi satu-satunya cara yang baik untuk mencapai ini, tetapi saya tidak ingin menempuh rute itu. Bukannya saya tidak tahu caranya, karena saya melakukan apa yang telah saya lakukan sebelumnya, tetapi untuk apa yang saya lakukan, itu tidak ada masalah dan itu bukan prioritas.
rfgamaral
2

Dengan pencarian cepat melalui spesifikasi GLUT, GLUT tampaknya tidak memiliki kemampuan menangkap mouse. Yang terbaik yang dapat Anda lakukan (seperti yang tampaknya Anda lakukan) adalah untuk melengkung kursor ke pusat dan berharap pengguna tidak cukup cepat (atau tidak menggunakan tablet) =)

Atau, Anda dapat beralih ke SDL atau SFML , karena GLUT hanya dirancang untuk pengujian, bukan perangkat lunak "nyata".

Jari Komppa
sumber
Sementara saya setuju dengan komentar Anda secara umum, saya ingin sekali mendesak SDL karena oh man SDL memiliki masalah besar. SFML bagus, gunakan itu!
ZorbaTHut
Mereka berdua memiliki sisi mereka, dan saya suka SDL, jadi .. =)
Jari Komppa
1
Tolong jangan salah paham, tapi, ini kali kedua Anda menyuruh saya untuk pindah. Meskipun saya menghargai jawaban siapa pun, jika saya bersikeras memposting pertanyaan spesifik GLUT, mungkin saya punya alasan bagus untuk hal ini dan tidak bisa beralih? Saya sudah menyadari bagaimana GLUT menyebalkan, tapi saya harus tahan dengan itu, itu bukan pilihan saya. Maaf jika saya terdengar kasar, tapi saya benci ketika orang bersikeras seperti ini, saya "mendengar" Anda pertama kali.
rfgamaral
Saya memilih jawaban Anda karena saya mengabaikan paragraf terakhir. :)
rfgamaral
2
Nazgulled, maaf jika saya sepertinya mengulangi hal-hal, saya tidak benar-benar melacak pertanyaan siapa yang saya jawab =). Selain itu, orang akhirnya akan menemukan pertanyaan ini melalui pencarian, dan saya juga ingin menjawabnya, tidak hanya untuk Anda.
Jari Komppa
2

Coba freeglut versi yang lebih baru; V2.6 saya, menjebak kursor dengan glutWarpPointer tanpa ada kemungkinan untuk melarikan diri dengan mouse.

Palax
sumber
1

Dalam kasus saya, modifikasi

glutWarpPointer(centerX, centerY);

untuk sesuatu seperti

if (x != centerX || y != centerY) glutWarpPointer(centerX, centerY);

memecahkan masalah dengan sempurna.

Masalahnya disebabkan oleh glutWarpPointer memicu peristiwa gerakan pasif lain ke (centerX, centerY), yang menghasilkan loop dan / atau membanjiri antrian acara. Untuk menghindarinya, cukup periksa apakah mouse berada di (centerX, centerY), jika demikian, jangan melengkung.

Giumo
sumber