青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

清源游民  gameogre@gmail.com
在第一部分里分析了 ExampleFrameListener 大部內容,不過沒有窮盡,它其實也包含了輸入部分。因為 CEGUI 本身沒輸入偵測功能,他需要外部力量的幫助。在 ogre1.4 之間的 demo 中,輸入部分是 ogre 自帶的,功能有限(對于我這個菜鳥,暫時還用不到特別的功能 ^_^ )。新版本里,干脆把這部分去掉了,輸入部分采用了新的類庫 OIS - Object-oriented Input Library . 他的作者本身就是 OGRE team 的成員,我們可以相信,他可以與 Ogre 一起工作得很好 .OIS 支持鍵盤,鼠標,游戲桿,最后一項暫時不討論 . 在 windows 平臺下, OIS 提供了對 DirectInput 的封裝,基本的輸入功能是由后者來實現的。既然是學習,我們不防先大概理解一下 DirectInput 基本功能與使用流程以及 OIS 是如何將這些功能封裝進去的。我的目的是要討論 CEGUI 的,現在轉到了 OIS, 又轉到了 DirectxInput, 似乎是離目標越來越遠了。呵,在菜鳥的眼中,什么東西都是菜,都有營養,不防咀嚼個一下下。 CEGUI 固然是好東西,但是如果我們菜鳥整天只會學一堆堆沒完沒了的類庫,那么我們可能永遠就只是個菜鳥了,一句話,知道他做了些什么,比光知道他怎么用那可是相當有效!費話少說了,先看一下 DirectInput, 從 MSDN 上直接抄了一段, 懶得翻譯了: 下面第一段話,說了理解directInput需要了解的一些基本概念與術語,因為以前看過一點,大概知道是些什么。而我現在主要是做學習筆記,不是教程,所以不解釋了。
To understand DirectInput, it is essential to understand the following terms.?
DirectInput object: The root DirectInput interface. ·?Device: A keyboard, mouse, joystick, or other input device. ·? DirectInputDevice object: Code representing a keyboard, mouse, joystick, or other input device.·??
Device object: Code representing a key, button, trigger, and so on found on a DirectInput device object. Also called device object instance.
第二段話說明了使用 DirectInput 的基本步驟, OIS 把這些東西封裝起來了 .
The following steps represent a simple implementation of DirectInput in which the application takes responsibility for ascertaining what device object (button, axis, and so on) generated each item of data.

1.? Create the DirectInput object. You use methods of this object to enumerate devices and create DirectInput device objects.

2.? Enumerate devices. This is not an essential step if you intend to use only the system mouse or keyboard. To ascertain what other input devices are available on the user's system, have DirectInput enumerate them. Each time DirectInput finds a device that matches the criteria you set, it gives you the opportunity to examine the device's capabilities. It also retrieves a unique identifier that you can use to create a DirectInput device object representing the device.

3.? Create a DirectInputDevice object for each device you want to use. To do this, you need the unique identifier retrieved during enumeration. For the system mouse or keyboard, you can use a standard GUID.

4.? Set up the device. For each device, first set the cooperative level, which determines the way the device is shared with other applications or the system. You must also set the data format used for identifying device objects, such as buttons and axes, within data packets. If you intend to retrieve buffered data—that is, events rather than states—you also need to set a buffer size. Optionally, at this stage you can retrieve information about the device and tailor the application's behavior accordingly. You can also set properties such as the range of values returned by joystick axes.

5.? Acquire the device. At this stage you tell DirectInput that you are ready to receive data from the device.

6.? Retrieve data. At regular intervals, typically on each pass through the message loop or rendering loop, get either the current state of each device or a record of events that have taken place since the last retrieval. If you prefer, you can have DirectInput notify you whenever an event occurs.

7.? Act on the data. The application can respond either to the state of buttons and axes or to events such as a key being pressed or released.

8.? Close DirectInput. Before exiting, your application should unacquire all devices and release them, then release the DirectInput object.

