このページの目次

Jun Mizutani 2009/11/08

O3Dとは

Google O3D はブラウザ上で3Dアニメーションを可能とするプラグインでIE、Firefox、Google Chrome といったブラウザで動作します。リアルタイムに操作可能な3DアニメーションのプログラムをJavaScriptを使って記述します。処理に時間のかかる部分はプラグイン側が担当しているため、JavaScript でも秒間60フレームの高速なアニメーションが可能です。

実際に描画する部分はバーテックスシェーダ、ピクセルシェーダのコードが行います。 例えばHTMLの <textarea> にシェーダコードをテキストで埋め込んだり、テキストファイルを別に置いて読み込んで使うこともできます。

HTML、JavaScript、シェーダコードもすべてテキストファイルなので、エディタさえあればブラウザ上で3Dアニメーションを動作させることができます。ただし、O3D自体は低レベルな機能を提供するだけであるため、柔軟性が高いものの簡単に3Dのプログラムが作成できるわけではありません。O3Dプログラミングに関するドキュメントはhttps://code.google.com/intl/ja/apis/o3d/docs/techoverview.htmlに英語で大量にありますが、あまり分かりやすいものではありません。 https://code.google.com/p/o3d/downloads/listから sample.zip (約40MB) をダウンロードしてサンプルコードとドキュメントを見比べて下さい。そのうち入門用の解説を書くかもしれません。

JavaScript で直接 OpenGL のコードを記述する WebGL と競合する技術ですが、頂点情報をバイナリデータで持てたり、tar.gz で圧縮したデータを扱えたりと複雑なモデルも使用できるため、速度や実用性ではO3Dの方がかなり有利であると思います。

Linux用O3Dプラグイン

O3DプラグインのWindows版とMac版は https://code.google.com/intl/ja/apis/o3d/からダウンロードすれば自動的にインストールされますが、Linuxで使うためには、Subversionでソースを入手し、Googleの専用ツール(depot-tools)を使ってコンパイルする必要があります。

今回、32bitのUbuntu 9.10をクリーンインストールした環境で O3Dをビルドしてみました。

名前空間関連の問題でコンパイルエラーが発生しました。適当にソースを変更(fopenやsetenvなどの関数にグローバル名前空間を指定し、対応するヘッダファイルをインクルード)するとビルドに成功し、動作確認できました。

Windows版とMac版はすでに安定していますが、Linux版は実験段階のようです。
また、すべての機能が実装されているわけではありません。
このページの内容を試すのは自己責任でお願いします。

実行例

https://o3d.googlecode.com/svn/trunk/samples/animated-scene.html

o3d demo

ビルドの準備

Google Code の HowToBuild - o3d - How to get the source and build. を参考に行いました。

パッケージの追加

Ubuntu 9.10(32bit) で O3D をビルドするためには、以下のパッケージをapt-get で導入する必要があります。

apt-get install subversion
apt-get install libgtk2.0-dev
apt-get install g++-multilib
apt-get install libnss3-dev
apt-get install libgconf2-dev
apt-get install libgl1-mesa-dev
apt-get install libglib2.0-dev
apt-get install libglu1-mesa-dev
apt-get install libglew1.5
apt-get install libx11-dev
apt-get install libxt-dev
apt-get install sun-java6-jre

パッケージ一覧

導入された開発系のパッケージを見てみます。

