2012年5月2日 星期三

Android 開發教學筆記 - 研究 Renderscript 之 Fountain 與 FountainFbo 的差異

fountainFbo


關於 Fountain 和 FountainFbo 的介紹,可以看 Renderscript>Graphics 官網得到更詳細的介紹,在此僅簡易筆記。


首先快速帶一下 Fountain 的特效,就是在螢幕上點擊、久按、拖拉著任何一點,這時螢幕會隨著點擊事件產生一個點畫在螢幕上,接著亂數決定這個點的顏色以及該如何移動並會隨著時間往下掉,這樣的效果就接近煙火。其中在 FountainRS 有定義最多顯示 50000 個點(PART_COUNT變數),所以拖曳時的效果又跟煙火不太一樣。而 FountainFbo 則是多顯示一塊小區域,重複繪出螢幕上的特效,並使用 Framebuffer Object。


先用 vimdiff 看一下 FountainRS.java 和 FountainFboRS.java 的差異:


$ cd ~/workspace
$ vimdiff Fountain/src/com/example/android/rs/fountain/FountainRS.java FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboRS.java


java_FountainRS_FountainFboRS


扣除 package name 這類東西外,看得出來主要差別在 public void init(RenderScriptGL rs, Resources res) 中所使用的流程。


先看一下共同項目:


ProgramFragmentFixedFunction,其定義 http://developer.android.com/reference/android/renderscript/ProgramFragmentFixedFunction.html


ProgramFragmentFixedFunction is a helper class that provides a way to make a simple fragment shader without writing any GLSL code. This class allows for display of constant color, interpolated color from the vertex shader, or combinations of the both blended with results of up to two texture lookups.


Mesh,其定義 http://developer.android.com/reference/android/renderscript/Mesh.html


This class is a container for geometric data displayed with Renderscript. Internally, a mesh is a collection of allocations that represent vertex data (positions, normals, texture coordinates) and index data such as triangles and lines.


Vertex data could either be interleaved within one allocation that is provided separately, as multiple allocation objects, or done as a combination of both. When a vertex channel name matches an input in the vertex program, Renderscript automatically connects the two together.


Parts of the mesh can be rendered with either explicit index sets or primitive types.


ScriptField_Point,其定義在 renderscript 裡頭(C99語法)


typedef struct __attribute__((packed, aligned(4))) Point {
        float2 delta;
        float2 position;
        uchar4 color;
} Point_t;


ScriptField_Point 是自訂結構,定義於在 *.rs,編譯後自動產生的,用途是紀錄每一個點的資訊;Mesh為一種資料結構,用來收集一批資料,最重要的是 Renderscript 有 rsgDrawMesh API,可以一次把 Mesh 收集的資料繪出,因此程式架構上,並非用 loop 繪每個 Point,有點像寫 C 時,用 memset 取代用 loop 對 array 的初始化,更多細節請參考 Renderscript>Graphics>Drawing with a mesh;ProgramFragmentFixedFunction 對我而言是比較生疏的部份,這跟 OpenGL Shading Language (GLSL) 有關,其中 Google Translate 對 Shader 翻譯為"著色",我把 GLSL 當作繪圖相關的基本需求,另外,從描述的意思是使用 ProgramFragmentFixedFunction 可以省去從頭到尾定義 GLSL 出來,何謂 GLSL 呢?可以參考 Renderscript>Sample>Balls>BallsRS.java,裡頭有用 ProgramVertex 引入 GLSL 語法,更多細節請參考 Renderscript>Graphics>Programs


不一樣的地方:


對 FountainRS.java 來說,使用 ProgramFragmentFixedFunction 建立 GLSL 環境後,傳給 RenderScriptGL rs 環境使用,但在 FountainFboRS.java 中,多定義兩個 ProgramFragment 變數,mProgramFragment 和 mTextureProgramFragment,並且在 Renederscript 裡頭接應,接用 vimdiff 看一下 fountain.rs 和 fountainfbo.rs 的差異:


$ cd ~/workspace
$ vimdiff Fountain/src/com/example/android/rs/fountain/fountain.rs FountainFbo/src/com/example/android/rs/fountainfbo/fountainfbo.rs


rs_fountain_fountainfbo


可看出 fountain.rs 裡的東西基本上都出現在 fountainfbo.rs 了,所以了解 fountrain.rs 在 void root 做事後,可以細看 fountainfbo.rs 的變化,此部份在官網 Renderscript > Graphics > Framebuffer Object 有很多細部介紹,在此就不多提囉。


總結一下,在 fountainfbo 中採用 Framebuffer Object 的繪圖技巧,可以讓開發者先在某一處 buffer 繪圖(offscreen),繪完後在貼到螢幕上(onscreen)。


[PHP] CodeIgniter - session->unset_userdata is not working


圖片來源:http://codeigniter.com/


自從上次發現把東西存進 session 存不了後,發現 CodeIgniter Session 預設採用 Cookie 實做 Server Session 的機制,就開始對 CI 的好感下降很多 XD 今天又碰到一個非常擾人的問題,那就想要把存進 session 的東西清掉,但一直用 unset_userdata 卻無法清掉,原先也有碰到,但那時的情境是 logout,所以採用 session->sess_destroy() 來解決即可,現在則不是,所以非常棘手。


最後找到的解法,那就是刪除前,先對待刪除的 key 設值 NULL,如此一來就可以正常處理,這真的太瞎了。這也是為啥我對用 cookie 實做 session 會那麼反感 :P 因為 cookie 是跟瀏覽器實做有十分密切的關係,把 session 搞成 cookie,就會存在很多不可預期的問題產生。


程式碼:


