HTML5與WebGL程式設計(1):介紹
程式碼https://github.com/tparisi/Programming3DApplications
HTML5是HTML標準的大規模修訂,包括語法的清理、新的JavaScript語言特性和API、移動端支援以及突破性的多媒體支援。HTML5平臺的核心是一系列先進的圖形技術。
- WebGL,使得JavaScript支援硬體3D加速渲染。WebGL基於OpenGL,幾乎所有的PC端瀏覽器都支援WebGL,而越來越多的移動端瀏覽器也開始支援WebGL。
- CSS3 3D變換、平移以及可以支援更高階頁面效果的使用者自定義濾鏡。經過過去幾年的發展,CSS現在已經支援硬體3D加速渲染和動畫。
- Canvas元素和相應的2D繪圖API。瀏覽器普遍支援這個JavaScript的API,它使得開發者可以在一個DOM元素上繪製任意圖形。儘管Canvas是一個2D繪圖API,但如果使用一些JavaScript庫的話,它也可以用於渲染3D效果---在不支援WebGL和CSS3 3D的平臺上,這通常被作為3D渲染的替代解決方案。
這些技術各有其優勢和適用場景,它們在構建3D視覺化互動的過程中發揮著各自的作用。至於究竟要選擇哪一種,你需要綜合考慮多方面的因素---你想要構建什麼,需要支援哪些平臺,效能問題,等等。舉例來說,如果你開發一個具有高質量影像的第一人稱射擊遊戲,若不借助WebGL訪問圖形硬體的能力,這將很難實現。又或者你在為某個視訊網站開發一個有趣的調臺器介面,包括當前視訊縮圖、換頻道的旋轉效果,以及視訊剪輯切換間隙的雪花噪點特效。在這個場景下,CSS3會是創造優秀體驗的良好選擇。
requestAnimationFrame()函式是替代setInterval()和setTimeout()來驅動動畫,使得開發這能夠以和瀏覽器重新整理頁面元素同步的重新整理頻率來更新canvas元素的繪圖內容,這大大地提升了效能,並防止了繪圖殘影的產生。
HTML5瀏覽器同時也支援多執行緒程式設計(Web Workers)、全雙工TCP/IP通訊(WebSockets)、本地資料儲存等新特性。
3D座標系
網格、多邊形和頂點
材質、紋理與光源
變換與矩陣
相機、透視、視口與投影
著色器
<html>
<head>
<title>Programming 3D Applications in HTML5 and WebGL — Example 2-3</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<script src="../libs/jquery-1.9.1/jquery-1.9.1.js"></script>
<script src="../libs/gl-matrix/gl-matrix.js"></script>
<script src="../libs/requestAnimationFrame/RequestAnimationFrame.js"></script>
<script type="text/javascript">
function initWebGL(canvas) {
var gl = null;
var msg = "Your browser does not support WebGL, " +
"or it is not enabled by default.";
try
{
gl = canvas.getContext("experimental-webgl");
}
catch (e)
{
msg = "Error creating WebGL Context!: " + e.toString();
}
if (!gl)
{
alert(msg);
throw new Error(msg);
}
return gl;
}
function initViewport(gl, canvas)
{
gl.viewport(0, 0, canvas.width, canvas.height);
}
var projectionMatrix, modelViewMatrix;
var rotationAxis;
function initMatrices(canvas)
{
// Create a model view matrix with object at 0, 0, -8
modelViewMatrix = mat4.create();
mat4.translate(modelViewMatrix, modelViewMatrix, [0, 0, -8]);
// Create a project matrix with 45 degree field of view
projectionMatrix = mat4.create();
mat4.perspective(projectionMatrix, Math.PI / 4, canvas.width / canvas.height, 1, 10000);
rotationAxis = vec3.create();
vec3.normalize(rotationAxis, [1, 1, 1]);
}
// Create the vertex, color and index data for a multi-colored cube
function createCube(gl) {
// Vertex Data
var vertexBuffer;
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
var verts = [
// Front face
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Back face
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Top face
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// Bottom face
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Right face
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// Left face
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
var texCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
var textureCoords = [
// Front face
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Back face
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
// Top face
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
// Bottom face
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
// Right face
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
// Left face
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
// Index data (defines the triangles to be drawn)
var cubeIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeIndexBuffer);
var cubeIndices = [
0, 1, 2, 0, 2, 3, // Front face
4, 5, 6, 4, 6, 7, // Back face
8, 9, 10, 8, 10, 11, // Top face
12, 13, 14, 12, 14, 15, // Bottom face
16, 17, 18, 16, 18, 19, // Right face
20, 21, 22, 20, 22, 23 // Left face
];
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeIndices), gl.STATIC_DRAW);
var cube = {buffer:vertexBuffer, texCoordBuffer:texCoordBuffer, indices:cubeIndexBuffer,
vertSize:3, nVerts:24, texCoordSize:2, nTexCoords: 24, nIndices:36,
primtype:gl.TRIANGLES};
return cube;
}
function createShader(gl, str, type) {
var shader;
if (type == "fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (type == "vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var vertexShaderSource =
" attribute vec3 vertexPos;\n" +
" attribute vec2 texCoord;\n" +
" uniform mat4 modelViewMatrix;\n" +
" uniform mat4 projectionMatrix;\n" +
" varying vec2 vTexCoord;\n" +
" void main(void) {\n" +
" // Return the transformed and projected vertex value\n" +
" gl_Position = projectionMatrix * modelViewMatrix * \n" +
" vec4(vertexPos, 1.0);\n" +
" // Output the texture coordinate in vTexCoord\n" +
" vTexCoord = texCoord;\n" +
" }\n";
var fragmentShaderSource =
" precision mediump float;\n" +
" varying vec2 vTexCoord;\n" +
" uniform sampler2D uSampler;\n" +
" void main(void) {\n" +
" // Return the pixel color: always output white\n" +
" gl_FragColor = texture2D(uSampler, vec2(vTexCoord.s, vTexCoord.t));\n" +
"}\n";
var shaderProgram, shaderVertexPositionAttribute, shaderVertexColorAttribute,
shaderProjectionMatrixUniform, shaderModelViewMatrixUniform, shaderSamplerUniform;
function initShader(gl) {
// load and compile the fragment and vertex shader
//var fragmentShader = getShader(gl, "fragmentShader");
//var vertexShader = getShader(gl, "vertexShader");
var fragmentShader = createShader(gl, fragmentShaderSource, "fragment");
var vertexShader = createShader(gl, vertexShaderSource, "vertex");
// link them together into a new program
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
// get pointers to the shader params
shaderVertexPositionAttribute = gl.getAttribLocation(shaderProgram, "vertexPos");
gl.enableVertexAttribArray(shaderVertexPositionAttribute);
shaderTexCoordAttribute = gl.getAttribLocation(shaderProgram, "texCoord");
gl.enableVertexAttribArray(shaderTexCoordAttribute);
shaderProjectionMatrixUniform = gl.getUniformLocation(shaderProgram, "projectionMatrix");
shaderModelViewMatrixUniform = gl.getUniformLocation(shaderProgram, "modelViewMatrix");
shaderSamplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
}
var okToRun = false;
function handleTextureLoaded(gl, texture) {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, null);
okToRun = true;
}
var webGLTexture;
function initTexture(gl) {
webGLTexture = gl.createTexture();
webGLTexture.image = new Image();
webGLTexture.image.onload = function () {
handleTextureLoaded(gl, webGLTexture)
}
webGLTexture.image.crossOrigin = "anonymous";
webGLTexture.image.src = "../images/webgl-logo-256.jpg";
}
function draw(gl, obj) {
// clear the background (with black)
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// set the shader to use
gl.useProgram(shaderProgram);
// connect up the shader parameters: vertex position, texture coordinate,
// projection/model matrices and texture
// set up the buffers
gl.bindBuffer(gl.ARRAY_BUFFER, obj.buffer);
gl.vertexAttribPointer(shaderVertexPositionAttribute, obj.vertSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, obj.texCoordBuffer);
gl.vertexAttribPointer(shaderTexCoordAttribute, obj.texCoordSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, obj.indices);
gl.uniformMatrix4fv(shaderProjectionMatrixUniform, false, projectionMatrix);
gl.uniformMatrix4fv(shaderModelViewMatrixUniform, false, modelViewMatrix);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, webGLTexture);
gl.uniform1i(shaderSamplerUniform, 0);
// draw the object
gl.drawElements(obj.primtype, obj.nIndices, gl.UNSIGNED_SHORT, 0);
}
var duration = 5000; // ms
var currentTime = Date.now();
function animate() {
var now = Date.now();
var deltat = now - currentTime;
currentTime = now;
var fract = deltat / duration;
var angle = Math.PI * 2 * fract;
mat4.rotate(modelViewMatrix, modelViewMatrix, angle, rotationAxis);
}
function run(gl, cube) {
requestAnimationFrame(function() { run(gl, cube); });
if (okToRun)
{
draw(gl, cube);
animate();
}
}
$(document).ready(
function() {
var canvas = document.getElementById("webglcanvas");
var gl = initWebGL(canvas);
initViewport(gl, canvas);
initMatrices(canvas);
var cube = createCube(gl);
initShader(gl);
initTexture(gl);
run(gl, cube);
}
);
</script>
</head>
<body>
<canvas id="webglcanvas" style="border: none;" width="500" height="500"></canvas>
</body>
</html>
相關文章
- WebGL程式設計指南(1)簡介Web程式設計
- HTML5與WebGL程式設計(2):Three.jsHTMLWeb程式設計JS
- 邏輯程式設計與函式程式設計的介紹程式設計函式
- 《WebGL程式設計指南》學習筆記——1.WebGL概述Web程式設計筆記
- HTML5學習(1)–介紹HTML
- NIO程式設計介紹程式設計
- HTML5與WebGL程式設計(3):Three.js中的圖形和渲染HTMLWeb程式設計JS
- Shell程式設計 --- Shell介紹程式設計
- Delphi COM程式設計介紹程式設計
- JAVA設計模式 1 設計模式介紹、單例模式的理解與使用Java設計模式單例
- 面向方面程式設計的介紹----基本概念(1) (轉)程式設計
- 如何向新手程式設計師介紹程式設計?程式設計師
- MATLAB 超程式設計介紹Matlab程式設計
- WebGL程式設計指南(4)顏色與紋理Web程式設計
- C++併發程式設計框架Theron(1)——Actor模型介紹C++程式設計框架模型
- 平行計算與並行程式設計課程內容介紹並行行程程式設計
- HTML5 介紹HTML
- WebGL程式設計指南(6)光照Web程式設計
- Rust 程式設計影片教程(進階)——029_1 宏介紹Rust程式設計
- Rust 程式設計影片教程(進階)——003_1 迭代器介紹Rust程式設計
- shell程式設計–bash變數介紹程式設計變數
- Python多工程式設計介紹Python程式設計
- 介紹Java Socket程式設計的文章Java程式設計
- mod_perl 程式設計介紹 (轉)程式設計
- Linux Shell程式設計(1)——shell程式設計簡介Linux程式設計
- Linux系統程式設計之程式介紹Linux程式設計
- 設計模式:介紹設計模式
- Rust 程式設計視訊教程(進階)——029_1 巨集介紹Rust程式設計
- Rust 程式設計視訊教程(進階)——003_1 迭代器介紹Rust程式設計
- Rust 程式設計影片教程(進階)——004_1 生命週期介紹Rust程式設計
- Rust 程式設計影片教程(進階)——010_1Box 介紹Rust程式設計
- Rust 程式設計視訊教程(進階)——005_1 閉包介紹Rust程式設計
- [MAUI 專案實戰] 筆記App(一):介紹與程式設計UI筆記APP程式設計
- HTML5基本介紹HTML
- 005 Rust 非同步程式設計,Pin 介紹Rust非同步程式設計
- Linux中Libevent程式設計介紹Linux程式設計
- js DSL超程式設計簡單介紹JS程式設計
- JavaScript 模組化程式設計簡單介紹JavaScript程式設計