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

清源游民  gameogre@gmail.com
在第一部分里分析了 ExampleFrameListener 大部?jī)?nèi)容,不過(guò)沒(méi)有窮盡,它其實(shí)也包含了輸入部分。因?yàn)?CEGUI 本身沒(méi)輸入偵測(cè)功能,他需要外部力量的幫助。在 ogre1.4 之間的 demo 中,輸入部分是 ogre 自帶的,功能有限(對(duì)于我這個(gè)菜鳥(niǎo),暫時(shí)還用不到特別的功能 ^_^ )。新版本里,干脆把這部分去掉了,輸入部分采用了新的類庫(kù) OIS - Object-oriented Input Library . 他的作者本身就是 OGRE team 的成員,我們可以相信,他可以與 Ogre 一起工作得很好 .OIS 支持鍵盤(pán),鼠標(biāo),游戲桿,最后一項(xiàng)暫時(shí)不討論 . 在 windows 平臺(tái)下, OIS 提供了對(duì) DirectInput 的封裝,基本的輸入功能是由后者來(lái)實(shí)現(xiàn)的。既然是學(xué)習(xí),我們不防先大概理解一下 DirectInput 基本功能與使用流程以及 OIS 是如何將這些功能封裝進(jìn)去的。我的目的是要討論 CEGUI 的,現(xiàn)在轉(zhuǎn)到了 OIS, 又轉(zhuǎn)到了 DirectxInput, 似乎是離目標(biāo)越來(lái)越遠(yuǎn)了。呵,在菜鳥(niǎo)的眼中,什么東西都是菜,都有營(yíng)養(yǎng),不防咀嚼個(gè)一下下。 CEGUI 固然是好東西,但是如果我們菜鳥(niǎo)整天只會(huì)學(xué)一堆堆沒(méi)完沒(méi)了的類庫(kù),那么我們可能永遠(yuǎn)就只是個(gè)菜鳥(niǎo)了,一句話,知道他做了些什么,比光知道他怎么用那可是相當(dāng)有效!費(fèi)話少說(shuō)了,先看一下 DirectInput, 從 MSDN 上直接抄了一段, 懶得翻譯了: 下面第一段話,說(shuō)了理解directInput需要了解的一些基本概念與術(shù)語(yǔ),因?yàn)橐郧翱催^(guò)一點(diǎn),大概知道是些什么。而我現(xiàn)在主要是做學(xué)習(xí)筆記,不是教程,所以不解釋了。
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.
第二段話說(shuō)明了使用 DirectInput 的基本步驟, OIS 把這些東西封裝起來(lái)了 .
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.

了解了這些基本步驟,下面我們打開(kāi)OIS的源碼,看看上面這8步驟封裝到了哪里。然后我們返回 ExampleFrameListener, 看看 demo 中是如何使用 OIS 的 .
第一個(gè)要看的是InputManager類。他提供了平臺(tái)無(wú)關(guān)的接口,負(fù)責(zé)輸入系統(tǒng)的創(chuàng)建。沒(méi)啥好說(shuō)的,看源碼吧(只列出核心代碼):
InputManager * InputManager::createInputSystem( ParamList &paramList )
{????
???? ?InputManager* im = 0;
????? #elif defined OIS_WIN32_PLATFORM?
?????? ??? im = newWin32InputManager();
??? #endif?
?????? im->_initialize(paramList);?
??? return im;
}
自然,我們只關(guān)心windows平臺(tái)下的。于是找到源碼繼續(xù)看:
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 ); 中對(duì)以后將要?jiǎng)?chuàng)建的設(shè)備(鍵盤(pán),鼠標(biāo)等)的屬性,例如獨(dú)占模式,前臺(tái)模式等。這些屬性列表paramList?? 經(jīng)過(guò)處理后,之后在創(chuàng)建設(shè)備的時(shí)候傳入。
void Win32InputManager::_enumerateDevices()
{???? //Enumerate all attached devices?
??? mDirectInput->EnumDevices(NULL, _DIEnumKbdCallback, this, DIEDFL_ATTACHEDONLY);
}