$CI->session->set_userdata( $k , NULL );
$CI->session->unset_userdata( $k );


[Linux] 安裝 ADT 問題 - Missing requirement: Android Development Tools 18.0.0.v201203301601-306762 @ Ubuntu 10.04 64Bit

missing


最近開始使用 OpenJDK,不知道是不是這個關係,從 Eclipse 官網下載 Eclipse 3.7.2 Classic 後,安裝 Android Development Tools (ADT) 時,發現會出現錯誤訊息:


Cannot complete the install because one or more required items could not be found.
Software being installed: Android Development Tools 18.0.0.v201203301601-306762 (com.android.ide.eclipse.adt.feature.group 18.0.0.v201203301601-306762)
Missing requirement: Android Development Tools 18.0.0.v201203301601-306762 (com.android.ide.eclipse.adt.feature.group 18.0.0.v201203301601-306762) requires 'org.eclipse.wst.sse.core 0.0.0' but it could not be found


查閱一些資訊,有人說這是 JRE/JDK 的問題,讓我想起來我是用 OpenJDK 的,找了找,有人說解法就是去更新 Eclipse,於是我也嘗試看看,慶幸的解掉了。


環境簡介:


Eclipse 3.7.2 Classic
Build id: M20120208-0800


$ java -version
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.13) (6b20-1.9.13-0ubuntu1~10.04.1)
OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)


 解法:


Eclipse 3.7.2 Update


[Eclipse] -> [help] -> [Install New Software] -> http://download.eclipse.org/releases/indigo


Mobile Tools for Java
Mobile Tools for Java SDK


裝完後,再改去裝 ADT 就可以順利進行啦!


如果又碰到了下載回來的 ADT 不能執行,那記得裝一下 ia32-lib 吧!


adb_error


$ ./adb
bash: ./adb: No such file or directory


$ sudo apt-get install ia32-lib


2012年4月25日 星期三

[Linux] 透過 Tarball 安裝軟體與桌面環境設定 @ Ubuntu 10.04

eclipse


安裝 Android 開發環境時,從 Android 官網介紹,安裝新版 ADT Plugin for Eclipse 建議採用 Eclipse 3.6.2 以上的版本,但 Ubuntu 10.04 環境中,預設是 3.5.2-2ubuntu4.3,因此打算從 Eclipse 官網下載 Eclipse Classic 3.7.2 版本,只是解壓縮後,要執行他還是必須透過 /path/eclipse/eclipse 方式,好一點是把他擺在系統環境變數可節省一些打字,然而,這些對使用 Ubuntu Desktop 的人來說,仍舊不方便。


幸運地,在網路上找到了解法:How to install Eclipse 3.7 on Ubuntu 11.04,在此就筆記一下對於 tarball 安裝該如何整合 desktop 環境操作。


主要三個步驟:



  • 安置 tarball 軟體

  • 設定環境變數

  • 設定 Desktop 選單環境


流程:


$ cd ~/
$ tar -xvf eclipse-SDK-3.7.2-linux-gtk.tar.gz
$ sudo mv eclipse /opt/
$ sudo chown -R root:root /opt/eclipse
$ sudo chmod -R +r /opt/eclipse


$ sudo touch /usr/bin/eclipse
$ sudo chmod 755 /usr/bin/eclipse
$ sudo vim /usr/bin/eclipse
#!/bin/sh
export ECLIPSE_HOME="/opt/eclipse"
$ECLIPSE_HOME/eclipse $*


$ sudo vim /usr/share/applications/eclipse.desktop
[Desktop Entry]
Encoding=UTF-8
Name=Eclipse
Comment=Eclipse IDE
Exec=eclipse
Icon=/opt/eclipse/icon.xpm
Terminal=false
Type=Application
Categories=GNOME;Application;Development;
StartupNotify=true


如此一來,在 Ubuntu Desktop 的功能分類就能看到 Eclipse 了,並且也能正確顯示 icon 圖示,收工!


2012年4月22日 星期日

[Android] 更改 AOSP 顯示的帳號資訊

setting_about


最近把玩 AOSP 時,在 setting/about 可以看到此 AOSP 的編譯相關資訊,基於隱私想要更改他 XD 接著透過 grep -r "username" 的搜尋方式,發現此資訊擺放處:out/target/product/panda/system/build.prop 裡頭。


來回測試,發現修改方式有三種,第一種就是建立一個假帳號來編譯,讓 AOSP 編譯過程中取得假帳號的資訊;第二種方式則是變更環境變數 User 資訊,接著再重新編譯;第三種則是直接修改 out/target/product/panda/system/build.prop 資訊,並刪掉系統關鍵檔案,使之只重新編譯關鍵東西即可。


第二種方式:


$ cd ~/aosp
~/aosp$ source build/envsetup.sh
~/aosp$ make clean
~/aosp$ User=username
~/aosp$ lunch full_panda-eng
~/aosp$ make -j4


大約執行兩三分鐘後,就可以去翻 ~/aosp/out/target/product/panda/system/build.prop 出來看看,搜尋一下應該看不到自己的帳號名稱。此流程適合剛開始編譯或剛好打算全部重編用的。


第三種方式:


$ cd ~/aosp
~/aosp$ source build/envsetup.sh
~/aosp$ lunch full_panda-eng
~/aosp$ vim out/target/product/panda/system/build.prop
~/aosp$ rm out/target/product/panda/system.img
~/aosp$ make -j4


由於許多東西早已編好了,只是重新 build system.img 而已,算是最快的解法吧。


以上算是無聊想到的東西,但第二種跟第三種解法跟一比較起來,不曉得有沒更細節的東西沒清掉 XD