DirectX Input
Level 12 GRAFIKA KOMPUTER DAN ANIMASI
Adding Text to the Display
All About Fonts
Creating Fonts and Displaying Text
The Finished Program
Building a Game Display
A Too-Simple Wrapper for Sprites
Constructing the Radar
Constructing the Health Bar
Constructing the Ammo Indicator
The Finished Program
Simple Input
Reading the Keyboard
Reading the Mouse
The Finished Program
Raw Mouse Input
Initializing Raw Input
The WM_INPUT Message
Using the Data
The Finished Program
G
V-Sync and Mouse Lag
The Source of Mouse Lag
Disabling V-Sync
The Finished Program
Picking in Direct3D
The Picking Ray
Checking Intersection
Sekarang kita akan melihat cara untuk membaca
input
dari
keyboard
dan
mouse
, bagaimana cara
untuk menerapkannya dalam suatu
game
, dan
bagaimana membuatnya berinteraksi dengan baik
dalam lingkungan
game
Anda.
Pertama, kita akan mempelajari teknik sederhana
Suatu key state adalah status dari sebuah tombol (key), yakni apakah tombol tersebut ditekan atau tidak.
Untuk menentukan key state dari sebuah tombol
digunakan fungsi GetAsyncKeyState().
Suatu virtual key code adalah suatu code yang
ditetapkan pada suatu tombol tertentu di keyboard.
Selanjutnya bagaimana caranya untuk mengetahui sebuah tombol ditekan atau tidak?
Fungsi GetAsyncKeyState() mengembalikan suatu
SHORT bukan BOOL, karena fungsi ini
mengembalikan lebih banyak data ketimbang hanya apakah sebuah tombol ditekan atau tidak.
Untuk mengetahui sebuah tombol ditekan, kita cek
bit paling signifikan di dalam SHORT yang dikembalikan.
Kita AND-kan nilai yang dikembalikan dengan 0x8000 untuk mengetahui status sebuah key.
Sayangnya, menambahkan code di atas
terus-menerus dapat membuat code terlihat rumit.
Dapat dibuat macro untuk menyederhanakan
penulisannya sebagai berikut.
Dengan menggunakan macro ini, kita dapat dengan
mudah menentukan status sembarang key, seperti
Perhatikan bahwa tombol-tombol huruf dan angka tidak selalu diwakili nilai-nilainya sendiri.
Untuk menggunakannya, Anda memakai nilai
hexadecimal, seperti berikut. G
Membaca posisi tetikus (mouse) sangatlah mudah.
Kita akan gunakan fungsi GetCursorPos(), seperti
berikut. G
A struct that contains 2 int values, x and y
Kebanyakan game tidak menggunakan mouse position,
namun menggunakan mouse movement.
Solusi yang mudah dan kerap digunakan adalah
dengan membaca lokasi mouse, lalu memindahkan
mouse tersebut ke pusat layar.
Saat Anda membaca data mouse kembali, Anda dapat
memperoleh perubahan mouse, dibandingkan posisi
G -H A N S U N
Simple function to set the position of the mouse, the x and y coordinates
Selain fungsi input umumnya terdapat suatu API yang disebut Raw Input.
API ini direkomendasikan oleh Microsoft untuk
pembangunan game, yang dapat memberikan kendali
penuh untuk semua perangkat input.
Sekarang kita akan mempelajari cara memulai Raw
Input, dan bagaimana membaca pergerakan mouse
dengan menggunakan pesan WM_INPUT yang dihasilkan oleh Raw Input.
Sebelum menggunakan Raw Input, kita harus menginisialisasinya terlebih dahulu.
Kita harus memberitahu Windows perangkat mana
yang ingin kita kendalikan → mendaftarkan perangkat.
Untuk meregister suatu perangkat, kita gunakan fungsi RegisterRawInputDevices().
Sebelum memanggil fungsi ini, kita harus mengisi
struct untuk memberitahu apa yang akan diregister. G
A series of input devices, use ‘0x01’
A device within a usage page
Customization flags
Fungsi ini digunakan untuk meregister mouse dan memiliki 3 parameter.
Yang pertama adalah suatu pointer ke struct
RAWINPUTDEVICE yang telah dibuat sebelumnya.
Parameter kedua adalah jumlah perangkat yang
diregister (hanya 1 untuk contoh ini).
Terakhir adalah ukuran struct RAWINPUTDEVICE.
Dengan menggunakan fungsi ini, kita dapat
meregister beberapa perangkat sekaligus dengan
membuat suatu larik RAWINPUTDEVICE structs
G -H A N S U N
Setelah meregister perangkatnya, sekarang akan kita lihat cara membaca datanya.
Untuk membaca data di dalam Raw Input API, akan
digunakan WM_INPUT message.
Kapanpun terdapat input untuk ditangani dari API ini,
WM_INPUT message akan mengirimkannya pada
kita untuk digunakan.
Kita letakkan WM_INPUT message di dalam
G
A struct which will be filled with all the input information we want
Contains some general data that is sent every time there is any input
message, regardless of where it’s from
Fungsi ini merupakan fungsi utama yang paling
penting.
Memanggil fungsi ini akan mengisi RAWINPUT struct
kita dengan seluruh informasi dari suatu input event. G
Setelah mengisi RAWINPUT dengan informasi yang dibutuhkan, kita dapat menggunakannya untuk
memutar teapot dengan masukan dari mouse.
2 langkah:
1. Create a BOOL to keep track of the mouse
button’s state
2. It there is movement, rotate the teapot
Karena WM_INPUT message hanya akan
memberitahu kita kapan status mouse berubah, kita harus menyimpan record-nya sendiri.
Sekarang kita akan membahas topik permasalahan
yang kerap ditemui dalam games, bahkan yang
terbaik sekalipun.
Terdapat 2 permasalahan umum, yakni input lag dan
tearing.
Sekarang kita akan membahas V-Syncing dan
Istilah ini muncul sebelum era monitor LCD modern.
Pada masa CRT, images digambarkan dengan suatu
light-pin yang bergerak secara horizontal sepanjang layar dan zig-zag hingga mencapai bawah layar.
Setelah pin tersebut mencapai bawah layar, pin akan kembali ke atas dan mulai lagi dari awal.
Jeda waktu ini, saat tidak ada penggambaran, disebut dengan vertical sync, disingkat v-sync.
Di awal perkuliahan, kita telah membahas tearing dan
page swapping (page flipping).
Teknik page flipping ini dapat disebut juga v-sync, karena pertukaran terjadi pada saat jeda waktu
singkat ketika layar mempersiapkan dirinya kembali untuk menampilkan gambar lainnya ke layar.
Hal ini membuat frame rate tergantung pada refresh rate dari layar monitor Anda.
Sementara beberapa monitor memiliki refresh rate
akan selalu memiliki lag.
Namun, mouse di Windows umumnya bergerak dengan lancar, tanpa terdeteksi adanya lag.
Sinyal mouse dijalankan oleh Windows pada thread
terpisah, membaca informasi dari mouse tersebut dan segera menggantinya di layar monitor.
Kecepatan pemrosesannya tergantung pada kecepatan
mouse tersebut bergerak.
Setelah mouse mengirim informasi ke Windows, kursor
mouse baru segera digambarkan kembali di layar.
Ingat bahwa tidak seperti pada games, Windows tidak
58
Dalam sebuah game dimana mouse mengontrol suatu
camera, mesin mau tidak mau harus me-render kembali keseluruhan scene saat mouse digerakkan.
Akibatnya, pergerakan mouse dibatasi oleh frame rate
monitor, sehingga memperlambat update-rate mouse
tersebut.
Pada saat menghindari tearing, kita lakukan render pada
suatu back-buffer, dan saat monitor VSyncing, kita tukar
back dengan front buffer-nya.
Pada dasarnya, apa yang ditampilkan adalah data lama.
Saat render scene didasarkan pada pergerakan mouse, timbul mouse lag, karena gambar tersebut telah di-render
pada beberapa frame sebelumnya.
Solusi dari mouse lag adalah dengan menonaktifkan
V-Sync.
Caranya dengan menggunakan PresentationInterval, yang bertujuan mengatur hubungan antara refresh rate
monitor dan rate dimana Present() selesai.
60
Terdapat beberapa nilai untuk PresentationInterval, namun yang akan dijelaskan hanya 2.
1. D3DPRESENT_INTERVAL_DEFAULT
Menggunakan back buffer untuk membentuk suatu antrian
frames. Setelah 1 frame ditampilkan, frame berikutnya akan mengambil alih dan ditampilkan.
2. D3DPRESENT_INTERVAL_IMMEDIATE
Memberitahu DirectX untuk menggunakan back buffer, namun langsung melakukan pertukaran saat render gambar selesai. Artinya tidak ada time lag antara render completion
Jadi, sebuah game dapat memiliki tearing dan hampir tidak ada mouse lag, atau sebaliknya.
Mana yang lebih baik?
Umumnya gamers dapat lebih menerima tearing
ketimbang mouse lag, karena mouse lag dapat menimbulkan gangguan yang lebih besar.
Akibatnya, banyak games yang menyediakan V-Sync
sebagai option, dan default-nya disable.
Trik lain untuk mengurangi visibility tearing adalah
G -H A N S U N
Saat Anda menggunakan mouse pointer dalam sebuah
game, tentunya Anda harus tahu apa yang diklik oleh
player.
Dalam aplikasi 2D hal ini mudah, karena biasanya obyek disimpan dalam suatu bentuk faktor persegi dan Anda dapat dengan mudah menggunakan koordinat untuk menentukan apakah mouse diklik atau tidak.
Untuk 3D, mouse tidak diberikan dalam koordinat 3D, sehingga Anda tidak tahu apa yang Anda klik.
Namun, Direct3D menyediakan beberapa fungsi yang memungkinkan Anda menentukan apa yang diklik
76
Sebelum Anda menentukan apa yang diklik oleh
player, Anda harus membuat sebuah garis sepanjang 3D space yang merepresentasikan klik itu sendiri.
Pada gambar sebelah kanan, Anda dapat melihat
garis merah yang mewakili setiap titik dalam 3D
space yang diklik oleh user.
Garis ini disebut sebagai picking ray. G
Dengan menggunakan beberapa fungsi DirectX kita
dapat menggunakan ray ini untuk menentukan obyek
apa yang beririsan dengannya.
Pertama, ray tersebut harus dibuat dalam memory.
Dapat digunakan 2 buah structs D3DVECTOR3, yang
satu merepresentasikan posisi kamera, dan lainnya merepresentasikan arah mouse klik terhadap posisi kamera.
Kedua nilai ini akan disebut sebagai origin dan
direction.
Beberapa langkah untuk menghitung picking ray:
1. Get the current transform matrices, including
projection, view, and world
2. Convert the mouse coordinates into the mouse
angle
3. Find the inverse matrix
4. Use the inverse matrix to shift the origin and
Pertama kita harus memperoleh matriks-matriks
yang digunakan untuk me-render gambar 3D terakhir
(mesh).
Digunakan fungsi GetTransfrom() untuk mengambil
data dari video memory dan mengisi matriks dengan nilainya.
Untuk membuat sebuah garis yang merepresentasi-kan mouse klik, kita harus menemukan sudut garis tersebut dalam koordinat x dan y (z infinite).
Kita akan gunakan nilai float untuk
merepresentasi-kan dimana garis tersebut mengarah dalam viewing
frustum.
Jika Anda melihat viewing frustum dari kamera, maka terlihat seperti sebuah persegi panjang.
Untuk tujuan picking, kita akan scale “sudut”-nya
Pada bagian pertama persamaan di atas, terdapat ekspresi
(((2.0f * MousePos.x) / SCREEN_WIDTH) - 1.0f)
Ekspresi ini mengambil posisi mouse pada layar dan
mengubah skalanya menjadi antara -1 dan 1.
Di bagian kedua, kita bagi hasilnya dengan suatu cell dari matProjection.
X dibagi dengan cell (0,0) dan Y dibagi dengan cell (1,1). Nilai kedua cell merepresentasikan sudut dari viewing
Setelah memperoleh sudut picking ray, kita gunakan
84
Dalam rendering, kita mengambil titik-titik,
memindahkannya dalam dunia (world space), mengatur orientasinya agar sesuai dengan kamera (view space), dan me-resize-nya untuk memperlihatkan kedalaman
(projection space).
Dalam picking, kita lakukan hal sebaliknya.
Dimulai dengan menentukan lokasi dalam projection
space, kita harus melakukan un-resize menjadi view space,
un-orient menjadi world space, dan undo world transform
untuk mendapatkan model space.
Alasannya daripada meletakkan seluruh titik dalam
pipeline 2 kali, akan lebih cepat untuk meletakkan picking ray dalam pipeline sekali, namun berjalan secara backward.
Untuk meletakkan sesuatu dalam pipeline secara
backward, pertama harus didapatkan inverse matrix.
Inverse matrix dapat diperoleh dengan fungsi D3DXMatrixInverse() .
Perhatikan bahwa kita telah memfaktorkan projection
menjadi mouse’s angle, sehingga tidak perlu ditemukan lagi di sini.
Kita hanya akan melakukan inverse terhadap world
Untuk origin, kita gunakan
D3DXVec3TransformCoord(), yang mengambil
koordinat dan mengalikannya dengan suatu matriks.
Parameter pertamanya adalah pointer ke resulting
vector, parameter kedua adalah pointer ke original vector, dan parameter ketiga adalah pointer ke
matriksnya.
Kita lakukan hal yang serupa untuk direction, namun karena direction merupakan suatu normal, bukan
koordinat, maka digunakan fungsi D3DXVec3TransformNormal().
Fungsi ini akan mengubah direction menjadi model space.
Baris ketiga digunakan untuk menormalisasi direction, yang berarti kita ubah garis direction sehingga
Untuk melakukan picking diperlukan satu fungsi, yakni D3DXIntersect().
Meskipun fungsi ini memiliki banyak parameter,
kebanyakan parameter tersebut bersifat optional.
Kita hanya akan menggunakan 4 parameter pertama
Contoh pemanggilannya:
Jika dimanfaatkan parameter pHit:
http://directxtutorial.com/
http://www.highgraphic.com/thumbs-up-and-down-icons/
Other web resources. G