無法播放電影

無法播放電影

近日發現有些電影有像無音.提示如下

無法播放該影訊.

DirectX驅動程式未正確安裝或音效裝置被停用.

在渲染下列Pin時失敗了

Built-in AVI<->AC3/DTS::XForm Out

其實這類播放器均用DirectPlay解碼.下載PotPlayer codec安裝解碼器:

解碼元件 文檔
Core Files FFmpegMininum64.dll
OpenCodec Files OpenCodecUnity64.dll
FFmpeg Files FFmpeg64.dll
Inter H.264 MVC Decoder Libmfxsw64.dll

 

FPS第一人稱視角射擊遊戲

是時候將之前所學OpenGL/DirectX知識粘合成一完整遊戲.最簡單是『第一人稱視角射擊遊戲』FPS(First-person Shooter). 通過控制『準星』描准『怪物』按滑鼠左鍵發射『飛彈』.若擊中便會『爆炸』並擊殺『怪物』,其實它會在另地在生.若擊中地面則會『爆炸』.按鍵盤上下鍵在山地中前後移動.若近距離接近『怪物』它會另轉面自動走開(AI部分). 所有『怪物』與『飛彈』都是MD2模型.按ESC鍵退出遊戲.下載FPS:

下面所需要文章與代碼:

  1. AI之行走
  2. 準星
  3. 粒子爆炸特效
  4. 邊界球
  5. MD2文檔讀取與解析
  6. WAV音檔分釋與讀取
  7. DirectSound3D
  8. DirectInput之查詢滑鼠
  9. DirectInput之查詢鍵盤
  10. 粒子系統
  11. 廣告牌
  12. 紋理地形
  13. 天幕
  14. 紋理映射

DirectX SDK下載與設定

DirectX SDK下載與設定

DirectX本是用於取替OpenGL給遊戲廠商使用.但遊戲廠商集體反抗.才另microsoft支持OpenGL.而且自DirectX6全面使用COM模型開發.DirectX是設計用於『影片』『聲音』『輸入』『網絡』抽象軟件界面結口.DirectX接口由microsoft定義.而底層則有驅動程式與硬件進行通信.開發者完全無需理會硬件之間差異.如果硬件不支持則由DirectX進行模擬.

  1. DirectX SDK 下載『DirectX Software Development Kit
  2. 下載『exe』運行後自動進行解壓.
  3. 其實你只需要『Lib』與『Include』這兩個『資料夾』.『Lib』下面分別有『x86』與『x64』
  4. 接下來讓工程生成『DirectX』目錄並複製『Lib』與『Include』下所有『頭文檔』與『庫文檔』
  5. 包含『頭文檔』

#include “..\DirectX\Include\ddraw.h”

#include “..\DirectX\Include\dinput.h”

#include “..\DirectX\Include\dsound.h”

  1. 包含『庫文檔』你編譯時需要分開x86與x64的LIB文檔

#ifdef  _WIN64

#pragma comment(lib, “DirectX\Lib\x64\ddraw.LIB”)

#pragma comment(lib, “DirectX\Lib\x64\dinput8.LIB”)

#pragma comment(lib, “DirectX\Lib\x64\dxguid.LIB”)

#pragma comment(lib, “DirectX\Lib\x64\dsound.LIB”)

#else

#pragma comment(lib, “DirectX\Lib\x86\ddraw.LIB”)

#pragma comment(lib, “DirectX\Lib\x86\dinput8.LIB”)

#pragma comment(lib, “DirectX\Lib\x86\dxguid.LIB”)

#pragma comment(lib, “DirectX\Lib\x86\dsound.LIB”)

#endif

 

上面方法是指定工程目錄.令外你還可制定Visual Studio搜索目錄:

  1. 設定『項目』『屬性』『VC++目錄』.然後分別設定『Include目錄』與『程式庫目錄』
  2. 『Include目錄』包含『D:\ DirectX\Include』.
  3. Win32平臺『程式庫目錄』包含『D:\DirectX\Lib\x64』
  4. Win64平臺『程式庫目錄』包含『D:\DirectX\Lib\x86』
  5. 在包含『頭文檔』與『庫文檔』時無需設定相對路徑

 

