<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Chia´s Small Shop</title>
	<atom:link href="http://chia0418.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://chia0418.wordpress.com</link>
	<description>Chia小鋪，陳列隨手的文字</description>
	<lastBuildDate>Mon, 21 Nov 2011 07:38:15 +0000</lastBuildDate>
	<language>zh-tw</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='chia0418.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Chia´s Small Shop</title>
		<link>http://chia0418.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://chia0418.wordpress.com/osd.xml" title="Chia´s Small Shop" />
	<atom:link rel='hub' href='http://chia0418.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Nokia N900 裝置端上的c/c++開發環境設置</title>
		<link>http://chia0418.wordpress.com/2010/06/01/nokia-n900-%e8%a3%9d%e7%bd%ae%e7%ab%af%e4%b8%8a%e7%9a%84cc%e9%96%8b%e7%99%bc%e7%92%b0%e5%a2%83%e8%a8%ad%e7%bd%ae/</link>
		<comments>http://chia0418.wordpress.com/2010/06/01/nokia-n900-%e8%a3%9d%e7%bd%ae%e7%ab%af%e4%b8%8a%e7%9a%84cc%e9%96%8b%e7%99%bc%e7%92%b0%e5%a2%83%e8%a8%ad%e7%bd%ae/#comments</comments>
		<pubDate>Mon, 31 May 2010 16:43:12 +0000</pubDate>
		<dc:creator>chia0418</dc:creator>
				<category><![CDATA[Maemo]]></category>
		<category><![CDATA[Nokia N900]]></category>

		<guid isPermaLink="false">http://chia0418.wordpress.com/?p=387</guid>
		<description><![CDATA[最近入手了新玩具，Nokia N900，給自己換這隻手機的藉口是：噢耶～這隻手機跑的是Linux耶～沒錯，N900的Maemo 5作業系統，引起了廣大的(?)迴響。許多在Linux上看得到的軟體與相關應用，都可以在N900上看到。玩得大一點的，甚至安裝修改過核心的Ubuntu或是來個OOo。N900，絕對不是手機而已！ 以下簡單紀錄如何在N900的裝置端上開發應用軟體，建構gcc/g++編譯器的開發環境。為了縮短篇幅，假設你已經了解並熟悉： 有N900了（沒有的快去買XD） 會基本的Linux操作與知識 在N900上擁有root的操作能力，最好安裝SSH server方便操作 以下的操作，最壞的情況會導致裝置功能不正常，需要重新刷機才能恢復 關於上述第3點，雖然N900有硬體鍵盤，但拿來寫程式還是有點小痛苦，建議使用SSH server來操作比較簡單。SSH client在Windows環境，推薦PuTTY或是Tera Term都很適合。首先，添加開發套件的檔案來源。在「程式管理員」(App Manager)中，點選「應用程式目錄」(Catalogue)，新增 目錄名稱(Catalogue name): Maemo SDK 網址(Web address): http://repository.maemo.org/ 分發版本(Distribution): fremantle 元件(Components): sdk/free sdk/non-free tools/free tools/non-free 接下來，安裝build-essential套件，會自動把該裝的裝好。在X terminal（或在SSH client中），切換成root，用apt-get安裝： # apt-get install build-essential 接著耐心的等套件裝好後，開發環境就建置好啦！為了測試一下，來個』Hello Nokia N900!』吧！用vi編輯一小段c++的程式碼』hello.cpp』： 接著編譯： # g++ -o hello hello.cpp 如果正確編譯，表示開發環境安裝正確無誤！執行程式，會在終端機中印出』Hello Nokia N900!』。 要是沒辦法執行呢？ 嗯&#8230;&#8230;如果沒辦法執行，先看看hello是放在哪邊吧！如果是丟在/home/user/MyDocs底下的話，不怪你，因為執行個mount就會出現原因了： /dev/mmcblk0p1 on /home/user/MyDocs type vfat (rw,noauto,nodev,noexec,nosuid,noatime,nodiratime,utf8,uid=29999,shortname=mixed,dmask=000,fmask=0133,rodir) [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chia0418.wordpress.com&amp;blog=3262473&amp;post=387&amp;subd=chia0418&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
		<wfw:commentRss>http://chia0418.wordpress.com/2010/06/01/nokia-n900-%e8%a3%9d%e7%bd%ae%e7%ab%af%e4%b8%8a%e7%9a%84cc%e9%96%8b%e7%99%bc%e7%92%b0%e5%a2%83%e8%a8%ad%e7%bd%ae/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">嘉嘉</media:title>
		</media:content>
	</item>
		<item>
		<title>別讓你的多核心只是裝飾品！Intel TBB 2.2 發布</title>
		<link>http://chia0418.wordpress.com/2009/08/18/%e5%88%a5%e8%ae%93%e4%bd%a0%e7%9a%84%e5%a4%9a%e6%a0%b8%e5%bf%83%e5%8f%aa%e6%98%af%e8%a3%9d%e9%a3%be%e5%93%81%ef%bc%81intel-tbb-2-2-%e7%99%bc%e5%b8%83/</link>
		<comments>http://chia0418.wordpress.com/2009/08/18/%e5%88%a5%e8%ae%93%e4%bd%a0%e7%9a%84%e5%a4%9a%e6%a0%b8%e5%bf%83%e5%8f%aa%e6%98%af%e8%a3%9d%e9%a3%be%e5%93%81%ef%bc%81intel-tbb-2-2-%e7%99%bc%e5%b8%83/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 15:09:04 +0000</pubDate>
		<dc:creator>chia0418</dc:creator>
				<category><![CDATA[TBB]]></category>
		<category><![CDATA[Intel Threading Building Blocks]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[multithread]]></category>

		<guid isPermaLink="false">http://chia0418.wordpress.com/?p=379</guid>
		<description><![CDATA[Intel® Threading Building Blocks (TBB) 是一個協助將演算法平行化處理的函式庫。利用多核心可以同時處理多執行緒的優點，TBB自動將資料拆成數塊，分別由各個執行緒執行後，再將結果彙整。以往要自己手動處理多個執行緒的管理以及同步等問題，TBB都已經幫你包辦好了。雖然寫起來不若OpenMP那樣簡潔，不過我對於程式碼中飛來飛去的#pragma實在有點感冒&#8230; TBB 的開放原始碼版本(GPL 2)，在2009年8月9日發布2.2版囉！跟2.1版相比，架構有一點點小小地變動。除了效能的增進外，新加入的parallel_invoke與parallel_for_each方法，可以簡化原先parallel_for使用functor的繁複寫法，同時也支援C++0x的lambda functions。還有一個小小驚喜，終於不用初始化task scheduler了，2.2版會自動幫你做好這件事。眼下先把2.1版的projects升級一下囉～ 拜訪 TBB - TBB Home - TBB 2.2 stable version download - What’s New in Intel® TBB 2.2 Posted in TBB Tagged: Intel Threading Building Blocks, multicore, multithread, TBB<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chia0418.wordpress.com&amp;blog=3262473&amp;post=379&amp;subd=chia0418&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
		<wfw:commentRss>http://chia0418.wordpress.com/2009/08/18/%e5%88%a5%e8%ae%93%e4%bd%a0%e7%9a%84%e5%a4%9a%e6%a0%b8%e5%bf%83%e5%8f%aa%e6%98%af%e8%a3%9d%e9%a3%be%e5%93%81%ef%bc%81intel-tbb-2-2-%e7%99%bc%e5%b8%83/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">嘉嘉</media:title>
		</media:content>
	</item>
		<item>
		<title>在VC中利用Qt Designer建立自訂的slot</title>
		<link>http://chia0418.wordpress.com/2009/05/19/%e5%9c%a8vc%e4%b8%ad%e5%88%a9%e7%94%a8qt-designer%e5%bb%ba%e7%ab%8b%e8%87%aa%e8%a8%82%e7%9a%84slot/</link>
		<comments>http://chia0418.wordpress.com/2009/05/19/%e5%9c%a8vc%e4%b8%ad%e5%88%a9%e7%94%a8qt-designer%e5%bb%ba%e7%ab%8b%e8%87%aa%e8%a8%82%e7%9a%84slot/#comments</comments>
		<pubDate>Tue, 19 May 2009 12:34:23 +0000</pubDate>
		<dc:creator>chia0418</dc:creator>
				<category><![CDATA[Qt]]></category>
		<category><![CDATA[add-in]]></category>
		<category><![CDATA[Qt Designer]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://chia0418.wordpress.com/?p=343</guid>
		<description><![CDATA[Qt自己出了個IDE，Qt Creator，支援GNU的編譯器與GDB除錯器 整合度之高，感覺真像是先前使用Borland C++ Builder的經驗一樣 不過，假如已經習慣了VC的編譯環境，就只能望著Qt Creator乾瞪眼嗎？ 好在從Qt釋出了Visual Studio add-in (for open-source version)以後 Qt跟VC之間的距離就越來越近了 不用管什麼三部曲、uic與moc 視窗拉一拉，元件放一放，一個可口的GUI就完成了 打造複雜的GUI再也不是夢想！ 在設計GUI的過程中，往往會碰到需要自行定義被觸發事件(signal)的處理方法(slot) signal沒啥問題，通常是按鈕、選單等元件發出(e.g. 滑鼠點擊) 但是slot呢？並不是每個signal都找得到合適的預設slot 比方說，按一個按鈕開啟檔案對話框，然後載入一張圖片 應該找不到一個slot是剛好設定為「開啟檔案對話框」的吧！ 這個時候，就需要自訂的slot來解決問題 signal跟slot的宣告，可以依照自己的喜好來設計（不過要照規則唷） 或是由Designer協助建立signal與slot的連結關係 為什麼要由Designer來協助呢？個人認為有兩個好處 1. 由Designer建立signal與slot的連結，不容易出錯 當使用Designer建立連結時，會幫你檢查signal傳送資料的型別與參數量與slot的是否相符 如果兩者的函式簽名對應不起來，你連看到slot的機會都沒有，大大的降低了出錯的可能性 2. 統一管理，程式碼不再亂糟糟 Designer提供了signal/slot編輯器，所有的連結關係都由此編輯器完成 在實做類別中，就不需要再手動寫連結signal/slot的程式碼了 講了一堆，就拿上面提到的例子開始吧～ 以下的操作，以VC2008作為編譯環境 Qt版本是4.5.0 (open-source 編譯版)，配上Visual Studio add-in 1.0.0 首先，開啟VC，建立一個新的Qt應用程式專案 假設應用程式的class name叫做MyQtApp 設定完成後，點兩下』myqtapp.ui』，帶出Qt Designer 就開始畫UI囉 在這個小範例中，需要兩個元件，一個是QLabel，用來顯示影像 另一個就是QPushButton，用來開啟檔案對話框用的 那檔案對話框呢？嗯&#8230;必須由程式產生了[註1]，所以暫時先不管 最後設計好的視窗看起來會像這樣： 接著，重點出現了，要設定pushButton的signal/slot連結 按下pushButton，自然會用到clicked()這個signal [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chia0418.wordpress.com&amp;blog=3262473&amp;post=343&amp;subd=chia0418&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
		<wfw:commentRss>http://chia0418.wordpress.com/2009/05/19/%e5%9c%a8vc%e4%b8%ad%e5%88%a9%e7%94%a8qt-designer%e5%bb%ba%e7%ab%8b%e8%87%aa%e8%a8%82%e7%9a%84slot/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">嘉嘉</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-18-41-04.png" medium="image">
			<media:title type="html">Open new Qt Application project</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-18-41-05.png" medium="image">
			<media:title type="html">Qt Application settings</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-18-55-30.png" medium="image">
			<media:title type="html">MyQtApp gui design</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-18-59-31.png" medium="image">
			<media:title type="html">edit slot</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-18-59-49.png" medium="image">
			<media:title type="html">signal and slot editor</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-19-00-39.png" medium="image">
			<media:title type="html">new slot</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-19-02-01.png" medium="image">
			<media:title type="html">connect to the slot</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-19-02-25.png" medium="image">
			<media:title type="html">connection result</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-19-29-59.png" medium="image">
			<media:title type="html">open file dialog</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/05/2009-05-19-19-30-26.png" medium="image">
			<media:title type="html">MyQtApp</media:title>
		</media:content>
	</item>
		<item>
		<title>與Ogre共舞：第六步，敲敲鍵盤、動動滑鼠</title>
		<link>http://chia0418.wordpress.com/2009/04/01/%e8%88%87ogre%e5%85%b1%e8%88%9e%ef%bc%9a%e7%ac%ac%e5%85%ad%e6%ad%a5%ef%bc%8c%e6%95%b2%e6%95%b2%e9%8d%b5%e7%9b%a4%e3%80%81%e5%8b%95%e5%8b%95%e6%bb%91%e9%bc%a0/</link>
		<comments>http://chia0418.wordpress.com/2009/04/01/%e8%88%87ogre%e5%85%b1%e8%88%9e%ef%bc%9a%e7%ac%ac%e5%85%ad%e6%ad%a5%ef%bc%8c%e6%95%b2%e6%95%b2%e9%8d%b5%e7%9b%a4%e3%80%81%e5%8b%95%e5%8b%95%e6%bb%91%e9%bc%a0/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 14:59:59 +0000</pubDate>
		<dc:creator>chia0418</dc:creator>
				<category><![CDATA[Ogre]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://chia0418.wordpress.com/?p=299</guid>
		<description><![CDATA[從建立了Ogre的視窗開始，我們的目標就是透過攝影機，來看所設計的3D場景。為了能夠自由自在的瀏覽，我們得用輸入裝置來控制攝影機的位置與拍攝角度。由於Ogre本身只是個純繪圖引擎，對於處理鍵盤滑鼠之類的裝置非常不擅長，因此特地請來另外一個小巧簡單的套件 &#8211; OIS（Object Oriented Input System，別問我為什麼不叫OOIS呀&#8230;），幫忙解決這個問題。而這所有的過程，都會由FrameListener來接管。我們將繼續上一步的FrameListener範例，添加了滑鼠鍵盤輸入的處理，達到控制攝影機的目的。 先來簡單介紹一下OIS，這是個跨平台處理輸入裝置的函式庫，以物件導向的方式設計。OIS可以支援的輸入裝置主要是鍵盤、滑鼠、搖桿，同時也支援力回饋裝置。Ogre在編譯的時候，已經把OIS當成其中的一部分，所以我們可以簡單的使用，而不需要另外作安裝或設定的動作。不過，OIS本身沒有提供說明文件，Ogre的API裡也查不到（當然的嘛～），所以除了Wiki上有得找以外，就得直接看source code，或是OIS的API參考文件囉！ 使用OIS，必須定義OIS_DYNAMIC_LIB與引入』OIS.h』，順序不能錯，這樣OIS才會正確的使用dll檔的export的定義。接著，我們接受輸入裝置的目標是視窗，因此要讓OIS知道是哪一個視窗取得輸入裝置的訊息。OIS的初始化比較囉唆一點，因為一開始要準備初始化用的參數，看起來就很嚇人。下段code中，第3行的m_render_window是我們所建立的RenderWindow的指標，由其成員函式getCustomAttribute()取得視窗的handle。第一個傳入參數』WINDOW』是RenderWindow屬性的鍵值，是固定的寫法。得到的window_handle隨後由第6~7兩行轉換為字串，準備給OIS的初始化參數使用。 接著要產生OIS初始化用的參數列，先宣告OIS::ParamList的變數一枚，接著用insert()加入參數對(std::pair)。下面的程式碼中，第4行就是把剛剛取得的RenderWindow的handle，對應鍵值為』WINDOW』，加入初始化的參數中。到這裡OIS的初始化參數已經算是建立完成了，可以建立OIS的InputManager。在全螢幕或是視窗的應用上，通常（特別是遊戲）不會讓滑鼠的游標露出來給你看，或是在遊戲中使用自訂的滑鼠游標。第8~9行的作用是讓滑鼠的游標可以顯示出來，就像一般的視窗應用程式那樣。DISCL_FOREGROUND與DISCL_NONEXCLUSIVE設定了滑鼠的前景模式與非獨站模式[註1]，定義在DirectX的DirectInput中。 初始化參數設定好後，交由OIS建立InputManager（第2行）。接著，由InputManager建立輸入裝置的物件。前面提過，OIS支援許多輸入裝置，但一般電腦以鍵盤與滑鼠最為普遍。第5~6行分別建立鍵盤輸入與滑鼠輸入的物件，稍候取得輸入裝置的事件就由這兩個物件來操作。要注意的是，如果該裝置不存在，可是會丟出例外的！因為大家操作電腦都會有鍵盤跟滑鼠，所以這邊就省略了例外處理。建立輸入裝置物件的第二個參數,&#8217;false&#8217;,表示使用無緩衝的輸入模式(unbuffered input)，另外一種當然是緩衝式輸入(buffered input)了。這兩種輸入方式最大的差異是，如果用緩衝式輸入模式，輸入裝置會以事件通知的方式來傳遞輸入訊號。這種處理會以Listener的方法，來判斷哪個按鍵被按下，或是滑鼠動了多少。而無緩衝的輸入模式，需要由程式主動檢查輸入裝置的狀態，來獲取輸入的訊號。相較之下，無緩衝的輸入方式處理上較為簡單，因此先以無緩衝的為主。 OIS的部份暫告一段落，先來介紹另一個協助處理視窗狀態的小幫手：WindowEventListener。看到Listener，就想到這是個聽候差遣的類別。沒錯，這個WindowEventListener負責視窗改變事件的觸發，如尺寸改變、被關閉、被移動等等。WindowEventListener提供虛擬函式，因此需要一個衍生類別來重載虛擬函式。在Ogre的範例程式』ExampleFrameListener.h』中，ExampleFrameListener類別繼承了FrameListener與WindowEventListener，在這裡，我們也以那樣的方式同時繼承這兩個類別。類別的宣告如下面那樣： 和上一步相比，成員函式多了windowResized()與windowClosed()，分別處理視窗尺寸改變與被關閉時該做的動作。視窗尺寸改變的時候，要處理的事情只有設定新的縱橫比[註2]。我們只有一個Viewport，因此getViewport()的參數永遠是&#8217;0&#8242;。 而windowClosed()的處理也不複雜，就是將建立的OIS輸入物件釋放掉，最後釋放掉InputManager。話說，這個windowClosed()事件的觸發，是要「使用者關閉視窗」的動作發生時（像是按下視窗的&#8217;x'按鈕關閉）才會被觸發。如果是由程式關閉的，它也不會被作動。 回到WindowEventListener類別，當我們繼承並實做其中的函式後，當然要讓Ogre認識這個Listener。下面就是向目前的描繪視窗(m_render_window)註冊我們定義的WindowEventListener類別。不意外的，那個&#8217;this&#8217;就是當前的WindowEventListener類別（也就是MyOgreFrameListener）。 看了一堆，休息一下吧！接下來就是真正的主角：如何偵測鍵盤與滑鼠的輸入，來控制攝影機。對一個無緩衝的輸入裝置，要知道裝置目前的狀態（哪個鍵被按下），必須一直不斷地去偵測。FrameListener提供的事件是最恰當的，因為每描繪一張畫面，就要執行一次。以下開始，將說明MyOgreFrameListener::frameRenderingQueued()裡的程式碼。 很久很久以前，Hello, Ogre!視窗就一直沒辦法好好的關掉，不，是就算被關起來，自動描繪迴圈也不會結束。現在，只要讓false被回傳，繪圖迴圈就會結束了。第1行的任務，就是當視窗被關閉的時候，回傳false。第4~5行，分別擷取滑鼠與鍵盤目前的狀態。 為了要控制攝影機動作，一些關於攝影機控制的參數在這裡被定義。move_scale與rot_scale分別表示每次移動與旋轉的量，受到timeSinceLastFrame的作用，移動量為每秒100個單位而旋轉量為每秒36度(degree)。cam_translate為相機的位移（三個軸向），rot_x與rot_y則是相機左右轉動與俯仰傾的弧度。這些數值會由鍵盤與滑鼠的輸入，產生對應的值，達到改變相機位置與拍攝角度的目的。 上面這段程式碼，處理鍵盤輸入的對應動作。檢查鍵盤上的某個按鍵是否被按下，可以用OIS::Keyboard::isKeyDown()的回傳值來判斷。如果該按鍵有被按下，則函式回傳true，按鍵碼(KC_xxx)可以參考』OISKeyboard.h』裡的定義。這裡比較特別的是第5~9行的敘述，在按下F12按鍵後，會將目前畫面擷取後存為檔名』screenshot』加上時間戳記的png圖檔。而這個m_time_until_next_toggle的處理是比較有趣的，後面再詳細說明。 緊接著是滑鼠輸入的處理。在OIS::Mouse::capture()之後，滑鼠的輸入狀態會被保存在OIS::Mouse物件中，透過getMouseState()來取得。第3行是判斷滑鼠的哪個按鍵被按下，和鍵盤按鍵一樣，參考』OISMouse.h』可以查詢所定義的按鍵。在OIS::MouseState的定義中，滑鼠包含三個軸(OIS::Axis)，X,Y,Z，X與Y就不用說了，Z軸就是滾輪的動作。而每個軸產生的輸入量，則由其資料成員abs表示絕對量（這個超難用），或是rel表示相對量。 MyOgreFrameListener::frameRenderingQueued()裡的最後幾行敘述，就是將鍵盤輸入與滑鼠輸入的量，轉換為相機位移與旋轉的量後，更新相機的位置與角度。由於輸入的是相對量，相機的移動與轉動也是採用相對的方式。在最後，回傳true，讓描繪迴圈繼續執行下去。 最後，來談談關於無緩衝輸入的一個有趣的問題，與m_time_until_next_toggle這個變數的作用。當我們在按下按鍵的時候，我們會希望該按鍵能啟動某個動作，像是移動相機，或是開關燈光。別忘了按鍵的偵測是「每個畫面」檢查的，因此移動相機的時候，也許感覺不出來（我按著相機就動，一直動），但是如果是切換某個狀態呢？通常，按下按鍵到放開按鍵，會花上一段時間。這段時間對人來說非常短，但對一個每秒鐘畫上幾十幾百張的Ogre來講，實在是長得太多啦！因此，按鍵按下的時候，可能會被OIS發現保持「按下」的狀態好幾次，而導致狀態的改變（像是燈光開關）每張畫面都切換一次（開關開關&#8230;），這是個很糟也很蠢的事情。m_time_until_next_toggle變數，就是企圖利用一個倒數的時間，保證在該時間內不會有重複發生按鍵按下的對應事件被觸發。 上圖說明了按鍵按下去到起來時，發生在Ogre::FrameListener與OIS擷取鍵盤狀態的示意圖。淺灰虛線是每一次frameRenderingQueued()被執行的開始，假設很規律地每10ms一次。同時，假設按鍵按下去到放開會花上150ms，這時，Capture的綠色區塊表示了按鍵#1被按下時，OIS::Keyboard所擷取到按鍵被按下的動作，看起來真不妙啊！如果是控制電燈開關，那就每10ms切換一次開或關，燈會被玩壞的。而Capture w/ countdown則是加上一段延遲時間的控制，這裡設定time_until_next_toggle為200ms長，可以發現當第一次按鍵被偵測後（橘色區塊），time_until_next_toggle會被減去timeSinceLastFrame，也就是10ms。如果在 if-判斷句中設定time_until_next_toggle小於0才成立，那就會如圖那樣，只要time_until_next_toggle還沒倒數完，就不可能產生對應事件的觸發了。如果又有個按鍵#2被按下，那得等到time_until_next_toggle小於0後才會觸發對應事件（當然，按鍵#2的if-判斷句也要加上對time_until_next_toggle小於0的限制條件才行）。 也就是說，無緩衝輸入討厭的地方就是某些動作必須加上上述的限制條件，才能保證其執行的結果符合需求。就像前面將畫面存檔的動作，如果沒有設定延遲的時間，那光按一下F12可能就會存個好幾張圖。當然，維護這個條件也需要多一點點的成本，包括多一個m_time_until_next_toggle，以及： [下載] 範例程式 (VC2008 專案) ogre_tutorial_6.zip 7.5 Kb 這次的說明為了顧及理解上的方便，沒有完全按照程式碼的順序進行。建議把範例下載後對照來看，會更加清楚。 [註1] 裝置輸入的合作模式(cooperative level)，可以分為「前 / 後景模式」與「獨占 / 非獨占模式」兩種的組合。前後景模式，指示視窗在什麼狀態下能接受裝置的輸入。前景模式(DISCL_FOREGROUND)表示視窗僅在前景(focused)時接受輸入，而背景模式(DISCL_BACKGROUND)則表示視窗在背景時(unfocused)，仍然可以接收裝置的輸入（在前景時亦然）。獨占模式就比較容易理解，表示目前的輸入裝置（如滑鼠）是否僅能由該視窗使用。所以，如果設定為獨占模式(DISCL_EXCLUSIVE)，其他視窗就沒辦法接收裝置的輸入（看起來很像被綁架）。OIS對輸入裝置的預設值是採用「前景」且「獨占」的模式。結論是，如果對於一個「視窗化」的應用程式設定合作模式，會改變裝置對於該視窗的輸入表現。但是，對一個「全螢幕」的應用程式，前 / 後景模式的設定就不是那麼重要了。另外，鍵盤裝置是不允許使用獨占模式的。 若在OIS設定輸入裝置時，改變裝置輸入的前 / 後景模式，以本範例來說看不出效果。原因是，當Ogre發現視窗失去焦點時(unfocused)，會停止描繪迴圈的處理。因此，必須在初始化Ogre時，加上RenderWindow::setDeactivateOnFocusChange( false );這個敘述，強迫在視窗變背景時，仍然處理描繪的工作，才會看出輸入裝置的前 / 後景模式所造成的不同效果。 [註2] [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chia0418.wordpress.com&amp;blog=3262473&amp;post=299&amp;subd=chia0418&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
		<wfw:commentRss>http://chia0418.wordpress.com/2009/04/01/%e8%88%87ogre%e5%85%b1%e8%88%9e%ef%bc%9a%e7%ac%ac%e5%85%ad%e6%ad%a5%ef%bc%8c%e6%95%b2%e6%95%b2%e9%8d%b5%e7%9b%a4%e3%80%81%e5%8b%95%e5%8b%95%e6%bb%91%e9%bc%a0/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">嘉嘉</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/04/ogre-unbuffered_input.png" medium="image">
			<media:title type="html">ogre-unbuffered_input</media:title>
		</media:content>
	</item>
		<item>
		<title>與Ogre共舞：第五步，轉轉乳酪方塊</title>
		<link>http://chia0418.wordpress.com/2009/03/28/%e8%88%87ogre%e5%85%b1%e8%88%9e%ef%bc%9a%e7%ac%ac%e4%ba%94%e6%ad%a5%ef%bc%8c%e8%bd%89%e8%bd%89%e4%b9%b3%e9%85%aa%e6%96%b9%e5%a1%8a/</link>
		<comments>http://chia0418.wordpress.com/2009/03/28/%e8%88%87ogre%e5%85%b1%e8%88%9e%ef%bc%9a%e7%ac%ac%e4%ba%94%e6%ad%a5%ef%bc%8c%e8%bd%89%e8%bd%89%e4%b9%b3%e9%85%aa%e6%96%b9%e5%a1%8a/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 08:47:15 +0000</pubDate>
		<dc:creator>chia0418</dc:creator>
				<category><![CDATA[Ogre]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://chia0418.wordpress.com/?p=261</guid>
		<description><![CDATA[在這步中，將要介紹Ogre在描繪場景時，一個參與描繪流程的重要的類別：FrameListener，顧名思義就是Ogre每描繪一張畫面時，在旁邊「聽候通知」的類別。在行為上，FrameListener與回呼函數(callback function)相當，每當Ogre描繪一張畫面，會在適當事件發生的時候通知FrameListener來處理。我們可以利用FrameListener來處理每一個畫面中，物件的操作、攝影機視角的改變、以及其他輸出輸入的處理，讓使用者能夠與Ogre的場景有所互動。 Ogre提供的FrameListener類別不能直接使用，必須產生一個衍生類別後，實做FrameListener提供的虛擬函式。先來看看一個簡單的衍生FrameListener的例子： 在第1行，我們定義MyOgreFrameListener繼承了FrameListener類別。我們希望在描繪過程中，要能操作物件的位置與姿態，因此在data member中宣告Camera與SceneManager的指標，並在第4行建構子的地方初始化。第9~11行，就是FrameListener提供的三個事件通知的函式。函式所傳入的參數FrameEvent，包含了事件發生到目前為止的時間，與上一張畫面描繪的時間。 顯然的，FrameListener提供的三種「事件通知」就是今天的重點，這三個函式被執行的時機為： frameStarted() – 在描繪一張新畫面的開始之前。 frameRenderQueued() – 在描繪指令已經傳送出去（到顯示卡）後，並且在切換畫面的緩衝區之前。 frameEnded() – 在描繪這張畫面完成/結束後（切換畫面緩衝區之後）。 在先前版本的Ogre僅包含frameStarted()與frameEnded()兩個函式，frameRenderQueued()是1.6新增的。在Ogre提供的範例程式”ExampleFrameListener.h”中，就使用了frameRenderQueued()代替frameStarted()，處理使用者輸入的部份，到底frameRenderQueued()有什麼過人之處呢？ 上圖是FrameListener三種事件通知的執行時機，與GPU繪圖的時間關係示意圖。每一張畫面的描繪，Ogre (CPU)會順序執行： frameStarted() Ogre更新所有描繪的目標(render target) 傳送描繪指令到底層硬體(GPU) frameRenderQueued() 切換畫面緩衝區（這個時候，GPU已經把畫面描繪好，存在畫面緩衝區中，只要切換緩衝區，描繪好的畫面就會顯示在螢幕上） frameEnded() 在這個流程中，在3.執行完成後，CPU就暫時沒事了，描繪場景的工作交由顯示卡(GPU)處理。而frameRenderQueued()就是為了避免CPU閒置而出現的，進而提昇每秒鐘能處理的畫面數量。譬如說，原先在frameStarted()裡的處理步驟，搬到frameRenderQueued()裡面執行，就可以縮短每個畫面描繪的時間，這對注重效能的應用（像是遊戲）是個重要的設計。在Ogre的API參考文件中也說明，frameRenderQueued()很適合用來進行「每個畫面都需要」的處理。當然，這也有個小小小的缺點，那就是在frameRenderQueued()中所做的處理，必須等到下一張畫面才會出現。不過，對每秒能處理幾十到上百張畫面的情況來說，差這一張畫面的時間間隔似乎沒有太大的影響。 接下來就是這次的工作了！我們要在frameRenderQueued()中，設計物件的出現方式 &#8211; 旋轉。下面是讓12個乳酪方塊轉啊轉的程式碼： 還記得在上一步中提到的物件操作嗎？對，就是透過SceneNode來改變物件的位置與姿態。首先，我們要用SceneManager取得要操作的SceneNode。可是，在上一步的範例中，只有幫Entity取了”cube0”, “cube1”,&#8230;之類的名稱，沒有SceneNode的名稱怎麼辦？沒關係，可以透過Entity提供的getParentSceneNode()取得所依附的SceneNode。根據之前乳酪方塊們建立的關係，在第6行，任意選擇一個乳酪方塊的名稱，找出這個名字的Entity。接著，第10行，呼叫兩次getParentSceneNode()得到12個乳酪方塊的共同父節點（第一次呼叫取得該Entity的節點，第二次就是該節點的父節點），用center_node指標來表示。第13行，我們讓center_node以他自己(TS_LOCAL)的z軸方向，每個畫面旋轉angle角度。這個步驟會讓12個子節點跟著「旋轉」，但事實上是因為12個節點必須相對於父節點(center_node)保持位置與姿態的不變。而為了增加一點點華麗度(?)，第14行中center_node會以它的父節點(TS_PARENT)的x軸方向，每個畫面旋轉一半的angle角度（轉得慢一點）。這裡的angle定義在第4行，表示每個畫面要旋轉的角度量。最後，在第17行，回傳true讓描繪迴圈持續執行下去。 在實際執行時，如果你有處理能力較強的硬體，那麼乳酪方塊就會轉得比較快一點；反之，在較慢的電腦上，就會像慢動作那樣的轉啊轉。或許可以來點什麼辦法，讓不同的硬體都可以擁有同樣的表現。嗯&#8230;注意到那個傳進frameRenderingQueued()的參數了嗎？ 我們用FrameEvent::timeSinceLastFrame作為調整旋轉角度使用。在較快的電腦上，畫一張畫面的時間短，因此相對的旋轉角度會較小。這個timeSinceLastFrame的單位是秒，上面的敘述是讓angle設定為每秒鐘可以轉90度的數值。 好啦！FrameListener設計完成，該來看看成果了。不過，別忘了在開始執行前，要讓Ogre知道FrameListener的存在。在Ogre執行startRendering()之前，加上 第4行先產生一個自己定義的FrmaeListener，然後利用Root::addFrameListener()將我們的FrameListener加入Root。Ogre不限制FrameListener的數量，如果有需要，可以產生多個FrameListener分別擔任不同的任務。不過要使用FrameListener，僅限於使用自動描繪迴圈的方式（就是用startRendering()開始描繪迴圈）。如果是利用RenderTarget::update()自行描繪場景，則FrameListener不會收到任何的呼叫。 [下載] 範例程式 (VC2008 專案) ogre_tutorial_5.zip 5.6 Kb 在這個範例裡，多了兩個檔案，分別是』MyOgreFrameListener.h』與』MyOgreFrameListener.cpp』，宣告與實做MyOgreFrameListener類別。另外，參數與旋轉使用的參考座標系，可以自行改變，看看各有什麼效果。例如：將前面提到的center_node對自己的x軸旋轉，會發生什麼事呢？由於center_node的z軸也會旋轉，因此它的x軸是會改變方向的（相對於其父節點的座標系），所以&#8230;趕快自己改改看吧！ Posted in Ogre Tagged: Ogre, tutorial<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chia0418.wordpress.com&amp;blog=3262473&amp;post=261&amp;subd=chia0418&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
		<wfw:commentRss>http://chia0418.wordpress.com/2009/03/28/%e8%88%87ogre%e5%85%b1%e8%88%9e%ef%bc%9a%e7%ac%ac%e4%ba%94%e6%ad%a5%ef%bc%8c%e8%bd%89%e8%bd%89%e4%b9%b3%e9%85%aa%e6%96%b9%e5%a1%8a/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">嘉嘉</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/03/ogre-framelistener1.png" medium="image">
			<media:title type="html">ogre-framelistener</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/03/2009-03-28-15-58-32.gif" medium="image">
			<media:title type="html">轉轉乳酪方塊</media:title>
		</media:content>
	</item>
		<item>
		<title>與Ogre共舞：第四步，乳酪方塊的協奏曲</title>
		<link>http://chia0418.wordpress.com/2009/03/23/%e8%88%87ogre%e5%85%b1%e8%88%9e%ef%bc%9a%e7%ac%ac%e5%9b%9b%e6%ad%a5%ef%bc%8c%e4%b9%b3%e9%85%aa%e6%96%b9%e5%a1%8a%e7%9a%84%e5%8d%94%e5%a5%8f%e6%9b%b2/</link>
		<comments>http://chia0418.wordpress.com/2009/03/23/%e8%88%87ogre%e5%85%b1%e8%88%9e%ef%bc%9a%e7%ac%ac%e5%9b%9b%e6%ad%a5%ef%bc%8c%e4%b9%b3%e9%85%aa%e6%96%b9%e5%a1%8a%e7%9a%84%e5%8d%94%e5%a5%8f%e6%9b%b2/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 07:49:56 +0000</pubDate>
		<dc:creator>chia0418</dc:creator>
				<category><![CDATA[Ogre]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://chia0418.wordpress.com/?p=225</guid>
		<description><![CDATA[在前三步中，從安裝Ogre開始，到建立視窗並在Ogre中放了一個彩色三角片，我們已經接觸了幾個Ogre中重要的元件：Ogre根本的Root，系統繪圖API介面的RenderSystem，掌控物件配置的SceneManager，隸屬於ResourceManager、產生材質的MaterialManager，以及建立自訂幾何構成物件的ManualObject。在這步中，我們要用SceneManager在場景中擺設12個乳酪方塊，認識SceneManager如何控制元件的位置與姿態。當然，還是只用程式碼來完成一切唷。 首先，我們需要12個乳酪方塊，前面學會用ManualObject來產生一個三角片，當然也可以產生一個方塊囉！嗯～沒錯，產生立方體的程式不難，不過今天的重點不是ManualObject，所以暫時把它忘了吧！今天要登場的主角是Entity， 中文意思是「實體」，表示在場景中的物件其幾何構成的實體&#8230;真難解釋，還是先叫Entity吧。在Ogre中，多邊形物件(mesh)都由ResourceManager管理與載入。載入以後，Ogre還不能描繪它，必須由SceneManager產生該Mesh物件的Entity，才能上場。 上段程式碼的第1行，Entity是由SceneManager產生的，如同ManualObject一樣。”cube0”是產生Entity時給定的名字，在整個場景中必須是獨一無二的，不然Ogre會不爽給你看。在大多數的場合，createEntity()的第二個參數是Mesh物件的名稱，用來產生Mesh物件的Entity。不過SceneManager提供另外一種產生Entity的方式：使用預先製好的幾何模型，平面(PT_PLANE)、立方體(PT_CUBE)與球體(PT_SPHERE)。所以第1行就是產生一個名叫”cube0”的立方體（的Entity，你知道的）。第2行，我們透過ent這個指標來設定剛剛被產生Entity的材質。這個材質的名稱叫做”CheeseCube”，後面會說明它的產生方式。最後，和先前一樣，把Entity加入RootSceneNode，乳酪方塊就可以被Ogre畫出來囉。 Entity屬於MovableObject，看字面就知道他是個可以亂動的東西。SceneManager提供了七種可以亂動的物件：Camera, Light, Entity, ManualObject, BillboardChain (RibbonTrail), ParticleSystem。那麼，物件想放在場景中，要怎樣「擺」呢？SceneManager利用了一個樹狀節點的結構，來描述物件彼此間的關係，以及紀錄在場景中的位置與姿態。每一個節點，可以裝上(attach)一或多個「可以亂動的物件」，而物件的位置與姿態，就由該節點表示。換句話說，物件本身並不知道自己在哪裡，只有查詢節點才知道它的位置。舉例來說，你(SceneManager)把一個杯子(Mesh)放在房間(RootSceneNode)的桌上(SceneNode)，如果我想知道杯子在哪裡，問杯子一定沒有答案。杯子會知道自己在哪裡嗎？不會吧！只有你會記得它在哪裡。進一步來說，我問杯子在哪裡，你的回答會是：在房間(RootSceneNode)裡的桌子(SceneNode)上。如果桌子被搬動，那麼杯子在房間裡的位置就會跟著改變。這就是SceneNode簡單的概念。 我們先來看個改變位置的小例子。SceneNode提供兩種方法設定在場景中的位置：translate()跟setPosition()。translate()是設定相對的x,y,z位移量，預設是根據其父節點的座標系來平移。而setPosition()則是直接設定節點位置，只能根據其父節點的座標系。這個例子中，兩行敘述會讓RootSceneNode移動到(200, 200, 0)的位置： 這等同於下面這行敘述，直接把RootSceneNode的位置設成(200, 200, 0)： 如果上述三行敘述一起按照順序執行，最後RootSceneNode的位置會在哪？答案是(200, 200, 0)，答對了嗎？又，如果先執行setPosition()的敘述，再執行上述的兩個translate()敘述，RootSceneNode的位置會在哪？答案是(400, 400, 0)，不意外吧！ 接著，我們考慮旋轉的情形。在3D場景中，旋轉的操作往往會帶來許多意外的混亂。讓我們先弄清楚幾個重點： 1. 不論怎麼旋轉某節點，它的local space永遠不會改變。 2. 對某節點一起做旋轉與平移的操作，具有不可交換性。也就是旋轉與平移操作的順序會影響結果。 有點抽象，不過還好，看看小例子吧！（暗紅線標示世界座標系的x水平軸與y鉛直軸，水藍色箭頭表示平移操作，橘色箭頭表示旋轉操作） 上面兩組程式中，旋轉是以+z為轉軸，轉動30度。要注意的是，所有的操作都參考local space。如果換成SceneNode::TS_PARENT，表示平移或旋轉的操作是參考父節點座標系(parent space)。這就當成作業吧！在嘗試之前，不妨先推測看看會得到什麼樣的結果。 講了一大堆，其他的乳酪方塊呢？沒問題！我們打算把乳酪方塊繞著原點排成一圈，用一個for迴圈來完成。在節點的架構上，先由一個節點產生12個子節點，依序設定好位置後，再一一把Entity掛上去。另一個問題則是，每個Entity都需要一個不會重複的名字，所以就用索引值分別產生』cube0&#8243;, 『cube1&#8243;, 『cube2&#8243;,&#8230;這樣的名字。 在第2行先產生一個新的子節點，因為如果要移動這12個乳酪方塊，只要移動該節點就好囉！什麼？前面不是都用RootSceneNode嗎？也是可以啦，不過等物件一多，你就會知道手忙腳亂在哪裡了。排出這12個乳酪方塊的重點是第15,16行，請參考上面的小例子就可以明白其結果。而從前面使用到現在的』CheeseCube』材質，它的身份是： ColorValue裡填的分別是代表乳酪色的R,G,B值（範圍在0~1之間）。為了讓乳酪方塊看起來有「方塊」的感覺（因為我們現在還沒有去改變視角），所以範例中偷偷加了一個平行光源，讓乳酪方塊的不同面有亮暗之分。燈光與材質間的關係，以及他們錯綜複雜的參數設定，往後有機會碰到的。 在這個協奏曲中，主要的重點在Entity的使用，以及SceneNode的意義與操作。而旋轉與平移操作所參考的座標系統，會影響最後的結果，這部份也是需要多花點心思去理解的。最後，來個挑戰題吧！如同上面12個乳酪方塊的排列方式，但希望節點的設計是「串列」的方式，也就是每個節點（除了最後一個）都只有一個子節點跟在屁股後面，該怎麼做呢？不要先偷看答案喔！ [下載] 範例程式 (VC2008 專案) ogre_tutorial_4.zip 4.9 Kb 從這個範例開始，程式架構有一些變動。範例採用Ogre的sample裡的』ExampleApplication.h』的方式，將基本的部份定義為一個基礎類別，產生場景的部份宣告為純虛函數(pure virtual function)，由範例的需求來繼承與實做。如果class, pure virtual function看起來有點吃力，趁現在快去翻翻書吧！不然Ogre可是不會手下留情的喔！ [解答] 數值是大約值，沒有經過計算 ogre_tutorial_4_ans.zip 0.6kb [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chia0418.wordpress.com&amp;blog=3262473&amp;post=225&amp;subd=chia0418&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
		<wfw:commentRss>http://chia0418.wordpress.com/2009/03/23/%e8%88%87ogre%e5%85%b1%e8%88%9e%ef%bc%9a%e7%ac%ac%e5%9b%9b%e6%ad%a5%ef%bc%8c%e4%b9%b3%e9%85%aa%e6%96%b9%e5%a1%8a%e7%9a%84%e5%8d%94%e5%a5%8f%e6%9b%b2/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">嘉嘉</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/03/2009-03-23-11-26-44.png" medium="image">
			<media:title type="html">乳酪方塊x1</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/03/2009-03-23-13-59-48.png" medium="image">
			<media:title type="html">TRT範例</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/03/2009-03-23-13-59-01.png" medium="image">
			<media:title type="html">RTT範例</media:title>
		</media:content>

		<media:content url="http://chia0418.files.wordpress.com/2009/03/2009-03-23-14-56-54.png" medium="image">
			<media:title type="html">乳酪方塊x12</media:title>
		</media:content>
	</item>
	</channel>
</rss>
