6

クロスプラットフォームのレンダラーを書いています。Windows、Linux、Android、iOSで使いたいです。

絶対的な抽象化を避けて、OpenGL ES 2.0で直接書き込むのは良い考えだと思いますか?

私の知る限り、コンテキストとウィンドウシステムへの接続を処理するコードを少し変更するだけで、標準のOpenGLに対してPC上でコンパイルできるはずです。

4

2 に答える 2

9

絶対的な抽象化を避けて、OpenGL ES 2.0 で直接記述した方がよいと思いますか?

これに関する主な問題は、実際には OpenGL 2.1 と同じではない ES 2.0 仕様の部分を扱うことです。

たとえば、ES 2.0 シェーダーをデスクトップ GLSL 1.20 コンパイラーに押し込むことはできません。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、さまざまなプラットフォーム用にコーディングできます。

両者には他にも違いがあります。たとえば、有効な ES 2.0 テクスチャ アップロード関数呼び出しデスクトップ GL 2.1 で正常に動作しますが、必ずしも最適であるとは限りません。すべてのモバイル システムのように、ビッグ エンディアンのマシンで正常にアップロードされるものは、リトル エンディアンのデスクトップ マシンのドライバーから少しいじる必要があります。そのため、GL ES とデスクトップ GL で異なるピクセル転送パラメータを指定する方法が必要になる場合があります。

また、ES 2.0 とデスクトップ GL 2.1 には、利用したい拡張セットがいくつかあります。それらの多くは互いにミラーリングしようとしますが (OES_framebuffer_object は EXT_framebuffer_object のサブセットです)、上記のような「完全なサブセットではない」問題に遭遇する可能性があります。

于 2012-01-19T14:59:24.420 に答える
3

私の謙虚な経験では、この種の要件に対する最善のアプローチは、追加のレイヤーを使用せずに純粋な C フレーバーでエンジンを開発することです。

私はPATRIA 3Dエンジンの主な開発者であり、ポータビリティに関してあなたが今言及した基本原則に基づいており、基本的な標準ライブラリでツールを開発するだけでこれを達成しました。

さまざまなプラットフォームでコードをコンパイルする労力は非常に最小限です。

ソリューション全体を移植するための実際の労力は、エンジンに組み込みたいコンポーネントに応じて計算できます。

例えば:


標準 C:

エンジン 3D

ゲームロジック

ゲームAI

物理


+


ウィンドウ インターフェイス (GLUT、EGL など) - プラットフォームによって異なりますが、デスクトップ用の GLUT とモバイル デバイス用の EGL が考えられます。

ヒューマン インターフェイス - 移植、Android 用の Java、IOS 用の OC、デスクトップのバージョンに依存します。

サウンドマネージャー - 移植に依存

市場サービス - 移植に依存


このようにして、作業の 95% をシームレスに再利用できます。

このソリューションをエンジンに採用しましたが、これまでのところ、初期投資の価値があります。

于 2012-01-19T11:06:41.837 に答える