了解了這些基本步驟,下面我們打開OIS的源碼,看看上面這8步驟封裝到了哪里。然后我們返回 ExampleFrameListener, 看看 demo 中是如何使用 OIS 的 .
第一個要看的是InputManager類。他提供了平臺無關的接口,負責輸入系統的創建。沒啥好說的,看源碼吧(只列出核心代碼):
InputManager * InputManager::createInputSystem( ParamList &paramList )
{????
???? ?InputManager* im = 0;
????? #elif defined OIS_WIN32_PLATFORM?
?????? ??? im = newWin32InputManager();
??? #endif?
?????? im->_initialize(paramList);?
??? return im;
}
自然,我們只關心windows平臺下的。于是找到源碼繼續看:
void Win32InputManager::_initialize( ParamList &paramList )
{?
? //Create the device?
?? hr = DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL );
?? /Ok, now we have DirectInput, parse whatever extra settings were sent to us?
??? _parseConfigSettings( paramList );?
??? _enumerateDevices();
}

首先,完成了8步驟中的第1步, Create the DirectInput object 。 在_parseConfigSettings ( paramList ); 中對以后將要創建的設備(鍵盤,鼠標等)的屬性,例如獨占模式,前臺模式等。這些屬性列表paramList?? 經過處理后,之后在創建設備的時候傳入。
void Win32InputManager::_enumerateDevices()
{???? //Enumerate all attached devices?
??? mDirectInput->EnumDevices(NULL, _DIEnumKbdCallback, this, DIEDFL_ATTACHEDONLY);
}

完成了8步驟中的第2 部分 Enumerate devices ,它是針對游戲桿這類設計的,對于鍵盤,鼠標并不需要。InputManager 創建之后,就可以用它來創建鍵盤,鼠標了。它提供了如下的方法:
Object * Win32InputManager::createInputObject( TypeiType, boolbufferMode )
{???
? Object* obj = 0;???
??? switch( iType )?
??? {?
??? case OISKeyboard: obj = newWin32Keyboard( this, mDirectInput, bufferMode, kbSettings ); break;?
??? case OISMouse: obj = newWin32Mouse( this, mDirectInput, bufferMode, mouseSettings ); break;?
??? obj->_initialize();?
??? return obj;
}

鼠標,鍵盤都有各自的類封裝。下面以鍵盤為例,看看它的源碼中都做了些什么:
void Win32Keyboard::_initialize()
{

1????? mDirectInput->CreateDevice(GUID_SysKeyboard, &mKeyboard, NULL);

2????? mKeyboard->SetDataFormat(&c_dfDIKeyboard)

3????? HWNDhwin = ((Win32InputManager*)mCreator)->getWindowHandle();

4????? mKeyboard->SetCooperativeLevel( hwin, coopSetting)))

5????? mKeyboard ->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph )))

6????? HRESULThr = mKeyboard->Acquire();?

}

這里可是做了不少的工作,看看方法名就可以明白。為說明方便加上了標號。
1, 它做了8步驟中的第3步, Create a DirectInputDevice object for each device you want to use 。
2, 3 4,5它們共同做了8步驟中的第4步- Set up the device 。這里面包括:設置鍵盤的數據格式,協作模式,其他屬性。很明顯,6做了8 步步驟中的第5步- Acquire the device 。 意思是告訴DirectInput,我準備從設備上獲取數據了,給我做好生伺侯著。準備工作都做好了,可以獲取數據了,通過設備提供的下面這個方法來做這件事。這就是8 步驟中的第6件事- Retrieve data
void Win32Keyboard::capture()
{???? if( mBuffered )?
?????? _readBuffered();?
???? ? else?
?????? _read();
}

從源碼中我們可以看到,根據數據的不同,進行了不同的處理。呵,什么不同呢,再從MSDN上抄一段吧,一看就明白: Buffered and Immediate Data
DirectInput supplies two types of data: buffered and immediate. Buffered data is a record of events that are stored until an application retrieves them. Immediate data is a snapshot of the current state of a device. You might use immediate data in an application that is concerned only with the current state of a device - for example, a flight combat simulation that responds to the current position of the joystick and the state of one or more buttons. Buffered data might be the better choice where events are more important than states - for example, in an application that responds to movement of the mouse and button clicks. You can also use both types of data, as you might, for example, if you wanted to get immediate data for joystick axes but buffered data for the buttons.