root@ubuntu910-32:~/o3d# dpkg-query --show '*-dev'
amd64-libs-dev
c++abi2-dev
cli-common-dev
dpkg-dev    1.15.4ubuntu2
dvb-dev
erlang-dev
freetype0-dev
freetype1-dev
ivtools-dev
lib64c-dev
libapt-pkg-dev
libasprintf-dev
libatk-dev
libatk0-dev
libatk1.0-dev  1.28.0-0ubuntu1
libatspi-dev
libboost-python-dev
libboost-python1.35-dev
libbrlapi-dev
libbrlapi1-dev
libc-dev
libc0.1-dev
libc0.3-dev
libc6-dev   2.10.1-0ubuntu15
libc6.1-dev
libcairo-dev
libcairo-directfb2-dev
libcairo0.5.1-dev
libcairo0.6.0-dev
libcairo0.9.0-dev
libcairo2-dev  1.8.8-2ubuntu1
libcwidget-dev
libdbus-1-dev  1.2.16-0ubuntu9
libdirectfb-dev 1.2.7-2ubuntu1
libdrm-dev
libenchant-dev
libexpat-dev
libexpat1-dev  2.0.1-4ubuntu1
libfontconfig-dev
libfontconfig1-dev      2.6.0-1ubuntu12
libfreetype6-dev 2.3.9-5
libg++2.8-dev
libg++27-dev
libg++272-dev
libgconf2-dev  2.28.0-0ubuntu2
libgettextpo-dev
libgl-dev
libgl1-mesa-dev 7.6.0-1ubuntu4
libgl1-mesa-dri-dev
libgl1-mesa-swx11-dev
libglib1.3-dev
libglib2.0-dev 2.22.2-0ubuntu1
libglu-dev
libglu1-mesa-dev 7.6.0-1ubuntu4
libgnome-pilot0-dev
libgsm-dev
libgtk2.0-dev  2.18.3-1
libgtksourceview2.0-dev
libice-dev  2:1.0.5-1
libidl-dev  0.8.13-0.1
libidn11-dev
libidn9-dev
libjpeg-dev
libjpeg62-dev  6b-14build1
liblinc-dev
libmng-dev
libmotif-dev
libmozjs-dev
libmudflap0-4.4-dev
libnautilus2-dev
libnspr-dev
libnspr4-dev 4.8-0ubuntu1
libnss3-dev 3.12.3.1-0ubuntu2
liborbit2-dev  1:2.14.17-0.1
libpam0g-dev
libpango-dev
libpango1.0-dev 1.26.0-1
libparted1.8-dev
libpcap0.8-dev
libpcre3-dev
libpcsclite-dev
libpixman-1-dev 0.14.0-1
libpixman1-dev
libpng-dev
libpng12-0-dev
libpng12-dev 1.2.37-1
libpng2-dev
libpng3-dev
libpopt-dev
libproc-dev
libpthread-stubs0-dev   0.1-2
libsm-dev   2:1.1.0-2
libsnmp-dev
libsnmp5-dev
libsnmp9-dev
libssl096-dev
libstdc++-dev
libstdc++2.10-dev
libstdc++2.8-dev
libstdc++2.9-dev
libstdc++2.9-glibc2.1-dev
libstdc++3.0-dev
libstdc++6-4.4-dev      4.4.1-4ubuntu8
libsysfs-dev 2.1.0-5
libx11-dev  2:1.2.2-1ubuntu1
libxau-dev  1:1.0.4-2
libxcb-render-util0-dev 0.3.6-1
libxcb-render0-dev      1.4-1
libxcb0-dev
libxcb1-dev 1.4-1
libxcomposite-dev       1:0.4.0-4
libxcursor-dev 1:1.1.9-1build1
libxdamage-dev 1:1.1.1-4
libxdmcp-dev 1:1.0.2-3
libxext-dev 2:1.0.99.1-0ubuntu4
libxfixes-dev  1:4.0.3-2build1
libxft-dev  2.1.13-3ubuntu1
libxft2-dev
libxi-dev   2:1.2.1-2ubuntu1
libxinerama-dev 2:1.0.3-2
libxkbfile-dev
libxrandr-dev  2:1.3.0-2
libxrender-dev 1:0.9.4-2ubuntu1
libxt-dev   1:1.0.5-3ubuntu1
libxtst-dev
libxul-dev
libz-dev
linux-libc-dev 2.6.31-14.48
manpages-dev
mesa-common-dev 7.6.0-1ubuntu4
mesa-glide2-dev
mesag-dev
mesag3+ggi-dev
nvu-dev
openoffice.org-dev
python-gst0.10-dev
render-dev
x-dev
x11proto-composite-dev  1:0.4-2
x11proto-core-dev       7.0.15-1
x11proto-damage-dev     1:1.1.0-2build1
x11proto-fixes-dev      1:4.0-3
x11proto-input-dev      1.5.0-2ubuntu1
x11proto-kb-dev 1.0.3-3ubuntu1
x11proto-panoramix-dev
x11proto-randr-dev      1.3.0-1
x11proto-render-dev     2:0.9.3-2
x11proto-xext-dev       7.0.4-2
x11proto-xinerama-dev   1.1.2-5ubuntu1
xlibmesa-dev
xlibmesa-gl-dev
xlibmesa-glu-dev
xlibosmesa-dev
xlibs-dev
xtrans-dev  1.2.4-1
xviewg-dev
zlib1-dev
zlib1g-dev  1:1.2.3.3.dfsg-13ubuntu3

作業用のディレクトリの用意

今回は以下のように /home/jun/o3d で作業します。

cd
mkdir o3d
cd o3d

depot-toolsのインストール

最初に Subversionで Googleのビルドツール(depot-tools)を入手します。スクリプトなので特にコンパイルする必要はありません。

