摘要: 若想成大事,雷軍認為有三條秘訣:預判未來、在對的時間做對的事情、順勢而為。頗為贊同,自己也有一些思考,記錄下來。 閱讀全文
摘要: 對于OpenGL的初學者來說,有兩個不應該成為困難點的困難點。一個是編寫OpenGL程序需要依賴特定平臺的窗體系統。另外一個是OpenGL的擴展機制需要我們自己去處理。
這里推薦兩個利器來解決這兩個問題。讓我們可以更加專注和有效的學習OpenGL。分別是GLUT和GLEW 閱讀全文
摘要: 最近在Android平臺上寫NDK程序,使用OpenGL ES(注意:這里是OpenGL ES 1.0和1.1版本),發現程序在運行過程中出現如下錯誤:
通過log,在android的源碼中的\frameworks\base\opengl\libs\EGL\目錄下有Loader.cpp文件,通過這 個文件我們可以發現,我們的OpenGL的調用都是通過加載實現了OpenGL ES的dll,然后在該dll中查找我們調用的接口,如果接口沒有找到,EGL就會打印出log,如上所示。
閱讀全文
今天突然發現ANDROID模擬器啟動失敗,log顯示如下錯誤信息:
ERROR: the user data image is used by another emulator. aborting
問題原因:avd的加鎖機制使然。 .lock是加鎖,如果程序崩潰等原因導致無法清除這些以.lock結尾的文件夾,就會出現這個問題,也就是這個avd的鎖沒有被釋放,導致avd manager以為這個avd正在使用當中。
解決辦法:刪除C:\Documents and Settings\@USER@\.android\avd.找到該目錄下與模擬器對應的avd,然后刪除其中的.lock文件即可。
摘要: OpenGL中的Frame Buffer Object(FBO)擴展,被推薦用于把數據渲染到紋理對像。相對于其它同類技術,如數據拷貝或交換緩沖區等,使用FBO技術會更高效并且更容易實現。
FBO一個最常見的應用就是:渲染到紋理(render to texture),通過這項技術可以實現發光效果,環境映射,陰影映射等很炫的效果。
在OpenGL渲染管線中,幾何數據和紋理最終都是以2d像素繪制到屏幕上。最后一步的渲染目標在OpenGL渲染管線中被稱為幀緩存(frame buffer)。幀緩存是顏色緩存、深度緩存、模板緩存、累積緩存的集合。默認情況下, OpenGL使用的幀緩存是由窗體系統創建和管理的。
在OpenGL擴展中,GL_EXT_framebuffer_object擴展提供了一個創建額外幀緩存對象(FBO)的接口。這個幀緩存的創建和控制完全是由OpenGL完成的,有別于窗體系統創建的默認的幀緩存。與系統默認的幀緩存類似,一個FBO也是顏色緩存、深度緩存、模板緩存的集合(FBO不包括累積緩存),然后OpenGL程序就可以把渲染重定向到FBO 閱讀全文
這段時間使用vim,寫了不少測試代碼,既然是測試代碼,注釋測試代碼,取消注釋就是一個經常性的操作,到今天才動手去找了一個vim的注釋代碼的插件。
下載地址:NERD Commenter
下載以后解壓。把doc放doc目錄下,NERD_commenter.vim放plugin目錄下,啟動vim,OK了。
注釋代碼:
在可視模式下,選擇要注釋的代碼,輸入: ,cc
取消注釋: 選擇要取消注釋的代碼,輸入: ,cu
不錯的插件。
在OpenGL中我們可以使用gluPerspective來設置視椎體。但是在OpenGL ES中卻沒有提供這樣的實用庫支持,其實我們可以自己來完成這個函數的功能。代碼如下:
1
2 void __gluPerspective(double fovy, double aspect, double zNear, double zFar)
3 {
4 glMatrixMode(GL_PROJECTION);
5 glLoadIdentity();
6
7 double xmin, xmax, ymin, ymax;
8 ymax = zNear * tan(fovy * KPI / 360);
9 ymin = -ymax;
10 xmin = ymin * aspect;
11 xmax = ymax * aspect;
12
13 glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar);
14 }
15
16
在需要調用gluPerspective的地方,用該函數替換即可。
學習3D編程,四元數是不得不學的。其概念的引入和定義都比較抽象,今學了,總結歸納如下:
介紹四元數之前,先做如下約定:
1.采用右手坐標系(OpenGL)
2.旋轉次序:x->y->z
3. 矩陣是列優先存儲
1.什么是四元數?
直接用數學上的定義來解釋,因為我很難在現實生活中找到可以描述明白的例子。
i, j, k 為虛數
Q = w + xi + yj
+ zk
其中w是實數,而x,y,z為復數。
另外一種常見的表達方式是:
Q = [w, v]
其中v=(x,y,z)稱為矢量部(雖然稱為矢量,但是這個不是三維空間中的矢量,而是四維空間的,想象吧L),w稱為標量部。
2.四元數可以做什么?
有了四元數的概念還不行,四元數可以干什么?四元數可以用來描述方向。
先來看下如何求取四元數的長度:
||q|| = Norm(q)
= sqrt(w2 + x2 + y2 + z2)
單位長度的四元數有以下屬性:
w2 +
x2 + y2 + z2 = 1
所以我們使用如下方法來標準化(Normalize)一個四元數:
q = q / ||q|| =
q / sqrt(w2 + x2 + y2 + z2)
使用一個單位四元數來描述方向,請記住必須是單位四元數才可以描述方向。
3.四元數的乘法
因為一個單位四元數可以代表一個三維空間中的方向,那么兩個四元數相乘得到的結果仍然是一個四元數,這個四元素依舊可以標識一個方向。
給定兩個四元數:
Q1 = (w1, x1,
y1, z1)
Q2 = (w2, x2,
y2, z2)
Q1 * Q2 = (w1.w2
– v1.v2, w1.v2 + w2.v1 + v1 x v2)
注意:.代表向量間的點積,x代表叉積。v1=(x1, y1, z1) v2=(x2, y2, z2)
優化一下:
w=w1w2 - x1x2 -
y1y2 - z1z2
x = w1x2 + x1w2 + y1z2 - z1y2
y = w1y2 + y1w2 + z1x2 - x1z2
z = w1z2 + z1w2 + x1y2 - y1x2
4.四元數的轉換
為什么要轉換,因為我們還不能直接使用四元數來進行3D物體的旋轉。在OpenGL中和Direct3D中都是通過矩陣來描述3D旋轉的。
4.1 四元數到矩陣的轉換
使用單位四元數轉換到矩陣:
Matrix = [ 1 - 2y2 - 2z2 2xy - 2wz 2xz + 2wy
2xy + 2wz 1 - 2x2 - 2z2 2yz - 2wx
2xz - 2wy 2yz + 2wx 1 - 2x2 - 2y2 ]
4.2 四元數到軸角的轉換
軸角也是一種表達空間旋轉的方式。
如果旋轉軸是:(ax, ay, az)
旋轉角度是:angle (單位:弧度)
那么四元數與軸角之間的轉換關系如下:
angle = 2 *
acos(w)
ax = x / scale
ay = y / scale
az = y / scale
其中scale = sqrt(x2 + y2 + z2)
4.3 軸角到四元數的轉換
假設旋轉軸是(ax, ay, az),記得必須是一個單位向量。
旋轉角度是theta. (單位:弧度)
那么轉換如下:
w = cos(theta / 2
)
x = ax *
sin(theta / 2)
y = ay *
sin(theta / 2)
z = az *
sin(theta / 2 )
4.4 歐拉角到四元數的轉換
如果你的歐拉角為(a, b, c)那么就可以形成三個獨立的四元數,如下:
Qx = [ cos(a/2),
(sin(a/2), 0, 0)]
Qy = [ cos(b/2), (0, sin(b/2), 0)]
Qz = [ cos(c/2), (0, 0, sin(c/2))]
最終的四元數是Qx * Qy
* Qz的乘積的結果。
5.使用四元數來避免Gimbal
Lock
基本思路如下:
1)
使用一個四元數來標識一個方向
2)
創建一個臨時的四元數來標識當前方向到新方向的變化
3)
右乘臨時的四元數和初始四元數,結果是一個合并了兩個四元數的新的四元數
4)
將四元數轉換成矩陣
6.更深入的學習四元數
SLERP:球狀線性插值對于三位模型進行動畫處理非常有用,因為這種方式在模型的各種方向之間提供了平滑的轉換。
摘要: 如果對象需要進行有意義的(non-trival)初始化,考慮使用明確的init()的方法來進行初始化操作。因為如果在構造函數中進行有意義的初始化操作,一旦這些操作失敗,對象將進入不確定的狀態。symbian編程中廣泛使用一種稱為“兩階段構造法”的方法來解決這個問題,值得借鑒。 閱讀全文