CSharpGL(0)一個易學易用的C#版OpenGL
CSharpGL是我受到SharpGL的啟發,在整理了SharpGL,GLM,SharpFont等開源庫的基礎上,做的一個新的C#版OpenGL庫,希望它能做到易學易用,簡化OpenGL開發,減少低級錯誤,幫助初學者更快地由入門到精通。
CSharpGL全部源代碼、示例、文檔都可以在(https://github.com/bitzhuwei/CSharpGL)下載。
下面這段話引自(http://blog.sina.com.cn/s/blog_7cfb366d0101eglm.html)
學習OpenGL之所以痛苦,是因為首先只有兩本推薦的,一本紅寶書《OpenGL編程指南》;一本藍寶書《OpenGL超級寶典》,初學者看他的東西往往會不知所云。在學習初期,除了少的可憐的書之外,更缺乏調試器。本身物體在三維空間,輸錯一個正負號就有可能讓你找不到你的物體在哪里,沒有調試的話你甚至不知道中間過程的時候,物體到底是什么樣子。也就是說基本就是一抹黑,你可能既不知道你頂點坐標是否正確,也不知道某些個API是不是調用錯誤,抑或者是像深度緩沖沒開等等,只能靠運氣一般的去調去試。我就是這么可憐的度過了那段時間,現在想起來真心感嘆,沒人帶沒人教就是這么慘。
2016-08-13
由于CSharpGL一直在更新,現在這個教程已經不適用最新的代碼了。CSharpGL源碼中包含10多個獨立的Demo,更適合入門參考。
為了盡可能提升渲染效率,CSharpGL是面向Shader的,因此稍有難度。
CSharpGL有什么?
- matrix\vector\quaternion
- OpenGL API
- GLSL shader
- vertex buffer object\vertex array object\uniform buffer\texture buffer\pixel pack buffer\pixel unpack buffer
- framebuffer\render buffer
- perspective\orthogonal camera
- texture
- query object
- transform\scene
- text
- UI
- Winform Control(GLCanvas)
- teapot\cube\sphere\axis
- arcball\satellite
下面是目前CSharpGL的一部分示例。
繪制模型
你可以用legacy opengl(glVertex)或modern opengl(VBO+Shader)繪制模型。當然這是最基本的功能。CSharpGL提供一個GLCanvas控件供你進行繪制。
使用紋理(貼圖)
你可以用legacy opengl(glVertex)或modern opengl(VBO+Shader)為模型貼上貼圖。例如下面是用一個含有ASCII碼的貼圖貼在一個Quad上實現的。(此例還含有Blend相關的操作)
用Shader實現光照效果
CSharpGL集成了一些《OpenGL Programming Guide》的Demo。例如在GLSL中實現光照效果。
用Shader制作Fur效果
下圖所示的模型數據中只有藍色的人物,外層的白色毛毛是geometry shader根據模型頂點信息制作出來的。這也是從redbook轉換到C#的Demo之一。
Particle Simulator
ParticleSimulator用Compute Shader和glMapBufferRange實現了一個簡單的例子效果。這也是從redbook轉換到C#的Demo之一。
Instanced Rendering
這個Demo演示了用DrawArraysInstanced實現Instanced Rendering的方法。這也是從redbook轉換到C#的Demo之一。
立方體紋理CubeMap
這個從redbook中轉換來的CubeMap示例,展示了如何加載DDS文件并用作CubeMap。
繪制文字
CSharpGL提供一個PointSpriteStringElement類型實現繪制所有Unicode范圍內文字的功能。你可以加載任何TTF/TTC文件中的字形來繪制文字。如果加載的TTF文件含有中文字形,就可以用來顯示中文字符。如果含有任何其他語言文字的字形,都是可以顯示的。
CSharpGL提供一個副產品:TTF2Bmps,可以從TTF/TTC字體文件中提取所有的字形,保存為PNG圖片。這演示了CSharpGL內部是如何獲取字形貼圖的。
PointSprite示例
CSharpGL提供了多個使用PointSprite進行繪制的Demo。CSharpGL還提供了很多其他OpenGL功能的用法的示例代碼。你可以在CSharpGL.Winforms.Demo項目中找到所有的Demo。
對VBO內的圖元的拾取
CSharpGL提供IColorCodedPicking接口用以實現拾取功能。你可以在下面的Demo程序中了解如何使用IColorCodedPicking及其輔助類型。
繪制UI控件
在上面的示例中你看到有的窗口左下角有一個坐標系,這就是一種UI元素。下面是另一個UI元素(色標)。UI元素可以指定其大小、是否綁定到上下左右邊框等屬性。只需實現IUILayout接口即可自動實現UI布局。你可以從示例代碼中看到這一布局機制是如何實現的。這一布局機制對legacy OpenGL和modern OpenGL的效果相同。
渲染*.3ds文件
CSharpGL實現了3ds文件的解析器和加載器,可以解析并渲染3ds文件里的模型。例如下面這個盆景就是從(http://www.cgrealm.org/d/downpage.php?n=2&id=15764::1326768548)得到的一個3ds文件的渲染結果。
CSharpGL提供的3ds解析器已經能夠解析40多種類型的3ds塊,涵蓋了大多數常用功能,且易于擴展。
其它
CSharpGL還提供了很多其他的Demo,如對基礎類型UnmanagedArray的使用、Debugging的使用、MapBuffer、Feedback、Instanced Rendering、3D紋理等。我會繼續添加新的功能和Demo。你既可以通過CSharpGL來學習OpenGL,也可以用CSharpGL來編寫OpenGL程序。
CSharpGL為了降低出錯可能,為OpenGL各項功能提供了針對性的枚舉類型、重載方法和易于理解的對象。例如等BufferTarget、BufferUsage、GetTarget、PolygonMode、PrimitiveMode、ShadeModel等枚舉類型,Camera、ShaderProgram、SceneElementBase、RenderContext、Texture2D等通用的類型,IColorCodedPicking、IUILayout、IMVP、IRenderable等包含著各自的功能機制的接口。
CSharpGL將為每項功能、機制編寫文檔,講解其原理和實現,并提供Demo。為了讓我能在未來多少年后都能順利地重拾OpenGL,我一定會盡心地把文檔做好。
CSharpGL還拿來了GLM、SharpFont等開源項目,用于計算矩陣、獲取字形貼圖等操作。
CSharpGL與其他C#OpenGL類庫的對比
SharpGL
創建OpenGL Render Context的過程只支持Windows平臺。
提供OpenGLControl控件供執行OpenGL指令。
提供SceneControl和一系列接口,用于繪制一個樹狀組織的場景。但樹狀組織的場景是基于legacy OpenGL的棧結構(glPushMatrix()、glPopMatrix())設計的,對modern OpenGL并不恰當(但仍可用)。
提供了一些Studio之類的工具,但幾乎不能使用。
提供了VSIX插件,可一鍵創建SharpGL項目。這很適合初學者研究OpenGL入門。
提供數十個Demo項目,分別演示了OpenGL的某些功能(貼圖、拾取、光照……)的實現方法。
在渲染文字、拾取等高級內容方面沒有針對modern OpenGL的方案。
到今天(2015年8月30日)已有半年多不更新。針對modern OpenGL的內容比較少。
文檔基本上沒有,不過也不需要太多文檔,直接追蹤代碼就可以了解了。
OpenTK
跨平臺。為實現跨平臺,大量使用了設計模式,代碼復雜度飆升,不利于學習掌握。
針對OpenGL、OpenGL ES的各個版本分別編寫底層接口,代碼量飆升,不利于學習理解。
同時含有OpenCL、OpenAL,功能可謂豐富。
部分功能尚未實現,只列出了代碼框架。
由于代碼量超大,內存占用稍多,速度稍慢。(待驗證)
文檔還是有一些的。
Tao.Framework
幾年前Tao.Framework已被OpenTK取代,我就不再關注了。
CSharpGL
創建OpenGL Render Context的過程只支持Windows平臺。
提供GLCanvas控件供執行OpenGL指令。
面向modern OpenGL,兼顧legacy OpenGL,為場景元素提供最簡設計。并用接口及其輔助機制實現矩陣變換、拾取、UI布局等功能。
提供數十個Demo,分別演示了OpenGL的某些功能(Shader、貼圖、拾取、光照、文字、UI……)的實現方法。
將部分《OpenGL Programming Guide(8th Edition)》中的代碼轉換為C#版。
提供TTF2Bmps,可讀取TTF/TTC字體文件后輸出含有字形的PNG圖片及其位置信息(XML)。
CSharpGL剛剛問世,文檔將針對各個功能點逐步添加。
總評
在跨平臺方面,只有OpenTK能做到。跨平臺到底有多大的價值,我不敢妄言。但對于水平有限的本人來說,能夠簡化一切不必要的復雜性,把OpenGL本身學好是第一位的,所以在學習階段能否跨平臺并不重要。
在功能方面,OpenTK也是最豐富的,但學習起來比較費力。SharpGL學起來比較輕松,但其功能在支持modern OpenGL方面比較少。很多很實用的功能又沒有很好的實現,導致難以使用。
在性能方面,OpenTK與SharpGL調用底層的OpenGL函數的機制是相同的,所以兩者應該沒有大的區別。但OpenTK本身的代碼量很大,所以可能稍微慢一點點,不過在目前的硬件配置能夠承受的情況下,這都不成問題。(若要追求最高速度,直接用C/C++才行。用C#主要是為了提升開發和調試效率,少折騰)
在OpenGL接口方面,OpenTK也是很全面的,SharpGL對modern OpenGL的支持則很少。
CSharpGL的目標是易學易用。為此,CSharpGL除了調用OpenGL指令、執行矩陣變換、創建Render Context等最基礎的功能外,都做成了可選的Demo項目。一方面Demo代碼可用作學習參考,另一方面可以去掉Demo項目,只用最基礎的類庫進行開發。CSharpGL的Demo涵蓋了OpenGL的各項功能,并對繪制文字、UI、拾取等高級功能也設計了可復用的機制,且全部面向modern OpenGL。
總之,OpenTK是強大而稍復雜,SharpGL是簡約而稍老舊,CSharpGL則結合使用簡便、功能豐富兩方面,用“一個Demo演示一項功能”的方式學用OpenGL。
計劃
首先,我想把redbook里的例子都轉換為C#版放到CSharpGL里,作為demo演示OpenGL的各項功能是如何實現的。在這一過程中,必然會涉及補充一些文件格式解析器、枚舉類型、類似Texture2D的實用類型等。
然后,我希望把NEHE的例子都集成進來。NEHE是用legacy OpenGL寫的,我除了集成legacy OpenGL版外,還要用modernOpenGL寫一遍。
還有,我找到一個很好的網站(http://ogldev.atspace.co.uk/),有很多實用強大的例子,我打算把這里的例子也都轉換為C#版,放到CSharpGL里。
可以看到,我的計劃就是找很多很多的例子,轉換成C#版,安排到CSharpGL里,在這過程中豐富CSharpGL的類庫。這樣,既有大量的例子可以學習模仿,又有強大的可復用類庫,CSharpGL就能實現易學易用的目標了。
我計劃針對所有實現了的功能、機制逐個寫一篇隨筆。本篇算是開篇。
總結
學OpenGL有2年了,從NEHE到SharpGL,從《3D Math Primer for Graphics and Game Development》到《OpenGL Programming Guide》,算是對OpenGL有了初級的認識。最近我糾集整理了SharpGL,GLM,SharpFont等開源庫,想做一個更好用的純C#版OpenGL。歡迎對OpenGL有興趣的同學加入(https://github.com/bitzhuwei/CSharpGL)
文章列表