<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-9004261571334633871</atom:id><lastBuildDate>Wed, 09 May 2012 10:05:45 +0000</lastBuildDate><category>旅行</category><category>電影雜記</category><category>寫不完的遊戲引擎</category><category>偶發雜感</category><category>遊戲雜記</category><category>程式雜技</category><category>生活筆記</category><title>藍斯洛‧雜技的雜記</title><description>"Good programmers copy, great programmers steal."</description><link>http://lancelotdiary.blogspot.com/</link><managingEditor>noreply@blogger.com (藍斯洛)</managingEditor><generator>Blogger</generator><openSearch:totalResults>96</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/lancelotdiary" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="lancelotdiary" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-814332234525372441</guid><pubDate>Wed, 09 May 2012 10:05:00 +0000</pubDate><atom:updated>2012-05-09T18:05:47.347+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>Unity3D Plug-in for Android -- Activity 擴展方法</title><description>&lt;p&gt;Unity3D 的 Android Plug-in 還有另一種實做方法。當需要使用 Android SDK 中的 Java 物件時，利用這個方法來將 Unity3D 與 Android SDK 結合是比較好的。&lt;/p&gt;  &lt;p&gt;簡單的步驟，&lt;/p&gt;  &lt;p&gt;1. 先在 Eclipse IDE 中，新建一個 Android Project。&lt;/p&gt;  &lt;p&gt;2. 在 Project 的 Property 中，點選 Java Build Path，切到 Libraries 的分頁，按鈕 &amp;quot;Add External JARs…&amp;quot;，然後選擇 Unity 安裝目錄，找到 &amp;quot;\Editor\Data\PlaybackEngines\androidplayer\bin&amp;quot; 子目錄裡的檔案 classes.jar 來加入    &lt;br /&gt;&lt;a href="http://lh5.ggpht.com/-ZQRMhQtt5R4/T6pBVsZcSxI/AAAAAAAAAa0/gIHNdHFVj2w/s1600-h/clip_image002%25255B5%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://lh4.ggpht.com/-rzgso4I50tk/T6pBYHstBmI/AAAAAAAAAa8/QCjJBaKzWt8/clip_image002_thumb%25255B2%25255D.jpg?imgmax=800" width="565" height="443" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;3. 修改 Activity 的 Java Code&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Activity 改成自 UnityPlayerActivity 繼承 ( import com.unity3d.player.UnityPlayerActivity )，在 Activity 的 OnCreate 函式裡，把預先產生的 setContentView() 函式呼叫刪除掉不要使用。 &lt;/p&gt;    &lt;p&gt;一個範例程式碼如下: ( UnityPlayerExtendActivity.java )      &lt;br /&gt;這個範例裡，我們不但使用了 Toast，還用到了Android SDK 中的 藍芽 API。這兩項功能，都是Unity3D無法提供的。&lt;/p&gt; &lt;/blockquote&gt; &lt;code style="width: 570px; height: 222px"&gt;   &lt;p&gt;&lt;b&gt;package&lt;/b&gt; com.activity.unityextend;&lt;/p&gt;    &lt;p&gt;&lt;b&gt;import&lt;/b&gt; com.unity3d.player.UnityPlayerActivity;&lt;/p&gt;    &lt;p&gt;&lt;b&gt;import&lt;/b&gt; android.os.Bundle;&lt;/p&gt;    &lt;p&gt;&lt;b&gt;import&lt;/b&gt; android.widget.Toast;&lt;/p&gt;    &lt;p&gt;&lt;b&gt;import&lt;/b&gt; android.bluetooth.BluetoothAdapter;&lt;/p&gt;    &lt;p&gt;&lt;b&gt;public&lt;/b&gt; &lt;b&gt;class&lt;/b&gt; UnityPlayerExtendActivity &lt;b&gt;extends&lt;/b&gt; UnityPlayerActivity {&lt;/p&gt;    &lt;p&gt;&lt;b&gt;private&lt;/b&gt; BluetoothAdapter mBluetoothAdapter = &lt;b&gt;null&lt;/b&gt;;&lt;/p&gt;    &lt;p&gt;/** Called when the activity is first created. */&lt;/p&gt;    &lt;p&gt;@Override&lt;/p&gt;    &lt;p&gt;&lt;b&gt;public&lt;/b&gt; &lt;b&gt;void&lt;/b&gt; onCreate(Bundle savedInstanceState) {&lt;/p&gt;    &lt;p&gt;&lt;b&gt;super&lt;/b&gt;.onCreate(savedInstanceState);&lt;/p&gt;    &lt;p&gt;//setContentView(R.layout.main);&lt;/p&gt;    &lt;p&gt;mBluetoothAdapter = BluetoothAdapter.&lt;i&gt;getDefaultAdapter&lt;/i&gt;(); &lt;/p&gt;    &lt;p&gt;&lt;b&gt;if&lt;/b&gt; (mBluetoothAdapter == &lt;b&gt;null&lt;/b&gt;) {&lt;/p&gt;    &lt;p&gt;Toast.&lt;i&gt;makeText&lt;/i&gt;(&lt;b&gt;this&lt;/b&gt;, &lt;/p&gt;    &lt;p&gt;&amp;quot;Bluetooth is not available.&amp;quot;, &lt;/p&gt;    &lt;p&gt;Toast.&lt;i&gt;LENGTH_LONG&lt;/i&gt;).show();&lt;/p&gt;    &lt;p&gt;finish();&lt;/p&gt;    &lt;p&gt;&lt;b&gt;return&lt;/b&gt;;&lt;/p&gt;    &lt;p&gt;}&lt;/p&gt;    &lt;p&gt;&lt;b&gt;if&lt;/b&gt; (!mBluetoothAdapter.isEnabled()) {&lt;/p&gt;    &lt;p&gt;Toast.&lt;i&gt;makeText&lt;/i&gt;(&lt;b&gt;this&lt;/b&gt;, &lt;/p&gt;    &lt;p&gt;&amp;quot;Please check your BT settings.&amp;quot;, // and re-run this program &lt;/p&gt;    &lt;p&gt;Toast.&lt;i&gt;LENGTH_LONG&lt;/i&gt;).show();&lt;/p&gt;    &lt;p&gt;//finish();&lt;/p&gt;    &lt;p&gt;//return;&lt;/p&gt;    &lt;p&gt;}&lt;/p&gt;    &lt;p&gt;}&lt;/p&gt;    &lt;p&gt;}&lt;/p&gt; &lt;/code&gt;  &lt;p&gt;4. 接著從 Eclipse IDE Export 出 jar 檔案。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh3.ggpht.com/-kmH_NZk9Of8/T6pBZF3QaEI/AAAAAAAAAbA/neSgm15EQXY/s1600-h/clip_image002%25255B6%25255D%25255B5%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image002[6]" border="0" alt="clip_image002[6]" src="http://lh5.ggpht.com/-Z8t1TwRPeCc/T6pBZyrXuWI/AAAAAAAAAbI/IKAdNeTAYpE/clip_image002%25255B6%25255D_thumb%25255B3%25255D.jpg?imgmax=800" width="430" height="454" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://lh6.ggpht.com/-G2XphyrKb8I/T6pBbN2_YFI/AAAAAAAAAbU/ZyEmAywO3ko/s1600-h/clip_image004%25255B6%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://lh3.ggpht.com/-x-HK6xjRiBU/T6pBcOt4xWI/AAAAAAAAAbc/o5fZ17TPFsI/clip_image004_thumb%25255B3%25255D.jpg?imgmax=800" width="409" height="493" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;5. 下一步，開啟 Unity3D，修改 Player Settings 設定。要注意的是， Bundle Identifier 與 Minimum API Level 要與 Eclipse 上的 Android Project 相同。&lt;/p&gt;  &lt;p&gt;6. 然後將 Eclipse 的 Android Project 檔案複製到 Unity 專案的目錄下， 這裡有幾個需要複製的檔案。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-iw16Xla-toU/T6pBcwUTXEI/AAAAAAAAAbg/SRX40uwS5zI/s1600-h/clip_image008%25255B4%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://lh6.ggpht.com/-seWpdYy5LMU/T6pBdqx1OII/AAAAAAAAAbo/5bzEL6cH_E0/clip_image008_thumb%25255B1%25255D.jpg?imgmax=800" width="360" height="261" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;     &lt;br /&gt;a. 在 Assets 目錄下建立 Plugins 目錄，再建立 Android 子目錄。 &lt;/p&gt;    &lt;p&gt;b. 將 Android Project 中的 AndroidManifest.xml 複製到 Plugins/Android 目錄內。&lt;/p&gt;    &lt;p&gt;c. 在 Plugins/Android 目錄內建立 bin 子目錄，將 Android Project 輸出的 jar 放進來。&lt;/p&gt;    &lt;p&gt;d. 最後將 Android Project 內的 res 子目錄複製到 Plugins/Android 目錄內&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;7. 最後，從 Unity3D Build &amp;amp; Run，就可以使用 Android SDK 提供的功能了。&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-814332234525372441?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2012/05/unity3d-plug-in-for-android-activity.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-rzgso4I50tk/T6pBYHstBmI/AAAAAAAAAa8/QCjJBaKzWt8/s72-c/clip_image002_thumb%25255B2%25255D.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-881606727753292813</guid><pubDate>Fri, 03 Feb 2012 09:22:00 +0000</pubDate><atom:updated>2012-02-03T17:22:19.098+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>Unity 3D Plug-in for Android 開發指南</title><description>&lt;p&gt;這是一個摸索筆記。&lt;/p&gt;  &lt;p&gt;以下是正文。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;一. &lt;/b&gt;&lt;b&gt;Unity3D Plug-in &lt;/b&gt;&lt;b&gt;必須知道的概念&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Unity 的 Plug-in 是以二進位存在的，所以，在不同的平台上，必須開發不同的 Plug-in，例如，在 PC Windows 平台，使用 dll 檔，在 Android 系統，使用 .so 檔。&lt;/p&gt;  &lt;p&gt;在使用 Unity 開發專案時，因為是在 PC Windows 平台上操作，所以當使用了 Android 的 .so 檔時，會造成無法在 Unity Editor 中即時操作遊戲的問題。至於是否可以有個取代方案，例如，另外寫個相同功能的 dll 檔來在 PC Windows 平台上操作，這要再做進一步測試。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;二. &lt;/b&gt;&lt;b&gt;Unity3D Plug-in &lt;/b&gt;&lt;b&gt;的安裝&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Unity 的官方文件，是建議將 Plug-in 複製到專案的 Assets/Plugins/Android 目錄下，如果沒這個目錄，就自行建立一個。&lt;/p&gt;  &lt;p&gt;所以，就是將寫好編譯好的 .so 檔，複製到這個目錄下就可。&lt;/p&gt;  &lt;p&gt;官方文件上有一個模稜兩可的說法，說 Plug-in 安裝後，Unity 會自動抓出其中的 Java Class 什麼的，不要相信它，因為完全試不出來。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;三. &lt;/b&gt;&lt;b&gt;Unity3D Plug-in &lt;/b&gt;&lt;b&gt;的使用&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;.so 檔複製到專案以後，是無法取得任何資料的。必須透過 C# Script 來載入。 官方文件中，只提供了使用 C# Script 來參考 Plug-in 的方法，找不到 Java Script 的方法，所以就先以 C# Script來做。&lt;/p&gt;  &lt;p&gt;官方網站上有一個可以參考的範例，&amp;quot;AndroidNativePlugin.zip&amp;quot;，可以下載來參考。&lt;/p&gt;  &lt;p&gt;zip 檔解開後，將 unity package import 進 Unity Editor，可以抓到 .so 檔，原始程式碼，以及使用 Plug-in 的 C# Script。 &lt;/p&gt;  &lt;p&gt;C# Script 如下 (已經改過了)&lt;/p&gt; &lt;code style="width: 571px; height: 222px"&gt;   &lt;p&gt;using UnityEngine;&lt;/p&gt;    &lt;p&gt;using System.Collections;&lt;/p&gt;    &lt;p&gt;using System.Runtime.InteropServices;&lt;/p&gt;    &lt;p&gt;public class CallNativeCode : MonoBehaviour {&lt;/p&gt;    &lt;p&gt;public GUISkin mySkin;&lt;/p&gt;    &lt;p&gt;[DllImport(&amp;quot;ttt&amp;quot;)]&lt;/p&gt;    &lt;p&gt;private static extern float add(float x, float y);&lt;/p&gt;    &lt;p&gt;void OnGUI ()&lt;/p&gt;    &lt;p&gt;{&lt;/p&gt;    &lt;p&gt;GUI.skin = mySkin;&lt;/p&gt;    &lt;p&gt;float x = 3;&lt;/p&gt;    &lt;p&gt;float y = 10;&lt;/p&gt;    &lt;p&gt;GUI.Label (new Rect (15, 125, 450, 100), &amp;quot;add&amp;quot; + x + &amp;quot; and &amp;quot; + y + &amp;quot; equals &amp;quot; + add(x,y));&lt;/p&gt;    &lt;p&gt;}&lt;/p&gt;    &lt;p&gt;}&lt;/p&gt; &lt;/code&gt;  &lt;p&gt;幾個重點:&lt;/p&gt;  &lt;p&gt;1. [DllImport(“ttt”)] : 這行程式，是負責載入 Plug-in，依照官方規定，這個Plug-in 的檔名是 libttt.so，也就是，前綴必須有”lib” 三個字母，後面是 .so 副檔名。&lt;/p&gt;  &lt;p&gt;2. private static extern float add(float x, float y); -- 這一行是宣告Plug-in中的函式。&lt;/p&gt;  &lt;p&gt;3. 載入與宣告函式完成後，在 Script 的 OnGUI 函式中，就可以使用這個函式了。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;四. &lt;/b&gt;&lt;b&gt;Android Plug-in &lt;/b&gt;&lt;b&gt;的開發&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;接著就是，.so 這個檔怎麼做出來了。&lt;/p&gt;  &lt;p&gt;.so 檔，可以視作是 Android 系統上的 Dynamic Load Library (dll)&lt;/p&gt;  &lt;p&gt;&lt;b&gt;1. &lt;/b&gt;&lt;b&gt;建立開發環境&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;一般書籍或網站上找到的 Android 應用開發，多是以 Java 環境來做的，這是無法編譯 .so 檔案的。&lt;/p&gt;  &lt;p&gt;Android 的 Development Kit 有兩種，一種是 SDK (Software Development Kit), 一種是 NDK (Native Development Kit)，編譯 .so 檔，需要 NDK。&lt;/p&gt;  &lt;p&gt;傳統的建立開發環境的方法是，要安裝 cygwin (Windows 上的 Linux 模擬器)、NDK、SDK、Eclipse IDE 等等，現在有個神人把整個開發環境整合到了 Visual Studio 2010上，所以建立開發環境的方法，就以整合 VS 2010 來做了。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://code.google.com/p/vs-android/"&gt;vs-android -- Integrated development of Android NDK C/C++ software under Visual Studio&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;下載vs-android，sample solution，然後下載 Android NDK (r7 or later)，SDK，Java SDK (32 bits版)，以及 Ant。&lt;/p&gt;  &lt;p&gt;需要安裝的安裝，可以解壓縮複製的，就解壓縮複製。( Android SDK 的安裝，比較複雜些，請找資料看看 )&lt;/p&gt;  &lt;p&gt;然後要設定幾個環境變數&lt;/p&gt;  &lt;p&gt;ANDROID_HOME : Android SDK 的根目錄位置，例如 C:\Develop\android-sdks &lt;/p&gt;  &lt;p&gt;ANDROID_NDK_ROOT : Android NDK 的根目錄位置，例如 C:\Develop\android-ndk-r7&lt;/p&gt;  &lt;p&gt;ANT_HOME : Apache Ant 的目錄，例如 C:\Develop\apache-ant-1.8.2&lt;/p&gt;  &lt;p&gt;&lt;b&gt;2. &lt;/b&gt;&lt;b&gt;測試範例程式 san-angeles&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;設定完成，打開 VS 2010，載入 Sample Solution，USB接上測試用設備，Build Solution，然後就 OK 了。&lt;/p&gt;  &lt;p&gt;&amp;lt;&amp;lt; 不過，還是會碰到編譯不過的情形啦。以下是幾個可能要處理的狀況。&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;a.      &lt;br /&gt;Unable to resolve target 'android-4'       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 因為在 SDK中的 Platform 版本裡沒有安裝 API Level 4，修改 project.properties 這個檔案中的 target=android-4，改為 SDK 有安裝的API&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;b.      &lt;br /&gt;ANTBUILD : [dx] error : Could not create the Java Virtual Machine.       &lt;br /&gt;ANTBUILD : [dx] error : A fatal exception has occurred. Program will exit.       &lt;br /&gt;[dx] Error occurred during initialization of VM       &lt;br /&gt;[dx] Could not reserve enough space for object heap       &lt;br /&gt;這問題，打開 android-sdks\platform-tools 目錄中的 dx.bat 檔案，將       &lt;br /&gt;set defaultXmx=-Xmx1024M       &lt;br /&gt;改為       &lt;br /&gt;set defaultXmx=-Xmx512M &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;gt;&amp;gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;3. &lt;/b&gt;&lt;b&gt;建立要編譯 .so 檔的專案&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;因為 vs-android 的神人作者，還沒有寫好 Project Wizard，所以，要靠半手動的方式來建立新專案。&lt;/p&gt;  &lt;p&gt;簡單一點的做法是，就在範例程式 solution 下新加入一個專案，選擇 Win32 Console App，然後建立 Empty Project。&lt;/p&gt;  &lt;p&gt;Project 的名稱，以 lib 開始，符合 Unity Plug-in 的規則。例如，libunityplug1&lt;/p&gt;  &lt;p&gt;專案建立完成，開啟專案的 Property Page，點選 Configuration Manager&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/--4bItb5mtgA/TyunOUZvC4I/AAAAAAAAAZ4/ksh7s7PWuNA/s1600-h/clip_image004%25255B5%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://lh5.ggpht.com/-DB4mTgCr6aI/TyunPLHVWoI/AAAAAAAAAZ8/DXbj4JbH0e8/clip_image004_thumb%25255B2%25255D.jpg?imgmax=800" width="574" height="346" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;新建立的專案還是 Win32 Platform，點選專案的 Platform 下拉箭頭，選擇 &amp;lt;&amp;lt;New&amp;gt;&amp;gt;，建立新的專案 Platform。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-3RfYwiMpn-I/TyunPvEOClI/AAAAAAAAAaE/PIEUQiDqgOw/s1600-h/clip_image006%25255B4%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://lh4.ggpht.com/-u43Mc4laI8I/TyunQnBW8sI/AAAAAAAAAaQ/zKsQbTtQmOo/clip_image006_thumb%25255B1%25255D.jpg?imgmax=800" width="552" height="273" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Platform 選擇 Android, Copy Setting 選擇 &amp;lt;Empty&amp;gt;，底下的 Create new solution platforms 要取消打勾。&lt;/p&gt;  &lt;p&gt;然後按下 OK&lt;/p&gt;  &lt;p&gt;新專案的 Project Platform 就會改成 Android，而專案中的 Property 也會自動調整為 Android 平台相關的設定。&lt;/p&gt;  &lt;p&gt;因為要產生的是 Dynamic Library ( .so ) 檔，所以，將 Configuration Type 調整為 Dynamic Library。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-nkPAjuxUc6E/TyunR-u5_-I/AAAAAAAAAaY/Ji-Cvxii0WU/s1600-h/clip_image008%25255B5%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://lh5.ggpht.com/-QQOHsxS2MW0/TyunSccgxWI/AAAAAAAAAac/9VgRN51nCbY/clip_image008_thumb%25255B2%25255D.jpg?imgmax=800" width="560" height="298" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;其他的 API Level, Architecture，有需要也可以改看看。&lt;/p&gt;  &lt;p&gt;然後就開始加入原始程式碼檔案吧!!&lt;/p&gt;  &lt;p&gt;&lt;b&gt;4. &lt;/b&gt;&lt;b&gt;Plug-in &lt;/b&gt;&lt;b&gt;程式碼與使用&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;很快，隨便寫了個 .c 的程式&lt;/p&gt; &lt;code&gt;   &lt;p&gt;float multiply(float x, float y)&lt;/p&gt;    &lt;p&gt;{&lt;/p&gt;    &lt;p&gt;return x * y;&lt;/p&gt;    &lt;p&gt;}&lt;/p&gt; &lt;/code&gt;  &lt;p&gt;然後 Build 這個 libunityplug1 專案，沒問題的話，會得到 libunityplug1.so 的檔案，把 .so 檔案複製到 Unity 的 Assets/Plugins/Android 目錄下&lt;/p&gt;  &lt;p&gt;修改 Unity C# Script&lt;/p&gt; &lt;code&gt;   &lt;p&gt;[DllImport(&amp;quot;unityplug1&amp;quot;)]&lt;/p&gt;    &lt;p&gt;private static extern float multiply(float x, float y);&lt;/p&gt; &lt;/code&gt;  &lt;p&gt;然後，就可以使用這個函式了。&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-881606727753292813?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2012/02/unity-3d-plug-in-for-android.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-DB4mTgCr6aI/TyunPLHVWoI/AAAAAAAAAZ8/DXbj4JbH0e8/s72-c/clip_image004_thumb%25255B2%25255D.jpg?imgmax=800" height="72" width="72" /><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-5285676898747187356</guid><pubDate>Fri, 07 Oct 2011 03:24:00 +0000</pubDate><atom:updated>2011-10-07T11:24:08.096+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>Visual Studio 2010 是好物</title><description>&lt;p&gt;很久沒碰 MFC了。&lt;/p&gt;  &lt;p&gt;前一陣子 CryEngine 釋出 SDK，抓來看了以後，發現它的編輯器介面很漂亮，多翻了翻，才知道原來是用 MFC Library 做的。&lt;/p&gt;  &lt;p&gt;這下子又引起我對 MFC 的興趣。&lt;/p&gt;  &lt;p&gt;顯然 MFC 還不至於像傳說中的那麼慘。&lt;/p&gt;  &lt;p&gt;最近打算重新改寫遊戲資源檔案打包上傳的工具程式，想到了 MFC，打算拿著來試試。&lt;/p&gt;  &lt;p&gt;發現了這麼一篇 Blog&lt;/p&gt;  &lt;p&gt;&lt;a href="http://10rem.net/blog/2010/03/25/your-first-mfc-cplusplus-ribbon-application-with-visual-studio-2010"&gt;Your First MFC C++ Ribbon Application with Visual Studio 2010&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;哦~~~&lt;/p&gt;  &lt;p&gt;MFC 做出來的應用程式介面不再那麼難看了耶~~&lt;/p&gt;  &lt;p&gt;趕快隨手很快的建了一個專案，勾選幾個項目後，完整功能的 Dock Panel, Ribbon Menu ( 還有一個 Outlook的 Navigation Bar 沒勾) 都有了...&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-7vs3GNJUE_8/To5w1JId5zI/AAAAAAAAAZI/IlgPX6Qh_oQ/s1600-h/clip_image001%25255B5%25255D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://lh6.ggpht.com/-rOFUdQ4LSK8/To5w1wpgrgI/AAAAAAAAAZM/B0RvWTxlDgM/clip_image001_thumb%25255B2%25255D.jpg?imgmax=800" width="553" height="356" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;沒做什麼事，而應用程式看上去的專業度大大提升...&lt;/p&gt;  &lt;p&gt;VS 2010 真是好物...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-5285676898747187356?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2011/10/visual-studio-2010.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-rOFUdQ4LSK8/To5w1wpgrgI/AAAAAAAAAZM/B0RvWTxlDgM/s72-c/clip_image001_thumb%25255B2%25255D.jpg?imgmax=800" height="72" width="72" /><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-6179688577871072209</guid><pubDate>Tue, 19 Jul 2011 14:30:00 +0000</pubDate><atom:updated>2011-07-19T22:30:35.579+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">寫不完的遊戲引擎</category><title>圖形除錯設備</title><description>&lt;p&gt;今年 GDC 給我的一個大震撼，就是，Game Engine / Graphic Engine 裡，要加上圖形除錯功能。&lt;/p&gt;  &lt;p&gt;回頭翻了一本 3D Game Engine Architecture 的書，才發現人家早早就有說了。&lt;/p&gt;  &lt;p&gt;這些功能的用處很大，做了絕對有好處。&lt;/p&gt;  &lt;p&gt;然後發現，啊，Engine 裡頭那個顯示 Bounding Box 的物件，不就是其中一個圖形除錯物件麼?&lt;/p&gt;  &lt;p&gt;Bungie 在開發 HALO 時，連網路封包的數據與優先權都用即時圖形顯示。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-VMD81sAkClQ/TiWU5Z2U7jI/AAAAAAAAAY0/ORVjF704c5U/s1600-h/image3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-cn02xGokqDk/TiWU6gcLVJI/AAAAAAAAAY4/oQZNHDe1Qsg/image_thumb1.png?imgmax=800" width="575" height="330" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;我們真的該把圖形除錯的功能加到 Engine 裡。&lt;/p&gt;  &lt;p&gt;我叫它做「圖形除錯設備」。 ( Graphic Debugging Facilities )&lt;/p&gt;  &lt;p&gt;首先，我把 Game Timer 做了修改。加上加速、放慢、暫停、甚至每個 Frame 更新固定時間的功能。這些在我們做 Animation 的除錯時，應該會很有幫助。另外，我還加了一個 Real Life 的 Timer，我們總還是會需要知道真實時間的吧?&lt;/p&gt;  &lt;p&gt;然後， Engine 裡面加了一整組的 Debug Drawing API，包括畫線、畫圓、畫顆 Wireframe 的球、畫個十字、畫個座標軸、顯示字串訊息在 3D 場景裡，還有一個很有用的，畫個 Frustum 出來。&lt;/p&gt;  &lt;p&gt;最後一個組件呢，就是弄了一組除錯用的 Camera 跟 Frustum。遊戲場景的攝影機，是場景管理中很重要的運算基礎，但是我們怎麼知道這些運算有沒有問題? 例如，Frustum 的 Culling 運算、遠方物件的 LOD 選擇，有了除錯 Camera 的模式，我們就可以很簡單的做檢查。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-n77P6GO_Rkk/TiWU7nLPZlI/AAAAAAAAAY8/k5zrYManpiE/s1600-h/image%25255B5%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-fzAAx2E2tQM/TiWU8H2FNfI/AAAAAAAAAZA/UhFF40R7k8g/image_thumb%25255B2%25255D.png?imgmax=800" width="439" height="314" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hmm... 看來 Frustum 的 Culling 並沒有算得很乾淨...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-6179688577871072209?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2011/07/graphic-debugging-facilities.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-cn02xGokqDk/TiWU6gcLVJI/AAAAAAAAAY4/oQZNHDe1Qsg/s72-c/image_thumb1.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-7799928981675528593</guid><pubDate>Sun, 05 Jun 2011 06:39:00 +0000</pubDate><atom:updated>2011-06-05T14:39:03.690+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>30 天打造 OS!</title><description>&lt;p&gt;其實這是我今天帶回的一本奇書，它的副標題。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-guEDaJEYVMM/Teskg_SKX6I/AAAAAAAAAYY/n1WfDrrlM4A/s1600-h/image%25255B3%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-l14KbAco0KE/TeskhsgQIMI/AAAAAAAAAYc/oWNwAOydiMc/image_thumb%25255B1%25255D.png?imgmax=800" width="243" height="339" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;(圖片來源: 博客來書籍館)&lt;/p&gt;  &lt;p&gt;日本人寫的，譯者有三位。&lt;/p&gt;  &lt;p&gt;為什麼說它是奇書 ?&lt;/p&gt;  &lt;p&gt;你看標題就知道了， 「自己做作業系統 ? 這什麼 ?」&lt;/p&gt;  &lt;p&gt;台灣的資訊相關書籍，多如過江之鯽，作業系統核心的內容已經夠硬了，還要自己寫程式來做 ? 而且一開始還是拿組合語言拼出來的開機程式，這絕對是硬派中的硬派。&lt;/p&gt;  &lt;p&gt;市場更是小之又小。&lt;/p&gt;  &lt;p&gt;幾個月前我在書店裡看到的時候，愣了一下，覺得很神奇，怎麼會有人出版這種書 ? 有個怪咖會寫這種書不奇怪，但是翻譯了出版來賣 ? 這就很匪夷所思了。&lt;/p&gt;  &lt;p&gt;就算上架了，大概也沒幾個人會在書店裡把它拿起來翻閱的吧?&lt;/p&gt;  &lt;p&gt;果然， 今天閒晃的時候又看到它，整本書還是跟新的一樣。&lt;/p&gt;  &lt;p&gt;我沒有多想，就把它買下帶回家了。&lt;/p&gt;  &lt;p&gt;這種市場小之又小的書，一不注意，就會消失在書店裡，再也找不著。&lt;/p&gt;  &lt;p&gt;話又說回來，書的封底是這麼寫的：&lt;/p&gt;  &lt;p&gt;-----&lt;/p&gt;  &lt;p&gt;可能是史上最有趣且實用的作業系統書籍！日文版已突破13刷！&lt;/p&gt;  &lt;p&gt; 這是一本兼具趣味、實用與學習性的作業系統書籍。作者以獨創手法，從電腦的構造、組合語言、C語言開始解說，讓讀者透過實作與測試學會演算法，並在自由愉悅的氛氛下，從零開始建構作業系統。&lt;/p&gt;  &lt;p&gt; 即使是初學者，也不需畏懼，因為連貓咪都能輕鬆學會自作作業系統！&lt;/p&gt;  &lt;p&gt;-----&lt;/p&gt;  &lt;p&gt;貓咪也能學會? 廣告不實...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-7799928981675528593?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2011/06/30-os.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-l14KbAco0KE/TeskhsgQIMI/AAAAAAAAAYc/oWNwAOydiMc/s72-c/image_thumb%25255B1%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-8864037071426683981</guid><pubDate>Tue, 08 Mar 2011 14:42:00 +0000</pubDate><atom:updated>2011-03-08T22:42:39.499+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>GDC 2011 Day 5</title><description>&lt;p&gt;最後一天，算算只有四個小時的課。&lt;/p&gt;  &lt;p&gt;今天的開場，由 Bungie 的 Halo : Reach 開始。&lt;/p&gt;  &lt;p&gt;首先是 Automated Level of Detail Generation。&lt;/p&gt;  &lt;p&gt;顧名思義，就是用程式算出 LOD Mesh。裡頭的演算方法，是很不錯的想法，可以找時間來模擬嘗試看看。&lt;/p&gt;  &lt;p&gt;而除了 LOD Mesh 之外，他們還提出了一個做法 – &amp;quot;Unified material model&amp;quot;。&lt;/p&gt;  &lt;p&gt;簡單講，就是所有的 LOD Mesh 都使用同一種材質 Shader ，這樣一來，也可以提升很多效能。更重要的是，反正距離很遠、物件很小的時候，就算畫的很粗略，也不是那麼明顯...&lt;/p&gt;  &lt;p&gt;在這裡，他們也展示了一個在除錯模式下的攝影機，可以用來檢查 LOD 的變化是否如預期。&lt;/p&gt;  &lt;p&gt;Hmm… 我們似乎也該弄個 Debug Mode Camera 來了。&lt;/p&gt;  &lt;p&gt;第二段，講述的是 Halo : Reach 裡的 Effect。&lt;/p&gt;  &lt;p&gt;第一個來的 Effect，就是嚇死人的粒子系統。&lt;/p&gt;  &lt;p&gt;有多恐怖? &lt;/p&gt;  &lt;p&gt;1. 粒子的運算全部交由 GPU 計算，CPU 只決定粒子的數量。&lt;/p&gt;  &lt;p&gt;2. 在 GPU 裡計算的粒子，照樣可以跟場景中的物件計算碰撞跟彈跳。&lt;/p&gt;  &lt;p&gt;所以，只要一個 GPU Draw Call ，就可以畫出所有的粒子，而且還會有碰撞彈跳。&lt;/p&gt;  &lt;p&gt;碰撞與彈跳計算的資料來源有兩個，Depth Buffer 與 Normal Buffer。計算的概念，說穿了一點都不難，但是，要能夠想到這點，還真的是不容易。&lt;/p&gt;  &lt;p&gt;接下來的效果，都跟 Depth Buffer 有關。&lt;/p&gt;  &lt;p&gt;Bungie 給了一個結論 – &amp;quot;Depth buffer is incredibly useful&amp;quot;&lt;/p&gt;  &lt;p&gt;前兩天，岩田聰社長說 : &amp;quot;Content is KING&amp;quot;&lt;/p&gt;  &lt;p&gt;今天我們的結論是 : &amp;quot;Depth Buffer is KING&amp;quot;&lt;/p&gt;  &lt;p&gt;接下來聽了一場跟想像中的內容不太一樣的講題。&lt;/p&gt;  &lt;p&gt;本來以為他們會介紹如何處理一個龐大遊戲場景的概念與方法，結果，他們是有介紹啦，但是卻是基於他們自己的工具系統，有一點失望，不過也還是有一點收穫就是。&lt;/p&gt;  &lt;p&gt;下午聽了一場是關於拳擊遊戲裡，對於拳手的皮膚效果的處理方式，很新鮮，而且他們的專業研究，也不得不讓人佩服。&lt;/p&gt;  &lt;p&gt;過去一整個看起來像 &amp;quot;塑膠&amp;quot; 的皮膚，經過研究分析改進之後，變得非常自然。&lt;/p&gt;  &lt;p&gt;真是夠專業。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;最後，把像素拼圖的完成圖拍了下來。 ( 雖然這已經是由工作人員完成的了... )&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kNRcDdsHvgQ/TXZASD2TR-I/AAAAAAAAAYQ/6MpZuRBkl8E/s1600-h/DSC01442%5B5%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="DSC01442" border="0" alt="DSC01442" src="http://lh5.ggpht.com/_kNRcDdsHvgQ/TXZAWwGb59I/AAAAAAAAAYU/fPi5GJyWXAI/DSC01442_thumb%5B2%5D.jpg?imgmax=800" width="510" height="384" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-8864037071426683981?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2011/03/gdc-2011-day-5.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_kNRcDdsHvgQ/TXZAWwGb59I/AAAAAAAAAYU/fPi5GJyWXAI/s72-c/DSC01442_thumb%5B2%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-7189214967318513100</guid><pubDate>Fri, 04 Mar 2011 05:42:00 +0000</pubDate><atom:updated>2011-03-04T13:42:04.945+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>GDC 2011 Day 4</title><description>&lt;p&gt;中午又跑去任天堂的展場去玩 3DS，本來是想要玩玩薩爾達的，可是人好多擠不進去，晃了一陣，只玩到 Street Fighter。&lt;/p&gt;  &lt;p&gt;也很讚。&lt;/p&gt;  &lt;p&gt;早上第一場，去聽了 Killzone 3 有關 Occlusion Culling 的技術，基本概念也還是用個 Buffer 來記錄深度，然後做測試運算，沒什麼新的。不過說的很詳細，比起昨天用兩三張畫面帶過的那一場，好太多了。&lt;/p&gt;  &lt;p&gt;更重點是，他們做了一整套在 Occlusion Culling 上的 Debug 工具，可以很清楚看到 Occlusion Culling 計算前計算後的結果。&lt;/p&gt;  &lt;p&gt;視覺化很重要，尤其是這東西跟美術有關。&lt;/p&gt;  &lt;p&gt;接下來去聽了 Dead Rising 2 在網路功能方面的經驗分享。&lt;/p&gt;  &lt;p&gt;這遊戲好像賣的很不錯? 整場聽眾有爆滿啊...不過我很懷疑有多少人不是技術背景的，至少最後發問的人裡頭有一兩個...( 問的問題居然是遊戲的銷售量?? )&lt;/p&gt;  &lt;p&gt;網路功能，嗯，對我們在 MMO 上面已經有些經驗的人來說，這些分享的內容並沒有太多的不同。反倒是，他們也做了個 工具來監看 Traffic、監看資料同步的結果...就顯示在遊戲畫面上...Real-Time…&lt;/p&gt;  &lt;p&gt;只能說，他們真的很愛做工具。不知道是因為專業還是因為人太多?&lt;/p&gt;  &lt;p&gt;下午，有一個題目很吸引人。&lt;/p&gt;  &lt;p&gt;&amp;quot;Adaptive Order Independent Transparency&amp;quot;&lt;/p&gt;  &lt;p&gt;Render 半透明物件不用先排序。&lt;/p&gt;  &lt;p&gt;基本概念還是與 A-Buffer 有關。只不過，將 A-Buffer 的第二階段 -- 排序與組成，引入一個 &amp;quot;Visibility Function&amp;quot;，以當作權重的方式，計算半透明 Pixel 最後合成的結果。用這樣的方式，刪去耗費時間的排序工作。&lt;/p&gt;  &lt;p&gt;效能增加很多。&lt;/p&gt;  &lt;p&gt;不過這 &amp;quot;Visibility Function&amp;quot;的計算有些複雜。&lt;/p&gt;  &lt;p&gt;接下來的課程是，Bugie 講述 Halo : Reach 遊戲裡網路相關的技術分享。&lt;/p&gt;  &lt;p&gt;有一句話寫得好 : &amp;quot;Technology to help multiple players sustain the belief that they are playing a fun game together&amp;quot;&lt;/p&gt;  &lt;p&gt;他舉了兩個遊戲中的例子，來看他們把網路延遲藏的有多好。&lt;/p&gt;  &lt;p&gt;然後，又看到了 Traffic 監看的工具...也是直接顯示在遊戲畫面上...也是 Real-Time…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kNRcDdsHvgQ/TXB7mDmBT1I/AAAAAAAAAYA/rBNIYsPVju8/s1600-h/DSC01306%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DSC01306" border="0" alt="DSC01306" src="http://lh6.ggpht.com/_kNRcDdsHvgQ/TXB7nHS9f9I/AAAAAAAAAYE/I0Ewh5pQWkY/DSC01306_thumb%5B1%5D.jpg?imgmax=800" width="532" height="400" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;他們真的很喜歡做工具...&lt;/p&gt;  &lt;p&gt;不過，這工具應該還是有用的，至少他們抓到了一個問題: 一個還在滾動的手榴彈用了很大量的頻寬...&lt;/p&gt;  &lt;p&gt;最後一堂課程是超大的一顆地雷...&lt;/p&gt;  &lt;p&gt;又沒有其他課程好去，所以就坐著混到下課...&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;今天的像素拼圖長這樣:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_kNRcDdsHvgQ/TXB7pt2ciVI/AAAAAAAAAYI/Ea1uLz_LNsc/s1600-h/DSC01234%5B5%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="DSC01234" border="0" alt="DSC01234" src="http://lh4.ggpht.com/_kNRcDdsHvgQ/TXB7qq5xfBI/AAAAAAAAAYM/oK1lO7QKC98/DSC01234_thumb%5B2%5D.jpg?imgmax=800" width="499" height="375" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;昨天那個日本人做的馬力歐已經不見了，應該是工作人員把它拆了。&lt;/p&gt;  &lt;p&gt;那個蹲著在拼的，應該就是工作人員。手上有一大包同樣顏色的方塊，拼完了又去拿了一大包來拼。&lt;/p&gt;  &lt;p&gt;有工作人員做修正，那這個活動也沒什麼意思了...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-7189214967318513100?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2011/03/gdc-2011-day-4.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_kNRcDdsHvgQ/TXB7nHS9f9I/AAAAAAAAAYE/I0Ewh5pQWkY/s72-c/DSC01306_thumb%5B1%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-9020255914885646812</guid><pubDate>Thu, 03 Mar 2011 03:55:00 +0000</pubDate><atom:updated>2011-03-03T12:15:24.570+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>GDC 2011 Day 3</title><description>&lt;p&gt;Game Develop Conference 今天算是正式開始。&lt;/p&gt;  &lt;p&gt;一開始的盛事，就是任天堂社長岩田聰的 Keynote 演講。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/TW8RD1b9oYI/AAAAAAAAAXg/eh2Ben-tOlw/s1600-h/DSC01132%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="DSC01132" border="0" alt="DSC01132" src="http://lh3.ggpht.com/_kNRcDdsHvgQ/TW8RElNtSVI/AAAAAAAAAXk/k9xPAnDU9Ig/DSC01132_thumb%5B1%5D.jpg?imgmax=800" width="440" height="331" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/TW8RFgNy6hI/AAAAAAAAAXo/b9SglRvVUmg/s1600-h/DSC01134%5B5%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="DSC01134" border="0" alt="DSC01134" src="http://lh3.ggpht.com/_kNRcDdsHvgQ/TW8RGDzj9DI/AAAAAAAAAXs/TU-VEng3zx4/DSC01134_thumb%5B2%5D.jpg?imgmax=800" width="441" height="331" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;說真的，日本人講的英文聽起來有難度，我想他說起來也不會簡單...&lt;/p&gt;  &lt;p&gt;所以，在他演講台的正對面有大字報...&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/TW8RHHEoC2I/AAAAAAAAAXw/YKH92q_0M_U/s1600-h/DSC01135%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="DSC01135" border="0" alt="DSC01135" src="http://lh5.ggpht.com/_kNRcDdsHvgQ/TW8RHgLDLLI/AAAAAAAAAX0/c2UXDQijbLM/DSC01135_thumb%5B1%5D.jpg?imgmax=800" width="435" height="327" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;演講主題呢，就是內容啦、創意啦、熱情啦...這些東西...&lt;/p&gt;  &lt;p&gt;一個小時的演講，中間還讓北美的任天堂主管進來工商服務一段 N3DS…&lt;/p&gt;  &lt;p&gt;N3DS&lt;/p&gt;  &lt;p&gt;真的是很讚。&lt;/p&gt;  &lt;p&gt;中午休息時間，到任天堂的展場去，搶到空位，把玩了一下 N3DS 的任天貓狗，整個裸眼 3D 的畫面效果好逼真啊...&lt;/p&gt;  &lt;p&gt;不過這個真的要親眼看，有圖就沒真相了。&lt;/p&gt;  &lt;p&gt;其他的四堂課，好像都碰到了大大小小不等的地雷，沒有什麼非常 Exciting 的東西。倒是另一位同事選到了一兩個有意思的課程。&lt;/p&gt;  &lt;p&gt;首先是 Autodesk 講他們正在進行的新計畫 -- DNA Language，用來做為 Game Runtime, Game Editor, DCC Tools 之間的資料庫管理橋樑。讓 Asset 的製作與測試，能夠有更快速順暢的 Workflow。&lt;/p&gt;  &lt;p&gt;可是，我只是想知道 Asset 的版本管理方法啊... 課程簡介上不是寫的是這個嗎? 你們不能就這樣輕輕鬆鬆帶過啊...&lt;/p&gt;  &lt;p&gt;下午，先去聽 Valve 的演講，這場技術性比較高些，可能跟這個演講者老是在玩組合語言有關。&lt;/p&gt;  &lt;p&gt;網頁： &lt;a href="http://bit.ly/hPCmVW"&gt;http://bit.ly/hPCmVW&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;然後去聽了 BattleField 3 的新的場景 Culling 的方法。&lt;/p&gt;  &lt;p&gt;什麼新方法?&lt;/p&gt;  &lt;p&gt;把矩陣行列轉過來，讓 SIMD 運算比較快些，也算新方法?&lt;/p&gt;  &lt;p&gt;然後講 Software Culling，什麼? 就畫在一張比較小的 Z-Buffer 上然後做 Z-Test ?&lt;/p&gt;  &lt;p&gt;我快昏了...&lt;/p&gt;  &lt;p&gt;最後一堂課，去聽 AMD 介紹新版 PerfStudio。心得就是 : AMD 用了一張顯示卡，換到了幾十張開發者的名片...&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;今天的像素拼圖是這樣--&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/TW8RJuMCeCI/AAAAAAAAAX4/IxY-WV3bKdw/s1600-h/DSC01151%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="DSC01151" border="0" alt="DSC01151" src="http://lh5.ggpht.com/_kNRcDdsHvgQ/TW8RKTkQu7I/AAAAAAAAAX8/vQzztCSKKCQ/DSC01151_thumb%5B1%5D.jpg?imgmax=800" width="435" height="327" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;那個蹲跪著在拼的應該是日本人，他也不管格子上面寫的是什麼符號，反正就是要從別的地方拆方塊下來拼馬利歐就對了。&lt;/p&gt;  &lt;p&gt;我開始覺得，每個人都想要做自己的創意，這張圖應該沒辦法完成了...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-9020255914885646812?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2011/03/gdc-2011-day-3.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_kNRcDdsHvgQ/TW8RElNtSVI/AAAAAAAAAXk/k9xPAnDU9Ig/s72-c/DSC01132_thumb%5B1%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-3499750219521335142</guid><pubDate>Wed, 02 Mar 2011 04:31:00 +0000</pubDate><atom:updated>2011-03-03T12:17:26.190+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>GDC 2011 Day 2</title><description>&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_kNRcDdsHvgQ/TW3Hp_Y2ceI/AAAAAAAAAXU/cZn_DVPj9wE/s1600-h/DSC01131%5B5%5D.jpg"&gt;&lt;img style="background-image: none; border: 0px none; margin: 3px 5px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="DSC01131" alt="DSC01131" src="http://lh4.ggpht.com/_kNRcDdsHvgQ/TW3ID9_nWcI/AAAAAAAAAXc/SNvO66XuPg8/DSC01131_thumb%5B2%5D.jpg?imgmax=800" width="561" border="0" height="421" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;這是一道壁報牆，上面的一點一點紅色藍色黃色黑色的小方塊，是由每一位 GDC 的參加者，一人一塊貼上去的。&lt;/p&gt;  &lt;p&gt;白色的格子上有小小的標示，寫著方格該貼的顏色，每一位 GDC 的參加者會拿到一塊方塊，自己對著顏色貼上去。&lt;/p&gt;  &lt;p&gt;很有意思的活動，象徵著古早時代的遊戲美術一個像素一個像素的"刻點"。&lt;/p&gt;  &lt;p&gt;不過那個戴帽子的老兄不知道在幹嘛，一直從別的地方把方塊拔下來黏到他要的地方去...&lt;/p&gt;  &lt;p&gt;明天再去看看完成度如何...&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;第二天的課程，選擇去微軟的 Kinect Develop Summit。&lt;/p&gt;  &lt;p&gt;據說 Kinect XDK for Windows 即將要釋出，不知道是不是表示 Kinect 可以裝在 PC 上了。這會是什麼景象?&lt;/p&gt;  &lt;p&gt;---------------------------------------------------------------------------------------------------------------------&lt;/p&gt;  &lt;p&gt;微軟還是很上道，去聽的人都能夠拿到一份光碟，所以就不用拼命低頭寫重點或是把投影片拍下來。&lt;/p&gt;  &lt;p&gt;還送了一小疊很有質感的筆記紙。&lt;/p&gt;  &lt;p&gt;一開場的簡介，快講完的時候，有這麼一段--&lt;/p&gt;  &lt;p&gt;本來完全不玩遊戲的媽媽，跟參與 Kinect 開發的兒子說，要買 Kinect 來玩，而且，現在每天玩。所以，這是一個遊戲產業的世代革命...&lt;/p&gt;  &lt;p&gt;好，這故事從 Wii 換成 Kinect，故事主角從宮本茂的老婆換成某位微軟員工的媽...&lt;/p&gt;  &lt;p&gt;老梗。&lt;/p&gt;  &lt;p&gt;Kinect 有幾個主題，Joint Filter, Gesture Detection, Speech Recognition, 還有 Mechine Learning, Neural Network。&lt;/p&gt;  &lt;p&gt;我們能說，整個系統已經不再是 true / false, 0 與 1 的思考方式，必須改用機率、權重、取樣分佈來想。&lt;/p&gt;  &lt;p&gt;而且，這樣的系統裡，取得的資料很多，資料裡的雜訊更多，如何取得能用與有用的資料，就變成是 Filter 的技術所在。&lt;/p&gt;  &lt;p&gt;Gesture Detection 也不簡單，因為每個人的姿勢手勢都不同，很多元，所以設計就變得很複雜，要考慮的狀況、要測試的條件也很多。&lt;/p&gt;  &lt;p&gt;例如，"伸出你的右手"。&lt;/p&gt;  &lt;p&gt;男人女人的伸手方式就不一樣了，老人與小孩的伸手方式也不會相同。&lt;/p&gt;  &lt;p&gt;這程式要怎麼寫?&lt;/p&gt;  &lt;p&gt;Hmm…&lt;/p&gt;  &lt;p&gt;Mechine Learning&lt;/p&gt;  &lt;p&gt;我們決定演算法之後，讓機器自己去決定參數與權重...&lt;/p&gt;  &lt;p&gt;不知道是不是所有的體感遊戲平台都有這樣的做法，不過對習慣於 Input 始終是 0 與 1 組成的我們來說，應該是很有挑戰性。&lt;/p&gt;  &lt;p&gt;課程結束，填了問卷交回。&lt;/p&gt;  &lt;p&gt;哇咧，今年沒有 "填問卷送 T Shirt" ?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-3499750219521335142?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2011/03/gdc-2011-day-2.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_kNRcDdsHvgQ/TW3ID9_nWcI/AAAAAAAAAXc/SNvO66XuPg8/s72-c/DSC01131_thumb%5B2%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-6510417360593589915</guid><pubDate>Tue, 01 Mar 2011 05:29:00 +0000</pubDate><atom:updated>2011-03-01T13:29:51.564+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>GDC 2011 Day 1</title><description>&lt;p&gt;2011 年的 GDC，是第 25 屆，不過也好像沒有特別盛大什麼的。反而是讓人感覺規模越來越小，就連報名參加所給的一個資料袋，質感都越來越糟...&lt;/p&gt;  &lt;p&gt;依照慣例，前兩天是 Tutorial 課程跟一些 Summit 演講。&lt;/p&gt;  &lt;p&gt;今天還是參加了一整天的 Tutorial，題目是 – &amp;quot;Advanced Visual Effects with DirectX 11&amp;quot;&lt;/p&gt;  &lt;p&gt;--------------------------------------------------------------------------------------------------------&lt;/p&gt;  &lt;p&gt;早上第一堂課，介紹的是 DX 11 裡的 Device Context &amp;amp; Command List，多緒繪製的架構。&lt;/p&gt;  &lt;p&gt;接下來，是 Deferred Shading 的最佳化策略。包括 Light Pre-pass, Light Geometry Optimization 幾個方法。不過，Light Pre-pass 馬上在下午的課程裡被打槍...&lt;/p&gt;  &lt;p&gt;接著是 Civilization V 。&lt;/p&gt;  &lt;p&gt;他們用了一個稱為 &amp;quot;Packetized Rendering&amp;quot; 的設計策略，將所有的 API call 包裝成一個 packet，送到 engine 去處理，每個獨立的 render job 可以降低彼此之間的關聯性，甚至沒有關聯。然後可以很自豪的說，&amp;quot;No threading bugs&amp;quot;。&lt;/p&gt;  &lt;p&gt;展示了一個很壯觀的 Screen Shot -- 滿滿畫面的兵，底下還秀了CPU 效能，12個核心同時在跑!!&lt;/p&gt;  &lt;p&gt;然後是 Dragon Age II ，介紹他們所使用的 DX11相關技術。&lt;/p&gt;  &lt;p&gt;他們主要用在 Dynamic Lighting ( Light Pre-pass method ), Tessellation, Diffusion Depth of Field (DDOF), Contact Hardening Shadows 上。&lt;/p&gt;  &lt;p&gt;從這裡開始，DDOF 就一直出現了...&lt;/p&gt;  &lt;p&gt;根據他們所說， Tessellation 是一個效能殺手。所以，只用在看得到的、很靠近攝影機的地形上。&lt;/p&gt;  &lt;p&gt;也就是，這技術並不是什麼都適用的好物...&lt;/p&gt;  &lt;p&gt;Contact Hardening Shadows 做出來的 Soft-shadow 效果，比過去用的 PCF Filtering 好非常多。DX11 SDK 上有 Sample，不過，我的電腦還是 DX10的顯卡，跑不起來，只能看靜態的圖...&lt;/p&gt;  &lt;p&gt;下午第一堂課，就由 DICE 介紹他們的大作 Battle Field 3。&lt;/p&gt;  &lt;p&gt;這遊戲，只支援 DX11，拋棄 DX9。&lt;/p&gt;  &lt;p&gt;他們說，BF3 是大作，所以可以推動 OS 以及硬體的更新。&lt;/p&gt;  &lt;p&gt;我們在旁邊，表示 .. &amp;quot;一切樂觀其成&amp;quot;...&lt;/p&gt;  &lt;p&gt;太樂觀了...&lt;/p&gt;  &lt;p&gt;BF3 的 Deferred Shading 並沒有使用 Light Pre-pass 方法，因為 Light Pre-pass 要對 Geometry render 兩個 pass，對 BF3 而言，Geometry 太多，不適用。&lt;/p&gt;  &lt;p&gt;BF3 用了一個特殊的想法。&lt;/p&gt;  &lt;p&gt;將 Screen Image 切分成幾十個 Tile，每個 Tile 用 Compute Shader 計算相關的 Light Info，這樣，據說可以計算場景裡高達 1000 個點光源...&lt;/p&gt;  &lt;p&gt;BF3 的場景裡的物件也是很多的，所以依舊存在著 Draw Call 的 Bottleneck。所以， BF3 將 Instancing 發揮到最大極限，從一個 Object 一個 Draw Call ，變成 &amp;quot;一種&amp;quot; Object 一個 Draw Call...&lt;/p&gt;  &lt;p&gt;效能大提升。&lt;/p&gt;  &lt;p&gt;最後，BF3 呼籲 : Drop DX9!!&lt;/p&gt;  &lt;p&gt;(我們還是繼續在旁邊... &amp;quot;樂觀其成&amp;quot;...)&lt;/p&gt;  &lt;p&gt;接下來是一個日本人的介紹。&lt;/p&gt;  &lt;p&gt;精神不濟加上日式發音很難懂，以致這半個多小時全部不知道什麼是什麼...&lt;/p&gt;  &lt;p&gt;然後，又來 DDOF 了。&lt;/p&gt;  &lt;p&gt;主題是 DDOF Solver，不太懂在做什麼，回去要開始找資料開始瞭解。&lt;/p&gt;  &lt;p&gt;接下來的主題是 Separable Filters。&lt;/p&gt;  &lt;p&gt;是用 Compute Shader 取代 Pixel Shader 做 Image Base Filter 的想法。&lt;/p&gt;  &lt;p&gt;舉例就舉例嘛，不知道為什麼，又拿 DDOF 來舉例...&lt;/p&gt;  &lt;p&gt;DDOF 看起來好像真的很重要...&lt;/p&gt;  &lt;p&gt;然後談到 Tessellation, Displacement Shading, 重點 : 請用在 &amp;quot;Key Assets&amp;quot; 上...&lt;/p&gt;  &lt;p&gt;最後，再經過一段冗長的 Post-Processing Performance Optimizing 演講，好不容易，下課休息。&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-6510417360593589915?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2011/03/gdc-2011-day-1.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-5127658921689618381</guid><pubDate>Fri, 17 Dec 2010 06:07:00 +0000</pubDate><atom:updated>2010-12-17T14:08:23.963+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">寫不完的遊戲引擎</category><title>引擎中不可或缺的事件訊息系統</title><description>&lt;p&gt;嗯...對...&lt;/p&gt;  &lt;p&gt;很久沒有發文了...&lt;/p&gt;  &lt;p&gt;「懶」是唯一的解釋...&lt;/p&gt;  &lt;p&gt;前一陣子看到一個引擎中的訊息系統架構，突然間，對整個引擎的架構設計有了新的想法。或者該說，解決了我心中長久以來的難題。&lt;/p&gt;  &lt;p&gt;說穿了，不過就是事件訊息驅動式 ( Event Driven ) 的架構設計。&lt;/p&gt;  &lt;p&gt;這東西被我晾在一旁太久，已經完全忘記它的存在了。&lt;/p&gt;  &lt;p&gt;簡單舉個例子說吧...&lt;/p&gt;  &lt;p&gt;遊戲中有很多系統，會受到攝影機的位置方向的影響，例如，天空盒子 ( Sky box ) 必須隨著攝影機的位置變動位置，動態讀取的無接縫地圖系統也必須檢查攝影機的位置來決定是否讀取地圖或是釋放地圖。如果在一個單純的程序式的架構中，我們會在攝影機位置變動的時候，呼叫這兩個物件系統來做相應的更新檢查。&lt;/p&gt;  &lt;p&gt;像是這樣:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;CameraManager::UpdatePosition(Camera* camera, Vector3 pos)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160; camera-&amp;gt;UpdatePosition(pos);       &lt;br /&gt;&amp;#160; skybox-&amp;gt;UpdatePosition(pos);       &lt;br /&gt;&amp;#160; seamless_world-&amp;gt;CheckLoading(pos);       &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;只不過，這麼一來，我們可以非常確定的是， Camera Manager 這個物件已經跟 Skybox 、 Seamless World 分不開了。三個物件綁在一起的結果是，物件的再利用性大大降低。( 想想如果我們需要將 sky box 改為 sky doom, 又或者我們不再需要無接縫地圖的時候... )&lt;/p&gt;  &lt;p&gt;這還只是其中一個問題。&lt;/p&gt;  &lt;p&gt;另外一個問題是，在我們遊戲越做越大，引擎越寫越深入的時候，我們發現， LOD ( Level of Detail ) 的計算也需要隨著攝影機變動而更新，水面倒影效果也跟攝影機有關，粒子系統的繪製也需要攝影機的資料...&lt;/p&gt;  &lt;p&gt;於是乎，我們又把 LOD 系統、水面倒影、粒子系統全綁到了攝影機物件裡。&lt;/p&gt;  &lt;p&gt;更甚至於，第三人稱視角的遊戲裡，攝影機是跟著主角走的，所以，又把攝影機綁到了主角身上，跟著主角更新。&lt;/p&gt;  &lt;p&gt;最後的結果就是，整個引擎裡各式各樣的系統物件，因為彼此之間相互影響的關係，全部混成一團。&lt;/p&gt;  &lt;p&gt;現在換個角度，改用事件驅動來做。&lt;/p&gt;  &lt;p&gt;攝影機變動的時候，我們不管 Skybox 、 Seamless World，只送個訊息給事件系統。&lt;/p&gt;  &lt;p&gt;像是這樣:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;CameraManager::UpdatePosition(Camera* camera, Vector3 pos)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160; camera-&amp;gt;UpdatePosition(pos);       &lt;br /&gt;&amp;#160; event_system-&amp;gt;Send(idCameraPositionUpdated, camera);       &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;而對於 Skybox, Seamless World 來說，必須有函式負責來接收這個事件，同時，在物件的初始化的時候，必須先把這個函式登記到事件系統裡。&lt;/p&gt;  &lt;p&gt;Sky Box 的接收函式大概會長得像這樣:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;Skybox::OnCameraPositionUpdated(Camera* camera)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160; UpdatePosition(camera-&amp;gt;GetPosition());       &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;其他的，需要隨著攝影機更新而更新的物件，也都會有相類似的函式，同時也都需要將函式登記到事件系統中，事件系統在收到攝影機送來的事件後，就會分發事件，一一呼叫每個需要的事件處理函式。&lt;/p&gt;  &lt;p&gt;這樣子，事件系統將我們的各個物件獨立開來，減少了很多錯綜複雜的關連。&lt;/p&gt;  &lt;p&gt;更進一步來，我們可以在玩家主角的位置更新的時候，發送一個事件出來，然後在攝影機系統裡，寫個這樣的函式:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;CameraManager::OnPlayerPositionUpdate(Player* player)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160; UpdatePosition(player-&amp;gt;GetPosition());       &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;當然了，這樣的事件驅動架構不是沒有缺點的。缺點就是，為了遵循這個架構模式，我們必須多寫很多 code ，例如，本來可以直接在攝影機裡呼叫的函式，現在必須寫一個事件處理函式來呼叫它，而且還必須要把事件處理函式登記到系統裡，有點煩...&lt;/p&gt;  &lt;p&gt;但是多花這些工絕對是值得的...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-5127658921689618381?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/12/event-system-in-engine.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-27771917128150537</guid><pubDate>Fri, 11 Jun 2010 02:08:00 +0000</pubDate><atom:updated>2010-06-11T10:08:56.656+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>一個「偽」亂數的演算法</title><description>&lt;p&gt;這是前一陣子從 &amp;quot;Game Code Complete&amp;quot; 裡看到的演算法。&lt;/p&gt;  &lt;p&gt;說是「偽」亂數，因為它並不夠亂。但是它非常節省效能。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;需求是這樣:&lt;/p&gt;  &lt;p&gt;有某個數量的獎品，我們希望每次亂數取出一個來，不能重複，而且每個都要取到。&lt;/p&gt;  &lt;p&gt;演算法是這樣:&lt;/p&gt;  &lt;p&gt;假設獎品數量為 member，比 member 大的一個質數為 prime，&lt;/p&gt;  &lt;p&gt;首先先取三個亂數 RandomA, RandomB, RandomC&lt;/p&gt;  &lt;p&gt;計算&lt;/p&gt;  &lt;p&gt;Skip = RandomA * member * member + RandomB * member + RandomC&lt;/p&gt;  &lt;p&gt;取得 Skip 數值後，在每次需要取亂數數值時，&lt;/p&gt;  &lt;p&gt;nextNumber += Skip&lt;/p&gt;  &lt;p&gt;nextNumber %= prime&lt;/p&gt;  &lt;p&gt;也就是，每次計算時，把前一次的數值加上 Skip, 然後用這個質數來取餘數, 這樣算出來的 nextNumber 就絕對不會重複。當然餘數可能會比 member 數量還大，那就再計算一次，取下一個。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;看完之後，霎時間覺得很神奇，一時半刻還想不透，於是用試算表建公式來算，果然，產生了一個不會重複數字的序列。&lt;/p&gt;  &lt;p&gt;但是，從這序列也發現了缺點。就是取出來的數值是有某種規律的，而且規律很明顯。不過如果不把數列排出來，也不容易發現就是了。&lt;/p&gt;  &lt;p&gt;效能是這個演算法最大的優點，每次取亂數只需要一個加法跟一個取餘數的運算。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;再深入去看，這演算法還可以多做一些簡化。&lt;/p&gt;  &lt;p&gt;Skip 這個數值，只要取小於 prime，大於 0 ( 最好也不要等於 1 ) 的數值就可以，不需要取三個亂數再去加減乘除。&lt;/p&gt;  &lt;p&gt;取出的數值的規律是，從第一個取出的 nextNumber 開始，每次遞增 Skip 指定的數量，超過 prime 的時候，再回到 0 繼續算，而之所以會全部都選取到的原因，就是因為質數的特性 -- 只能被 1 與自己整除。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;這個演算法可以用在什麼地方呢?&lt;/p&gt;  &lt;p&gt;分配掉寶當然是不能用啦，這個數列太過規律了。但是任務物品的掉落倒是可以用得上，怪物的重生也可以用，適用的場合應該還不少。&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-27771917128150537?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/06/fake-random-number-algorism.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-8727234523492124272</guid><pubDate>Thu, 29 Apr 2010 07:31:00 +0000</pubDate><atom:updated>2010-04-29T18:35:15.748+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">遊戲雜記</category><title>Activision 把金雞母 Infinity Ward 送給 EA 的事件</title><description>&lt;p&gt;今天看到了這樣一篇新聞。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://g4tv.com/thefeed/blog/post/704273/Infinity-Ward-Employee-Group-Files-Lawsuit-Against-Activision-Over-Unpaid-Royalties-Alleges-Devs-Held-Hostage.html"&gt;38 Infinity Wards employees and ex-employees file class action lawsuit&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;霎時間，還搞不清楚這到底是什麼，為什麼沸沸揚揚。&lt;/p&gt;  &lt;p&gt;於是開始Google搜索。&lt;/p&gt;  &lt;p&gt;原來 Infinity Ward 是製作 &amp;quot;決勝時刻:現代戰爭2&amp;quot;的研發公司，母公司是遊戲發行商 Activision Blizzard。&lt;/p&gt;  &lt;p&gt;現代戰爭2是2009年非常風光的一款遊戲，怎麼現在鬧出權利金跟獎金的糾紛來了?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;故事要從今年三月說起。&lt;/p&gt;  &lt;p&gt;三月初， Activision 以違約與不服從命令為由，強迫兩個 Infinity Ward 高高層離職。&lt;/p&gt;  &lt;p&gt;總裁 Jason West 與執行長 Vince Zampella。&lt;/p&gt;  &lt;p&gt;到底這兩人不服從什麼命令，沒人知道，但是猜測是說，Activision 希望他們繼續把現代戰爭繼續製作下去，做個沒完沒了。研發單位當然不肯。&lt;/p&gt;  &lt;p&gt;沒想到重演當年在 EA 的 2015工作室一樣的不爽事件。&lt;/p&gt;  &lt;p&gt;據說，那時候 2015工作室做了個很賣錢的&amp;quot;榮譽勳章&amp;quot;，EA 龍心大悅，希望他們一直做下去，把這個招牌賣到不能再賣為止。結果自然也是不太愉快，帶了幾個人，兩人投靠 Activision。&lt;/p&gt;  &lt;p&gt;只不過這次 Activision 更惡劣， 連該給的權利金與獎金，也一直扣著沒發放。&lt;/p&gt;  &lt;p&gt;大概是鬧得非常非常不高興，這兩人就離職了。&lt;/p&gt;  &lt;p&gt;然後，事件就一發不可收拾。&lt;/p&gt;  &lt;p&gt;四月中，同樣也是遊戲發行商的 EA，宣布成立了一個新的工作室，叫做 &amp;quot;Respawn Entertainment&amp;quot;，重生。並且由 Jason 與 Vince 兩位來帶領。&lt;/p&gt;  &lt;p&gt;隔天，報導說，首席設計師 Mackey McCandlish 與程式設計師 Jon Shiring 從 IW 離職，當時雖未明講，但猜也猜得到，去 Respawn 了，後來也得到了證實。&lt;/p&gt;  &lt;p&gt;這兩三週以來， IW 持續失血，老員工成雙成對的離職。人才流失就像潰堤一般，止都止不住。而且流失的人才還大部分都是菁英。首席軟體工程師 Francesco Gigliotti，首席動畫師 Mark Grigsby，首席角色動畫 John Paul Messerly，首席環境美術設計 Chris Cherubini，軟體工程師 Rayme C. Vinson，一堆的『首席』全都跑去了『重生』。&lt;/p&gt;  &lt;p&gt;Activision 在這幾週來，悄悄的進行組織重整，也開始對留下來的還忠誠的 IW 員工發放積欠的獎金跟權利金，但終究是喚不回 IW 員工的信任了，失血非但沒止住，IW 員工還給了 Activision 一個暱稱 -- &amp;quot;shit&amp;quot;。&lt;/p&gt;  &lt;p&gt;到今天，估計 IW 原先的員工已經有一半離職。Activision 調動了其他工作室的人到 IW 裡，希望維持住產品的開發運作，但想也知道，基本上起不了什麼作用。&lt;/p&gt;  &lt;p&gt;Activision 的某個高層，前幾天也辭去了職務 ( 不過還是以類似顧問的身分留著 )，沒講理由，大概是辭職以示負責。有人毒舌的說，「不會也是要去Respawn吧?」&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;故事寫到這邊。&lt;/p&gt;  &lt;p&gt;IW 的兩個頭子真正的離職原因是什麼很難說，也有人說是他們打算把現代戰爭這個招牌賣到別的發行商手上才被開除，但是會引發後面一連串的『首席』離職，Activision 也必有虧欠員工之處。我想權利金與獎金發放的太不乾脆，應該會是主因之一。&lt;/p&gt;  &lt;p&gt;不管怎麼說，這一場風波下來， EA 這個風評也不甚好的發行商，光是躺著就能撿到一整隊的金雞母，還不只是一兩隻而已。&lt;/p&gt;  &lt;p&gt;天上掉下來的會生金蛋的母雞，誰不帶回家?&lt;/p&gt;  &lt;p&gt;現在， EA 說的很漂亮了，完全不會干涉他們開發的內容，未來也會盡全力去發行遊戲...&lt;/p&gt;  &lt;p&gt;Activision 一個錯誤的決定，把白花花的美金平白的又還給了 EA。EA 應該是暗爽在心裡吧?&lt;/p&gt;  &lt;p&gt;(Update : 又看到幾篇精彩的歷史，修改了一些...)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-8727234523492124272?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/04/activision-infinity-ward-ea.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-3332234117441097965</guid><pubDate>Fri, 02 Apr 2010 08:54:00 +0000</pubDate><atom:updated>2010-04-02T16:56:13.811+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">遊戲雜記</category><title>一年一度的愚人節歡樂日</title><description>&lt;p&gt;愚人節是很歡樂的日子。&lt;/p&gt;  &lt;p&gt;Blizzard 依照慣例出了好幾道搞笑的假新聞，國內的遊戲公司也有的開始玩起來了。&lt;/p&gt;  &lt;p&gt;Google 照例還是玩很大。&lt;/p&gt;  &lt;p&gt;MLB 也有一堆假新聞。&lt;/p&gt;  &lt;p&gt;今天看到一個說法是，「愚人節是 IT 產業的國定假日」。&lt;/p&gt;  &lt;p&gt;同事說，那我們應該放假一天的呀...&lt;/p&gt;  &lt;p&gt;來轉貼個&lt;a href="http://www.zdnet.com.tw/news/software/0,2000085678,20144894,00.htm"&gt;歡度愚人節總整理&lt;/a&gt;好了。&lt;/p&gt;  &lt;p&gt;剛剛在 GameDev.net 上，看到 The Daily GameDev.net 編輯所寫的一段，算是最好的註解。&lt;/p&gt;  &lt;p&gt;他寫，&lt;/p&gt;  &lt;p&gt;If you're expecting news from today well, you can forget about it. I refuse to look at any headlines today because... well, if you don't know than you deserve what you get :P&lt;/p&gt;  &lt;p&gt;他「拒絕」在今天看任何的頭條新聞...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-3332234117441097965?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/04/april-fool.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-6000386386541448195</guid><pubDate>Fri, 26 Mar 2010 03:16:00 +0000</pubDate><atom:updated>2010-03-26T11:16:23.131+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>My GDC 2010 (Day 5)</title><description>&lt;p&gt;GDC 最後一天。下午上完課，晚上就要到機場去，很操...&lt;/p&gt;  &lt;p&gt;Day 5&lt;/p&gt;  &lt;p&gt;第一堂課，本來要參加一個滿有意思的課程，但是，由於出發得較晚，結果因為人數已滿而進不去。( 我又要抱怨這糟糕的課程安排了... )&lt;/p&gt;  &lt;p&gt;跑去聽了一場比較另類的題目，&amp;quot;&lt;b&gt;Paint-by-Gender: How to Add Pink Gameplay to Your 'Blue' Title (and Still Keep All the Boys Happy)&lt;/b&gt;&amp;quot;。&lt;/p&gt;  &lt;p&gt;意思是，如何讓你的遊戲可以受女生歡迎，男生也不會太反感。&lt;/p&gt;  &lt;p&gt;底下有Check-List&lt;/p&gt;  &lt;p&gt;Female-Friendly Checklist&lt;/p&gt;  &lt;p&gt;1. Detailed backstory for characters and the world&lt;/p&gt;  &lt;p&gt;2. Major female character(s), non-stereotypical&lt;/p&gt;  &lt;p&gt;3. In-game relationships, especially ones the player can affect&lt;/p&gt;  &lt;p&gt;4. Emotional moments&lt;/p&gt;  &lt;p&gt;5. Moral complexity in characters and situations&lt;/p&gt;  &lt;p&gt;6. Opportunities for non-violent action&lt;/p&gt;  &lt;p&gt;7. Gameplay variety that creates strategic options&lt;/p&gt;  &lt;p&gt;8. Important choices&lt;/p&gt;  &lt;p&gt;9. Meaningful victory condition&lt;/p&gt;  &lt;p&gt;其實說穿了，就是要多一點的Fu，少一點暴力，女性角色不要只是花瓶...&lt;/p&gt;  &lt;p&gt;第二堂課，去聽了模擬市民3，講述他們怎樣去模擬遊戲中的每個小人。&lt;/p&gt;  &lt;p&gt;感覺上就是，這是一個很龐大的資料驅動式系統，每個小人有 motives, traits, long-term progression, production rules, …&lt;/p&gt;  &lt;p&gt;還看到了一個2D Top-view，專門用來測試小人的生活狀況的測試工具...&lt;/p&gt;  &lt;p&gt;今天下午，GDC 到 1600 就結束，下午課程只有兩場。&lt;/p&gt;  &lt;p&gt;下午第一場去聽的是，&amp;quot;&lt;b&gt;The Rendering Tools and Techniques of Splinter Cell: Conviction&lt;/b&gt;&amp;quot;。&lt;/p&gt;  &lt;p&gt;內容主題好幾個，Occlusion Query, Cascaded Shadow Map ( 啊...又見到它了... ), SSAO…&lt;/p&gt;  &lt;p&gt;他們用的Occlusion Query方法，是改良過的 Hierarchical Z buffer。效果還不錯。&lt;/p&gt;  &lt;p&gt;Cascaded Shadow Map就不多說了。&lt;/p&gt;  &lt;p&gt;SSAO的部分，偷吃偷得很兇。完完全全是事先算好，甚至美術修過圖的一張貼圖，然後用類似 lightmap 的方式，計算貼圖軸後貼上去。效果沒差多少，但是效能差很多...&lt;/p&gt;  &lt;p&gt;( 我們來參加 GDC，簡直就是來觀摩各式各樣的偷吃步的... )&lt;/p&gt;  &lt;p&gt;最後一場，本來並沒有期待很多，不過卻真的有些收穫。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&amp;quot;Uncharted 2: HDR Lighting&amp;quot;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;一開場，講了很多 Gamma 曲線的東西，本來搞不懂是什麼，後來在朋友的 Blog 上看到 Gamma Correction 的觀念，才瞭解了。&lt;/p&gt;  &lt;p&gt;簡單說，美術製作的貼圖素材，所有的顏色與亮度數值，都不是線性的，而我們在 Pixel Shader 裡，卻拿這些數值去做線性運算，這中間就有誤差了。&lt;/p&gt;  &lt;p&gt;這就是人家比我們專業的地方，就是人家可以上台發表，我們只能在台下鴨子聽雷的差別。&lt;/p&gt;  &lt;p&gt;故事還沒完，Gamma Correction 之外，他們還做了所謂 Filmic Tonemapping 的修正，修正掉過亮以及過暗的地方。&lt;/p&gt;  &lt;p&gt;再來是SSAO。印象最深的，就是 &amp;quot;Who needs sphere? A box will do just as well&amp;quot;。&lt;/p&gt;  &lt;p&gt;用個盒子算AO就好啦。 ( 怎樣? 又觀摩到一個偷吃步... )&lt;/p&gt;  &lt;p&gt;最後呢，講述了他們的 Rendering Pass 架構，以及他們很自豪的最佳化的做法。不過，這部分完全是 PS3 硬體上的東西，真的是有看沒懂。&lt;/p&gt;  &lt;p&gt;( 就在那一瞬間， 四個 Cascaded Shadow Map 畫在一張貼圖上的畫面，又閃過在我眼前... )&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;THE END&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-6000386386541448195?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/03/my-gdc-2010-day-5.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-2902972569541915267</guid><pubDate>Mon, 22 Mar 2010 06:22:00 +0000</pubDate><atom:updated>2010-03-22T14:22:13.990+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>My GDC 2010 (Day 4)</title><description>&lt;p&gt;GDC 的講題，分成幾類，程式、美術、設計、製作等等，參加 GDC 的人也算是各領域的人都有了。不過，有點要注意的是，可以的話，最好不要跑到別人的場子去。&lt;/p&gt;  &lt;p&gt;例如昨天 Blizzard 的場子就是程式領域的，所以，當程式人聽到這麼重要的 Hotspot 分析工具， Designer 卻覺得 &amp;quot;not so valuable&amp;quot; 的時候，底下會響起一片 &amp;quot;你們真是不識貨啊&amp;quot; 的笑聲。&lt;/p&gt;  &lt;p&gt;不過程式人在美術人的場子裡也好不到哪裡去。根據我們美術同事轉述，以下是演講人講述在他們公司裡的對話:&lt;/p&gt;  &lt;p&gt;美術 : 「這個功能可以做嗎?」&lt;/p&gt;  &lt;p&gt;程式 : 「不行」&lt;/p&gt;  &lt;p&gt;美術 : (中指)&lt;/p&gt;  &lt;p&gt;程式 : (當作沒看見)&lt;/p&gt;  &lt;p&gt;美術 : (遞...)美鈔&lt;/p&gt;  &lt;p&gt;程式 : (眼睛上全是Dollar Sign)&lt;/p&gt;  &lt;p&gt;「兩天後，我們有了這個酷功能...」&lt;/p&gt;  &lt;p&gt;( 類似的故事好像有發生在我跟我的美術好友 Louis 的身上，不過我當然是不記得的啦... )&lt;/p&gt;  &lt;p&gt;Day 4&lt;/p&gt;  &lt;p&gt;一大早參加的課程是由冰島的 CCP (做 EVE 的那家公司)演講的題目，&amp;quot;&lt;strong&gt;Code and Complexity: Managing EVE's Expanding Universe&lt;/strong&gt;&amp;quot;，演講人是個金髮正妹的程式設計師，大清早看見金髮正妹的同行，一整個讓人神清氣爽啊...&lt;/p&gt;  &lt;p&gt;好吧，內容。&lt;/p&gt;  &lt;p&gt;內容是，EVE Online 營運了七年下來，他們怎麼去控制程式的各種版本，各種狀況。版本控制方面，用了四條 Stream—Dev, Stage, Release, Hotfix，沒有很多的分支。程式碼方面，有幾個重要的點,&lt;/p&gt;  &lt;p&gt;Think ahead – simple, clear, and clean&lt;/p&gt;  &lt;p&gt;Follow a coding standard&lt;/p&gt;  &lt;p&gt;Think big – optimize&lt;/p&gt;  &lt;p&gt;Think carefully&lt;/p&gt;  &lt;p&gt;Balance features vs. technical debt&lt;/p&gt;  &lt;p&gt;很重要的就是，不要去標新立異，寫一堆別人很難看懂的 Code，也不要去做一些技術性很高，但沒什麼用途的東西。&lt;/p&gt;  &lt;p&gt;接著下一場，全會場只有一堂課程，就是 Sid Meier 的演講。大製作人，所以逼著全部的人都要去聽。我就不多寫了，同行的 Designer 說，沒什麼新鮮的。&lt;/p&gt;  &lt;p&gt;下午第一場，聽的是&amp;quot;&lt;b&gt;Streaming Massive Environments from 0 to 200 MPH&lt;/b&gt;&amp;quot;，講的是他們的賽車遊戲，如何將賽道 Streaming。&lt;/p&gt;  &lt;p&gt;用了很多的技巧，似乎是能節省時間的技法全都用上了。LOD, 貼圖壓縮, 甚至連 Disk I/O Cache 都考慮進去了。因為有這樣的需求，所以他們自己發展了一套 Pipeline 工具。&lt;/p&gt;  &lt;p&gt;也算是很猛的啦...&lt;/p&gt;  &lt;p&gt;接著呢，不小心選到一場地雷課。聽了十分鐘就跑出來了。可是課程的安排很糟糕，又沒別的課好去，所以就又去微軟講 Windows Phone 7 的場子裡，看看還有沒有禮物可拿...&lt;/p&gt;  &lt;p&gt;本日最後一場，走到了 Intel 的場子，聽聽有沒有什麼多緒的新概念。&lt;/p&gt;  &lt;p&gt;不多。&lt;/p&gt;  &lt;p&gt;新的 Windows 作業系統裡好像有個 Slim reader/writer locks 和 Condition variables，據說比 Critical sections 還要節省資源，可以找天來試試看到底是什麼東西。&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-2902972569541915267?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/03/my-gdc-2010-day-4.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-4153551945426961062</guid><pubDate>Sun, 21 Mar 2010 03:06:00 +0000</pubDate><atom:updated>2010-03-21T11:06:02.452+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>My GDC 2010 (Day 3)</title><description>&lt;p&gt;現在開始進入正式的 Main Conference。&lt;/p&gt;  &lt;p&gt;Day 3&lt;/p&gt;  &lt;p&gt;第一場重頭戲，就是 Blizzard 的 keynote 。鐵定會爆滿，所以我們早早就從飯店出發到會場去排隊。&lt;/p&gt;  &lt;p&gt;題目是 &amp;quot;&lt;strong&gt;Designing for Performance, Scalability &amp;amp; Reliability: StarCraft II's Approach&lt;/strong&gt;&amp;quot;&lt;/p&gt;  &lt;p&gt;一開場，先講幾個 Blizzard 的 Core Value。&lt;/p&gt;  &lt;p&gt;Gameplay first – the “invisible” tech. ( 這個尤其重要，所以放在第一個... )&lt;/p&gt;  &lt;p&gt;Think globally – games are global&lt;/p&gt;  &lt;p&gt;Commit to quality – we are all QA&lt;/p&gt;  &lt;p&gt;接下來，展示了 StarCraft II 的 Performance 分析工具。是的，這一場演講的最主要主題，就是 Blizzard &amp;quot;自己做&amp;quot; 的效能分析工具。雖然是自己做的，但是功能絕不輸專業的分析工具。&lt;/p&gt;  &lt;p&gt;( 後來想到，你們就是因為自己做這個工具，才會讓遊戲 Delay 這麼久吧? )&lt;/p&gt;  &lt;p&gt;B社抱持的想法其實也不是沒道理，因為第三方的效能分析工具很難做到即時的分析，換句話說，即使有很多分析的資料，但是依然沒辦法跟遊戲畫面或狀況結合起來，對於分析效能來講，效果總是打了折扣。&lt;/p&gt;  &lt;p&gt;所以我們就看見了，在 StarCraft II 的遊戲畫面上又多了一層效能分析的 Layer ，所有的分析曲線都能夠顯示在上面。&lt;/p&gt;  &lt;p&gt;程式團隊還另外做了一個分析地圖 Hotspot 的工具，可以讓 Designer 了解地圖的效能狀況。有人問，這東西 Designer 覺得怎樣，答案是 : &amp;quot;Not so valuable…&amp;quot;&lt;/p&gt;  &lt;p&gt;接下來，就像我之前說的，因為課程時段安排的很糟糕，我又多出了很多時間。&lt;/p&gt;  &lt;p&gt;於是跑去聽了一場主題是 &amp;quot;&lt;b&gt;The AI of BioShock 2&lt;/b&gt;&amp;quot; ，內容是跟製作流程相關的演講。&lt;/p&gt;  &lt;p&gt;幾個重點:&lt;/p&gt;  &lt;p&gt;Less document, more prototype&lt;/p&gt;  &lt;p&gt;Don’t over concept &amp;amp; over document&lt;/p&gt;  &lt;p&gt;Prototype early&lt;/p&gt;  &lt;p&gt;Prove features before enter production&lt;/p&gt;  &lt;p&gt;Work iteratively as a group&lt;/p&gt;  &lt;p&gt;下午，時間還是很多，所以到底下的展場晃了很久，看了一些有興趣的攤位。&lt;/p&gt;  &lt;p&gt;下午的最後一場，跑到了戰神III的課程去聽。主題是戰神III的影子。&lt;/p&gt;  &lt;p&gt;Cascade Shadow Map。&lt;/p&gt;  &lt;p&gt;對，又是它。&lt;/p&gt;  &lt;p&gt;也許是PS3的運算比較快，記憶體比較小的關係，這裡的 CSM 運算，跟PC上的運算有些不同，但基本理論跟演算是一樣的。&lt;/p&gt;  &lt;p&gt;而戰神III也另外做了一些最佳化的處理，減少運算量，這部分，PC上倒是也可以應用的。&lt;/p&gt;  &lt;p&gt;簡單講，兩個偷吃步。&lt;/p&gt;  &lt;p&gt;看不見的不要算&lt;/p&gt;  &lt;p&gt;看不清楚的也不要算&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-4153551945426961062?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/03/my-gdc-2010-day-3.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-5215604702470364784</guid><pubDate>Thu, 18 Mar 2010 08:35:00 +0000</pubDate><atom:updated>2010-03-18T16:35:55.619+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>My GDC 2010 (Day 2)</title><description>&lt;p&gt;今年的GDC是在 3/9 至 3/13 ，所以我現在寫的是回憶錄...XD&lt;/p&gt;  &lt;p&gt;Day 2&lt;/p&gt;  &lt;p&gt;早上還是待在微軟的場子裡，聽了兩堂關於 DirectCompute 以及 Tessellation 的課程。&lt;/p&gt;  &lt;p&gt;DirectCompute 主要在介紹 Compute Shader 的使用( 對..今天也還是Tutorial.. )，重點在於，Compute Shader 本身就是為了做平行化計算而生的，所以各式各樣我們在做平行化、多執行緒的程式所需要考慮到的問題，例如Shared Memory, Atomic Operation...等等，都在這裡一一出現。&lt;/p&gt;  &lt;p&gt;平行處理始終是個大課題啊...&lt;/p&gt;  &lt;p&gt;在 HDR 計算時，可以將平均亮度的計算拉到 Compute Shader 來做，這算是很好的應用了。&lt;/p&gt;  &lt;p&gt;DirectCompute 是 DX11 的規格，不過某些 DX10 顯卡已經有 Compute Shader 可用，DX10 也有函式可以呼叫來使用說。&lt;/p&gt;  &lt;p&gt;Tessellation 課程的演講人是個華人，他說大部分的 DX SDK Sample 都是他寫的。&lt;/p&gt;  &lt;p&gt;這個課程的主題，就是介紹幾個 Tessellation 的 Sample，每個 Sample就解說一下做法，然後把範例跑一跑，還不算太無聊。&lt;/p&gt;  &lt;p&gt;範例咧，在 Dx11 的 SDK Sample 裡都有。&lt;/p&gt;  &lt;p&gt;下午，微軟的課程就走到即將發表的 Windows Phone 7 作業系統上了，所以我就先到了 iPhone 的場子去。iPhone 有一場很有意思的講題 -- &amp;quot;如何讓你的 iPhone App 保持 Apple Store 的排名上&amp;quot;。&lt;/p&gt;  &lt;p&gt;答案就是，跟我們的MMO要保持在遊戲社群網站排名的手法一樣...&lt;/p&gt;  &lt;p&gt;持續的做更新&lt;/p&gt;  &lt;p&gt;節慶的時候出個更新做 in-game 活動&lt;/p&gt;  &lt;p&gt;網站上面弄點相關新聞&lt;/p&gt;  &lt;p&gt;官方人員有事沒事在社群網站上放點消息，跟玩家溝通&lt;/p&gt;  &lt;p&gt;...&lt;/p&gt;  &lt;p&gt;MMO Game, Mobile Game, Social Game, ... 只要是在網路上玩、網路上營銷的遊戲，操作手法都極為相似啊...&lt;/p&gt;  &lt;p&gt;下午最後一堂課，又回到了微軟的場子裡，聽聽 Windows Phone 7 這個系統。&lt;/p&gt;  &lt;p&gt;微軟打算把這個系統跟 XBox Live, Windows Live Games 結合起來，然後把 Apple Store 的功能、Facebook 的社群功能全部包在這裡面...&lt;/p&gt;  &lt;p&gt;換句話說，就是整碗捧去啦...&lt;/p&gt;  &lt;p&gt;一天結束，有始有終，又填了一份問卷，又拿了一件微軟 T-Shirt&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-5215604702470364784?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/03/my-gdc-2010-day-2.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-6445229291190218952</guid><pubDate>Wed, 17 Mar 2010 02:33:00 +0000</pubDate><atom:updated>2010-03-17T10:33:43.963+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>My GDC 2010 (Day 1)</title><description>&lt;p&gt;到了會場後的第一個感覺，就是規模縮小了。&lt;/p&gt;  &lt;p&gt;過去兩年都使用了西、南、北三個館，今年只剩下了南北兩個館做為會場。&lt;/p&gt;  &lt;p&gt;課程變少了，而且課程的安排很糟糕，常常會是，要不是這個時段沒課可上，就是想上的課衝堂衝很嚴重。例如，有個時段 Program Track 的課，只有兩堂，而另外有個時段，Program Track 的課少說有八九堂，其中NVidia跟AMD還各佔了一堂課，這是怎樣? 逼我們選邊站嗎?&lt;/p&gt;  &lt;p&gt;GDC五天，前兩天是 Tutorial &amp;amp; Summit 的課程，後三天才是正題 Main Conference。&lt;/p&gt;  &lt;p&gt;Day 1&lt;/p&gt;  &lt;p&gt;一整天待在微軟的場子裡。&lt;/p&gt;  &lt;p&gt;一入場，微軟就先發個筆、筆記紙、還有投影片檔的 CD ( 省得裡頭的人拼命把投影片拍照... )&lt;/p&gt;  &lt;p&gt;一開始，題目是VC 2010。&lt;/p&gt;  &lt;p&gt;有點鳥。&lt;/p&gt;  &lt;p&gt;不過，聽到一個很奇特的東西，&amp;quot; Move Constructor &amp;quot;。&lt;/p&gt;  &lt;p&gt;回頭翻光碟片，google了一下，原來這是C++的新規格，號稱 C++0x。VC 2010會支援全套的C++0x規格。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www2.research.att.com/~bs/C++0xFAQ.html"&gt;C++0x FAQ&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Move Constructor 可以處理掉某些效能上的問題，應該是個頗實用的東西。&lt;/p&gt;  &lt;p&gt;接下來聽到的是，xperf的介紹。&lt;/p&gt;  &lt;p&gt;這是一套效能分析的工具組， Windows Performance Toolkit ，功能很強大。甚至能夠收集處理Disk I/O, seek time, content switch的資料。&lt;/p&gt;  &lt;p&gt;找時間要抓來瞧瞧。&lt;/p&gt;  &lt;p&gt;接著下午聽了一個重頭戲， Cascade Shadow Map 。&lt;/p&gt;  &lt;p&gt;只不過裡頭的內容，早就發表在 MSDN 上了。微軟還是有點混。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee416324%28VS.85%29.aspx"&gt;Common Techniques to Improve Shadow Depth Maps&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Cascade Shadow Map 在當前，基本上已經成為影子計算的最佳解法了， God of War III 用到它，Uncharted 2 也用到它，更不要說PC上的遊戲了，WOW已經用了，你要不要跟進咧?&lt;/p&gt;  &lt;p&gt;微軟一天的課程結束，把問卷填一填，換了一件 T-Shirt。還滿好穿，不過就是大了點。&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-6445229291190218952?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/03/my-gdc-2010-day-1.html</link><author>noreply@blogger.com (藍斯洛)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-6330752857452436928</guid><pubDate>Mon, 08 Mar 2010 09:00:00 +0000</pubDate><atom:updated>2010-03-15T16:29:21.812+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">旅行</category><title>GDC前的舊金山一日遊</title><description>&lt;p&gt;今年的GDC是從週二開始，週一是我們多出來的一天調整時差以及城市旅遊日。因為是週一上班日，所以連續陪了我們兩年的地陪朋友，就沒辦法再來帶隊了。&lt;/p&gt;  &lt;p&gt;這一回，因為也還是有幾位頭一次來舊金山的同事，所以，這一日遊的行程，就還是那樣，萬年不變的舊金山行程景點--漁人碼頭和金門大橋。&lt;/p&gt;  &lt;p&gt;只不過這一次，我們是在舊金山自己找交通工具。&lt;/p&gt;  &lt;p&gt;去漁人碼頭，叮噹車一定是首選。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/S53voXyFCFI/AAAAAAAAAVo/AScu5r0_0wc/s1600-h/DSC00828%5B3%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00828" border="0" alt="DSC00828" src="http://lh5.ggpht.com/_kNRcDdsHvgQ/S53vpBonBQI/AAAAAAAAAVs/NyrZJHUHtdU/DSC00828_thumb%5B1%5D.jpg?imgmax=800" width="438" height="330" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kNRcDdsHvgQ/S53vp3GtV9I/AAAAAAAAAVw/usIMvk4gMJg/s1600-h/DSC00829%5B3%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00829" border="0" alt="DSC00829" src="http://lh6.ggpht.com/_kNRcDdsHvgQ/S53vq0IZJWI/AAAAAAAAAV0/7-b8y1eQyiw/DSC00829_thumb%5B1%5D.jpg?imgmax=800" width="434" height="326" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;叮噹車最有 fu 的搭乘方法呢，就是抓住車旁的欄杆，然後一路上這麼掛著，到了站，直接跳下車。不過今天早上氣溫很低，這樣掛著吹風不是好事...&lt;/p&gt;  &lt;p&gt;我們從 Powell Street 上車，經過幾個上下坡，就可以到漁人碼頭。&lt;/p&gt;  &lt;p&gt;如果叮噹車沒有壞掉的話。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/S53vr9SjszI/AAAAAAAAAV4/9LUvP_OPmSc/s1600-h/DSC00831%5B3%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00831" border="0" alt="DSC00831" src="http://lh3.ggpht.com/_kNRcDdsHvgQ/S53vtEc9lQI/AAAAAAAAAV8/y921ZkKDUJA/DSC00831_thumb%5B1%5D.jpg?imgmax=800" width="437" height="329" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;就在最後一個下坡之前，叮噹車壞掉了，只見前面的駕駛員 ( 很高很壯，就像哈利波特裡的海格那種體型 ) 跳下車，大喊&amp;quot;Take off”，叫後面的售票員下車，然後..兩個人就這樣連人帶車..在“推車”啦!!!&lt;/p&gt;  &lt;p&gt;車子開始動，兩個人就跳上車，前面的駕駛員用煞車控制車速，就這樣讓車子滑進了終點站。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/S53vt_OHX1I/AAAAAAAAAWA/MKJUbUefA-E/s1600-h/DSC00834%5B3%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00834" border="0" alt="DSC00834" src="http://lh4.ggpht.com/_kNRcDdsHvgQ/S53vupDsBOI/AAAAAAAAAWE/xeIwD8xthsA/DSC00834_thumb%5B1%5D.jpg?imgmax=800" width="440" height="331" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_kNRcDdsHvgQ/S53vvlePLGI/AAAAAAAAAWI/MYE-f23tCfA/s1600-h/DSC00837%5B3%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00837" border="0" alt="DSC00837" src="http://lh3.ggpht.com/_kNRcDdsHvgQ/S53vwfwoTZI/AAAAAAAAAWM/YBU_CVwyMTk/DSC00837_thumb%5B1%5D.jpg?imgmax=800" width="447" height="336" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;這次來漁人碼頭，也還是只有遠遠的眺望惡魔島，真的，如果還有下次的話，應該要坐船到惡魔島上去逛逛。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kNRcDdsHvgQ/S53vxUgzPeI/AAAAAAAAAWQ/JZLQ_tWWSGA/s1600-h/DSC00839%5B4%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00839" border="0" alt="DSC00839" src="http://lh4.ggpht.com/_kNRcDdsHvgQ/S53vyCWanCI/AAAAAAAAAWU/nzPhDK4h8KQ/DSC00839_thumb%5B2%5D.jpg?imgmax=800" width="451" height="339" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;吃完午餐，一群人就走到公車站牌，坐公車到金門大橋去。公車很貴，成人票2元。( 不過後來才知道，這個票不是算次數的，算時間的....)&lt;/p&gt;  &lt;p&gt;這次到金門大橋，就可以有很充裕的時間多走一走了，前幾次真的只是拍照來個到此一遊而已。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/S53vy3rfLFI/AAAAAAAAAWY/pIFMLfkez0o/s1600-h/DSC00847%5B4%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00847" border="0" alt="DSC00847" src="http://lh3.ggpht.com/_kNRcDdsHvgQ/S53vzxcCM0I/AAAAAAAAAWc/UJ6VDxl1gR8/DSC00847_thumb%5B2%5D.jpg?imgmax=800" width="456" height="343" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/S53v0vr0avI/AAAAAAAAAWg/8Ja_eCSCFIw/s1600-h/DSC00853%5B3%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00853" border="0" alt="DSC00853" src="http://lh3.ggpht.com/_kNRcDdsHvgQ/S53v1EUBwCI/AAAAAAAAAWk/YdHvPKIG8kU/DSC00853_thumb%5B1%5D.jpg?imgmax=800" width="454" height="342" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;橋上還有兩個警告，貼得到處都是。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_kNRcDdsHvgQ/S53v2DJBP2I/AAAAAAAAAWo/6wEUxlb1P1w/s1600-h/DSC00852%5B3%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00852" border="0" alt="DSC00852" src="http://lh6.ggpht.com/_kNRcDdsHvgQ/S53v2vIGciI/AAAAAAAAAWs/RQUE-8PG56M/DSC00852_thumb%5B1%5D.jpg?imgmax=800" width="353" height="266" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;不准從橋上丟東西或飛彈(??)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/S53v3TqtroI/AAAAAAAAAWw/LT0nU-f5gV4/s1600-h/DSC00854%5B4%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC00854" border="0" alt="DSC00854" src="http://lh4.ggpht.com/_kNRcDdsHvgQ/S53v4BRanPI/AAAAAAAAAW0/afKdYsd0nOM/DSC00854_thumb%5B2%5D.jpg?imgmax=800" width="348" height="262" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;『還有希望，打個電話吧!』『從橋上跳下去的結果是致命而悲慘的..』&lt;/p&gt;  &lt;p&gt;兩個景點晃完，就回到飯店房間宅一下，準備到GDC會場去領識別證去....&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-6330752857452436928?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/03/gdc.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_kNRcDdsHvgQ/S53vpBonBQI/AAAAAAAAAVs/NyrZJHUHtdU/s72-c/DSC00828_thumb%5B1%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-2266178623874209832</guid><pubDate>Tue, 23 Feb 2010 10:46:00 +0000</pubDate><atom:updated>2010-02-23T18:46:24.736+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">遊戲雜記</category><category domain="http://www.blogger.com/atom/ns#">電影雜記</category><title>Carmack的終身成就獎</title><description>&lt;p&gt;今天看到這則新聞，&lt;a href="http://www.shacknews.com/onearticle.x/62452"&gt;John Carmack Wins GDC Lifetime Achievement Award&lt;/a&gt;。神人卡馬克將獲得終身成就獎。&lt;/p&gt;  &lt;p&gt;於是我想起了之前看過的Doom電影。&lt;/p&gt;  &lt;p&gt;我大概是第二次或第三次重看 ( 因為電影台老是一直重播，真的不是我愛看.... ) 的時候，突然發現，耶，怎麼有個卡馬克博士?&lt;/p&gt;  &lt;p&gt;網路上面查了一查，原來真的有這樣一個 Dr. Carmack 的角色，而且還是整個作怪的基地上的首席科學家。也就是 Dr. Carmack 發出了求救訊息之後，巨石強森那一夥軍人才會趕來救援。&lt;/p&gt;  &lt;p&gt;然後，Dr. Carmack 就被怪物蹂躪了。&lt;/p&gt;  &lt;p&gt;Dr. Carmack 出現的時間非常短，好像也沒什麼台詞。&lt;/p&gt;  &lt;p&gt;但是短短幾秒鐘，已經向 John Carmack 致上最崇高敬意了。&lt;/p&gt;  &lt;p&gt;( 雖然說，死得也是很慘.... )&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="220px-Robert_Russell" border="0" alt="220px-Robert_Russell" src="http://lh5.ggpht.com/_kNRcDdsHvgQ/S4Ox6p0nEjI/AAAAAAAAAVk/29SNM9OZgvY/220px-Robert_Russell_thumb.jpg?imgmax=800" width="184" height="244" /&gt;&lt;/p&gt;  &lt;p&gt;找不到劇照，只好用演員的照片。注意，這是演 Dr. Carmack 的演員，不是 John Carmack 本人，不過面相似乎有些神似....呵....&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-2266178623874209832?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/02/carmacklifetime-achievement.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_kNRcDdsHvgQ/S4Ox6p0nEjI/AAAAAAAAAVk/29SNM9OZgvY/s72-c/220px-Robert_Russell_thumb.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-3486206836037026217</guid><pubDate>Mon, 25 Jan 2010 14:11:00 +0000</pubDate><atom:updated>2010-01-25T22:11:56.913+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">程式雜技</category><title>Multi-Thread Debugger</title><description>&lt;p&gt;前幾天，下載了Visual Studio 2010 Beta版來安裝，人家問，有什麼新功能值得裝來的呀?&lt;/p&gt;  &lt;p&gt;我也不知道。&lt;/p&gt;  &lt;p&gt;回頭看了一看，有些附加功能 -- 效能分析、單元測試、程式碼靜態分析....好像都提不起勁....&lt;/p&gt;  &lt;p&gt;然後是這個 – Multi-Thread Debugger。&lt;/p&gt;  &lt;p&gt;啊....發現好東西....&lt;/p&gt;  &lt;p&gt;Multi-Thread的時代，一定要有Multi-Thread 的Debugger啊!!&lt;/p&gt;  &lt;p&gt;趕快開了個Multi-Thread的專案來測試。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kNRcDdsHvgQ/S12mon8CFJI/AAAAAAAAAVQ/k19_QUSMvvI/s1600-h/Image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="未命名vs10_thread" border="0" alt="未命名vs10_thread" src="http://lh5.ggpht.com/_kNRcDdsHvgQ/S12mpb3atBI/AAAAAAAAAVU/w0HF8xKpphw/Image.png?imgmax=800" width="603" height="166" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;當我在主緒中斷的時候，左邊的這個Thread視窗，會列出執行中的執行緒，在執行緒上點擊兩下，就會跳到所選擇的執行緒上，右邊視窗就可以看到這個執行緒的Call Stack，同時也可以知道變數的數值。&lt;/p&gt;  &lt;p&gt;於是，多個執行緒的狀況可以同時掌握，對多緒程式的除錯真是一大福音啊....&lt;/p&gt;  &lt;p&gt;VS 2010還有一個Parallel Stacks的視窗。不過我還看不出來它的用途。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/S12mqNyiN4I/AAAAAAAAAVY/_dKFHbuW3B4/s1600-h/Image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="未命名vs10_call_stack" border="0" alt="未命名vs10_call_stack" src="http://lh5.ggpht.com/_kNRcDdsHvgQ/S12mq-_AejI/AAAAAAAAAVc/Yfz3-dx1Q-U/Image.png?imgmax=800" width="602" height="236" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;VS 2008好像也有多緒除錯的功能，不過說實話，VS 2008沒有去詳細探究。畢竟人家說，VS 2008跟Vista一樣是個失敗品啊...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-3486206836037026217?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/01/multi-thread-debugger.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_kNRcDdsHvgQ/S12mpb3atBI/AAAAAAAAAVU/w0HF8xKpphw/s72-c/Image.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-5059911937011144936</guid><pubDate>Tue, 12 Jan 2010 05:32:00 +0000</pubDate><atom:updated>2010-01-12T13:32:56.607+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">寫不完的遊戲引擎</category><title>3dsMax Exporter Plug-in (3)</title><description>&lt;p&gt;Well, 我們的Exporter還沒做完。&lt;/p&gt;  &lt;p&gt;我們在MyExporter1::DoExport設定中斷點，會發現，這個函式會在我們選定了輸出檔，按下存檔之後才被呼叫。這時候，就開始了輸出工作。&lt;/p&gt;  &lt;p&gt;首先會看到一個對話盒。&lt;/p&gt;  &lt;p&gt;DoExport的程式碼裡，也就呼叫這個對話盒而已，實際輸出工作的呼叫，還是得要我們自己來。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/S0wJgXV6BXI/AAAAAAAAAVA/nHDYyXztjTw/s1600-h/clip_image001%5B3%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://lh6.ggpht.com/_kNRcDdsHvgQ/S0wJgwsSQ4I/AAAAAAAAAVE/VJqdjqgN-vM/clip_image001_thumb.jpg?imgmax=800" width="150" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;這個對話盒是project wizard幫我們建立的，專案裡面有一個rc檔，我們可以打開來自己改。&lt;/p&gt;  &lt;p&gt;例如，改成這樣，&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kNRcDdsHvgQ/S0wJhXgEhSI/AAAAAAAAAVI/NlhleSLjp2M/s1600-h/clip_image002%5B3%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://lh6.ggpht.com/_kNRcDdsHvgQ/S0wJhyICG_I/AAAAAAAAAVM/LlgYXr7tMzM/clip_image002_thumb.jpg?imgmax=800" width="235" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;我們可以將輸出時候需要的設定與選項，放在這對話盒裡頭，使用者按下了OK，實際的輸出工作就會開始進行了。&lt;/p&gt;  &lt;p&gt;接下來，我們真的要開始從Max抓資料了。&lt;/p&gt;  &lt;p&gt;Max有SDK，SDK也有Help文件。但是我們看習慣了MSDN, DirectX SDK文件之後，會發現Max SDK的文件真的是弄得很糟糕。但是我們還是得看。&lt;/p&gt;  &lt;p&gt;有總比沒有好。&lt;/p&gt;  &lt;p&gt;為了讓程式碼結構清晰些，我們建立一個ExporterPipeline物件來做這一堆苦工。&lt;/p&gt;  &lt;p&gt;&lt;code&gt;class CExporterPipeline      &lt;br /&gt;{       &lt;br /&gt;public:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CExporterPipeline();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ~CExporterPipeline();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; HRESULT Create(const char* model_name,const ExporterParameters&amp;amp; param);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SyncData();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; HRESULT Destroy();       &lt;br /&gt;private:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void BeginSync();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void EndSync();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SyncScene();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SyncGameNodeTree(int level,IGameNode* node,IGameNode* parent_node);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SyncGameNode(int level, IGameNode* node,IGameNode* parent_node);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SyncGameNodeGameObject(IGameNode* node, IGameObject* go);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SyncGameNodeMesh(IGameNode* node, IGameMesh* gm);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SyncGameNodeMaterial(IGameNode* node);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SyncGeometryData(IGameNode* node,IGameMesh* gm);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void SyncMaterial(IGameNode* node, int matid, Mtl* mtl);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void UpdateMeshSkinVertex(IGameNode* node,IGameMesh* gm);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void UpdateNodeFrameAnimation(IGameNode* node);       &lt;br /&gt;private:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Interface* m_MaxCore;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; IGameScene* m_Scene;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; IGameConversionManager* m_ConversionMgr;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FILE* m_fpExportFile;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ExporterParameters m_ExportParameters;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; int m_nTotalNodeCount;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; int m_nProgressNodeCount;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; std::vector&amp;lt;int&amp;gt; m_GameNodeIDArray;       &lt;br /&gt;};       &lt;br /&gt;extern CExporterPipeline g_ExporterPipeline;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;ExporterPipeline只有幾個public函式: Create, SyncData, Destroy。其餘的苦工全部寫在private函式裡。&lt;/p&gt;  &lt;p&gt;我們在MyExporter1::DoExport裡面這樣呼叫 :&lt;/p&gt;  &lt;p&gt;&lt;code&gt;int&amp;#160;&amp;#160;&amp;#160; MyExporter1::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; #pragma message(TODO(&amp;quot;Implement the actual file Export here and&amp;quot;))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if(!suppressPrompts)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DialogBoxParam(hInstance,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MAKEINTRESOURCE(IDD_PANEL),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GetActiveWindow(),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MyExporter1OptionsDlgProc, (LPARAM)this);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ExporterParameters params;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; g_ExporterPipeline.Create(name,params);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; g_ExporterPipeline.SyncData();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; g_ExporterPipeline.Destroy();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; #pragma message(TODO(&amp;quot;return TRUE If the file is exported properly&amp;quot;))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return FALSE;       &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Create建立需要的物件與檔案，SyncData處理資料輸出，Destroy清除物件以及關閉檔案。&lt;/p&gt;  &lt;p&gt;大致上外部的步驟就這樣。細節都藏在Exporter Pipeline裡，下回再繼續吧...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-5059911937011144936?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2010/01/3dsmax-exporter-plug-in-3.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_kNRcDdsHvgQ/S0wJgwsSQ4I/AAAAAAAAAVE/VJqdjqgN-vM/s72-c/clip_image001_thumb.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-4032186517239476269</guid><pubDate>Sun, 27 Dec 2009 06:51:00 +0000</pubDate><atom:updated>2009-12-27T14:51:26.205+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">寫不完的遊戲引擎</category><title>3dsMax Exporter Plug-in (2)</title><description>&lt;p&gt;在實際執行之前，要先改一些程式碼。&lt;/p&gt;  &lt;p&gt;打開專案程式的主檔案MyExporter1.cpp。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_kNRcDdsHvgQ/SzcD3xLcp1I/AAAAAAAAAUo/ezC7Oha9JFg/s1600-h/clip_image002%5B8%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://lh6.ggpht.com/_kNRcDdsHvgQ/SzcD4ojs3xI/AAAAAAAAAUs/wRtVoDpxDP0/clip_image002_thumb%5B5%5D.jpg?imgmax=800" width="595" height="314" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;這個就是我們的Exporter主物件。從SceneExport繼承而來。&lt;/p&gt;  &lt;p&gt;DoExport函式是實際進行輸出工作的入口函式。其他還有一些設定的函式，不過只有設定輸出檔副檔名的Ext函式比較重要。&lt;/p&gt;  &lt;p&gt;&lt;code&gt;int MyExporter1::ExtCount()      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; #pragma message(TODO(&amp;quot;Returns the number of file name extensions supported by the plug-in.&amp;quot;))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return 1;       &lt;br /&gt;} &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&lt;code&gt;const TCHAR *MyExporter1::Ext(int n)      &lt;br /&gt;{&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; #pragma message(TODO(&amp;quot;Return the 'i-th' file name extension (i.e. \&amp;quot;3DS\&amp;quot;).&amp;quot;))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return _T(&amp;quot;me1&amp;quot;);       &lt;br /&gt;} &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&lt;code&gt;const TCHAR *MyExporter1::LongDesc()      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; #pragma message(TODO(&amp;quot;Return long ASCII description (i.e. \&amp;quot;Targa 2.0 Image File\&amp;quot;)&amp;quot;))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return _T(&amp;quot;My Exporter Sample 1&amp;quot;);       &lt;br /&gt;}       &lt;br /&gt;const TCHAR *MyExporter1::ShortDesc()       &lt;br /&gt;{&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; #pragma message(TODO(&amp;quot;Return short ASCII description (i.e. \&amp;quot;Targa\&amp;quot;)&amp;quot;))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return _T(&amp;quot;My Exporter 1&amp;quot;);       &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;我們把 ExtCount, Ext, LongDesc, ShortDesc 函式簡單實做之後，重新編譯一次。&lt;/p&gt;  &lt;p&gt;然後，從 Visual Studio Debug 執行它。&lt;/p&gt;  &lt;p&gt;跑不起來是正常的。&lt;/p&gt;  &lt;p&gt;打開專案的 Property 設定，在 Debugging –&amp;gt; Command 那一項，把 3ds max 的執行檔設定進去。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_kNRcDdsHvgQ/SzcD5bHK8HI/AAAAAAAAAUw/BtpaQb9WqTM/s1600-h/clip_image002%5B9%5D%5B3%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002[9]" border="0" alt="clip_image002[9]" src="http://lh5.ggpht.com/_kNRcDdsHvgQ/SzcD53N6LZI/AAAAAAAAAU0/5kHERrszewk/clip_image002%5B9%5D_thumb%5B1%5D.jpg?imgmax=800" width="573" height="412" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;然後我們可以 Start Debugging。&lt;/p&gt;  &lt;p&gt;Visual Studio 會啟動 3ds max，而 max 會將我們的 plug-in load 進去。&lt;/p&gt;  &lt;p&gt;我們的 exporter 是在 export 檔案時才會用到的，所以，先 export 看看。&lt;/p&gt;  &lt;p&gt;我們會在存檔類型那裏，找到我們的輸出檔格式。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kNRcDdsHvgQ/SzcD6iNcMEI/AAAAAAAAAU4/b3O6vCm9mxo/s1600-h/clip_image001%5B5%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://lh6.ggpht.com/_kNRcDdsHvgQ/SzcD7Rv100I/AAAAAAAAAU8/pgvvXPZA0P4/clip_image001_thumb%5B2%5D.jpg?imgmax=800" width="492" height="463" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;到這裏，我們的 exporter 算是可以掛上 max 系統裡了。&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-4032186517239476269?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2009/12/3dsmax-exporter-plug-in-2.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_kNRcDdsHvgQ/SzcD4ojs3xI/AAAAAAAAAUs/wRtVoDpxDP0/s72-c/clip_image002_thumb%5B5%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9004261571334633871.post-1291071828219053757</guid><pubDate>Thu, 24 Dec 2009 14:50:00 +0000</pubDate><atom:updated>2009-12-24T22:50:42.743+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">寫不完的遊戲引擎</category><title>3dsMax Exporter Plug-in (1)</title><description>&lt;p&gt;&lt;strong&gt;序言&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Exporter 是我們在製作 3D 遊戲時，非常常用的一項工具程式。由於美術所製作的 3dsMax 模型，對於 3D 引擎來說，資料過多且複雜，所以我們需要借助 Exporter 將模型資料轉出成我們所需要的資料格式。DirectX X-File 即為其中一種格式。&lt;/p&gt;  &lt;p&gt;3dsMax 利用了抽象介面的概念，定義了非常多的 Interface，Plug-in 設計者可以繼承這些 Interface 來實做，3dsMax 便可以透過抽象介面虛擬函式的動態連結，在需要的時候呼叫 Plug-in 所提供的實作物件。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step by Step&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;第一步，當然是先把 3dsMax 安裝起來，同時，要安裝 3dsMax SDK，是的，Max 也有 SDK。&lt;/p&gt;  &lt;p&gt;接著，為了自己的便利，最好把 &amp;quot;3ds max Plugin Wizard&amp;quot; 安裝起來。通常 SDK 的目錄文件裡都有，如果沒有，就花點時間請 Google 大神幫忙。&lt;/p&gt;  &lt;p&gt;安裝完畢，Visual Studio的專案裡，會多了一種專案。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kNRcDdsHvgQ/SzN_ug8Gm_I/AAAAAAAAAUY/riOlmIPehJY/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_kNRcDdsHvgQ/SzN_vXRgVvI/AAAAAAAAAUc/21abFx6wQa0/image_thumb%5B2%5D.png?imgmax=800" width="550" height="312" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;建立一個新專案 ( MyExporter1 )，當然，要選取3ds max Plugin Wizard。&lt;/p&gt;  &lt;p&gt;然後Wizard會出現以下的選擇畫面。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_kNRcDdsHvgQ/SzN_v3_ClyI/AAAAAAAAAUg/MVqgG52MY84/s1600-h/clip_image001%5B6%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://lh6.ggpht.com/_kNRcDdsHvgQ/SzN_wRPpiWI/AAAAAAAAAUk/kpq4UUIza3M/clip_image001_thumb%5B3%5D.jpg?imgmax=800" width="549" height="397" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;看到麼? 沒在騙人，真的有很多種類型的 Plug-in。&lt;/p&gt;  &lt;p&gt;我們這次需要的是 File Exporter 。&lt;/p&gt;  &lt;p&gt;選擇以後，後面兩個步驟就照著需要，填寫裡面內容。&lt;/p&gt;  &lt;p&gt;然後，Wizard 就會協助建立一個 Plug-in 專案。&lt;/p&gt;  &lt;p&gt;有了專案，編譯看看。&lt;/p&gt;  &lt;p&gt;如果，我們前面的設定沒有問題，編譯通常就沒問題。我們會得到一個附檔名是 dle 的檔案，直接輸出在 3dsMax 的 plugin 目錄下。&lt;/p&gt;  &lt;p&gt;dle 檔案實際上就是一個 dll ，改成 dle 只是表示這是一個 exporter 。&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9004261571334633871-1291071828219053757?l=lancelotdiary.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://lancelotdiary.blogspot.com/2009/12/3dsmax-exporter-plug-in-1.html</link><author>noreply@blogger.com (藍斯洛)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_kNRcDdsHvgQ/SzN_vXRgVvI/AAAAAAAAAUc/21abFx6wQa0/s72-c/image_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total></item></channel></rss>

