2010/09/07
ZALMAN モニタでとりあえず 3D (立体視)レンダリング
立体視対応のモニタもかなり入手しやすくなりました。
ZALMAN の 3D モニタは偏光式で、チラツキもなくメガネも軽量で安価なのが特徴です。
その原理も非常にシンプルで、ラスタ単位に交互に右目と左目の映像を描画するだけで
立体現できます。
・ZALMAN ZM-M215W
推奨された使い方ではないと思いますが、RealD の映画館でもらえる円偏光式のメガネが
そのまま使えました。モニタについてくるメガネは幅が狭いのでこちらの方が快適です。
HDMI の 3D フォーマットの入力はできないので PS3 はつながりません。
でも原理が簡単なのでとりあえずプログラムで描画するだけなら簡単に対応できそうです。
眼鏡をつけると縦の解像度が半分になるものの、そのまま他の(非ZALMAN)モニタを
見ることが可能。
画面は暗くなるけど開発時の作業をしていても比較的負担が少ないと感じました。
●レンダリング
ラスタ単位に左右 2枚の絵を交互に合成します。

・バッファに左右分 2枚レンダリングしてからあとから合成
・Alpha Test や Stencil Test を使ってマスク
等の方法が考えられますが、とりあえずすぐに効果を確認したかったので効率は考えず
Pixel Shader (Fragment Shader) でラスタ分離してみました。
既存のシェーダーに追加したのは上の 5行だけです。
gl_FragCoord はフラグメントのスクリーン座標が入る予約 Uniform です。
この gl_FragCoord.y を見るだけで偶数ラインか奇数ラインかわかります。
LeftRight.x には左画面か右画面かに応じて 0 or 1 の値を入れておきます。
あとはカメラを変えて、同じフレームバッファに 2回同じ絵をレンダリングするだけです。
右目と左目が逆になる可能性があります。
ウィンドウの位置によって、描画を開始するラスタが変わるからです。
よってウィンドウのクライアント領域の座標を求めて、左右の切り替えに反映させる
必要があります。
ただの確認だけなら、手動で左右切り替えられるようにしておけば問題ないでしょう。
裸眼立体視の交差法モードとして使えるので左右切り替えは何かと役に立ちます。
即席の Zalman モニタ対応でした。
関連エントリ
・Vuzix Wrap 310
・3D開発環境(立体視)まとめ
ZALMAN の 3D モニタは偏光式で、チラツキもなくメガネも軽量で安価なのが特徴です。
その原理も非常にシンプルで、ラスタ単位に交互に右目と左目の映像を描画するだけで
立体現できます。
・ZALMAN ZM-M215W
推奨された使い方ではないと思いますが、RealD の映画館でもらえる円偏光式のメガネが
そのまま使えました。モニタについてくるメガネは幅が狭いのでこちらの方が快適です。
HDMI の 3D フォーマットの入力はできないので PS3 はつながりません。
でも原理が簡単なのでとりあえずプログラムで描画するだけなら簡単に対応できそうです。
眼鏡をつけると縦の解像度が半分になるものの、そのまま他の(非ZALMAN)モニタを
見ることが可能。
画面は暗くなるけど開発時の作業をしていても比較的負担が少ないと感じました。
●レンダリング
ラスタ単位に左右 2枚の絵を交互に合成します。

