2008年7月31日 星期四

每個人都是韓國人

繼成功的將孔子歸化為韓國人之後,韓國的大學教授們,又將孫中山先生歸化為韓國人。

教授說,有一支古朝鮮人軍隊為周朝作戰,其中一群人由於戰功彪炳,被周文王冊封於孫。這就是孫氏的起源,所以孫中山先生有韓國人血統。

那麼,孫悟空應該也是韓國人。

朋友問我,『這些韓國人到底是什麼心態?』,我說,『就像是歐洲的有錢人,想去買個貴族爵位來坐坐一樣』。

『不懂』。

『你們這些泱泱大國,又有悠久文化的民族是不會懂的』。

其實並不是只有韓國人這樣搞。

以前曾經看過報導,有很多美國總統都有歐洲國家的皇室血統。甘迺迪啦,柯林頓啦,好像連演電影的雷根都有。

最好是。

如果今年歐巴馬當選,搞不好也能夠扯出歐巴馬有皇室血統,而且還是來自非洲肯亞,他父親那一系。

真是夠了。

(不過這應該是大陸人搞出來的假新聞,把大家呼攏一兩天。我看不到這份報紙新聞,也看不懂韓文,所以不知道是真是假,反正笑笑罵罵就好.......)

2008年7月30日 星期三

Graphic Debugger ( Part V )

Pixel History是使用PIX做Shader Debug的第一個步驟。

首先當然還是先抓一個Frame的資料下來,在Details圖表中切到Render那一頁,可以看到整個Render最後的樣子,在圖片上的某個pixel上按下滑鼠右鍵,選擇"Debug this pixel",Pixel History就顯示在Details圖表中的"Debugger"頁面。


Pixel History給我們的資訊,是這個Pixel從初始顏色一直到最後顏色的變化,包括R,G,B以及Alpha的數值。上面這張圖是一開始的兩個數值變化,第一個是Frame buffer最初的顏色,也可以說是上個Frame留下來的顏色。第二個數值則是Clear Backbuffer之後所得到的顏色。
接著往下看。


第三個階段,顯示了pixel shader的輸出結果,以及計算後的最後Frame buffer顏色。左邊有幾個超連結,點選之後,頁面就會切換成shader debugger。


Shader Debugger的上半部是Shader code,下半部是暫存器的內容。左上角有幾個按鈕,可以讓我們一步一步執行Shader code,同時檢查暫存器內容數值的變化。

2008年7月25日 星期五

Why so serious?

看過電影的就知道我在說哪一部電影。

這句話其實是很恐怖的一句話,想想看,有一個幾近發狂的人,拿著小刀放在你嘴裡,威脅著要幫你劃出一道笑容,還說著:『為什麼這麼嚴肅啊?』

小丑才是『黑暗騎士』的電影主角。

超級英雄的電影一直有個通病,那就是越拍越難看,蜘蛛人是如此,以前的蝙蝠俠是如此,就連老字號的超人都是如此。不過這一回的蝙蝠俠可就不同了,編導演三方面用了很大的心力去塑造一個反派角色,就讓這部續集電影的評價變得很高。小丑變成了主角,蝙蝠俠搶不到觀眾的太多目光。

我想,也許這樣一來,就不會讓這部超級英雄電影,越拍越難看。超級英雄的電影,除了炫麗的聲光效果之外,還是需要人物塑造、故事劇情的。超級英雄在第一集已經塑造過了,第二集開始,就塑造一個一個的反派角色吧!

還記得小丑炸掉醫院的那一幕嗎? 沉睡在心裏深處的瘋狂性格是否被喚醒了? 也許有吧,因為從小丑瘋狂的亂按遙控器,到整個醫院化為灰燼的這一段劇情,居然會引起我心裏的共鳴,隔了兩天,一整段畫面還在腦海裡。