svn co https://src.chromium.org/svn/trunk/tools/depot_tools

depot_toolsでインストールされたファイルの一覧です。gclient と hammer を使います。

jun@ubuntu910-32:~/o3d$ ls depot_tools/
LICENSE                        drover              git-try
PRESUBMIT.py                   drover.bat          git_cl_hooks.py
README                         drover.py           hammer
README.gclient                 gcl                 hammer.bat
README.git-cl                  gcl.bat             presubmit_canned_checks.py
README.git-cl.codereview       gcl.py              presubmit_support.py
WATCHLISTS                     gclient             profile.xml
bootstrap                      gclient.bat         revert
chrome-update-create-task.bat  gclient.py          revert.bat
chrome-update.bat              gclient_scm.py      revert.py
chrome-update.py               gclient_utils.py    tests
cpplint.bat                    git-cl              trychange.py
cpplint.py                     git-cl-upload-hook  upload.py
create-chromium-git-src        git-gs              watchlists.py

コマンド検索パスの追加

depot_toolsの gclient と hammer を使うために検索パスに depot_tools のディレクトリを追加します。

export PATH=$PATH:/home/jun/o3d/depot_tools

o3dのソースの取得

depot_tools の gclient コマンドで o3d のソースを取得します。

gclient config https://src.chromium.org/svn/trunk/src/o3d
gclient.py sync

しばらく時間がかかりますが、ソースを取得したら /home/o3d/o3d/build に移動します。

cd o3d/build

ビルド

o3d のビルドはdepot_tools の hammer コマンドを以下のように使います。10分程度でビルドは終了します。

hammer -f o3d_main.scons

ソースの修正

以下の記述は11/17に修正されたため不要です。

2009/11/08時点のソースをLinuxでコンパイルすると、名前空間関連でコンパイルエラーが発生しました。以下に示すようにソースを変更(fopenやsetenvなどの関数にグローバル名前空間を指定し、対応するヘッダファイルをインクルード)する必要がありました。先頭の数字は行番号です。

~/o3d/o3d/import/cross/archive_processor.cc を以下のように修正します。

ヘッダファイルの追加

     32 #include <sys/stat.h>
     33 #include <stdio.h>
     34
     35 #include "import/cross/archive_processor.h"

グローバル名前空間を指定

     76   FILE *fp = ::fopen(filename, "rb");
     77   if (!fp) return FAILURE;  // can't open file!
     78   ::fread(p, sizeof(uint8), file_length, fp);
     79   ::fclose(fp);

~/o3d/o3d/plugin/linux/envvars.cc を以下のように修正します。

ヘッダファイルの追加


     32 #include <stdio.h>
     33 #include <string.h>

     34 #include <stdlib.h>
     35
     36 #include "plugin/linux/envvars.h"

グローバル名前空間を指定

     63         if (::setenv(buffer, value, 1) != 0) {
     64           LOG(ERROR) << "Couldn't add " << buffer << "=" << value
     65               << " to environment";
     66         } else {
     67           // Custom environment variables could be relevant for debugging
     68           // problem reports, so log this too.
     69           LOG(INFO) << "Defined " << buffer << "=" << value;
     70         }

~/o3d/o3d/import/cross/file_output_stream_processor.cc を以下のように修正します。

ヘッダファイルの追加

     34
     35 #include <stdio.h>
     36 #include "base/logging.h"

     37 #include "import/cross/file_output_stream_processor.h"

グローバル名前空間を指定

     45 StreamProcessor::Status FileOutputStreamProcessor::ProcessBytes(
     46     MemoryReadStream *stream,
     47     size_t bytes_to_process) {
     48   DCHECK(file_ != NULL);
     49   size_t num_written = ::fwrite(stream->GetDirectMemoryPointer(),
     50                               1,
     51                               bytes_to_process,
     52                               file_);
     53   return num_written == bytes_to_process ? IN_PROGRESS : FAILURE;
     54 }
     55
     56 void FileOutputStreamProcessor::Close(bool success) {
     57   ::fclose(file_);
     58   file_ = NULL;
     59 }

~/o3d/o3d/import/cross/collada_conditioner.cc を以下のように修正します。

括弧を追加する必要がありました。

    135     const PassDeclaration& pass = i->pass[0];
    136     if ((pass.vertex_shader_profile == "vs_2_0" &&

    137         pass.fragment_shader_profile == "ps_2_0") ||
    138         (pass.vertex_shader_profile == "arbvp1" &&
    139         pass.fragment_shader_profile == "arbfp1")) {
    140       return &pass;
    141     }

ビルドの結果

