STEM 隨筆︰古典力學︰模擬術【小工具】九《WebGL》

實現一個長青之程式庫非常不容易︰

OpenGL

OpenGL英語:Open Graphics Library,譯名:開放圖形庫或者「開放式圖形庫」)是用於彩現2D3D向量圖形的跨語言跨平台應用程式編程介面(API)。這個介面由近350個不同的函式呼叫組成,用來從簡單的圖形位元繪製複雜的三維景象。而另一種程式介面系統是僅用於Microsoft Windows上的Direct3D。OpenGL常用於CAD虛擬實境、科學視覺化程式和電子遊戲開發

OpenGL的高效實現(利用了圖形加速硬體)存在於Windows,部分UNIX平台和Mac OS。這些實現一般由顯示裝置廠商提供,而且非常依賴於該廠商提供的硬體。開放原始碼函式庫Mesa是一個純基於軟體的圖形API,它的代碼相容於OpenGL。但是,由於許可證的原因,它只聲稱是一個「非常相似」的API。

OpenGL規範由1992年成立的OpenGL架構評審委員會(ARB)維護。ARB由一些對建立一個統一的、普遍可用的API特別感興趣的公司組成。根據OpenGL官方網站,2002年6月的ARB投票成員包括3DlabsApple ComputerATI TechnologiesDell ComputerEvans & SutherlandHewlett-PackardIBMIntelMatroxNVIDIASGISun MicrosystemsMicrosoft曾是創立成員之一,但已於2003年3月退出。

設計

 圖形管線

OpenGL規範描述了繪製2D和3D圖形的抽象API。儘管這些API可以完全通過軟體實現,但它是為大部分或者全部使用硬體加速而設計的。

OpenGL的API定義了若干可被客戶端程式調用的函式,以及一些具名整型常數(例如,常數GL_TEXTURE_2D對應的十進制整數為3553)。雖然這些函式的定義表面上類似於C編程語言,但它們是語言獨立的。因此,OpenGL有許多語言綁定,值得一提的包括 :JavaScript綁定的WebGL(基於OpenGL ES 2.0在Web瀏覽器中的進行3D彩現的API);C綁定的WGL、GLX和CGL;iOS提供的C綁定;Android提供的Java和C綁定。

OpenGL不僅語言無關,而且平台無關。規範隻字未提獲得和管理OpenGL上下文相關的內容,而是將這些作為細節交給底層的窗口系統。出於同樣的原因,OpenGL純粹專注於彩現,而不提供輸入 、音訊以及窗口相關的API。

OpenGL是一個不斷進化的API。新版OpenGL規範會定期由Khronos Group發布,新版本通過擴展API來支援各種新功能。每個版本的細節由Khronos Group的成員一致決定,包括顯卡廠商、作業系統設計人員以及類似MozillaGoogle的一般性技術公司

除了核心API要求的功能之外,GPU供應商可以通過擴展的形式提供額外功能。擴展可能會引入新功能和新常數,並且可能放鬆或取消現有的OpenGL函式的限制。然後一個擴充功能就分成兩部分發布:包含擴充功能函式原型的表頭檔和作為廠商的裝置驅動。供應商使用擴展公開自定義的API而無需獲得其他供應商或Khronos Group的支援,這大大增加了OpenGL的靈活性。OpenGL Registry負責所有擴展的收集和定義。

每個擴展都與一個簡短的標識符關聯,該標識符基於開發公司的名稱。例如,英偉達(nVidia)的標識符是NV。如果多個供應商同意使用相同的API來實現相同的功能,那麼就用EXT標誌符。這種情況更進一步,Khronos Group的架構評審委員(Architecture Review Board,ARB)正式批准該擴展,那麼這就被稱為一個「標準擴展」,標識符使用ARB。第一個ARB擴展是GL_ARB_multitexture。

OpenGL每個新版本中引入的功能,特別是ARB和EXT類型的擴展,通常由數個被廣泛實現的擴展功能組合而成。

 

推廣一種共通的標準又談何簡單︰

WebGL

WebGL是一種JavaScript API,用於在不使用外掛程式的情況下在任何相容的網頁瀏覽器中呈現互動式2D和3D圖形[2]。WebGL完全整合到瀏覽器的所有網頁標準中,可將影像處理和效果的GPU加速使用方式當做網頁Canvas的一部分。WebGL元素可以加入其他HTML元素之中並與網頁或網頁背景的其他部分混合[3]。WebGL程式由JavaScript編寫的控制代碼和OpenGL Shading Language(GLSL)編寫的著色器代碼組成,該語言類似於CC++,並在電腦的圖形處理器(GPU)上執行。WebGL由非營利Khronos Group設計和維護[4]

設計

WebGL 1.0基於OpenGL ES 2.0,並提供了3D圖形的API[5]。它使用HTML5 Canvas並允許利用文件物件模型介面。WebGL 2.0基於OpenGL ES 3.0,確保了提供許多選擇性的WebGL 1.0擴充功能,並引入新的API[6]。可利用部分Javascript實現自動記憶體管理[4]

歷史

WebGL起源於Mozilla員工弗拉基米爾·弗基西維奇的一項稱為Canvas 3D實驗計畫。2006年,弗基西維奇首次展示了Canvas 3D的原型。2007年底在Firefox[7]和Opera[8]被實作。

在2009年初,非營利技術聯盟Khronos Group啟動了WebGL的工作組,最初的工作成員包括AppleGoogleMozillaOpera[4][9]。2011年3月發布WebGL 1.0規範[1]。截至2012年3月,工作組的主席由肯·羅素(Ken Russell,全名「Kenneth Bradley Russell」)擔任。

WebGL的早期應用包括Zygote Body[10][11]

WebGL 2規範的發展始於2013年,並於2017年1月完成[12]。該規範基於OpenGL ES 3.0[13]。首度實作在Firefox 51、Chrome 56和Opera 43中[14]

 

因著原本打算介紹

pythreejs

Version: 1.1.0

pythreejs is a Jupyter widgets based notebook extension that allows Jupyter to leverage the WebGL capabilities of modern browsers by creating bindings to the javascript library three.js.

By being based on top of the jupyter-widgets infrastructure, it allows for eased integration with other interactive tools for notebooks.

 

。此處先提 three.js ,不過權充啟始引言耳。

three.jsr93

 

【範例】

Creating a scene

The goal of this section is to give a brief introduction to three.js. We will start by setting up a scene, with a spinning cube. A working example is provided at the bottom of the page in case you get stuck and need help.

Before we start

Before you can use three.js, you need somewhere to display it. Save the following HTML to a file on your computer, along with a copy of three.js in the js/ directory, and open it in your browser.

……

 

【稿本】

<html>
	<head>
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
			canvas { width: 100%; height: 100% }
		</style>
	</head>
	<body>
		<script src="js/three.js"></script>
		<script>
			var scene = new THREE.Scene();
			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

			var renderer = new THREE.WebGLRenderer();
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.body.appendChild( renderer.domElement );

			var geometry = new THREE.BoxGeometry( 1, 1, 1 );
			var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
			var cube = new THREE.Mesh( geometry, material );
			scene.add( cube );

			camera.position.z = 5;

			var animate = function () {
				requestAnimationFrame( animate );

				cube.rotation.x += 0.1;
				cube.rotation.y += 0.1;

				renderer.render( scene, camera );
			};

			animate();
		</script>
	</body>
</html>

 

【顯示】