在DirectX8之前分別使用DirectSound和DirectMusic處理音頻播放. DirectSound用于處理聲波回放和捕足,而DirectMusic則是加載和播放所有聲音主要組件.但在DirectX8之後合平DirectXAudio組件.若你需要播放MIDI睇『DirectMusic之播放MIDI

 

 

 

DirectMusic之播放MIDI

DirectMusic之播放MIDI

DirectMusic主要用於播放midi數據,而且你無需寫分析器.DirectMusic自動完成所有操作,本.演示程式按ALT鍵彈出MENU再Open打開midi音檔.按+/-鍵控制音量.本想編譯X64版本卻出現『REGDB_E_CLASSNOTREG Class not registered.』所以只有x86程式下載:

DirectMusic是建基於DirectSound,不過DirectMusic會在Init()中自啟動它.DirectMusic是Dirext中第一個完全COM化組件,所以DirectMusic無需LIB庫.只需以下幾個頭文檔.

#include “..\DirectX\Include\dmplugin.h”

#include “..\DirectX\Include\dmksctrl.h”

#include “..\DirectX\Include\dmusici.h”

#include “..\DirectX\Include\dmusicc.h”

#include “..\DirectX\Include\dmusicf.h”

但安裝最新DXSDK安裝包(DX11),以上幾文件頭文件據然穩唔倒.我只可在舊版SDK拷貝過來工程文檔下.如果你把文檔拷貝到工程檔案下還需要小小修改#include <dmplugin.h>改為#include “dmplugin.h”

而編譯時DirectMusic有大量GUID無法鏈接.出現LNK2001下錯誤.

“錯誤  LNK2001        無法解析的外部符號 _CLSID_DirectMusicPerformance”

古計是從”dxguid.lib”刪除左.無需執著這些小問題.只要自已加上即可.你需要初此化GUID宏指令

#define INIT_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)   const GUID name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}

並把下面GUID複製到全域變量

