bada開發(fā):OpenGL ES 2.0程序 創(chuàng)建簡(jiǎn)單3D圖形
我們期待消費(fèi)者積極關(guān)注bada這個(gè)全新的移動(dòng)游戲平臺(tái),因?yàn)閺?qiáng)大的圖形API可以實(shí)現(xiàn)2D和3D圖形。從3D圖形API中獲益的程序包括游戲,地圖可視化,用戶界面,動(dòng)漫,屏保等。為了滿足廣大需求,bada API包括OpenGL® ES,用于高級(jí)嵌入式圖形,具有明確定義的OpenGL的subset profile的規(guī)格,支持高級(jí)和低級(jí)圖形功能。
如何使用bada基于OpenGL ES 2.0創(chuàng)建簡(jiǎn)單的3D圖形應(yīng)用程序
我們看看如何創(chuàng)建一個(gè)OpenGL ES 2.0應(yīng)用程序。為了介紹基于bada平臺(tái)開發(fā)OpenGL ES 2.0程序的基本概念,我們首先開始介紹一個(gè)簡(jiǎn)單的范例。我們要處理的一個(gè)程序就是基本的OpenGL ES 2.0程序,畫出簡(jiǎn)單的3D立方。這個(gè)范例說明許多重要的概念。
初始化
• 初始化,并且處理EGL和GL;
• 使用EGL,創(chuàng)建一個(gè)屏幕上的渲染面
• 創(chuàng)建安裝和上載遮影及程序
圖畫
• 設(shè)置viewport.
• 繪制簡(jiǎn)單的圖元
圖:bada 3D Graphics API
初始化
1. 初始化和處理EGL和GL
bada GlesCube樣例程序遵循的基本步驟使用特定的API以完成EGLand GL初始化(通過 GlesCube::InitEGL() 和 InitGL() 方法)。
1.1. 檢索缺省設(shè)備屏幕
__eglDisplay變量代表設(shè)備顯示。OpenGL ES配置被存儲(chǔ)在 __eglConfig里。
__eglContext 變量代表OpenGL ES context。***, __eglSurface 代表繪圖表面。
- __eglDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
EGL_DEFAULT_DISPLAY 常量指的是缺省設(shè)備屏幕(在大多數(shù)情況下,只有一個(gè))。如果操作失敗,函數(shù)會(huì)返回EGL_NO_DISPLAY.
1.2.初始化 OpenGL ES
函數(shù)中的***兩個(gè)參數(shù)與EGL執(zhí)行版對(duì)應(yīng)。如果不需要指定,則取值為零。
- if (EGL_FALSE == eglInitialize(__eglDisplay, null, null) || EGL_SUCCESS != eglGetError())
1.3. 選擇OpenGL ES配置
下一步,必須指定程序要求的最小配置。
- if (EGL_FALSE == eglChooseConfig(__eglDisplay, eglConfigList, &__eglConfig, 1, &numConfigs) ||
- EGL_SUCCESS != eglGetError())
- {
- AppLog("[GlesCube] eglChooseConfig() has been failed. [0x%x]\n",eglGetError())
- goto CATCH;
- }
eglConfigList參數(shù)代表程序要求的屬性列表。函數(shù)在__eglConfig參數(shù)中返回所有可得配置(符合eglConfigList參數(shù))列表。列表的大小受到第四個(gè)參數(shù)(在本例中,我們只要一個(gè)配置)限制。在函數(shù)返回之后,numConfigs參數(shù)告知相匹配參數(shù)的數(shù)量。eglConfigList定義了 [attribute, value] 對(duì)的次序(作為數(shù)列)。EGL規(guī)格定義了所有受支持的屬性的常量。列表***是EGL_NONE常量。
- EGLint eglConfigList[] = {
- EGL_RED_SIZE, 5,
- EGL_GREEN_SIZE, 6,
- EGL_BLUE_SIZE, 5,
- EGL_ALPHA_SIZE, 0,
- EGL_DEPTH_SIZE, 8,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_NONE
- };
1.4. 創(chuàng)建OpenGL ES context
- __eglContext = eglCreateContext(__eglDisplay, __eglConfig, EGL_NO_CONTEXT, eglContextList);
- if (EGL_NO_CONTEXT == __eglContext || EGL_SUCCESS != eglGetError())
- {
- AppLog("[GlesCube] eglCreateContext()has been failed.[0x%x]\n", eglGetError());
- goto CATCH;
- }
第三個(gè)參數(shù)顯示 context 要分享紋理對(duì)象。這里,EGL_NO_CONTEXT被用來說明沒有這樣的 context 。***一個(gè)參數(shù)代表要映射到下一個(gè)context的屬性列表。
1.5. 激活context
如果要OpenGL ES 指令產(chǎn)生效果,必須激活context, 讓它成為現(xiàn)在式。在OpenGL ES中,一次只有一個(gè)context可以成為現(xiàn)在式。
- if (EGL_FALSE == eglMakeCurrent(__eglDisplay, __eglSurface, __eglSurface, __eglContext) ||
- EGL_SUCCESS != eglGetError())
- {
- AppLog("[GlesCube] eglMakeCurrent() has been failed. [0x%x]\n", eglGetError());
- goto CATCH;
- }
1.6 關(guān)閉OpenGL ES: 在使用OpenGL ES,必須釋放所有資源
- void GlesCube::DestroyGL()
- {
- glDeleteProgram(__programObject);
- if (__eglDisplay)
- {
- eglMakeCurrent(__eglDisplay, null, null, null);
- if (__eglContext)
- {
- eglDestroyContext(__eglDisplay, __eglContext);
- __eglContext = EGL_NO_CONTEXT;
- }
- if (__eglSurface)
- {
- eglDestroySurface(__eglDisplay, __eglSurface);
- __eglSurface = EGL_NO_SURFACE;
- }
- eglTerminate(__eglDisplay);
- __eglDisplay = EGL_NO_DISPLAY;
- }
- return;
- }
2. 使用EGL,創(chuàng)建一個(gè)屏幕上的渲染面
- __eglSurface = eglCreateWindowSurface(__eglDisplay, __eglConfig,
- (EGLNativeWindowType)__pForm, null);
- if (EGL_NO_SURFACE == __eglSurface || EGL_SUCCESS != eglGetError())
- {
- AppLog("[GlesCube] eglCreateWindowSurface() has been failed. EGL_NO_SURFACE [0x%x]\n", eglGetError());
- goto CATCH;
- }
3. 創(chuàng)建,安裝和上載 遮影及程序
要求采取下面的步驟設(shè)置OpenGL環(huán)境,上載并且編輯遮影。
3.1. 創(chuàng)建片元(fragment)和vertex shaders,及程序目標(biāo)
- GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
- GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
- __programObject = glCreateProgram();
3.2. 將shader的對(duì)象依附在程序?qū)ο笊?/p>
程序?qū)ο筇峁┮粋€(gè)機(jī)制,可以確定需要連接起來的事物的列表。
將被連接在一起,放入程序?qū)ο笾械腟haders必須首先與該程序?qū)ο筮B接起來。在源代碼被上載到shader的對(duì)象之前或在shader的對(duì)象被編譯之前,你可以向程序?qū)ο笳迟N一個(gè)shader的對(duì)象。
- glAttachShader(__programObject, fragShader);
- glAttachShader(__programObject, vertShader);
3.3. 上載shader的二元
函數(shù)glShaderBinary上載預(yù)先編輯的shader的二元。***個(gè)參數(shù)指定fragShader中shader object handle的數(shù)量。fragShader包含一個(gè)shader object handle。每個(gè)handle指示一個(gè)獨(dú)特的遮影類型( vertex shader 或片元shader).。(GLenum)0指定shader的二元格式。fragmentFragment 或 vertexVertex 向客戶端內(nèi)存里的shader二元數(shù)據(jù)指定一個(gè)指針。***一個(gè)參數(shù)指定字節(jié)中shader二元數(shù)據(jù)的長(zhǎng)度。
- glShaderBinary(1, &fragShader, (GLenum)0, fragmentFragment, fragmentFragmentLength *
- sizeof(int));
- glShaderBinary(1, &vertShader, (GLenum)0, vertexVertex, vertexVertexLength * sizeof(int));
3.4. 為遮影對(duì)象提供源代碼
這個(gè)方法將遮影中的源代碼設(shè)定到字符串列(fragmentFragmentText 和vertexVertexText參數(shù))中的源代碼上。任何之前存儲(chǔ)在遮影對(duì)象中的源代碼被完全取代。
- glShaderSource(fragShader, 1, (const char**)&fragmentFragmentText, null);
- glShaderSource(vertShader, 1, (const char**)&vertexVertexText, null);
3.5. 編輯shaders
glCompileShader編輯存儲(chǔ)在fragShader 和vertShader參數(shù)指定的shader object中的源字符串。編輯狀態(tài)作為shader object狀態(tài)的一部分被儲(chǔ)存。
- glCompileShader(fragShader);
- glCompileShader(vertShader);
注意,glCompileShader僅在GL version 2.0 或更高版本中可獲得。
3.6. 鏈接程序?qū)ο?/p>
glLinkProgram鏈接程序指定的程序?qū)ο?。如果任何GL_VERTEX_SHADER 類型的shader object被粘貼到程序上,它們被用來創(chuàng)建一個(gè)可執(zhí)行文件,在可編程vertex處理器上運(yùn)行。如果任何GL_FRAGMENT_SHADER類型的shader object被粘貼到程序上,它們創(chuàng)建一個(gè)可執(zhí)行文件,在可編程片元處理器上運(yùn)行。
- glLinkProgram(__programObject);
3.7. 使用程序?qū)ο?,而不是固定的函?shù)OpenGL
這個(gè)方法安裝程序指定的程序?qū)ο螅鰹楝F(xiàn)在的渲染狀態(tài)。一個(gè)或多個(gè)可執(zhí)行文件在程序?qū)ο笾袆?chuàng)建,使用glAttachShader將shader object成功地粘貼到它上面,使用glAttachShader成功編譯shader object,并且使用glLinkProgram連接程序?qū)ο蟆?/p>
- glUseProgram(__programObject);
程序?qū)ο蟀\(yùn)行在vertex(片元)處理器上的可執(zhí)行文件,如果它們包含一個(gè)或多個(gè)被成功編譯和鏈接的GL_VERTEX_SHADER (typeGL_FRAGMENT_SHADER)類型的shader object。
3.8你可以使用:
- glDeleteShader(vertShader);
- glDeleteShader(fragShader);
刪除shader object.
在GlesCube::InitGL()方法里,所有的初始化步驟完成。如果所有的shaders被成功編譯,并且程序?qū)ο蟊怀晒︽溄?,glUseProgram之后使用shader完成所有的渲染?,F(xiàn)在,有個(gè)準(zhǔn)備好的GL表面進(jìn)行處理。
我們來看看包含了OpenGL繪圖函數(shù)的GlesCube::Draw()方法。
繪圖
4.設(shè)定viewport
glViewport 函數(shù)向窗口坐標(biāo)指定被常規(guī)化的設(shè)備坐標(biāo)的X和Y的仿射轉(zhuǎn)換。***批兩個(gè)參數(shù)在viewport 長(zhǎng)方形的左下角(以像素為單位)。缺省值為 (0,0).。當(dāng)OpenGL context 首先被附加窗口,寬度和高度被設(shè)定到窗口的尺度上。
- int x, y, width, height;
- GetAppFrame()->GetFrame()->GetBounds(x, y, width, height);
- glViewport(0, 0, width, height);
讓 (xnd , ynd ) 成為常規(guī)化設(shè)備坐標(biāo)。窗口坐標(biāo)(xw , yw)然后如下所示進(jìn)行計(jì)算:
xw = (xnd + 1) * (width / 2) + x; yw = (ynd + 1) * (height / 2) + y; |
Viewport寬度和高度被堆放,其范圍根據(jù)執(zhí)行情況確定。這個(gè)范圍通過使用argument GL_MAX_VIEWPORT_DIMS 調(diào)用glGet進(jìn)行查詢。
5. 繪制簡(jiǎn)單的圖元
OpenGL ES渲染所有的來自vertex數(shù)列的集合。不用調(diào)用GL函數(shù)以傳遞每個(gè)
vertex, 常規(guī)項(xiàng),紋理,坐標(biāo),邊標(biāo)志或顏色,你可以分開vertex, 常規(guī)項(xiàng),和其它參數(shù)的數(shù)列,使用它們構(gòu)建一個(gè)圖元的次序(單獨(dú)調(diào)用glDrawElements),并渲染來自數(shù)據(jù)列的圖元。
例如,這顯示了如何渲染OpenGL ES中的三角形。
- const GLfloat vertices[] = {
- -0.5f, -0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- ………………….
- 0.5f, 0.5f, -0.5f
- };
- glVertexAttribPointer(__idxPosition, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), vertices);
- glVertexAttribPointer(__idxColor, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GL_FLOAT), colors);
- glEnableVertexAttribArray(__idxPosition);
- glEnableVertexAttribArray(__idxColor);
- glUniformMatrix4fv(__idxMVP, 1, GL_FALSE, (GLfloat*) &__matMVP.m[0][0]);
- glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, indices);
glDrawElements使用較少的次常式調(diào)用,指定多個(gè)子程序圖元。
當(dāng)glDrawElements被調(diào)用,它使用被啟用的數(shù)列中次序元素,首先從標(biāo)記體開始,構(gòu)建一系列集合圖元。***個(gè)參數(shù)指定構(gòu)建何種圖元,并且如何構(gòu)建這些圖元。
GlesCube樣例程序位于\<BADA_SDK_HOME>\Samples\GlesCube\
要求的文件:SDK已經(jīng)有了所有要求的文件,以創(chuàng)建OpenGL ES程序。OpenGL ES的頁眉文件包括:
• FGraphicsOpegngl2.h
• FGraphicsEgl
• FGraphicsOpengl
【編輯推薦】
- 三星bada開發(fā)平臺(tái)概述
- 三星bada全新UI界面設(shè)計(jì)
- 初體驗(yàn)三星手機(jī)系統(tǒng)bada開發(fā)
- 三星策反Symbian開發(fā)者轉(zhuǎn)向bada
- 詳解Windows Phone XNA 4.0 3D游戲開發(fā)