呵,清楚了吧。繼續看代碼, capture()有兩個分枝,分別處理緩沖數據與立即數據。
首先是緩沖數據,主干代碼如下:
void Win32Keyboard::_readBuffered()
{
? DIDEVICEOBJECTDATA diBuff[KEYBOARD_DX_BUFFERSIZE];?
??? DWORD entries = KEYBOARD_DX_BUFFERSIZE;??
?? mKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );?
??? //Update keyboard and modifier states.. And, if listener, fire events?
??? for(unsignedinti = 0; i < entries; ++i )?
??? {?
?????? KeyCode kc = (KeyCode)diBuff[ i ].dwOfs;?
???????????????????? if( diBuff[ i ].dwData & 0x80 )?
?????? {?
?? ?????? if( listener )?
??????????? istener->keyPressed( KeyEvent( this,kc,_translateText(kc) ) );?
?????? }?
?????? else
?????? {?
?????????? //Fire off event?
?????????? if( listener )?
??????????? listener->keyReleased( KeyEvent( this, kc, 0 ) );?
?????? }?
??? }
}

這段代碼中,GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );取得了緩沖數據,添入了一個數組:尺寸是EYBOARD_DX_BUFFERSIZE,可以看到entries也等于此值。Entries的作用除了開始調用時說明數組的大小,同時在函數調用返回時說明數組里有多少個數據填入(沒有足夠多的緩沖數據,當然填不滿啦,假如entries返回6,說明還有6個按鍵信息在緩沖里等待處理)。很明顯,for循環就是對這些未處理的信息進行處理。KeyCode kc = (KeyCode)diBuff[ i ].dwOfs; 這是看看,這個事件是由哪個鍵引走.KeyCode是個枚舉型:
enum KeyCode?
??? {?
???  ? C_1?????????? = 0x02,?
?????? KC_2??????????? = 0x03,?
?????? KC_3??????????? = 0x04,?
?????? KC_A??????????? = 0x1E,?
?????? KC_S??????????? = 0x1F,?
?????? KC_D??????????? = 0x20,?
??? }

確定了是哪個鍵,接下來就要問了,是按下還是釋放?
?if ( diBuff[ i ].dwData & 0x80 )  回答了這個問題,下面做的是
if ( listener )?
??????????? istener->keyPressed( KeyEvent( this,kc,_translateText(kc) ) );