ビルドが終了すると /home/jun/o3d/sconsbuild/Debug に以下のようにファイルが格納されます。libnpo3dautoplugin.so が O3Dプラグインの本体、libCg.so と libCgGL.so がシェーダコンパイラになります。libnpo3dautoplugin.so は非常に大きいですが strip すると 9MB 程度になります。

jun@ubuntu910-32:~/o3d/sconsbuild/Debug$ ls -l
合計 160016
drwxr-xr-x  2 jun jun     4096 2009-11-08 14:43 archive_files
drwxr-xr-x  2 jun jun     4096 2009-11-08 14:43 bitmap_test
-rwxr-xr-x  1 jun jun  5392284 2009-11-08 14:13 cgc
drwxr-xr-x  2 jun jun     4096 2009-11-08 14:42 lib
-rw-r--r--  1 jun jun  7912580 2009-11-08 14:13 libCg.so
-rw-r--r--  1 jun jun   335124 2009-11-08 14:13 libCgGL.so
-rwxr-xr-x  1 jun jun 57653039 2009-11-08 14:34 libnpo3dautoplugin.so
-rw-r--r--  1 jun jun        0 2009-11-08 14:32 linker.lock
-rwxr-xr-x  1 jun jun 20998008 2009-11-08 14:32 mksnapshot
-rwxr-xr-x  1 jun jun 34387603 2009-11-08 14:42 o3dConverter
drwxr-xr-x 28 jun jun     4096 2009-11-08 14:42 obj
-rwxr-xr-x  1 jun jun  2575102 2009-11-08 14:15 perceptualdiff
drwxr-xr-x 13 jun jun     4096 2009-11-08 14:43 samples
drwxr-xr-x  3 jun jun     4096 2009-11-08 14:21 tests
-rwxr-xr-x  1 jun jun 34359967 2009-11-08 14:43 unit_tests
drwxr-xr-x  2 jun jun     4096 2009-11-08 14:42 unittest_data

libnpo3dautoplugin.so、libCg.so、libCgGL.so がダイナミックリンクしているライブラリを確認しておきます。

jun@ubuntu910-32:~/o3d/sconsbuild/Debug$ ldd libCg.so
   linux-gate.so.1 =>  (0xb77d6000)
   libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb6ef0000)
   /lib/ld-linux.so.2 (0xb77d7000)

jun@ubuntu910-32:~/o3d/sconsbuild/Debug$ ldd libCgGL.so
   linux-gate.so.1 =>  (0xb7753000)
   libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb75a9000)
   /lib/ld-linux.so.2 (0xb7754000)
   libCg.so => /usr/lib/libCg.so (0xb6e1a000)