希斯萊傑的詮釋也無可挑剔。有注意到小丑說話時斷斷續續,不時還舔一舔嘴唇嗎? 一開始還無法理解為何小丑有這樣的動作,後來才知道那是臉部有傷痕所造成的。

這部劇情是有人性哲理的,有人探討了很多黑白騎士、小丑的意義、雙面人的硬幣、兩艘炸藥船的社會實驗,甚至還有人討論擺滿了炸藥的兩艘船究竟合不合情理,小丑哪裡來的這麼多人力安排這樣的瘋狂計畫...
我想,這是個商業娛樂片,可以加點人性哲理的思考讓影片有深度,但是它畢竟還是個娛樂片,思考深度點到為止就好,讓觀眾能夠期待下一集有更棒的電影可看,真的,不用太嚴肅。

2008年7月24日 星期四

Graphic Debugger ( Part IV )

我們開始看"A single-frame capture of Direct3D whenever F12 is pressed"所得到的結果。請先回頭看這篇文章


Objects View顯示的是系統內的物件資料,包括物件的位址、格式、大小、型態等等。舉例來說,在這個圖表裡,我們可以看到D3D 貼圖物件所使用記憶體的容量、Pixel格式、寬、高等等的資料。
圖表的最上方有一排下拉式Filter選單,可以將列出的物件過濾。例如,在Type選單選擇D3D 貼圖物件,圖表中列出的就只剩貼圖物件。



Events View中,會顯示所有抓下來的D3D API呼叫,同時提供了呼叫的參數,如果參數是某個D3D物件的話,就會顯示物件的位址。在位址上按下滑鼠右鍵,就可以把這個物件的詳細內容顯示在右邊的Details View中。

Details 顯示的內容,跟物件的型態有關,各式各樣我們需要的資訊,都會鉅細靡遺的顯示出來。

現在,我們先來玩Depth-Stencil Buffer。
第一步當然是跑一個D3D程式,抓一個Frame的資料顯示在PIX中。
接著,在Objects View裡面,用"Usage" Filter將Depth-Stencil Buffer取出來。
在這個D3D 物件上用滑鼠右鍵點選,就會出現類似這樣的Pop-up選單,

選擇這第一個也是唯一一個可選的項目,Depth-Stencil Surface的內容就會顯示在Details View裡面了。

Depth數值,是用白色到黑色的灰階值,來表示0.0 ~ 1.0,紅色框框標記的地方,可以讓我們調整邊界數值,上面這張圖,是我將0.95以下的數值都調整成白色得到的結果。

左下的Events View跟Details View可以合併一起來看,我們在Events裡面選擇一個一個的Events,可以看見當時的Depth Surface內容,換句話說,我們可以對Depth Surface做Tracing!!

其他的各種D3D物件,使用方式都類似,只是在Details裡面的內容不同。

下一回,我們來介紹一下也很好玩的Pixel History。

2008年7月18日 星期五

隱身在幕後的Singleton

今天看到一個很好玩的架構,我稱之為「隱身在幕後的Singleton」。

我們有一個Symbol類別,物件放在Symbol Table中,這個Symbol Table是一個Singleton。


class CSymbol
{
public:
  // constructor, destructor
  CSymbol( char const* pStr );
protected:
  // Initializes the symbol table
  static void InitializeTable();
  // returns the current symbol table
  static CSymbolTable* GetTable();
  // The standard global symbol table
  static CSymbolTable* s_pSymbolTable;
  friend class CCleanupSymbolTable;
};


class CCleanupSymbolTable
{
public:
  ~CCleanupSymbolTable();
};


class CSymbolTable
{
public:
  CSymbolTable();
  ~CSymbolTable();
};

SymbolTable 是放在 Symbol 類別裡的一個靜態成員資料,所以,所有的 Symbol 都共用相同一個。
一開始這個 Table 是不存在的,在 Symbol 的建構子裡面,會呼叫 GetTable() 函式, 這個函式會new 一個 Table 出來,如果沒有的話。
也就是,第一次建立 Symbol 物件時,就會自動地建立 Symbol Table 。