INIT_GUID(CLSID_DirectMusicPerformance, 0xd2ac2881, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicSegment,     0xd2ac2882, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicSegmentState,0xd2ac2883, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicGraph,       0xd2ac2884, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicStyle,       0xd2ac288a, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicChordMap,    0xd2ac288f, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicComposer,    0xd2ac2890, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicLoader,      0xd2ac2892, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(CLSID_DirectMusicBand,        0x79ba9e00, 0xb6ee, 0x11d1, 0x86, 0xbe, 0x0, 0xc0, 0x4f, 0xbf, 0x8f, 0xef);

INIT_GUID(GUID_Download,            0xd2ac28a7,0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(GUID_Unload,              0xd2ac28a8,  0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(GUID_StandardMIDIFile,    0x6621075, 0xe92e, 0x11d1, 0xa8, 0xc5, 0x0, 0xc0, 0x4f, 0xa3, 0x72, 0x6e);

INIT_GUID(GUID_DirectMusicAllTypes, 0xd2ac2893, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(GUID_PerfMasterVolume,    0xd2ac28b1, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicLoader, 0x2ffaaca2, 0x5dca, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);

INIT_GUID(IID_IDirectMusicGetLoader, 0x68a04844, 0xd13d, 0x11d1, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);

INIT_GUID(IID_IDirectMusicObject, 0xd2ac28b5, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicSegment, 0xf96029a2, 0x4282, 0x11d2, 0x87, 0x17, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicSegmentState, 0xa3afdcc7, 0xd3ee, 0x11d1, 0xbc, 0x8d, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xeb);

INIT_GUID(IID_IDirectMusicPerformance, 0x7d43d03, 0x6523, 0x11d2, 0x87, 0x1d, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicGraph, 0x2befc277, 0x5497, 0x11d2, 0xbc, 0xcb, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xeb);

INIT_GUID(IID_IDirectMusicStyle, 0xd2ac28bd, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicChordMap, 0xd2ac28be, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicComposer, 0xd2ac28bf, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicBand, 0xd2ac28c0, 0xb39b, 0x11d1, 0x87, 0x4, 0x0, 0x60, 0x8, 0x93, 0xb1, 0xbd);

INIT_GUID(IID_IDirectMusicLoader8, 0x19e7c08c, 0xa44, 0x4e6a, 0xa1, 0x16, 0x59, 0x5a, 0x7c, 0xd5, 0xde, 0x8c);

INIT_GUID(IID_IDirectMusicPerformance8, 0x679c4137, 0xc62e, 0x4147, 0xb2, 0xb4, 0x9d, 0x56, 0x9a, 0xcb, 0x25, 0x4c);

INIT_GUID(IID_IDirectMusicSegment8, 0xc6784488, 0x41a3, 0x418f, 0xaa, 0x15, 0xb3, 0x50, 0x93, 0xba, 0x42, 0xd4);

INIT_GUID(IID_IDirectMusicSegmentState8, 0xa50e4730, 0xae4, 0x48a7, 0x98, 0x39, 0xbc, 0x4, 0xbf, 0xe0, 0x77, 0x72);

INIT_GUID(IID_IDirectMusicStyle8, 0xfd24ad8a, 0xa260, 0x453d, 0xbf, 0x50, 0x6f, 0x93, 0x84, 0xf7, 0x9, 0x85);

接口對像 簡介
IDirectMusic 你無需自已創建DirectMusic,因為她會自動創建
IDirectMusicPerformance 對MIDI播放進行控制,構建該對象時同時創建IDirectMusic
IDirectMusicLoader 用於加載音頻文檔,如MIDI.這樣你以擁有MIDI的載入器
IDirectMusicSegment Segment代表音樂數據塊
IDirectMusicSegmentState 數據塊狀態
IDirectMusicProt MIDI音樂輸出硬件設備.微軟合成器
IDirectMusic 擁有一個DSP(Digital Signal Processing)MIDI數字實時轉換器

下面是IDirectMusic播放MIDI代碼簡介:

1.首先你必須初此化COM

CoInitialize(NULL);

2.創建DirectMusicPerformance接口

IDirectMusicPerformance    *DirectMusic_Performance = NULL;

CoCreateInstance(CLSID_DirectMusicPerformance,NULL, CLSCTX_INPROC,             IID_IDirectMusicPerformance,(LPVOID*)&DirectMusic_Performance);

3.初此化 DirectMusicPerformance設置為audiopath,自動構建IDirectMusic和IDirectSound接口

DirectMusic_Performance->Init(NULL, NULL, hWnd);

4.增加數字輸出播放端口,使用微軟合成器作為默認設備

DirectMusic_Performance->AddPort(NULL);

5.創建MIDI載入器

IDirectMusicLoader  * DirectMusic_Loader = NULL;

CoCreateInstance(CLSID_DirectMusicLoader,NULL,CLSCTX_INPROC,                   IID_IDirectMusicLoader8,(LPVOID*)&DirectMusic_Loader);

6.你需要在初此化時設定音量

long volume = DMUS_VOLUME_MAX;

DirectMusic_Performance->SetGlobalParam(GUID_PerfMasterVolume, &volume, sizeof(long));

7.載入midi音檔. DirectMusic非常聰面.你只需給出『路徑』和『文檔名』即可完成MIDI載入

DMUS_OBJECTDESC objdesc;

memset(&objdesc, 0, sizeof(DMUS_OBJECTDESC));// 清零

objdesc.dwSize = sizeof(DMUS_OBJECTDESC);

objdesc.guidClass = CLSID_DirectMusicSegment;

objdesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME;

8.Utf8轉換為UNICODE寬字符

MultiByteToWideChar(CP_UTF8, NULL, filename, (int)strlen(filename), objdesc.wszFileName, DMUS_MAX_FILENAME);//文檔名

MultiByteToWideChar(CP_UTF8, NULL, category, (int)strlen(category), objdesc.wszCategory, DMUS_MAX_CATEGORY);//路徑

9.設置當前搜索目錄

hResult = DirectMusic_Loader->SetSearchDirectory(GUID_DirectMusicAllTypes, objdesc.wszCategory, false);

10.如果MIDI音檔編譯進資源文檔(resource)或者自已讀取MIDI音檔數據

objdesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_MEMORY;

objdesc.pbMemData = data;//指向midi數據

objdesc.llMemLength = size;// 數據長度

11.獲取IDirectMusicSegment音色庫接口,並自動載入midi數據

IDirectMusicSegment      * segment;

DirectMusic_Loader->GetObject(&objdesc,IID_IDirectMusicSegment,(void**)&segment);

12.指定音色庫segment

segment->SetParam(GUID_StandardMIDIFile,-1,0,0,DirectMusic_Performance);

13.將音色庫segment載入到IDirectMusicPerformance

segment->SetParam(GUID_Download, -1, 0, 0, DirectMusic_Performance);

14.設置循環播放

segment->SetRepeats(DMUS_SEG_REPEAT_INFINITE);

15.單次循環播放

midi->segment->SetRepeats(0);

16.終於可以播放MIDI音檔

IDirectMusicSegmentState * segstate;

DirectMusic_Performance->PlaySegment(segment,0,0, &segstate);

17.停止MIDI播放

DirectMusic_Performance->Stop(segment, NULL, 0, 0);

18.禦載DLS樂器段

segment->SetParam(GUID_Unload, -1, 0, 0, (void*)DirectMusic_Performance);

19.釋放指定MIDI音樂段.

segment->Release();

20.停止播放所有的MIDI音樂段

DirectMusic_Performance->Stop(NULL,NULL, 0, 0);

21.關閉IDirectMusicPerformance對像.

DirectMusic_Performance->CloseDown();

22.釋放IDirectMusicPerformance對像.

DirectMusic_Performance->Release();

23.釋放載入器.

DirectMusic_Loader->Release();

DirectSound之播放聲音

DirectSound之播放聲音

DirectSound顧明思義可以讓你控制聲卡播放聲音和音樂. DirectSound由許多模塊和接口組成,編譯時需要庫文檔DSOUND.LIB和頭文檔DSOUND.H

WAV音檔播放演示程式,按+/-鍵控制聲音音量.按Open載入WAV音檔:下載

1.啟動DirectSound

IDirectSound接口:DirectSound的主COM對象.它代表聲卡硬件.若你裝有多個聲卡,則每個DirectSound對象代表一個聲卡.創建主聲卡對象,輸入NULL與默認聲卡鏈接

LPDIRECTSOUND       direct_sound;

DirectSoundCreate(NULL,&direct_sound,NULL);

if (direct_sound == NULL)

return false;

2.設置默認協作等級

設定遊戲控制聲卡的等級.一般設定為DSSCL_NORMAL即可.當程式具有焦點時,即可播放聲音.但並不妨礙其它程式. DirectSound自動創建22kHz,立體聲,8bit主緩存(默認).hWnd為當前窗口句柄

direct_sound->SetCooperativeLevel(hWnd,DSSCL_NORMAL);

參數 簡介
DSSCL_NORMAL 默認等級
DSSCL_PRIORITY 優先等級.允許設定主緩存數據格式
DSSCL_EXCLUSIVE 當窗口在前臺時擁有優先等級
DSSCL_WRITEPRIMARY 完全控制主緩存

3.輔助(二級)音頻緩存

『輔助緩存』即代表你想播放的音頻.但聲卡上SRAM卻容量有限,而且我印象中只在ISA版CREATIVE(創新)聲卡有出現.『輔助緩存』分為『靜態緩存』與『動態緩存』.『靜態緩存』用於存儲經常播放短聲音.『動態緩存』用於存儲較長聲音.DirectSound不斷播放不斷把音頻數據寫入『輔助緩存』.使用稱為Circular Buffering(環形緩存)結構,一個指針寫入音頻數據,另一個指針讀取音頻數據.創建輔助聲音緩衝器

HRESULT IDirectSound::CreateSoundBuffer(

LPCDSBUFFERDESC lpcDSBufferDesc,

LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer,

IUnknown FAR* pUnkOuter

);

4.設置緩存格式描敘,單聲道11kHz,8bit

AVEFORMATEX format;

format.cbSize = 0;//高級,總是0.

format.wFormatTag = WAVE_FORMAT_PCM;//PCM編碼

format.nChannels = 1;//(聲道數目)1為單聲道播放

format.nSamplesPerSec = 11025;// 樣本速度11kHz

//設置字節對齊.

//單聲道乘以1字節(8Bit), 它將是1字節字節對齊.

//立體聲它將是雙聲道8Bit, 它將是2字節字節對齊.

//如果它是立體聲系統和16Bit它將是4字節對齊.

format.nBlockAlign     = 1;

format.wBitsPerSample = 8;//聲言位數為8BIT

format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign;// 每秒字節

3.設定聲音緩沖存儲器描敘表

DSBUFFERDESC buffer;// 描述結構

memset(&buffer,0,sizeof(DSBUFFERDESC));// 清零

buffer.dwSize = sizeof(DSBUFFERDESC);// 結構所占空間

//設置DirectSoundBuffer的描述結構的標誌

buffer.dwFlags = DSBCAPS_CTRLPAN | // 緩存擁有總控制功能

DSBCAPS_CTRLVOLUME | // 緩存擁有音量控制功能

DSBCAPS_CTRLFREQUENCY; // 緩存擁有頻率控制功能

buffer.dwBufferBytes = sound_size;//聲音數據大小.

buffer.lpwfxFormat  = &format;//”WAV文件格式描述結構”

4.創建輔助(二級)音頻緩存

LPDIRECTSOUNDBUFFER sound_buffer;

direct_sound->CreateSoundBuffer(&buffer, &sound_buffer, NULL);

if (sound_buffer == NULL)

return false;

5.鎖住緩存

UCHAR *audio_ptr_1 = NULL, //指向緩存第一部分

UCHAR *audio_ptr_2 = NULL; //指向緩存第二部分

DWORD  audio_len_1 = 0,  //第一緩存長度

DWORD  audio_len_2 = 0;  //第二緩存長度

sound_buffer->Lock(0,//寫入指針指向位置

sound_size,//要鎖定大小,音頻數據長度.

(void **)&audio_ptr_1,//第一個部分開始地址.

&audio_len_1,//第一個部分長度

(void **)&audio_ptr_2,//第二個部分開始地址.

&audio_len_2,//第二個部分長度

DSBLOCK_FROMWRITECURSOR);// 緩存當前寫入點將被鎖住.

6.拷貝到環形緩存第一部分, sound_size為音頻數據

memcpy(audio_ptr_1, sound_data, audio_len_1);

7.拷貝到環形緩存第二段中

memcpy(audio_ptr_2, (sound_data + audio_len_1), audio_len_2);

8.解鎖

sound_buffer->Unlock(audio_ptr_1,audio_len_1,audio_ptr_2,audio_len_2);

9.循環播放聲音

sound_buffer->Play(0,0,DSBPLAY_LOOPING);

10.若單次播放聲音

sound_buffer->Play(0, 0, 0);

11.當退出遊戲時需要釋放緩存和聲卡

sound_buffer->Release();

direct_sound->Release();

DirectInput之查詢滑鼠

DirectInput之查詢滑鼠

在windows你可以通過WM_MOUSEMOVE被動(消息驅動)接受滑鼠當前位置.但若在遊戲中若想得到滑鼠『偏移量』和『按扭』(是否按下)DirectInput則可以幫助你你重新獲得滑鼠每次『偏移量』和『按扭』信息(主動讀取).然後讓你可以重新繪畫新『指標』. 而無需Windows自帶『指標』.若你有多個滑鼠.則所有『偏移量』合併到單一設備中.

滑鼠移動演示程式:下載

演示代碼.在Init()中調用

1.調用DirectInputCreate()生成IDirectInput接口

IDirectInput * direct_input;

DirectInputCreate(GetModuleHandle(NULL),DIRECTINPUT_VERSION, &direct_input,NULL);

2.獲取滑鼠GUID_SysMouse為全域主滑鼠設備ID碼

direct_input->CreateDevice(GUID_SysMouse, &direct_mouse, NULL);

3.設置滑鼠協作等級(前臺) 非獨占訪問,訪問滑鼠時不會干涉其它應用程序訪問該滑鼠.當應用程序在前臺和後臺時都能時用該滑鼠.

direct_mouse->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE |                                             DISCL_BACKGROUND);

4.設置數據格式. c_dfDIMouse為DirectInput通用滑鼠全域常量

direct_mouse->SetDataFormat(&c_dfDIMouse);

5.從DirectInput獲取滑鼠

direct_mouse->Acquire();

6.載入滑鼠紋理,並且背景透明

mouse->texture.IsAlpha = true;

Load_File_Texture(&mouse->texture, hInstance, filename);

7.綁定紋理

Bind_Image_Texture(&mouse->texture,GL_REPEAT, GL_REPEAT,GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,GL_REPLACE);

8.滑鼠尺寸

mouse_size = 20;

9.現在你可以從滑鼠中獲取輸入.在你Update()更新中獲取滑鼠狀態.若你失去設備鍵盤,需要重新從DirectInput獲取鍵盤.

DIMOUSESTATE  state;

while (direct_mouse->GetDeviceState(sizeof(DIMOUSESTATE), &state) == DIERR_INPUTLOST)//

{         // 已失去設備,重新從DirectInput獲取鍵盤

if (direct_mouse->Acquire()==S_OK)

return false;

}

10.定義鼠標結構

typedef struct DIMOUSE_TYP{

int x, y;// 滑鼠座標

int screen_width, screen_height;// 窗口寬和高

float size;// 鼠標尺寸

bool button_left, button_right, button_middle; // 滑鼠按鈕,若true則為按下

TEXTURE texture;// 指標紋理

}DIMOUSE, *DIMOUSE_PTR;

DIMOUSE mouse;

11.重新計算滑鼠位置

mouse->x = mouse->x + state.lX;

mouse->y = mouse->y + state.lY;

12.判斷是否超出窗口邊界

if (mouse->x < 0)

mouse->x = 0;

if (mouse->x >= screen_width)

mouse->x = screen_width-1;

if (mouse->y < 0)

mouse->y = 0;

if (mouse->y >= screen_height)

mouse->y = screen_height – 1;

13.提取滑鼠按鈕

mouse->button_left = state.rgbButtons[0] & 0x80; //滑鼠左鍵

mouse->button_right = state.rgbButtons[1] & 0x80; // 滑鼠右鍵

mouse->button_middle = state.rgbButtons[2] & 0x80;// 滑鼠中鍵

14.當你退出遊戲時.需要釋放滑鼠和DirectInput對像

direct_mouse->Release();

direct_input->Release();

 

DirectInput之查詢鍵盤

DirectInput之查詢鍵盤

DirectInput是DirectX COM組件之一. 它讓你無需理會『鍵盤』硬件驅動程式. DirectInput為輸入設備提供統一接口,當然輸入設備需已安裝硬件驅動.而且你需要安裝『DirectX SDK』並設定include和LIB搜索路徑,或者加入工程項目中.若你想讀取鍵盤狀態.用法與GetAsyncKeyState()使用基本相似.但它的KEY鍵並非是ASCII碼.若你有多個鍵盤.則所有的輸入合併到單一設備中.

演示程式按鍵盤在屏幕中顯示對應字母:下載

演示代碼.在Init()中調用當然你需檢測返回值HRESULT

1.調用DirectInputCreate()生成IDirectInput接口

IDirectInput * direct_input;

DirectInputCreate(GetModuleHandle(NULL),DIRECTINPUT_VERSION, &direct_input,NULL);

2.獲取鍵盤, GUID_SysKeyboard為全域主鍵盤設備ID碼

IDirectInputDevice * direct_keyboard;

direct_input->CreateDevice(GUID_SysKeyboard, &direct_keyboard, NULL);

3.設置鍵盤協作等級, 非獨占訪問,訪問該設備時不會干涉其它應用程序訪問該設備. 並且當應用程序在前臺和後臺時都能時用該設備.

direct_keyboard->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE |DISCL_BACKGROUND);

4.設置數據格式. c_dfDIKeyboard為DirectInput通用鍵盤全域常量

direct_keyboard->SetDataFormat(&c_dfDIKeyboard);

5.從DirectInput獲取鍵盤.

direct_keyboard->Acquire();

6.你現在以可以從鍵盤中獲取輸入.在你Update()更新中獲取鍵盤狀態.若你失去設備鍵盤,需要重新從DirectInput獲取鍵盤

while(direct_keyboard->GetDeviceState(sizeof(UCHAR) * 256, direct_keystate)== DIERR_INPUTLOST)

{

if(direct_keyboard->Acquire() != S_OK)

return false;

}

7.當你退出遊戲時.需要釋放鍵盤和DirectInput對像

direct_keyboard->Release();

direct_input->Release();