私はクロスプラットフォームレンダラーを作成しています。私はWindows、Linux、Android、iOS上で使用したいです。OpenGL ESのクロスプラットフォームレンダラー
絶対抽象を避けてOpenGL ES 2.0で直接書くのは良い考えだと思いますか?
私が知る限り、標準のOpenGLに対してPC上でコンパイルできるはずです。文脈とウィンドウシステムへの接続を処理するコードのわずかな変更だけです。
私はクロスプラットフォームレンダラーを作成しています。私はWindows、Linux、Android、iOS上で使用したいです。OpenGL ESのクロスプラットフォームレンダラー
絶対抽象を避けてOpenGL ES 2.0で直接書くのは良い考えだと思いますか?
私が知る限り、標準のOpenGLに対してPC上でコンパイルできるはずです。文脈とウィンドウシステムへの接続を処理するコードのわずかな変更だけです。
絶対抽象を避けてOpenGL ES 2.0で直接書くのは良い考えだと思いますか?
あなたの主な問題は、OpenGL 2.1と実際には同じではないES 2.0仕様の部分を扱うことです。
たとえば、デスクトップGLSL 1.20コンパイラを使用してES 2.0シェーダを移動することはできません。 ES 2.0では、精度の指定などを使用します。それらはGLSL 1.20の違法構成物です。
あなたはです。しかし、#define
ですが、これには少し手作業が必要です。シェーダソースファイルに#ifdef
を挿入する必要があります。これを少し簡単にするためにできるシェーダのコンパイルトリックがあります。
実際、GL ESは完全に異なる拡張機能セットを使用しているため(実際にはデスクトップGL拡張機能のミラーとサブセットがあります)、これを行うことができます。
すべてのGLSLシェーダ(デスクトップまたはES)には「プリアンブル」が必要です。シェーダ内の最初のコメントでないものは、#version
宣言である必要があります。幸運なことに、バージョンはデスクトップGL 2.1とGL ES 2.0の間で同じです:#version 1.20
。問題は次に来るものです:#extension
リスト(もしあれば)。これにより、シェーダが必要とする拡張が可能になります。
GL ESはデスクトップGLとは異なる拡張機能を使用するため、この拡張機能リストを変更する必要があります。そして、オッズは良いので、デスクトップGL 2.1拡張よりも多くのGLSL ES拡張が必要になるでしょう。これらのリストは1:1マッピングではなく完全に異なるリストになります。
私の提案は、GLSLシェーダに複数の文字列を与える機能を使用することです。つまり、実際のシェーダファイルには、にはプリアンブルがありません。それらはのみが実際の定義と機能を持っています。シェーダの本体。
GL ESで実行している場合、シェーダの先頭に貼り付けるグローバルプリアンブルがあります。デスクトップGLには、別のグローバルプリアンブルがあります。コードは次のようになります。
GLuint shader = glCreateShader(/*shader type*/);
const char *shaderList[2];
shaderList[0] = GetGlobalPreambleString(); //Gets preamble for the right platform
shaderList[1] = LoadShaderFile(); //Get the actual shader file
glShaderSource(shader, 2, shaderList, NULL);
プリアンブルはもを含むことができ、プラットフォーム固有の#define
。もちろん、ユーザー定義。そうすれば、異なるプラットフォーム用のコード#ifdef
をコードすることができます。
他にも2つの違いがあります。たとえば、有効なES 2.0テクスチャアップロード関数は、デスクトップGL 2.1ではが正常に動作しますが、必ずしも最適であるとは限りません。すべてのモバイルシステムのようにビッグエンディアンのマシンでうまくアップロードされるものは、リトルエンディアンのデスクトップマシンのドライバからいくらかの手間がかかります。したがって、GL ESとデスクトップGLで異なるピクセル転送パラメータを指定する方法が必要な場合があります。
また、ES 2.0とデスクトップGL 2.1には、さまざまな拡張機能があります。それらの多くが互いにミラーリングしようとしていますが(OES_framebuffer_objectはEXT_framebuffer_objectのサブセットです)、上記と同様の問題はありません。
あなたの網羅的な答えをありがとう。OpenGLレンダラの抽象化を作成する方が良いと思いますか?例えば、Texture2Dクラスで表されるテクスチャを持つことができます。このクラスには両方の仕様に共通のものが含まれますが、いくつかの実装は異なります。 – runnydead
@hubrobin:抽象である必要はありません。特定の場所にプラットフォーム固有のコードが必要です。 2.1の代わりにGL 3.3をターゲットにしている場合は、はるかに抽象化が必要になります。 –
私はPCでもっと多くの機能をサポートしたくありません。だから、あなたは基本的にそれが実行可能であると言っていますか? – runnydead
私の謙虚な経験では、このような要件のための最良のアプローチは、純粋なCフレーバーでエンジンを開発することです。追加のレイヤーはありません。
私はPATRIA 3Dエンジンの主な開発者です。このエンジンは、移植性の面で言及した基本的な原則に基づいており、基本的な標準ライブラリのツールを開発するだけで実現しました。
異なるプラットフォームでコードをコンパイルする作業は、ごくわずかです。
ソリューション全体を移植する実際の努力は、エンジンに組み込むコンポーネントによって計算できます。
標準C:例えば
エンジン3D
ゲームロジック
ゲームAI
物理
+
ウィンドウインタフェース(GLUT、EGLなど) - モバイルデバイスのためのデスクトップおよびEGL用GLUTかもしれないとにかく、プラットフォームに依存します。
ヒューマンインターフェイスは - 移植に依存して、Android用のJava、IOS、どんなバージョンのデスクトップ
サウンドマネージャのためのOCは - 移植
市場のサービスに依存して - 移植
このように、努力の95%をシームレスに再利用できます。
私たちはこのソリューションを当社のエンジンに採用しており、これまでのところ初期投資に値する価値があります。
あなたはKivyのことを聞いたことがありますか?これは、Linux、Windows、MacOSX、Android、IOSのオープンソースのクロスプラットフォームプログラミング言語で、OpenGL(http://kivy.org)ですべてのビューをレンダリングします。言語には独自のウィジェットツールキットも含まれています。私はちょうど解決策が既に存在し、おそらくまだそれを発見していない場合、ホイールを再発明したくない可能性があるので、私はそこに投げ捨てると思っていました。 – trusktr
AndroidまたはiOSをお使いの場合は、PlayストアまたはApp Storeで「Kivy」を検索して、その使用例を確認してください。 – trusktr