・バッファに左右分 2枚レンダリングしてからあとから合成
・Alpha Test や Stencil Test を使ってマスク
等の方法が考えられますが、とりあえずすぐに効果を確認したかったので効率は考えず
Pixel Shader (Fragment Shader) でラスタ分離してみました。
// OpenGL GLSL 4.0 fragment shader in vec4 gl_FragCoord; uniform vec4 LeftRight; void main() { if( (int(gl_FragCoord.y + LeftRight.x) & 1) == 0 ){ discard; } ~ }
既存のシェーダーに追加したのは上の 5行だけです。
gl_FragCoord はフラグメントのスクリーン座標が入る予約 Uniform です。
この gl_FragCoord.y を見るだけで偶数ラインか奇数ラインかわかります。
LeftRight.x には左画面か右画面かに応じて 0 or 1 の値を入れておきます。
あとはカメラを変えて、同じフレームバッファに 2回同じ絵をレンダリングするだけです。
1. 左目用カメラを設定 2. LeftRight.x = 0 3. レンダリング 4. 右目用カメラを設定 5. LeftRight.x = 1 6. レンダリング
右目と左目が逆になる可能性があります。
ウィンドウの位置によって、描画を開始するラスタが変わるからです。
よってウィンドウのクライアント領域の座標を求めて、左右の切り替えに反映させる
必要があります。
ただの確認だけなら、手動で左右切り替えられるようにしておけば問題ないでしょう。
裸眼立体視の交差法モードとして使えるので左右切り替えは何かと役に立ちます。
即席の Zalman モニタ対応でした。
関連エントリ
・Vuzix Wrap 310
・3D開発環境(立体視)まとめ
2010/09/06
GeForce/RADEON で OpenGL ES 2.0 を動かす
OpenGL ES 2.0 を使う機会が増えています。
iOS や Android 等のモバイル機器をはじめ、デスクトップ環境でもサポートが始まりました。
これまでモバイル向けに書いたコードを PC 上で走らせる場合 2つの選択肢がありました。
(1) GPU / OS が提供する OpenGL ES 2.0 エミュレータ
(2) 自分で OpenGL との相互変換を行う
ここに新たに 3番目
(3) デスクトップ GPU の OpenGL ES 2.0 プロファイル
が加わります。
● (1) GPU / OS の OpenGL ES 2.0 エミュレータ
多くの場合 OS や GPU 毎にツールとして EGL/GLES2.0 エミュレーション用の
互換ライブラリが提供されています。
・OpenGL ES 2.0 Emulator
テクスチャフォーマットなど特殊な機能にも対応しており、ターゲットが一致して
いれば高い互換性が保てます。
あくまでエミュレーション用なのでそれ以上の用途には向きません。
開発ツールで利用していてもパフォーマンス不足を感じたり、プラグインから
呼び出す場合 64bit 非対応が問題になったりします。
デスクトップ GPU のドライバとの相性もあります。
● (2) 自分で OpenGL との変換を行う
OpenGL 自体もともと互換性が高いので、OpenGL と OpenGL ES の違いはそれほど
大きくありません。
うまくライブラリを作れば、比較的薄いレイヤーで両者の違いを吸収することができます。
完全に同じ API ではないので保守性は落ちます。
例えばシェーダーも GL 用と GLES 用 2セット管理することになります。
● (3) デスクトップ GPU の OpenGL ES 2.0 プロファイル
OpenGL 4.1 では公式に OpenGL ES 2.0 プロファイルに対応しました。
ドライバが対応していればそのまま OpenGL ES 2.0 API を用いることが可能です。
NVIDIA GeForce GTX 400 シリーズは 4.1 対応ドライバを公開しており
「GL_ARB_ES2_compatibility」が含まれています。
・OpenGL 4.1 Driver
GeForce GTX460 に対応ドライバを入れて GLES/gl2.h ヘッダのみで描画できることを
一応確認しました。
・EGL は無いので WGL をそのまま使う
・拡張 API 同様に必要な API の関数アドレスを自分で取り出す
GLES 2.0 のヘッダ gl2.h はそのままプロトタイプ宣言が記述されていて、
関数ポインタ型の定義が無い点は注意が必要です。
この辺の関数宣言ヘッダを自分で用意する必要があります。
GL1.1 gl/gl.h はそのまま使えるため、存在しない API のみ取り出すことになります。
シェーダー周りなどはまだ詳しく調べていません。
同じように AMD/ATI RADEON も Catalyst 10.8 より OpenGL ES 2.0 に対応しています。
OpenGL 4.1 プロファイルではなく独自に API エントリを求める仕様となっているようです。
・OpenGL ES 2.0 Coming to a Desktop Near You
上のサンプルを見ると、最初に dll から EGL を取り出し、さらに eglGetProcAddress()
を使って OpenGL ES 2.0 API アドレスを読みだしています。
・EGL が用意されており、専用の EGL API を用いる
・使用する API の関数ポインタをすべて取得する
こちらも関数のヘッダ定義を自分で用意する必要があります。
gl2.h のプロトタイプ宣言と衝突する可能性があります。
今まで各種 GPU の GL ES2.0 Emulator や NetWalker 等で共通に走らせていた
EGL + GLES2.0 のコードがそのまま走りました。使用したのは RADEON HD 5850
気がついたことなど
・eglGetDisplay() は EGL_DEFAULT_DISPLAY を渡す
・eglCreateWindowSurface() を複数作れないなど EGL の実装の制限がある
eglGetDisplay() は実装により HDC を用いるものと EGL_DEFAULT_DISPLAY (NULL)
が必要なものと二通りあります。今回は後者で、これらの動きは以前公開されていた
ATI 版の OpenGL ES 2.0 Emulator によく似ています。
参考にしたサンプルでは "atioglxx.dll" をロードしていますが、そのままでは
x64 で動作しません。64bit の場合 "atio6axx.dll" にします。
それぞれ GL ES 2.0 が走りました。
ドライバが標準対応することで扱いは容易になるはずですが使い方がばらばらです。
最終的には 4.1 での統一が望まれます。
関連エントリ
・OpenGL 4.1 GeForce GTX 460
・NetWalker PC-Z1 のその後と OpenGL ES 2.0 Emulator
・OpenGL ES 2.0 Emulator
・OpenGL ES 2.0 まとめ
iOS や Android 等のモバイル機器をはじめ、デスクトップ環境でもサポートが始まりました。
これまでモバイル向けに書いたコードを PC 上で走らせる場合 2つの選択肢がありました。
(1) GPU / OS が提供する OpenGL ES 2.0 エミュレータ
(2) 自分で OpenGL との相互変換を行う
ここに新たに 3番目
(3) デスクトップ GPU の OpenGL ES 2.0 プロファイル
が加わります。
● (1) GPU / OS の OpenGL ES 2.0 エミュレータ
多くの場合 OS や GPU 毎にツールとして EGL/GLES2.0 エミュレーション用の
互換ライブラリが提供されています。
・OpenGL ES 2.0 Emulator
テクスチャフォーマットなど特殊な機能にも対応しており、ターゲットが一致して
いれば高い互換性が保てます。
あくまでエミュレーション用なのでそれ以上の用途には向きません。
開発ツールで利用していてもパフォーマンス不足を感じたり、プラグインから
呼び出す場合 64bit 非対応が問題になったりします。
デスクトップ GPU のドライバとの相性もあります。
● (2) 自分で OpenGL との変換を行う
OpenGL 自体もともと互換性が高いので、OpenGL と OpenGL ES の違いはそれほど
大きくありません。
うまくライブラリを作れば、比較的薄いレイヤーで両者の違いを吸収することができます。
完全に同じ API ではないので保守性は落ちます。
例えばシェーダーも GL 用と GLES 用 2セット管理することになります。
● (3) デスクトップ GPU の OpenGL ES 2.0 プロファイル
OpenGL 4.1 では公式に OpenGL ES 2.0 プロファイルに対応しました。
ドライバが対応していればそのまま OpenGL ES 2.0 API を用いることが可能です。
NVIDIA GeForce GTX 400 シリーズは 4.1 対応ドライバを公開しており
「GL_ARB_ES2_compatibility」が含まれています。
・OpenGL 4.1 Driver
GeForce GTX460 に対応ドライバを入れて GLES/gl2.h ヘッダのみで描画できることを
一応確認しました。
・EGL は無いので WGL をそのまま使う
・拡張 API 同様に必要な API の関数アドレスを自分で取り出す
GLES 2.0 のヘッダ gl2.h はそのままプロトタイプ宣言が記述されていて、
関数ポインタ型の定義が無い点は注意が必要です。
この辺の関数宣言ヘッダを自分で用意する必要があります。
GL1.1 gl/gl.h はそのまま使えるため、存在しない API のみ取り出すことになります。
シェーダー周りなどはまだ詳しく調べていません。
同じように AMD/ATI RADEON も Catalyst 10.8 より OpenGL ES 2.0 に対応しています。
OpenGL 4.1 プロファイルではなく独自に API エントリを求める仕様となっているようです。
・OpenGL ES 2.0 Coming to a Desktop Near You
上のサンプルを見ると、最初に dll から EGL を取り出し、さらに eglGetProcAddress()
を使って OpenGL ES 2.0 API アドレスを読みだしています。
・EGL が用意されており、専用の EGL API を用いる
・使用する API の関数ポインタをすべて取得する
こちらも関数のヘッダ定義を自分で用意する必要があります。
gl2.h のプロトタイプ宣言と衝突する可能性があります。
今まで各種 GPU の GL ES2.0 Emulator や NetWalker 等で共通に走らせていた
EGL + GLES2.0 のコードがそのまま走りました。使用したのは RADEON HD 5850
GL_VERSION: OpenGL ES 2.0 10151 Release GL_RENDERER: ATI Radeon HD 5800 Series GL_VENDOR: Advanced Micro Devices, Inc. GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.0.17
気がついたことなど
・eglGetDisplay() は EGL_DEFAULT_DISPLAY を渡す
・eglCreateWindowSurface() を複数作れないなど EGL の実装の制限がある
eglGetDisplay() は実装により HDC を用いるものと EGL_DEFAULT_DISPLAY (NULL)
が必要なものと二通りあります。今回は後者で、これらの動きは以前公開されていた
ATI 版の OpenGL ES 2.0 Emulator によく似ています。
参考にしたサンプルでは "atioglxx.dll" をロードしていますが、そのままでは
x64 で動作しません。64bit の場合 "atio6axx.dll" にします。
それぞれ GL ES 2.0 が走りました。
ドライバが標準対応することで扱いは容易になるはずですが使い方がばらばらです。
最終的には 4.1 での統一が望まれます。
関連エントリ
・OpenGL 4.1 GeForce GTX 460
・NetWalker PC-Z1 のその後と OpenGL ES 2.0 Emulator
・OpenGL ES 2.0 Emulator
・OpenGL ES 2.0 まとめ