完成了8步驟中的第2 部分 Enumerate devices ,它是針對(duì)游戲桿這類設(shè)計(jì)的,對(duì)于鍵盤(pán),鼠標(biāo)并不需要。InputManager 創(chuàng)建之后,就可以用它來(lái)創(chuàng)建鍵盤(pán),鼠標(biāo)了。它提供了如下的方法:
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;
}

鼠標(biāo),鍵盤(pán)都有各自的類封裝。下面以鍵盤(pán)為例,看看它的源碼中都做了些什么:
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();?

}

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

從源碼中我們可以看到,根據(jù)數(shù)據(jù)的不同,進(jìn)行了不同的處理。呵,什么不同呢,再?gòu)腗SDN上抄一段吧,一看就明白: 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.

呵,清楚了吧。繼續(xù)看代碼, capture()有兩個(gè)分枝,分別處理緩沖數(shù)據(jù)與立即數(shù)據(jù)。
首先是緩沖數(shù)據(jù),主干代碼如下:
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 );取得了緩沖數(shù)據(jù),添入了一個(gè)數(shù)組:尺寸是EYBOARD_DX_BUFFERSIZE,可以看到entries也等于此值。Entries的作用除了開(kāi)始調(diào)用時(shí)說(shuō)明數(shù)組的大小,同時(shí)在函數(shù)調(diào)用返回時(shí)說(shuō)明數(shù)組里有多少個(gè)數(shù)據(jù)填入(沒(méi)有足夠多的緩沖數(shù)據(jù),當(dāng)然填不滿啦,假如entries返回6,說(shuō)明還有6個(gè)按鍵信息在緩沖里等待處理)。很明顯,for循環(huán)就是對(duì)這些未處理的信息進(jìn)行處理。KeyCode kc = (KeyCode)diBuff[ i ].dwOfs; 這是看看,這個(gè)事件是由哪個(gè)鍵引走.KeyCode是個(gè)枚舉型:
enum KeyCode?
??? {?
???  ? C_1?????????? = 0x02,?
?????? KC_2??????????? = 0x03,?
?????? KC_3??????????? = 0x04,?
?????? KC_A??????????? = 0x1E,?
?????? KC_S??????????? = 0x1F,?
?????? KC_D??????????? = 0x20,?
??? }

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

它把相關(guān)的信息內(nèi)容包裝成KeyEvent,作為參數(shù)發(fā)給了,已經(jīng)注冊(cè)了的偵聽(tīng)者.可能不太明白,解釋一下:當(dāng)我們按下了某個(gè)鍵,可以認(rèn)為是發(fā)生了個(gè)KeyEvent,程序里會(huì)響應(yīng)這個(gè)事件,方法就是把某個(gè)類實(shí)例注冊(cè)為偵聽(tīng)者(listener),說(shuō)白了就是告訴OIS,當(dāng)鍵盤(pán)按下釋放的時(shí)候你告訴我啊,我要響應(yīng)他。這里OIS檢測(cè)到按鍵事件發(fā)生了,根據(jù)偵聽(tīng)者的請(qǐng)求,調(diào)用偵聽(tīng)者的方法(keyPressed)。也許有疑問(wèn),OIS 怎么知道偵聽(tīng)者實(shí)現(xiàn)了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;????
??? };
哈哈,他正是定義了這兩個(gè)接口,既然繼承自他,當(dāng)然也就擁有了這兩個(gè)接口,于是GuiFrameListener成了合理合法的Listener了。
哦,它在哪里注冊(cè)的呢?很簡(jiǎn)單.在GuiFrameListener的構(gòu)造函數(shù)里我們看到:
{
?????? mMouse ->setEventCallback(this);?
?????? mKeyboard->setEventCallback(this);
}
繼續(xù)挖源碼:
virtual void Keyboard : :setEventCallback ( KeyListener *keyListener ) {listener=keyListener;}
這下應(yīng)該就明白了吧。很明顯GUI Demo里使用了緩沖模式.
剩下來(lái)就是立即模式的數(shù)據(jù)了,他很好理解:
void Win32Keyboard::_read()
{?
? mKeyboard->GetDeviceState( sizeof(KeyBuffer), &KeyBuffer );?
}
它把鍵盤(pán)當(dāng)下的狀態(tài)保存到緩沖中去,要想知道哪個(gè)鍵是否按下,只要對(duì)照緩沖“按圖索驥”就可以了。
?bool Win32Keyboard::isKeyDown( KeyCodekey )
{?
??? return (KeyBuffer[key] & 0x80) != 0;
}
這個(gè)鍵按下了嗎?那個(gè)鍵按下了嗎?那那個(gè)呢?呵,真啰嗦,得一個(gè)個(gè)的問(wèn)。
于是我們 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

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


