Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

iPhone実機とシミュレータのOpenGL ESを見比べる

タグ: iPhone OpenGL

そのむかし、出立てのiPhone SimulatorはOpenGL ESをサポートしていなかった。
そのためか、SDKが2.2.1になった今でも「iPhone実機ではできるがシミュレータではできない」ことが割とよくある。
目立つところではOES_matrix_palette拡張関数とOES_draw_texture拡張関数。
これらの関数はシミュレータでは完全にスルーされるため、実機でなければ挙動を確認することはできない。

逆に「シミュレータではできるが実機ではできない」ことも存在する。
例えば、新規プロジェクト「OpenGL ES Application」の

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glLineWidth(128);
glDrawArrays(GL_LINE_STRIP, 0, 4);

こう変えた場合、シミュレータでは以下のように描かれ、

GL_LINE_STRIP 幅64ピクセル シミュレータ

実機では以下のように描かれる。

GL_LINE_STRIP 幅64ピクセル 実機

この場合、両者に違いはない。
いや、まあ。
この画像だけ見ると、実機の方が崩れているように見えるが、これは「『幅』を作る軸をXとYのどちらにするかの切り替え角が実機とシミュレータで異なる」ためにこう見えているだけで、どちらもGL_ALIASED_LINE_WIDTH_RANGEが示す最大値64(指定値128は最大値を超えているので、最大値が適用される)で描けていることに変わりはない。
実際、少し回転させるとシミュレータも実機と同じように崩れてくる。

しかし、上記のコードを

glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glLineWidth(128);
glDrawArrays(GL_LINE_STRIP, 0, 4);

このように書き換えた場合、シミュレータではCore GraphicsでいうところのkCGLineCapButtでそれぞれの線分を描いたような形になるが、

GL_LINE_STRIP GL_LINE_SMOOTH 幅64ピクセル シミュレータ

実機では単に1本の線として描かれる。

GL_LINE_STRIP GL_LINE_SMOOTH 幅64ピクセル 実機

これは、実機のGL_SMOOTH_LINE_WIDTH_RANGEの最大値が1(シミュレータはGL_ALIASED_LINE_WIDTH_RANGEと同じ64)であるためで、それはすなわち実機ではGL_LINE_SMOOTHが意味を成さないことを示している。

これは結構痛い。
以前「星型にクリップした画像を貼り付ける」作業を行った時、あとでGL_LINE_SMOOTHで縁取ってアンチエイリアスを施そうと思っていたのだが、こんな状態なので諦めた。
今のiPhoneはFSAA/MSAAが効かないっぽいので、プリミティブ境界にアンチエイリアスを施すのは結構手間である。

ただ、GL_POINTSだけは、GL_SMOOTH_POINT_SIZE_RANGEが実機・シミュレータともに最大64であるため、アンチエイリアスを掛けられる。

glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPointSize(128);
glDrawArrays(GL_POINTS, 0, 4);
GL_POINTS 幅64ピクセル

そのため「直径64ピクセル以下の中抜きの円をアンチエリアス有りで描く」のは、「アンチエイリアスが施された線分を描く」より簡単だったりする。

glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
glPointSize(64);
glDrawArrays(GL_POINTS, 0, 4);
glBlendFunc(GL_ONE, GL_ONE);
glPointSize(60);
glDrawArrays(GL_POINTS, 0, 4);

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
glPointSize(64);
glDrawArrays(GL_POINTS, 0, 4);
直径62ピクセル・幅4ピクセルの円
スポンサーサイト

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://idlysphere.blog66.fc2.com/tb.php/174-639865c4
この記事にトラックバックする(FC2ブログユーザー)

Appendix

タグ

Blog内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。