2012-01-19 161 views
6

我正在編寫跨平臺渲染器。我想在Windows,Linux,Android,iOS上使用它。OpenGL ES中的跨平臺渲染器

你認爲這是爲了避免絕對的抽象和OpenGL ES 2.0的直接寫一個好主意嗎?

據我所知,我應該可以在PC上對照標準OpenGL進行編譯,只需要處理上下文和連接到窗口系統的代碼的小小更改。

+0

你聽過基維嗎?它是一種針對Linux,Windows,MacOSX,Android和IOS的開源跨平臺編程語言,可在OpenGL中呈現所有視圖(http://kivy.org)。該語言還包括它自己的小部件工具箱。我只是認爲我會把它放在那裏,因爲如果一個解決方案已經存在並且你可能還沒有發現它,那麼你可能不想重新發明輪子。 – trusktr

+0

如果您有Android或iOS,請嘗試在Play Store或App Store中搜索「Kivy」以查看正在使用的示例。 – trusktr

回答

8

你認爲這是爲了避免絕對的抽象和OpenGL ES 2.0的直接寫一個好主意嗎?

你的原則困難在於處理ES 2.0規範中與OpenGL 2.1實際不相同的部分。

例如,您無法通過桌面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

這兩者之間還有其他區別。例如,雖然有效的ES 2.0紋理上傳函數調用在桌面GL 2.1中正常工作,但它們不一定是最佳的。在所有移動系統等大端機器上正常上傳的東西,需要在小端臺式機上驅動一下。因此您可能想要在GL ES和桌面GL上指定不同的像素傳輸參數。

另外,ES 2.0和桌面GL 2.1中還有不同的擴展集,您可以利用它們。雖然他們中的許多人試圖互相鏡像(OES_framebuffer_object是EXT_framebuffer_object的子集),但您可能會遇到類似上述那些「不太相似」的問題。

+0

感謝您的詳盡答案。所以你認爲創建某種OpenGL渲染器會更好?例如,我可以擁有由Texture2D類表示的紋理。這個類將包含兩個規範通用的東西,但是有些東西的實現會有所不同。 – runnydead

+0

@hubrobin:它不需要那麼抽象。你只需要在特定的地方使用一些特定於平臺的代碼。現在,如果您的目標是GL 3.3而不是2.1,那麼您將需要更多的抽象。 –

+0

我不想在PC上支持更多功能。所以你基本上是說,這是可行的? – runnydead

3

以我卑微的經驗,這種需求的最佳方法是開發純C風格的引擎,而不需要額外的圖層。

我PATRIA 3D引擎的主要開發者是基於你只是在便攜性方面所提及的基本原理和我們通過剛剛制定基本標準庫的工具來實現這一點。

然後在不同平臺上編譯代碼的努力是非常小的。

實際移植整個解決方案的努力可以根據要嵌入引擎的組件進行計算。

例如:


標準C:

引擎3D

遊戲邏輯

遊戲AI

物理系


+


窗口界面(GLUT,EGL等) - 取決於平臺上,反正可能是臺式機和EGL用於移動設備的過剩。

人機接口 - 依賴於移植,爪哇爲Android,OC的IOS,任何版本的桌面

聲音管理器 - 依賴於移植

市場服務 - 依賴於移植


通過這種方式,您可以無縫地重複使用95%的工作。

我們爲我們的發動機採用了這種解決方案,到目前爲止它確實值得投資。