posted on 2007-03-02 15:27 清源游民 閱讀(3667) 評(píng)論(0)  編輯 收藏 引用 所屬分類: OGRE
<2014年1月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

留言簿(35)

隨筆分類(78)

隨筆檔案(74)

文章檔案(5)

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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| 欧美成人亚洲成人| 亚洲国产mv| 欧美激情区在线播放| 欧美mv日韩mv国产网站app| 老司机精品久久| 亚洲国产精品视频| 日韩一级免费| 亚洲欧美精品在线| 久久青青草原一区二区| 欧美va天堂va视频va在线| 欧美日韩精品一区二区三区四区| 欧美日韩一区二区三区| 国产欧美一区二区三区在线看蜜臀| 国产一区二区看久久| 亚洲国产91色在线| 亚洲欧美日韩视频一区| 久久久亚洲人| 亚洲国产婷婷综合在线精品 | 欧美精品亚洲一区二区在线播放| 欧美精品情趣视频| 国产精品网站在线观看| 樱桃成人精品视频在线播放| 一本色道久久综合亚洲精品不卡| 欧美尤物巨大精品爽| 欧美大片一区二区| 亚洲午夜小视频| 免费av成人在线| 国产精品视频在线观看| 亚洲蜜桃精久久久久久久| 性欧美精品高清| 亚洲国产免费| 久久久久国产免费免费| 国产美女精品一区二区三区| 日韩亚洲欧美高清| 男男成人高潮片免费网站| 亚洲女同在线| 国产精品v日韩精品| 亚洲日本va午夜在线电影| 蜜桃av一区二区在线观看| 欧美一区二区三区四区夜夜大片 | 亚洲欧美国产制服动漫| 免费成人高清视频| 香蕉乱码成人久久天堂爱免费| 欧美日韩精品欧美日韩精品| 亚洲经典自拍| 免费一区视频| 久久久午夜精品| 国产日韩欧美一区| 亚洲欧美经典视频| 99综合视频| 欧美美女日韩| 夜夜精品视频一区二区| 亚洲国产精品成人综合色在线婷婷 | 国产欧美亚洲日本| 性欧美办公室18xxxxhd| 中文一区在线| 国产精品国产三级国产普通话蜜臀| 99视频有精品| 亚洲黄色尤物视频| 欧美激情第二页| 99在线精品视频| 亚洲精品一区中文| 欧美三级第一页| 在线亚洲免费| 一个色综合av| 国产乱码精品一区二区三区av| 亚洲欧美日韩国产一区| 亚洲一区欧美二区| 国产一区二区av| 老司机一区二区| 欧美成年网站| 亚洲你懂的在线视频| 亚洲在线成人精品| 狠狠做深爱婷婷久久综合一区 | 亚洲午夜极品| 国产丝袜一区二区三区| 久久婷婷久久一区二区三区| 久热re这里精品视频在线6| 亚洲啪啪91| 中文在线资源观看视频网站免费不卡| 国产精品久久久久久亚洲毛片| 久久er精品视频| 久热成人在线视频| 亚洲永久在线| 欧美一区国产二区| 亚洲欧洲日本mm| 亚洲一区二区三区精品动漫| 国内精品嫩模av私拍在线观看| 老鸭窝毛片一区二区三区| 欧美国产日韩二区| 欧美一区二区在线观看| 美女视频网站黄色亚洲| 亚洲午夜精品在线| 久久嫩草精品久久久久| 久久人人爽爽爽人久久久| 亚洲剧情一区二区| 午夜精品久久久久久久白皮肤 | 久久久久.com| 欧美 日韩 国产精品免费观看| 亚洲视频久久| 久久裸体艺术| 亚洲网站在线| 麻豆精品91| 久久久精品国产免大香伊| 欧美人在线视频| 久久性天堂网| 国产精品欧美精品| 亚洲人成在线影院| 激情成人av| 亚洲制服少妇| 一区二区日韩| 免费亚洲电影| 老**午夜毛片一区二区三区| 国产精品久久久久久久久久久久久 | 影视先锋久久| 亚洲伊人一本大道中文字幕| 亚洲第一精品影视| 午夜在线成人av| 亚洲欧美日韩国产| 欧美日韩国产一区二区| 欧美成人第一页| 国内激情久久| 午夜视频在线观看一区二区三区| 一区二区三区欧美亚洲| 欧美精品v国产精品v日韩精品| 久久综合免费视频影院| 国产一区二区丝袜高跟鞋图片| 亚洲特级片在线| 亚洲综合日韩中文字幕v在线| 欧美成人一区二区三区| 欧美成人性网| 亚洲国产中文字幕在线观看| 久久人人97超碰人人澡爱香蕉| 久久伊人精品天天| 亚洲高清视频一区二区| 久久久久久久综合| 免费高清在线一区| 亚洲欧洲三级| 欧美精品免费观看二区| av成人动漫| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 国内精品亚洲| 久久黄色影院| 美女福利精品视频| 亚洲肉体裸体xxxx137| 麻豆亚洲精品| 亚洲日韩视频| 午夜国产精品视频| 国产精品人成在线观看免费 | 国产精品久久二区| 亚洲男人的天堂在线| 久久精品人人做人人爽| 国内精品久久久久久久果冻传媒| 久久精品99无色码中文字幕 | 欧美性色综合| 亚洲综合精品四区| 久热精品视频在线免费观看| 亚洲人成网站在线观看播放| 欧美日韩成人免费| 亚洲男人av电影| 欧美国产第一页| 亚洲欧美日韩国产一区| 影音先锋久久久| 欧美日韩国产综合视频在线观看| 亚洲视频网站在线观看| 久久久夜色精品亚洲| 亚洲卡通欧美制服中文| 国产精品综合久久久| 久久中文字幕导航| 亚洲色图综合久久| 欧美成人有码| 亚洲一区影音先锋| 亚洲丶国产丶欧美一区二区三区| 欧美精品一区二区三区很污很色的| 一区二区欧美在线观看| 久久久噜噜噜久久中文字免| 亚洲九九九在线观看| 国产香蕉久久精品综合网| 免播放器亚洲一区| 午夜久久黄色| 99精品欧美一区二区蜜桃免费| 久久久久国产成人精品亚洲午夜| 亚洲国产高清一区| 国产精品永久入口久久久| 欧美成人综合在线| 久久精品二区| 亚洲制服丝袜在线| 一本到12不卡视频在线dvd| 欧美本精品男人aⅴ天堂| 午夜免费日韩视频| 亚洲精品裸体| 亚洲欧洲在线一区| 在线播放中文一区| 国产专区一区| 国产欧美一区二区精品性|