CleanupSymbolTable 物件只有定義一個解構子,它的 code 是這樣:

CCleanupSymbolTable::~CCleanupSymbolTable()
{
  if (CSymbol::s_pSymbolTable) delete CSymbol::s_pSymbolTable;
  CSymbol::s_pSymbolTable = 0;
}


所以這個物件的用處沒別的,就是在解構子裡面 delete 掉 Symbol Table Singleton。
然後我們再宣告一個靜態物件變數。

static CCleanupSymbolTable g_CleanupSymbolTable;

這樣,當程式結束的時候,程式會清除靜態變數 g_CleanupSymbolTable,而這個變數被清除時,會 delete 掉 Symbol Table。 所以這個 Symbol Table 就像是隱形了一樣,不需要外部呼叫new / delete,用到它的時候,自然會 new 出來,程式結束會自動 delete 掉。

完全的全自動操作。

2008年7月17日 星期四

Graphic Debugger ( Part III )

接下去寫PIX其他的圖表之前,先讓我偷懶一次,寫一個很小卻很炫的功能。

這功能叫做抬頭顯示器,Heads-Up Display (HUD)。


HUD的設定就在每個Frame統計數據的選項後方,把這個項目打勾之後,Time line的數據線圖,就會即時的顯現在所要抓取數據的視窗中。


透過這樣的數據顯示,我們可以觀察即時的數據變化,對效能的分析也有很大的幫助。

不過PIX的這項功能在版本比較舊的DirectX SDK中並沒有提供,所以,如果你的PIX中沒看到這項功能,就更新一下SDK的版本吧...

2008年7月16日 星期三

Graphic Debugger ( Part II )

現在我們可以開始來看PIX的測試結果。
首先是Time line圖表。


Time line圖表有四個部分,灰色的Bar是CPU 負載圖,第二條Bar是GPU 負載圖(在Vista作業系統下才有這條Bar,XP是沒有的),底下的線圖會顯示每個Frame D3D 呼叫所統計出來的數值,最下方有四個下拉式選單,可以選擇在線圖上所要顯示的數值。選單右邊有Zoom in, Zoom out的按鈕,可以調整時間比例。

CPU 的負載Bar用黑色邊框圍起來的灰色長方形表示一個Frame,上面這張圖裡面,在左邊的箭頭處,我們看到一個花了很長時間的Frame,通常這是初始化的階段會有的現象,中間的箭頭,我們看見幾個分佈很平均的方塊,時間也不長,負載還算不錯,右方的箭頭所指的,是一條比較粗的黑線,這表示這個Frame的時間非常短。另外,在初始化的Frame之後,有一小段空隙,這段空隙表示CPU在這時候是空閒的。

GPU的負載Bar稍為複雜些。黑色邊框裡面的長方形會有三種顏色,藍色表示GPU正在執行所交付的工作,灰色表示GPU在idle狀態,等待CPU交代工作,如果出現紅色,就表示某些GPU執行工作所需要的資源被鎖住,以致GPU必須等待資源被釋放出來。

這兩條Bar最主要的用途在於效能分析,從線圖裡我們可以查看到CPU與GPU的相對負載狀況。


這裡我們看到一個狀況,CPU是持續負載的,而GPU負載則斷斷續續的,有不少的空閒時間。所以如果我們能夠找到一些工作,從CPU運算轉到GPU運算上的話,整體的效能就會上升。

至於數值統計線圖的部分,主要的功用在檢查是否有不尋常的數值變化,還有就是查看每個Frame的D3D API的呼叫次數、資源使用量等等的數值是否合理。這些都可以很簡單的從線圖上看出來,所以也不用多做什麼解釋。

Time line線圖的說明就到這邊,後面還有更好玩的數據資料圖表。