web-dev-qa-db-ja.com

OpenGL(およびOpenGL ES)を使用したSVGのレンダリング

現在、OpenGLとOpenGL ESを使用してSVGファイルからベクターグラフィックスをレンダリングする可能性を調査しています。 WindowsとAndroidをターゲットにするつもりです。私の理想的な解決策は、特定のSVGファイルから多角形の三角形分割を生成する最小限のCライブラリを持つことです。これにより、標準のOpenGLまたはOpenGL ES呼び出しが生成され、再描画時の最適化のためにディスプレイリストまたはvboが使用されます。表示リストを描画して、平行移動および回転後にベクトル画像を描画するだけで、これを他のOpenGL呼び出しと混在させることができます。

これまでのところ、最初にQTまたはCairoを使用することをお勧めします。 -これは、肥大化したライブラリなしで自分のOpenGLコンテキストを管理したいという理由で(私が達成しようとしているもののコンテキストで)オプションではありません。これはAndroidにも適していません。

2番目のオプションは、テクスチャにレンダリングするライブラリを使用することです。これは静的なベクターグラフィックスでは問題ないかもしれませんが、スケーリングや回転が頻繁に発生するゲームでは効率的または実行可能なオプションではありません。

第三に、OpenVGを使用する可能性があります。 OpenVG仕様のオープンソース実装(ShivaVGなど)がいくつかありますが、実行時に特定のSVGファイルから適切なOpenVG呼び出しを生成できるライブラリをまだ見つけていません。これを最適化する方法がわかりません。表示リストまたはvboを使用することもできます。

3つの方法すべてに制限があります。他のソリューションが存在しない場合、最も有望なオプションはOpenVG実装を使用することだと思います。だから私の質問は、私が望むことをするライブラリがありますか、私が望むものに近いですか?そうでない場合、そうでない理由がありますか?そして、代わりにこれを一からやり直そうとする方が良いでしょうか?

54
Matt Esch

から http://shivavg.svn.sourceforge.net/viewvc/shivavg/trunk/src/shPipeline.c?revision=14&view=markup

static void shDrawVertices(SHPath *p, GLenum mode)
{
int start = 0;
int size = 0;

/* We separate vertex arrays by contours to properly
handle the fill modes */
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(SHVertex), p->vertices.items);

while (start < p->vertices.size) {
size = p->vertices.items[start].flags;
glDrawArrays(mode, start, size);
start += size;
}

glDisableClientState(GL_VERTEX_ARRAY);
}

そのため、VBOを使用します。そのため、独自のSVGパーサーを作成するか、事前に作成したものを使用して、呼び出しをShivaVGに転送することをお勧めします。

