Beginning DirectX9
Lời giới thiệu
PHẦN I. NHỮNG KIẾN THỨC NỀN TẢNG
Chương 1. DirectX là gì, tại sao và làm thếnào đểsửdụng nó
Chương 2. Ví dụ đầu tiên sửdụng DirectX
Chương 3. Phông nền, khung hình, hoạt cảnh.
PHẦN II. NHỮNG THÀNH PHẦN CƠ BẢN CỦA MỘT THẾ GIỚI 3D
Chương 4. Những kiến thức cơbản về3D
Chương 5. Ma trận, các phép biến đổi và phép xoay trong không gian
Chương 6. Bảng mầu, vật liệu phủvà ánh sáng trong không gian
Chương 7. Chia nhỏvà làm mịn đối tượng
Chương 8. Vật thể, điểm chèn và các hiệu ứng
PHẦN III. NHỮNG KIẾN THỨC BỔ XUNG
Chương 9.Sửdụng DirectInput
Chương 10.Hiệu ứng âm thanh bằng DirectSound
Chương 11.Xây dựng một dựán mẫu
PHẦN IV. PHỤ LỤC
Phụlục A.Giải đáp các bài tập cuối các chương
Phụlục B.Cách sửdụng CD-ROM
Giải thích các thuật ngữ
Chỉmục các từkhoá
rong hàm Lock. - dwAudioBytes2. Số bytes viết vào pvAudioPtr2. Đọc từ dữ liệu âm thanh vào bộ đệm Đọc dữ liệu âm thanh vào bộ đệm thứ cấp (secondary buffer) có thể rất phức tạp. Để giải thích dễ hiểu hơn, tỗi sẽ giải thích quá trình này qua lớp CWaveFile trong các lớp DS framework. DS Framework cung cấp một cách đơn giản để load dữ liệu âm thanh sử dụng định dạng file WAV. Đây là định dạng âm thanh mặc định của Windows, có đuôi là WAV. Chú ý: Các lớp DS framework được khai báo trong file dsutil.cpp và dsutil.h, cung cấp các hàm chung gắn liền với DS. Bạn có thể tìm thấy chúng trong thư mục Samples\C++\Common\Src và Samples\C++\Common\Inc, trong folder mà bạn đã cài DirectX Software Development Kit (SDK). Bước đầu tiên trong việc load một file WAV vào bộ đệm là tạo một đối tượng CWaveFile. Đối tượng này cung cấp cho bạn các phương thức để mở, đóng và đọc một files WAV. Dòng code sau chỉ ra cách tạo một đối tượng CWaveFile. CWaveFile wavFileObj = new CWaveFile( ); Tiếp theo, sử dụng phương thức Open được cung cấp bởi lớp CWaveFile, bạn có thê nhận quyền truy cập vào file WAV bạn muốn dùng. Đoạn code sau sử dụng hàm Open và kiểm tra xem file WAV có chứa dữ liệu ko? // Mở 1 file dạng WAV có tên test.wav wavFile->Open(“test.wav”, NULL, WAVEFILE_READ ); // Kiểm tra để chắc chắn kích thước dữ liệu trong file là hợp lệ if( wavFile->GetSize( ) == 0 ) return false; Đoạn code trên mở một file tên là test.wav để đọc. Sau đó nó kiểm tra kích thước của dữ liệu bên trong file, nếu file ko chứa dữ liệu, nó dừng việc đọc. Bước tiếp theo là tạo một bộ đệm thứ cấp (secondary buffer) để chứa dữ liệu. Bước này đã được hướng dẫn ở trên. Sau khi tạo bộ đệm, bạn phải khoá(lock) nó trước khi bạn có thể viết dữ liệu WAV vào nó. Đoạn code tiếp theo giải thích cách dùng hàm Lock để chuẩn bị một bộ đệm đọc toàn bộ một file WAV. Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 174 HRESULT hr; VOID* pDSLockedBuffer = NULL; // con trỏ tới vùng nhớ bộ đệm bị khoá DWORD dwDSLockedBufferSize = 0; // kích thước bộ đệm DS bị khoá // Bắt đầu từ phần đầu của bộ đệm hr = DSBuffer->Lock( 0, // Nhận một bộ đệm 64000 bytes 64000, // Biến này lưu một con trỏ tới phần mở đầu // của bộ đệm &pDSLockedBuffer, // Biến này lưu kích thước của bộ đệm bị khoá &dwDSLockedBufferSize, NULL,// Ko cần cái thứ hai NULL, // Ko cần cái thứ hai // Khoá cả bộ đệm DSBLOCK_ENTIREBUFFER); // Kiểm tra code trả về để chắc chắc lock // thành công if FAILED (hr) return NULL; Đoạn code trên lock một bộ đệm bằng cờ DSBLOCK_ENTIREBUFFER. Cờ này khiến bộ đệm bị lock toàn bộ. Biến DSBuffer phải là một DirectSoundBuffer hợp lệ. Giờ bộ đệm đã được lock đúng, bạn có thể ghi dữ liệu WAV vào nó. Một lần nữa tôi lại dùng phương thức có trong lớp CWaveFile. Trước khi bạn đọc dữ liệu WAV vào bộ đệm, bạn phải reset lại dữ liệu WAV về phần đầu. Bạn làm điều này bằng cách dùng phương thức ResetFile. Tiếp theo bạn dùng phương thức Read để đưa dữ liệu WAV vào bộ đệm. Đoạn code tiếp theo reset lại file WAV để đọc và đưa dữ liệu vào bộ đệm. HRESULT hr; // biến lưu kết quả trả lại DWORD dwWavDataRead = 0; // biến chứa lượng dữ liệu đọc từ file // WAV wavFile->ResetFile( ); // Reset lại file WAV về đầu file // Đọc file hr = wavFile->Read( ( BYTE* ) pDSLockedBuffer, dwDSLockedBufferSize, &dwWavDataRead ); // Kiểm tra để chắc chắn đã thành công if FAILED (hr) return NULL; Biến wavFile phải chứa một đối tượng CWaveFile hợp lệ trước khi sử dụng. Đầu tiên, hàm ResetFile được gọi, tiếp theo là lời gọi hàm Read. Hàm Read cần ba tham số. Tham số thứ nhất là con trỏ tới vùng bộ nhớ Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 175 chứa bộ đệm để copy dữ liệu vào. Tham số tiếp theo là kích thước của vùng bộ đệm đã khoá, tham số cuối nhận khối lượng dữ liệu đọc từ file WAV, tính bằng bytes. Sau khi gọi hàm Read, bộ đệm được điền bằng dữ liệu từ file WAV. Bạn giờ đây có thể an toàn mở khoá bộ đệm. Play âm thanh trong bộ đệm Giờ bạn đã có dữ liệu âm thanh hợp lệ chứa trong DirectSoundBuffer, bạn có thể play dữ liệu mà nó chứa. Sau toàn bộ các công việc cần để tạo bộ đệm và điền dữ liệu vào đó, giừo việc play nó rất đơn giản. Một hàm đơn giản là Play hoàn thành việc này. Hàm này là một phương thức cung cấp bởi đối tượng DirectSoundBuffer. Nó như sau: HRESULT Play( DWORD dwReserved1, DWORD dwPriority, DWORD dwFlags ); Hàm này cần ba tham số: - dwReserved1. Một giá trị để dành trước phải là 0. - dwPriority. Mức độ ưu tiên để play âm thanh. Nó có thể là bất cứ giá trị nào trong khoảng 0 và 0xFFFFFFFF. Bạn phải đặt mức độ ưu tiên về 0 nếu cờ DSBCAPS_LOCDEFER chưa được bật khi bộ đệm được tạo ra. - dwFlags. Các cờ chỉ rõ âm thanh sẽ được play thế nào? Cờ duy nhất tôi sẽ giải thích ở đây là DSBPLAY_LOOPING. Cờ này khiến âm thanh lặp lại khi đạt đến cuối bộ đệm. Nếu âm thanh chỉ nên play một lần, tahm số dwFlags nên được truyền giá trị 0. Đoạn code dưới đây khiến 1 bộ đệm âm thanh play nội dung của nó: DSBuffer->Play( 0, 0, DSBPLAY_LOOPING); Biến DSBuffer phải chứa một đối tượng DirectSoundBuffer hợp lệ, chứa dữ liệu. Trong trường hợp này, cờ DSBPLAY_LOOPING được truyền vào hàm khiến âm thanh lặp lại sau khi hoàn thành một lượt. Dừng âm thanh Thường sau khi play âm thanh, bạn ko cần lo gì nữa, trừ khi bạn bảo âm thanh lặp lại. Trong trường hợp này, bạn cần ra lệnh dừng âm thanh. Bạn làm điều này nhờ phương thức Stop, cung cấp bởi đối tượng DirectSoundBuffer, như sau: HRESULT Stop( ); Hàm này ko cần tham số. Nó chỉ trả lại một kết quả cho biết hàm được gọi thành cồng hay ko? Bạn có thể tìm thấy một ví dụ đầy đủ về load một file âm thanh và play nó trong thư mục chapter10\example2 trên đĩa. Sử dụng các điều khiển của bộ đệm(buffer control) Như đã đề cập, bộ đệm DS có thể điều khiển diện mạo của những âm thanh trong nó. Ví dụ, qua một bộ đệm, bạ có thể thay đổi âm lượng, tần Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 176 số, hoặc pan(chỉnh âm lượng giữa hai loa) một âm thanh. Trong đoạn này bạn sẽ học cách dùng chúng. Thay đổi âm lượng Bạn có thể thay đổi âm lượng của âm thanh qua bộ đệm chứa nó. Bạn có thể điều chỉnh âm lượng trong khoảng giá trị DSBVOLUME_MIN và DSBVOLUMEMAX. Giá trị DSBVOLUME_MIN miêu tả im lặng và DSBVOLUME_MAX miêu tả âm lượng gốc của âm thanh. Chú ý: DS ko hỗ trợ khuếch đại âm, vì vậy bạn ko thể tăng âm lượng được. Bạn có thể điều chỉnh âm lượng của âm thanh qua hàm SetVolume như sau: HRESULT SetVolume ( LONG lVolume ); Hàm này chỉ cần một tham số: lVolume. Bạn có thể cho giá trị của nó từ - 10000(DSBVOLUME_MIN) và 0(DSBVOLUME_MAX). Bạn cũng có thể nhận giá trị âm lượng mà một âm thanh đang được play bằng hàm Getvolume. Hàm này như sau: HRESULT GetVolume ( LPLONG plVolume ); Hàm này cũng chỉ cần một tham số, là một con trỏ tới một biến sẽ nhận giá trị âm thanh hiện tại. Chú ý: Trước khi dùng hai hàm trên, bạn phải thiết lập bộ đệm cho phép dùng chúng, bằng cách bật cờ DSBCAPS_CTRLVOLUME trong cấu trúc DSBUFFERDESC khi bạn tạo bộ đệm thứ cấp (secondary buffer). Panning âm thanh(chỉnh âm lượng giữa hai loa) Bộ đệm DS cho phép một âm thanh được pan giữa hai loa. Pan là giảm âm lượng một loa và tăng ở bên kia. Âm thanh nghe như di chuyển vậy. Pan dùng một tư tưởng chung như hàm SetVolume. Loa trái và loa phải có thể tăng hoặc giảm âm lượng phụ thuộc hai giá trị: DSBPAN_LEFT và DSBPAN_RIGHT. Giá trị đầu DSBPAN_LEFT, tương đương -10000, tăng âm lượng của loa trái tới full, trong khi làm im loa kia. Và giá trị DSBPAN_RIGHT, tương đương 10000, tăng âm lượng loa phải trong khi làm câm loa trái. Bằng cách dùng giá trị giữa DSBPAN_LEFT và DSBPAN_RIGHT, âm thanh có thể bị pan từ một loa sang loa kia. Một giá trị thứ ba, là DSBPAN_CENTER, bằng 0, chỉnh cả hai tới full âm lượng. Giá trị pan âm thanh có thể được đặt bằng hàm SetPan, như sau: HRESULT SetPan( LONG lPan Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 177 ); Hàm này chỉ cần một tham số: lPan, nhận giá trị giữa DSBPAN_LEFT và DSBPAN_RIGHT(-10000->10000). Nếu bạn muốn biết giá trị pan hiện tại, bạn dùng hàm GetPan: HRESULT GetPan( LPLONG plPan ); Hàm này cũng chỉ cần một tham số: plPan, là con trỏ tới một biến LONG nhận giá trị pan hiện tại. Chú ý: Trước khi dung hai hàm này, bạn phải thiết lập bộ đệm cho phép dùng. Bạn cần đặt cờ DSBCAPS_CTRLPAN trong cấu trúc DSBUFFERDESC khi tạo bộ đệm. Tổng kết chương Dùng những gì vừa học, bạn có thể play nhạc nền hoặc các hiệu ứng âm thanh đơn giản cho game. Bạn có thể mở rộng bài học này để play nhiều âm thanh đồng thời, hay tạo các nhạc động, có thể sửa và điều khiển trong game. Trong chương sau, chúng ta sẽ đặt những thứ đã học với nhau để tạo một game đơn giản sử dụng mỗi phần đã nói trong sách. Những thứ bạn đã học Trong chương này, bạn đã học: - DS dùng thế nào? - Có những kiểu bộ đệm nào? - Liệt kê các thiết bị âm thanh đã có trong hệ thống. - Load và Play một file WAV. - Điều khiển sự phát lại(playback) của một file âm thanh. Câu hỏi ôn tập Bạn có thể tìm câu trả lời trong phụ lục A “Answers to End-of-Chapter Exercises”. 1. Khi nào bạn cần dùng hàm DirectSoundEnumerate? 2. Ba mẩu dữ liệu quan trọng nào được truyền cho hàm callback liệt kê?(enumeration callback function)? 3. Định dạng của một bộ đệm có cần giống định dạng của dữ liệu nó chứa ko? 4. Mục đích bộ đệm sơ cấp (primary buffer)? 5. Giá trị nào được truyền cho hàm DirectSoundCreate8 để chỉ rõ thiết bị âm thanh mặc định được dùng? Về phần bạn 1. Viết một cí dụ cho phéo điều chỉnh âm lượng âm thanh khi đang play nó? 2. Viết một ví dụ nhỏ cho phép âm thanh pan sử dụng các phím mũi tên. Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 178
File đính kèm:
- Beginning DirectX9.pdf