它把相關的信息內容包裝成KeyEvent,作為參數發給了,已經注冊了的偵聽者.可能不太明白,解釋一下:當我們按下了某個鍵,可以認為是發生了個KeyEvent,程序里會響應這個事件,方法就是把某個類實例注冊為偵聽者(listener),說白了就是告訴OIS,當鍵盤按下釋放的時候你告訴我啊,我要響應他。這里OIS檢測到按鍵事件發生了,根據偵聽者的請求,調用偵聽者的方法(keyPressed)。也許有疑問,OIS 怎么知道偵聽者實現了keypressed()方法呢?不急先看以下代碼,在GUI demo里:
class GuiFrameListener : publicExampleFrameListener, publicOIS::KeyListener, publicOIS::MouseListener
看到了吧,它繼承自? OIS:KeyListener ,從OIS的源碼中找到它:
class _OISExport KeyListener?
??? {?
??? public:?
?????? virtual ~KeyListener() {}?
?????? virtual bool keyPressed( constKeyEvent &arg ) = 0;?
?????? virtual bool keyReleased( constKeyEvent &arg ) = 0;????
??? };
哈哈,他正是定義了這兩個接口,既然繼承自他,當然也就擁有了這兩個接口,于是GuiFrameListener成了合理合法的Listener了。
哦,它在哪里注冊的呢?很簡單.在GuiFrameListener的構造函數里我們看到:
{
?????? mMouse ->setEventCallback(this);?
?????? mKeyboard->setEventCallback(this);
}
繼續挖源碼:
virtual void Keyboard : :setEventCallback ( KeyListener *keyListener ) {listener=keyListener;}
這下應該就明白了吧。很明顯GUI Demo里使用了緩沖模式.
剩下來就是立即模式的數據了,他很好理解:
void Win32Keyboard::_read()
{?
? mKeyboard->GetDeviceState( sizeof(KeyBuffer), &KeyBuffer );?
}
它把鍵盤當下的狀態保存到緩沖中去,要想知道哪個鍵是否按下,只要對照緩沖“按圖索驥”就可以了。
?bool Win32Keyboard::isKeyDown( KeyCodekey )
{?
??? return (KeyBuffer[key] & 0x80) != 0;
}
這個鍵按下了嗎?那個鍵按下了嗎?那那個呢?呵,真啰嗦,得一個個的問。
于是我們 GUI Demo 中可以看到下列的代碼:
virtual bool processUnbufferedKeyInput(const FrameEvent& evt)?
?????? {?

??????????? if(mKeyboard->isKeyDown(KC_A))?
???????????????????? ?mTranslateVector.x = -mMoveScale;??? // Move camera left?
??????????? if(mKeyboard->isKeyDown(KC_D))?
?????????????????? ?mTranslateVector.x = mMoveScale;????? // Move camera RIGHT?
????????????? if(mKeyboard->isKeyDown(KC_UP) || mKeyboard->isKeyDown(KC_W) )?
???????????????????? mTranslateVector.z = -mMoveScale;???? // Move camera forward?
????????????? if(mKeyboard->isKeyDown(KC_DOWN) || mKeyboard->isKeyDown(KC_S) )??
??????? ??????????? mTranslateVector.z = mMoveScale;????? // Move camera backward

我們用鍵盤要不是緩沖模式,要么立即模式,不可能一起上,這所有在 demo 中都能看到, demo 的作者懶得多寫代碼 ( 嘿嘿 ) ,它繼承了 ExampleFrameListener 的許多功能,而 ExampleFrameListener 也實現了些立即模式的按鍵處理。 Demo 沒有用到。寫了這么多了,還得 8  大步驟?? 該第 7 步了吧: ―― Act on the data , 這有什么好說的呢?愛咋咋地!最后一步,第 8 步――天龍八部 ! 呵錯了,是 Close DirectInput????? 其實很簡單, OIS 把他們封裝在各個類的析構函數里了,想當然,源碼也不用貼了 . 說了 OIS  如何把 DirectInput 封裝起來,參考 8 大步驟,如何使用 OIS 也基本很明白了。OIS ,就學到這里,接下來該主角上場 CEGUI?得休息了,打字,翻資料,看代碼,很累了。


posted on 2007-03-02 15:27 清源游民 閱讀(3657) 評論(0)  編輯 收藏 引用 所屬分類: OGRE
<2007年3月>
25262728123
45678910
11121314151617
18192021222324
25262728293031
1234567

留言簿(35)

隨筆分類(78)

隨筆檔案(74)

文章檔案(5)

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久婷婷成人综合色| 久久国产精品一区二区| 欧美午夜女人视频在线| 欧美成人中文| 欧美裸体一区二区三区| 欧美国产免费| 欧美午夜一区二区福利视频| 欧美午夜在线一二页| 国产裸体写真av一区二区| 国产一区二区三区电影在线观看 | 亚洲综合不卡| 久久精品成人欧美大片古装| 美女性感视频久久久| 欧美日韩精品免费观看视一区二区 | 亚洲欧美在线另类| 久久琪琪电影院| 欧美日产一区二区三区在线观看| 欧美性猛交99久久久久99按摩| 国产欧美日韩精品丝袜高跟鞋 | 亚洲免费影视第一页| 性色一区二区| 亚洲电影在线| 亚洲色诱最新| 女女同性女同一区二区三区91| 欧美日韩情趣电影| 黑人一区二区三区四区五区| 日韩视频在线播放| 久久精品人人做人人爽电影蜜月| 在线日韩中文字幕| 亚洲网站在线观看| 欧美粗暴jizz性欧美20| 亚洲女女做受ⅹxx高潮| 欧美成人一品| 国产中文一区二区三区| 亚洲一区二区三区影院| 欧美www在线| 性感少妇一区| 欧美午夜一区二区福利视频| 久久精品国产综合精品| 国产精品99免视看9| 亚洲国产精品一区二区尤物区| 性欧美大战久久久久久久久| 亚洲日本中文字幕| 麻豆精品视频在线观看| 国产一区二区久久| 久久精品成人一区二区三区| 亚洲视频播放| 欧美先锋影音| 亚洲在线国产日韩欧美| 99re6热只有精品免费观看 | 久久九九国产| 国产视频观看一区| 欧美一区二区在线免费观看| 一区二区三区欧美亚洲| 欧美日韩国产在线播放网站| 99pao成人国产永久免费视频| 欧美成人一品| 久久久噜噜噜久久狠狠50岁| 黑丝一区二区| 玖玖玖国产精品| 久久精品国产亚洲高清剧情介绍| 国产伦精品一区| 久久精品国产综合| 久久经典综合| 亚洲电影毛片| 亚洲风情亚aⅴ在线发布| 欧美插天视频在线播放| 亚洲毛片av| 一区二区三区精品国产| 国产伦精品一区二区三区免费迷| 亚洲图片在线观看| 亚洲一区在线播放| 国产亚洲人成网站在线观看| 久久久久综合一区二区三区| 久久久精品日韩| 亚洲欧洲精品一区二区三区波多野1战4| 欧美.www| 欧美日韩免费高清| 欧美一区二区高清在线观看| 欧美中文字幕视频在线观看| 亚洲第一精品久久忘忧草社区| 欧美激情一区二区三区在线| 欧美日韩三级电影在线| 性欧美暴力猛交另类hd| 久久久久久97三级| 99re6这里只有精品视频在线观看| 99亚洲视频| 精品动漫3d一区二区三区免费版| 欧美肥婆在线| 国产精品久久久久久妇女6080| 久久久久久999| 欧美精品高清视频| 久久国产加勒比精品无码| 久久婷婷国产综合国色天香| 99国产一区| 欧美一区二区观看视频| 亚洲精品在线电影| 香蕉成人久久| 99天天综合性| 欧美影院一区| 欧美多人爱爱视频网站| 欧美一区1区三区3区公司| 蜜臀久久99精品久久久久久9| 亚洲在线播放| 欧美不卡视频一区| 久久精品中文字幕一区二区三区| 欧美精品一区二区三区久久久竹菊| 小黄鸭精品密入口导航| 久久综合久久综合九色| 性做久久久久久免费观看欧美| 美女脱光内衣内裤视频久久影院| 欧美一区日本一区韩国一区| 欧美剧在线观看| 欧美高清视频一区二区三区在线观看 | 欧美成人国产一区二区| 久久国产精品电影| 欧美性大战久久久久| 亚洲国产精品成人久久综合一区| 国产视频一区在线观看一区免费| 亚洲裸体在线观看| 亚洲欧洲精品一区二区| 久久精品二区三区| 午夜激情综合网| 国产精品vip| 99精品久久免费看蜜臀剧情介绍| 亚洲国产精品小视频| 久久久久国产免费免费| 久久免费精品视频| 国产综合精品一区| 欧美一区二区三区四区在线观看地址 | 这里只有视频精品| 一二三区精品福利视频| 欧美大学生性色视频| 欧美高清在线视频观看不卡| 极品尤物一区二区三区| 久久精品国产免费| 美女视频一区免费观看| 在线视频国产日韩| 模特精品在线| 亚洲精品国产精品乱码不99按摩| 亚洲国产精品成人综合| 美日韩精品视频| 亚洲国产精品久久久久| 亚洲免费av片| 欧美日本精品一区二区三区| 亚洲高清视频在线观看| 亚洲免费电影在线| 国产精品sm| 香蕉视频成人在线观看| 美女图片一区二区| 夜色激情一区二区| 国产精品久久久久影院色老大 | 欧美日韩国产影片| 亚洲一区二区黄色| 韩国在线视频一区| 久久婷婷久久| 亚洲精品一区二区网址| 亚洲欧美日韩国产一区二区三区| 国产精品二区二区三区| 午夜一区二区三区不卡视频| 久久亚裔精品欧美| 亚洲精品日产精品乱码不卡| 欧美日韩国产首页| 先锋资源久久| 欧美aⅴ一区二区三区视频| 91久久精品一区二区三区| 欧美日韩精品久久| 性欧美1819性猛交| 亚洲激情欧美| 欧美一区二区三区久久精品| 伊人春色精品| 欧美日韩视频一区二区三区| 欧美一区二区在线视频| 亚洲成色777777在线观看影院| 99亚洲一区二区| 欧美专区在线观看一区| 亚洲韩日在线| 国产精品视频自拍| 男人插女人欧美| 亚洲一区二区三区乱码aⅴ蜜桃女| 久久综合久久88| 亚洲伊人一本大道中文字幕| 伊人激情综合| 国产精品伊人日日| 欧美精品免费在线| 久久久精品网| 亚洲淫片在线视频| 亚洲精品国精品久久99热一| 久久精品av麻豆的观看方式 | 老司机免费视频久久| 亚洲图片在线观看| 亚洲国产一区二区在线| 国产色婷婷国产综合在线理论片a| 欧美精品自拍| 老司机一区二区三区| 香蕉av福利精品导航| 亚洲在线观看视频网站| 夜夜嗨一区二区| 99精品福利视频| 亚洲精品极品|