ShivaVGはCにあり(Javaではなく)、openglコンテキストを作成するという問題がまだあります(コードを正しく読んだ場合、openglesではありません)。したがって、AndroidのNDKを使用してコンパイルした場合でも、コードを変更する必要があります(たとえば、周りにglVertex3fがいくつか見られますが、それほど必要ではないようです...もちろん、他のオプションは、CからJavaにコードを移植することです。想像できるほど苦痛ではないかもしれません。

幸運を !

3
Calvin1602

MonkVG OpenGL ESの上のAPI実装のようなOpenVGをチェックしてください。

また、OpenVG(MonkVG)チェックアウトの上でのSVGレンダリングの場合 MonkSVG

MonkVGは、iOS、OSX、およびAndroidプラットフォーム用に構築されています。

私は両方の図書館の著者であり、どんな質問にも喜んで答えます。

12
zerodog

私の答えは、一般にOpenGLでベクターグラフィックスを表示することです。なぜなら、この問題のすべてのソリューションは、特にSVGをかなり簡単にサポートできますが、アニメーションSVG(SMIL)をサポートするものはないからです。アニメーションについては何も言われていないので、質問は静的なSVGのみを暗示していると思います。

まず、OpenVGについては気にしません。MonkVGであっても、これはおそらく不完全ですが、おそらく最新の実装です。 OpenVG委員会は2011年に設立され、ほとんどの実装は放棄ソフトウェアまたはせいぜいレガシーソフトウェアです。

2011年以来、最新技術はMark Kilgardの赤ちゃん、NV_path_renderingであり、これは現在、既にベンダー(Nvidia)の拡張機能であり、既に推測している可能性がありますその名前。その上に多くの資料があります:

もちろん、SVGなどを読み込むことができます https://www.youtube.com/watch?v=bCrohG6PJQE 。また、パスのPostScript構文もサポートしています。次のデモで示すように、パスレンダリングを他のOpenGL(3D)のものと混在させることもできます。

NV_path_renderingは、GoogleのSkiaライブラリでバックグラウンドで使用可能になりました。 (Nvidiaは2013年後半と2014年にコードを提供しました。)cairo開発者の1人(Intelの従業員でもある)もそれを気に入っているようです http://lists.cairographics.org/archives/cairo/2013 -March/024134.html 、cairoがNV_path_renderingを使用するための具体的な努力を[まだ]知りませんが。

NV_path_renderingは固定パイプラインに若干の依存関係があるため、OpenGL ESで使用するのは少し面倒です。この問題は、上記の公式の拡張ドキュメントに記載されています。回避策については、たとえばSkia/Chromiumが行ったことを参照してください。 https://code.google.com/p/chromium/issues/detail?id=3443

ベンダーサポートやアカデミックグリッツがさらに少ない(またはまったくない)新興企業はNanoVGであり、現在開発および保守されています。 ( https://github.com/memononen/nanovg )OpenGLを介した2Dライブラリの数が徐々に増えてきたことを考えると、メジャーがサポートしていないものを使用して大きな賭けをしていることになります。ベンダー、私の謙虚な意見では。

12
Fizz

OpenGLまたはOpenGL ESでSVGまたはOpenVGをレンダリングすることは基本的に悪い考えであると言う必要があります。 OpenVGの実装がすべて非常に遅く、ほとんど放棄されている理由があります。 OpenGLで必要なパス(すべてのSVG/OpenVGレンダリングの基盤)を三角形リストにテッセレーションするプロセスは、基本的に時間がかかり、非効率的です。基本的に、3Dレンダリングパイプラインにソート/検索アルゴリズムを挿入する必要があり、パフォーマンスが低下します。また、SVGはパスジオメトリの複雑さを制限しないため、データセットのサイズが不明であるため、動的メモリ割り当てスキームが必要になるという問題もあります。本当に貧弱なデザイン。

SVGとOpenVGは、最新の3Dグラフィックスハードウェアエンジンが実際にどのように機能するかをほとんど理解していない開発者(三角形リスト)によって作成されました。これらはAdobe Flashのオープンな代替として作成されました。AdobeFlashには、予測不可能なパフォーマンスのために業界でFlashを非難した同じ欠陥アーキテクチャもあります。

私のアドバイスは、設計を再考し、OpenGL三角形リストを直接使用することです。より多くのコードを記述する必要があるかもしれませんが、アプリのパフォーマンスは約1000倍向上し、他の人よりも簡単にコードをデバッグできます。

7
ClayMontgomery

現在、OpenGLとOpenGL ESを使用して、SVGファイルからベクターグラフィックスをレンダリングする可能性を調査しています。 WindowsとAndroidをターゲットにするつもりです。私の理想的な解決策は、特定のSVGファイルから多角形の三角形分割を生成する最小限のCライブラリを持つことです。これにより、標準のOpenGLまたはOpenGL ES呼び出しが生成され、再描画時の最適化のためにディスプレイリストまたはvboが使用されます。表示リストを描画するだけで、平行移動および回転後にベクトル画像を描画し、これを他のOpenGL>呼び出しと混在させることができます。

SVGベクトルシェイプをOpenGL | ESにのみ変換する場合は、パーサーとロジックを自分で行うことをお勧めします。 SVGはペイントサーバー(グラデーション、パターンなど)、参照、フィルター、クリッピング、フォント処理、アニメーション、スクリプト、リンクなどのさまざまな機能を備えた巨大な仕様であることに注意してください。

Svgの完全なサポートが必要な場合は、 http://code.google.com/p/enesim にegueb(特にesvg)と呼ばれるライブラリがあり、enesim(ソフトウェアとopenglバックエンド)の図面。ほとんどの場合、シェーダーを使用し、すべてがテクスチャにレンダリングされます。ライブラリは非常に柔軟性があり、レンダリングされたシーンの変更、変換などの特定のニーズに適応できます。gl描画は常にテクスチャに行われます。

これまでのところ、最初にQTまたはCairoを使用することをお勧めします。 -これは、肥大化したライブラリなしで自分のOpenGLコンテキストを管理したいという理由で(私が達成しようとしているもののコンテキストで)オプションではありません。これはAndroidにも適していません。

2番目のオプションは、テクスチャにレンダリングするライブラリを使用することです。これは静的なベクターグラフィックスでは問題ないかもしれませんが、スケーリングや回転が頻繁に発生するゲームでは効率的または実行可能なオプションではありません。

Glバックエンドの特定のケースでは、enesimはGLX(または他のウィンドウ依存コンテキスト)を作成しないため、提供する必要があります。したがって、GL =呼び出し。

唯一の欠点は、glサポートまたは完全なSVG仕様サポートに関してライブラリがまだ完全ではないことですが、ニーズに応じて、良い選択肢のように思えます。

7
turran

AmanithVG を見ると、良いパス->三角形のパイプラインが実装されているようです。 iOS GL tigerの例を試しましたが、三角測量は実際のボトルネックではないようです。

1
mirknac