首页 [WindowsMobile]OpenGLES绘制3D图形

[WindowsMobile]OpenGLES绘制3D图形

举报
开通vip

[WindowsMobile]OpenGLES绘制3D图形[WindowsMobile]OpenGLES绘制3D图形 1. 簡介 想要在 Windows Mobile 畫3維圖形~就會想到 DirectX OpenGL~而想在 Windows Mobile 使用 OpenGL~則必須使用 OpenGL ES ( OpenGL for Embedded Systems )~OpenGL ES 為 OpenGL 三維圖形 API 的子集~主要針 手機、PDA 等嵌入式裝置所設計。而 OpenGL ES 可以算是 OpenGL 精簡版~捨去了 glBegin/glEnd~四...

[WindowsMobile]OpenGLES绘制3D图形
[WindowsMobile]OpenGLES绘制3D图形 1. 簡介 想要在 Windows Mobile 畫3維圖形~就會想到 DirectX OpenGL~而想在 Windows Mobile 使用 OpenGL~則必須使用 OpenGL ES ( OpenGL for Embedded Systems )~OpenGL ES 為 OpenGL 三維圖形 API 的子集~主要針 手機、PDA 等嵌入式裝置所設計。而 OpenGL ES 可以算是 OpenGL 精簡版~捨去了 glBegin/glEnd~四邊形;GL_QUADS,、多邊形;GL_POLYGONS,等複雜圖形繪製函式。 本文介紹如何使用.NET Compact Framework wrapper for OpenGL ES 函式庫~以 C# 撰寫程式~而程式功能一個旋轉的三角形~執行結果請參考為畫 以下影片。 2. OpenGL ES 2.1 初始化 EGL 要使用 OpenGL ES 於 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 單中~必須與要顯示的視做關聯~而這部是有標窗份 準~其標準 為EGL~初始化過程如下所示 接著介紹 EGL 標準會使用 EGL 函式與 流程 快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计 (1) 獲取 Display ( EGLDisplay ) Display 代表顯示器~在有些系統上可以有多個顯示器~也就會有多個 Display。獲得 Display 使用以下程式碼 1egl.GetDisplay(new EGLNativeDisplayType(this));(2) 初始化 EGL 使用以下程式碼進行初始化動作~回傳 並EGL 版本 ( major.minor )1egl.Initialize(myDisplay, out major, out minor);(3) 設定 EGLConfig ( EGLConfig ) 設定 EGLConfig 其實是指定 FrameBuffer 的參數~透過 egl.ChooseConfig(EGLDisplay myDisplay, const EGLint * attribList, 1EGLConfig * configs, EGLint config.Length, EGLint *numConfig) 其中 attribList 是以EGL_NONE 結束的參數群組~以 id, value 依次存放~ 對於個別標識性的屬性可以只有 id~沒有value~系統的總共的 Config 個數 儲存在 numConfig 中。Config 有多的屬性~這些屬性決定 眾FrameBuffer 的格式和能力~以下設定 為EGLConfig 的程式碼。 01EGLConfig[] configs = new EGLConfig[10]; int[] attribList 02= new int[] 03{ 04 egl.EGL_RED_SIZE, 5, 05 egl.EGL_GREEN_SIZE, 6, egl.EGL_BLU06E_SIZE, 5, egl.EGL_DEPTH_SIZE, 0716 , egl.EGL_SURFACE_TYPE, 08egl.EGL_WINDOW_BIT, 09 egl.EGL_STENCIL_SIZE, egl.EGL_DONT_CARE, egl.EGL_NONE, 10egl.EGL_NONE 11}; 12 13int numConfig; if (!egl.ChooseConfig(myDisplay, attribList, configs, 14configs.Length, out numConfig) || numConfig < 1)15 throw new InvalidOperationException("Unable to choose config."); 16 17EGLConfig config = configs[0]; (4) 構造 Surface ( EGLSurface ) Surface 是一個 FrameBuffer~透過 CreateWindowSurface 創建可實際顯示的 Surface 1egl.CreateWindowSurface(myDisplay, config, Handle, null); (5) 創建 Context ( EGLContext ) OpenGL 的 pipeline 從程式的角度看就是一個狀態機~有目前的色、紋理顏、變化矩陣等狀態~這些狀態作用於程式提交的頂點坐標等圖形元素~從而形成緩衝區內的像素。在 OpenGL 中~Context 就代表這個狀態機~程式的主要工作就是像 Context 提供圖型元素、設定狀態~偶爾從 Context 裡獲取一些訊息。使用 CreateContext 來創建一個 Context 1egl.CreateContext(myDisplay, config, EGLContext.None, null); (6) 設定繪製環境 Render Context 主要 上述設定之 EGL~透過 MakeCurrent 設定繪製環境~接著就可以透過 OpenGL API 進行繪製。 1egl.MakeCurrent(myDisplay, mySurface, mySurface, myContext); 2.2 進行繪製 (1) 初始化 OpenGL ES 開始繪製前~必須先做初始化~設定像背景~深度測試等參數 01void InitGL() 02{ gl.ShadeModel(gl.GL_SMOOTH); 03 // 設定陰影模式為平滑 04 // gl.ClearColor(1.0f, 1.0f, 1.0f, 0.5f); // 白色背景 05 gl.ClearColor(0.0f, 0.0f, 0.0f, 0.5f); // 黑色背景 gl.ClearDepthf(1.0f); // 設置06深度緩衝 gl.Enable(gl.GL_DEPTH_TEST); /07/ 使用深度測試 gl.BlendFunc(gl.GL_SRC_ALPHA, 08gl.GL_ONE_MINUS_SRC_ALPHA); // 設定混合函數~設定並為源因子 GL_SRC_ALPHA~目的因子為GL_ONE_MINUS_SRC_ALPHA09 gl.DepthFunc(gl.GL_LEQUAL); // 所做的深度測試為 GL_LEQUAL 深度小或相等的时候也渲染 10 gl.Hint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST); // 系統 測試進行修正 11} (2) OpenGL ES 繪圖部分的函式 以下程式碼 為OpenGL ES 繪圖部分的函式~並且在 OnPaint 重繪事件時調用此函式~假如 Color 部分的程式碼註解掉~則顯示之三角型為白色 float myRotation 01= 0; 02unsafe void DrawGLScene() 03{ gl.Viewport(ClientRectangle.Left, ClientRectangle.Top, 04ClientRectangle.Width, ClientRectangle.Height); // 設定圖形要顯示的區域05 gl.MatrixMode(gl.GL_PROJECTION); // 設定目前工作矩陣 為Projection 矩陣 06 gl.LoadIdentity(); // Projection 矩陣初始化 gluPerspective(45, (float)ClientSize.Width / (float)ClientSize.Height, .1f, 07100); // 設定圖形 gluPerspective 透視投影 08 float[] triangle = new float[] { 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, 09-1.0f, 0.0f }; float[] colors = new float[] { 1.0f, 0.0f, 0.0f, 9, 0.0f, 1.0f, 0.0f, 0, 100.0f, 0.0f, 1.0f, 0 }; 11 12 gl.Translatef(0.0f, 0.0f, -6.0f); // 平移函式~表示 x,y,z 偏移量 gl.Rotatef(myRotation, 0.0f, 1.0f, 0.0f); // 旋轉函式~參數x,y,z代表13一個向量~指旋轉所繞的軸~參數 myRotation 表示旋轉逆時針的角度14 15 fixed (float* trianglePointer = &triangle[0], colorPointer = &colors[0])16 { gl.EnableClientState(gl.GL_VERTEX_ARRAY); // 时動 Client 陣列17繪製模式 為GL_VERTEX_ARRAY gl.VertexPointer(3, gl.GL_FLOAT, 0, (IntPtr)trianglePointer); // 18設定指標陣列 trianglePointer 19 gl.EnableClientState(gl.GL_COLOR_ARRAY); // 时動 Client 陣列 繪製模式 為GL_COLOR_ARRAY gl.ColorPointer(4, gl.GL_FLOAT, 0, (IntPtr)colorPointer); // 設定20指標陣列 colorPointer 21 22 // gl.DrawArrays(gl.GL_TRIANGLES, 0, 3); // 繪製三角形 gl.DrawArrays(gl.GL_LINE_LOOP, 0, 3); // 繪製連續線段(封閉連23續線段) gl.DisableClientState(gl.GL_VERTEX_ARRAY); // 關閉 Client 陣24列繪製模式 GL_VERTEX_ARRAY 25 gl.DisableClientState(gl.GL_COLOR_ARRAY); // 關閉 Client 陣列繪製模式 GL_COLOR_ARRAY 26 gl.Flush(); // 立即 目前所有的繪圖指令輸出 27 } 28 29 myRotation += 2f; 30} 31 32// gluPerspective 透視投影 // fovy:可視角~範圍從0到33180度 34// aspect: 設定投影平面寬與高的比例 (double) w/h35// near: 投影近點~表示可視區域的最近距離 // far: 投影遠點~表示36可視區域的最遠距離 37void gluPerspective(float fovy, float aspect, float near, float far) 38{ 39 float xmin, xmax, ymin, ymax;40 41 ymax = near * (float)Math.Tan(fovy * 3.1415962f / 360.0);42 ymin = -ymax;43 xmin = ymin * aspect;44 xmax = ymax * aspect;45 46 gl.Frustumf(xmin, xmax, ymin, ymax, near, far); // 透視投影函式47} (3) 繪圖事件 以下程式碼為覆寫 OnPaint 事件~於並事件中進行圖形繪製 01// OnPaint 重繪事件 02protected override void OnPaint(PaintEventArgs e)03{ 04 base.OnPaint(e); 05 06 DrawGLScene(); // 繪圖 egl.SwapBuffers(myDisplay, 07mySurface); gl.Clear(gl.GL_COLOR_BUFFER_BIT | 08gl.GL_DEPTH_BUFFER_BIT); // 清顏除色緩衝區與深度緩衝區 09 Invalidate(); 10 int tickCount = Environment.TickCount; // 取得系統时動後經過的毫秒11數 12 int nextFrame = (myLastFrame + 1) % myFrameTracker.Length;13 // elapsed: 多久重繪 30 Frame14 float elapsed = (tickCount - myFrameTracker[nextFrame]) / 1000f;15 float timePerFrame = elapsed / 30; myFps = 1 / 16timePerFrame; myLastFrame = 17nextFrame; 18 myFrameTracker[nextFrame] = tickCount; 19} (4) 程式關閉時釋放資源 以下程式碼關為閉程式時~釋放 OpenGL ES 相關資源 01protected override void OnClosing(CancelEventArgs e) 02{ if (!egl.DestroySurface(myDisplay, 03mySurface)) 04 throw new Exception("Error while destroying surface."); if (!egl.DestroyContext(myDisplay, 05myContext)) 06 throw new Exception("Error while destroying context."); 07 if (!egl.Terminate(myDisplay))08 throw new Exception("Error while terminating display."); 09 base.OnClosing(e); 10} 3. 程式碼 以下為完整程式碼 001using System; 002using System.Collections.Generic;003using System.ComponentModel; 004using System.Data; 005using System.Drawing; using System.T006ext; using System.Windows.F007orms; 008using System.Runtime.InteropServices;009 010using OpenGLES; 011 012namespace TestOpenGLES 013{ 014 public partial class Form1 : Form 015 { 016 [DllImport("coredll")]017 extern static IntPtr GetDC(IntPtr hwnd); 018 019 EGLDisplay myDisplay; // 創建 EGLDisplay020 EGLSurface mySurface; // 創建 EGLSurface021 EGLContext myContext; // 創建 EGLContext022 023 public Form1() 024 { 025 InitializeComponent();026 // start ========== 027EGL 設定 ========== myDisplay = 028egl.GetDisplay(new EGLNativeDisplayType(this)); // 獲取 Display ( EGLDisplay ) 029 030 int major, minor;03 egl.Initialize(myDisplay, out major, out minor); // 初始化 1EGL 032 EGLConfig[] configs = new EGLConfig[10]; // 設定 033EGLConfig ( EGLConfig ) int[] attribList 034= new int[] 035 { 036 egl.EGL_RED_SIZE, 5,037 egl.EGL_GREEN_SIZE, 6, egl.EGL_BLUE038_SIZE, 5, egl.EGL_DEPTH_SIZ039E, 16 , 040 egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT, 041 egl.EGL_STENCIL_SIZE, egl.EGL_DONT_CARE, egl.EGL_NONE, 042egl.EGL_NONE 043 }; 044 045 int numConfig; if (!egl.ChooseConfig(myDisplay, attribList, configs, 046configs.Length, out numConfig) || numConfig < 1)04 throw new InvalidOperationException("Unable to choose 7config."); 048 EGLConfig config = 049configs[0]; mySurface = egl.CreateWindowSurface(myDisplay, config, 050Handle, null); // 構造 Surface ( EGLSurface ) myContext = egl.CreateContext(myDisplay, config, 051EGLContext.None, null); // 創建 Context ( EGLContext ) egl.MakeCurrent(myDisplay, mySurface, mySurface, 052myContext); // 設定繪製環境 Render Context 053 // end ========== EGL 初始化 ==========054 055 gl.ClearColor(0, 0, 0, 0); InitGL(); // 初始化 056OpenGL ES 057 } 058 059 int[] myFrameTracker = new int[30]; 060 int myLastFrame = 0; 061 float myFps = 0; 062 063 // 初始化 OpenGL ES void InitGL(064) 065 { 066 gl.ShadeModel(gl.GL_SMOOTH); // 設定陰影模式為平滑067 // gl.ClearColor(1.0f, 1.0f, 1.0f, 0.5f); // 白色背景068 gl.ClearColor(0.0f, 0.0f, 0.0f, 0.5f); // 黑色背景 gl.ClearDepthf(1.0f); // 069設置深度緩衝 070 gl.Enable(gl.GL_DEPTH_TEST); // 使用深度測試 gl.BlendFunc(gl.GL_SRC_ALPHA, 071gl.GL_ONE_MINUS_SRC_ALPHA); // 設定混合函數~設定並為源因子 GL_SRC_ALPHA~目的因子為GL_ONE_MINUS_SRC_ALPHA gl.DepthFunc(gl.GL_LEQUAL); // 所做的深度測試為 072GL_LEQUAL 深度小或相等的时候也渲染 073 gl.Hint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST); // 系統 測試進行修正 074 } 075 076 float myRotation = 0;077 unsafe void DrawGLScene()078 { gl.Viewport(ClientRectangle.Left, ClientRectangle.Top, 079ClientRectangle.Width, ClientRectangle.Height); // 設定圖形要顯示的區域 gl.MatrixMode(gl.GL_PROJECTION); // 設定目前工作矩陣080為 Projection 矩陣 081 gl.LoadIdentity(); // Projection 矩陣初始化 082 gluPerspective(45, (float)ClientSize.Width / (float)ClientSize.Height, .1f, 100); // 設定圖形 gluPerspective 透視投影083 float[] triangle = new float[] { 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0840.0f, 1.0f, -1.0f, 0.0f }; float[] colors = new float[] { 1.0f, 0.0f, 0.0f, 9, 0.0f, 1.0f, 0850.0f, 0, 0.0f, 0.0f, 1.0f, 0 };086 gl.Translatef(0.0f, 0.0f, -6.0f); // 平移函式~表示 x,y,z 偏087移量 gl.Rotatef(myRotation, 0.0f, 1.0f, 0.0f); // 旋轉函式~參數088x,y,z代表一個向量~指旋轉所繞的軸~參數 myRotation 表示旋轉逆時針的 角度 089 fixed (float* trianglePointer = &triangle[0], colorPointer = 090&colors[0]) 091 { 09 gl.EnableClientState(gl.GL_VERTEX_ARRAY); // 时動 2Client 陣列繪製模式 為GL_VERTEX_ARRAY gl.VertexPointer(3, gl.GL_FLOAT, 0, 093(IntPtr)trianglePointer); // 設定指標陣列 trianglePointer09 gl.EnableClientState(gl.GL_COLOR_ARRAY); // 时動 4Client 陣列繪製模式 為GL_COLOR_ARRAY gl.ColorPointer(4, gl.GL_FLOAT, 0, 095(IntPtr)colorPointer); // 設定指標陣列 colorPointer096 // gl.DrawArrays(gl.GL_TRIANGLES, 0, 3); // 繪製三097角形 gl.DrawArrays(gl.GL_LINE_LOOP, 0, 3); // 繪製連續線098段(封閉連續線段) 09 gl.DisableClientState(gl.GL_VERTEX_ARRAY); // 關閉 9Client 陣列繪製模式 GL_VERTEX_ARRAY 10 gl.DisableClientState(gl.GL_COLOR_ARRAY); // 關閉 0Client 陣列繪製模式 GL_COLOR_ARRAY 101 gl.Flush(); // 立即 目前所有的繪圖指令輸出 102 } 103 104 myRotation += 2f; 105 } 106 // gluPerspective 透107視投影 108 // fovy:可視角~範圍從0到180度 109 // aspect: 設定投影平面寬與高的比例 (double) w/h // near: 投影近點~表示可視110區域的最近距離 // far: 投影遠點~表示可視區111域的最遠距離 11 void gluPerspective(float fovy, float aspect, float near, float far)2 113 { 114 float xmin, xmax, ymin, ymax; 115 116 ymax = near * (float)Math.Tan(fovy * 3.1415962f / 360.0); ymin = 117-ymax; 118 xmin = ymin * aspect;119 xmax = ymax * aspect;120 gl.Frustumf(xmin, xmax, ymin, ymax, near, far); // 透視投121影函式 122 } 123 // OnPaintBackground 重繪背景事件~不可拿掉~拿掉後重繪時會124閃爍 12 protected override void OnPaintBackground(PaintEventArgs e)5 126 { 127 } 128 129 // OnPaint 重繪事件130 protected override void OnPaint(PaintEventArgs e) 131 { 132 base.OnPaint(e);133 134 DrawGLScene(); // 繪圖 egl.SwapBuffers(myDispla135y, mySurface); gl.Clear(gl.GL_COLOR_BUFFER_BIT | 136gl.GL_DEPTH_BUFFER_BIT); // 清顏除色緩衝區與深度緩衝區137 Invalidate();138 int tickCount = Environment.TickCount; // 取得系統时動後經139過的毫秒數 int nextFrame = (myLastFrame + 1) % 140myFrameTracker.Length; // elapsed: 多久重繪 30 141Frame float elapsed = (tickCount - myFrameTracker[nextFrame]) / 1421000f; 143 float timePerFrame = elapsed / 30;144 myFps = 1 / timePerFrame; myLastFrame = 145nextFrame; 146 myFrameTracker[nextFrame] = tickCount; 147 } 148 149 protected override void OnClosing(CancelEventArgs e)150 { 151 if (!egl.DestroySurface(myDisplay, mySurface))152 throw new Exception("Error while destroying surface.");153 if (!egl.DestroyContext(myDisplay, myContext))154 throw new Exception("Error while destroying context."); if (!155egl.Terminate(myDisplay)) 156 throw new Exception("Error while terminating display."); 157 base.OnClosing(e); 158 } 159 160 // 離開 161 private void myExitMenuItem_Click(object sender, EventArgs e) 162 { 163 Close(); 164 } 165 } 166} 4. 執行結果 (1) 使用 gl.DrawArrays(gl.GL_TRIANGLES, 0, 3); // 繪製三角形 (2) GL_VERTEX_ARRAY 部分註解 (3) 使用 gl.DrawArrays(gl.GL_LINE_LOOP, 0, 3); // 繪製連續線段(封閉連續線段) (4) GL_VERTEX_ARRAY 部分註解 (5) 背景設定為白色 gl.ClearColor(1.0f, 1.0f, 1.0f, 0.5f); // 白色背景 5. 參考 .NET Compact Framework wrapper for OpenGL ES OpenGL ES 系列之基本 -0: 了解 OpenGL ES 社區 OpenGL ES 系列之基本 -1: 初始化 EGL OpenGL 基礎圖形編程 - 總目錄
本文档为【[WindowsMobile]OpenGLES绘制3D图形】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_633808
暂无简介~
格式:doc
大小:97KB
软件:Word
页数:0
分类:生活休闲
上传时间:2017-10-06
浏览量:7