jun@ubuntu910-32:~/o3d/sconsbuild/Debug$ ldd libnpo3dautoplugin.so

   linux-gate.so.1 =>  (0xb77ab000)
   libCg.so => /usr/lib/libCg.so (0xb673a000)
   libCgGL.so => /usr/lib/libCgGL.so (0xb66e7000)
   libGL.so.1 => /usr/lib/libGL.so.1 (0xb6655000)
   libGLEW.so.1.5 => /usr/lib/libGLEW.so.1.5 (0xb6612000)
   libX11.so.6 => /usr/lib/libX11.so.6 (0xb64e3000)
   librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb64da000)
   libgtk-x11-2.0.so.0 => /usr/lib/libgtk-x11-2.0.so.0 (0xb6119000)
   libgdk-x11-2.0.so.0 => /usr/lib/libgdk-x11-2.0.so.0 (0xb6084000)
   libatk-1.0.so.0 => /usr/lib/libatk-1.0.so.0 (0xb6066000)
   libpangoft2-1.0.so.0 => /usr/lib/libpangoft2-1.0.so.0 (0xb603d000)
   libgdk_pixbuf-2.0.so.0 => /usr/lib/libgdk_pixbuf-2.0.so.0 (0xb6023000)
   libpangocairo-1.0.so.0 => /usr/lib/libpangocairo-1.0.so.0 (0xb6016000)
   libgio-2.0.so.0 => /usr/lib/libgio-2.0.so.0 (0xb5f80000)
   libcairo.so.2 => /usr/lib/libcairo.so.2 (0xb5ef8000)
   libpango-1.0.so.0 => /usr/lib/libpango-1.0.so.0 (0xb5eb0000)
   libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0xb5e31000)
   libfontconfig.so.1 => /usr/lib/libfontconfig.so.1 (0xb5e04000)
   libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0xb5dc6000)
   libgmodule-2.0.so.0 => /usr/lib/libgmodule-2.0.so.0 (0xb5dc0000)
   libgthread-2.0.so.0 => /usr/lib/libgthread-2.0.so.0 (0xb5dba000)
   libglib-2.0.so.0 => /lib/libglib-2.0.so.0 (0xb5d04000)
   libnss3.so => /usr/lib/libnss3.so (0xb5bda000)
   libnssutil3.so => /usr/lib/libnssutil3.so (0xb5bc0000)
   libsmime3.so => /usr/lib/libsmime3.so (0xb5b97000)
   libssl3.so => /usr/lib/libssl3.so (0xb5b62000)
   libplds4.so => /usr/lib/libplds4.so (0xb5b5d000)
   libplc4.so => /usr/lib/libplc4.so (0xb5b57000)
   libnspr4.so => /usr/lib/libnspr4.so (0xb5b1c000)
   libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb5b03000)
   libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb5aff000)
   libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb5ad8000)
   libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb59e6000)
   libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb59c8000)
   libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb5884000)
   /lib/ld-linux.so.2 (0xb77ac000)
   libXext.so.6 => /usr/lib/libXext.so.6 (0xb5874000)
   libXmu.so.6 => /usr/lib/libXmu.so.6 (0xb585a000)
   libXi.so.6 => /usr/lib/libXi.so.6 (0xb584f000)
   libGLU.so.1 => /usr/lib/libGLU.so.1 (0xb57df000)
   libxcb.so.1 => /usr/lib/libxcb.so.1 (0xb57c1000)
   libXcomposite.so.1 => /usr/lib/libXcomposite.so.1 (0xb57bd000)
   libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0xb57b9000)
   libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0xb57b3000)
   libXrender.so.1 => /usr/lib/libXrender.so.1 (0xb57a9000)
   libXinerama.so.1 => /usr/lib/libXinerama.so.1 (0xb57a6000)
   libXrandr.so.2 => /usr/lib/libXrandr.so.2 (0xb579d000)
   libXcursor.so.1 => /usr/lib/libXcursor.so.1 (0xb5791000)
   libz.so.1 => /lib/libz.so.1 (0xb577b000)
   libpcre.so.3 => /lib/libpcre.so.3 (0xb574a000)
   libresolv.so.2 => /lib/tls/i686/cmov/libresolv.so.2 (0xb5736000)
   libselinux.so.1 => /lib/libselinux.so.1 (0xb571b000)
   libpixman-1.so.0 => /usr/lib/libpixman-1.so.0 (0xb56d3000)
   libdirectfb-1.2.so.0 => /usr/lib/libdirectfb-1.2.so.0 (0xb5659000)
   libfusion-1.2.so.0 => /usr/lib/libfusion-1.2.so.0 (0xb564f000)
   libdirect-1.2.so.0 => /usr/lib/libdirect-1.2.so.0 (0xb5637000)
   libpng12.so.0 => /usr/lib/libpng12.so.0 (0xb560f000)
   libxcb-render-util.so.0 => /usr/lib/libxcb-render-util.so.0 (0xb5609000)
   libxcb-render.so.0 => /usr/lib/libxcb-render.so.0 (0xb5600000)
   libexpat.so.1 => /lib/libexpat.so.1 (0xb55d9000)
   libXau.so.6 => /usr/lib/libXau.so.6 (0xb55d5000)
   libXt.so.6 => /usr/lib/libXt.so.6 (0xb5581000)
   libSM.so.6 => /usr/lib/libSM.so.6 (0xb5578000)
   libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0xb5573000)
   libICE.so.6 => /usr/lib/libICE.so.6 (0xb5558000)
   libuuid.so.1 => /lib/libuuid.so.1 (0xb5552000)

インストール

~/.mozilla/plugins/ に libnpo3dautoplugin.so をコピーします。~/.mozilla/ 以下に plugins ディレクトリが無い場合は作成してください。

cd ~/o3d/sconsbuild/Debug
mkdir ~/.mozilla/plugins
cp libnpo3dautoplugin.so ~/.mozilla/plugins/

私の場合は libCg.so と libCgGL.so を /usr/lib に直接コピーしました。

sudo cp libCg.so libCgGL.so /usr/lib
sudo ldconfig

実行

Firefox を起動して URLに「about:plugins」を入力して、O3Dが有効になっているか確認します。


plugins


あとは Google O3D のサンプルを試してみてください。

https://code.google.com/intl/ja/apis/o3d/docs/samplesdirectory.html

Linux版はこれを書いている時点(2009/11/08)では3D画面に重ねてテキストを表示する機能が実装されていません。