4399html5 无法上传 html5/WebGL 游戏

在支持HTML5的浏览器上运行WebGL程序的方法
这篇文章主要介绍了在支持HTML5的浏览器上运行WebGL程序的方法,文中列举了一个hello world立方体动画的运行实例,需要的朋友可以参考下
&前提条件和预期结果
目前只有少数的浏览器支持 WebGL ,请看我的另外一篇文章:Can I use WebGL?.
下面的例子是在 Windows 下的 Chrome 16/23 以及 Android 下的 Firefox 17 进行测试。如果你使用的是非兼容浏览器访问则会弹出一个警告。&
&图1:包含 Hello world 文本的动画的 WebGL 立方体在兼容 HTML5 的浏览器上,你将会看到如下图所示的带动画效果的立方体:
&图2: 示例运行的屏幕截图
该代码基于 Lighting in WebGL - How to simulate lighting effects in your WebGL context - 非常感谢这篇教程。在该实例初始运行时,动画的立方体是通过一个静态的 Bitmap 图形对象渲染的。
下面的代码演示如何在程序中动态的渲染文本:
//&TODO&#1&New&method&to&create&a&texture &&
function&createCubeTexture(text)&{ &&
&&&&... &&
在这里使用 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); 是非常重要的,用来确保写文本时不会前后颠倒。剩下的就很容易理解了:
//&TODO&#2&Assign&the&created&texture&for&display &&
cubeTexture&=&createCubeTexture(&Hello&World!&);&&
// File #1: webgl-demo.htm
&&&&WebGL&-&Hello&World!&&
&&&&&http-equiv=&Content-Type&&content=&text/&charset=utf-8&&&
&&&&&src=&sylvester.js&&type=&text/javascript&&&
&&&&&src=&glUtils.js&&type=&text/javascript&&&
&&&&&src=&webgl-demo.js&&type=&text/javascript&&&
&&&&&id=&shader-fs&&type=&x-shader/x-fragment&&&
&&&&&&varying&highp&vec2&vTextureC &&
&&&&&&varying&highp&vec3&vL &&
&&&&&&& &&
&&&&&&uniform&sampler2D&uS &&
&&&&&&& &&
&&&&&&void&main(void)&{ &&
&&&&&&&&highp&vec4&texelColor&=&texture2D(uSampler,&vec2(vTextureCoord.s,&vTextureCoord.t)); &&
&&&&&&&&& &&
&&&&&&&&gl_FragColor&=&vec4(texelColor.rgb&*&vLighting,&texelColor.a); &&
&&&&&&} &&
&&&&&id=&shader-vs&&type=&x-shader/x-vertex&&&
&&&&&&attribute&highp&vec3&aVertexN &&
&&&&&&attribute&highp&vec3&aVertexP &&
&&&&&&attribute&highp&vec2&aTextureC &&
&&&&&&uniform&highp&mat4&uNormalM &&
&&&&&&uniform&highp&mat4&uMVM &&
&&&&&&uniform&highp&mat4&uPM &&
&&&&&&& &&
&&&&&&varying&highp&vec2&vTextureC &&
&&&&&&varying&highp&vec3&vL &&
&&&&&&void&main(void)&{ &&
&&&&&&&&gl_Position&=&uPMatrix&*&uMVMatrix&*&vec4(aVertexPosition,&1.0); &&
&&&&&&&&vTextureCoord&=&aTextureCoord; &&
&&&&&&&&& &&
&&&&&&&&//&Apply&lighting&effect &&
&&&&&&&&& &&
&&&&&&&&highp&vec3&ambientLight&=&vec3(0.6,&0.6,&0.6); &&
&&&&&&&&highp&vec3&directionalLightColor&=&vec3(0.5,&0.5,&0.75); &&
&&&&&&&&highp&vec3&directionalVector&=&vec3(0.85,&0.8,&0.75); &&
&&&&&&&&highp&vec4&transformedNormal&=&uNormalMatrix&*&vec4(aVertexNormal,&1.0); &&
&&&&&&&&highp&float&directional&=&max(dot(transformedNormal.xyz,&directionalVector),&0.0); &&
&&&&&&&&vLighting&=&ambientLight&+&(directionalLightColor&*&directional); &&
&&&&&&} &&
&&&&&&& &&
&&&onload=&start()&&&
&&&&&id=&glcanvas&&width=&640&&height=&480&&&
&&&&&&Your&browser&doesn't&appear&to&support&the&HTML5&&element. &&
// File #02: webgl-demo.js
var&cubeVerticesB &&
var&cubeVerticesTextureCoordB &&
var&cubeVerticesIndexB &&
var&cubeVerticesIndexB &&
var&cubeRotation&=&0.0; &&
var&lastCubeUpdateTime&=&0; &&
var&cubeI &&
var&cubeT &&
var&mvM &&
var&shaderP &&
var&vertexPositionA &&
var&vertexNormalA &&
var&textureCoordA &&
var&perspectiveM &&
//&start &&
//&Called&when&the&canvas&is&created&to&get&the&ball&rolling. &&
function&start()&{ &&
&&canvas&=&document.getElementById(&glcanvas&); &&
&&initWebGL(canvas);&&&&&&//&Initialize&the&GL&context &&
&&//&Only&continue&if&WebGL&is&available&and&working &&
&&if&(gl)&{ &&
&&&&gl.clearColor(0.0,&0.0,&0.0,&1.0);&&//&Clear&to&black,&fully&opaque &&
&&&&gl.clearDepth(1.0);&&&&&&&&&&&&&&&&&//&Clear&everything &&
&&&&gl.enable(gl.DEPTH_TEST);&&&&&&&&&&&//&Enable&depth&testing &&
&&&&gl.depthFunc(gl.LEQUAL);&&&&&&&&&&&&//&Near&things&obscure&far&things &&
&&&&//&Initialize&the&&this&is&where&all&the&lighting&for&the &&
&&&&//&vertices&and&so&forth&is&established. &&
&&&&initShaders(); &&
&&&&//&Here's&where&we&call&the&routine&that&builds&all&the&objects &&
&&&&//&we'll&be&drawing. &&
&&&&initBuffers(); &&
&&&&//&Next,&load&and&set&up&the&textures&we'll&be&using. &&
&&&&//&TODO#2&Start &&
&&&&cubeTexture&=&createCubeTexture(&Hello&World!&); &&
&&&&//&TODO#2&End &&
&&&&//&Set&up&to&draw&the&scene&periodically. &&
&&&&setInterval(drawScene,&15); &&
//&initWebGL &&
//&Initialize&WebGL,&returning&the&GL&context&or&null&if &&
//&WebGL&isn't&available&or&could&not&be&initialized. &&
function&initWebGL()&{ &&
&&gl&=&null; &&
&&try&{ &&
&&&&gl&=&canvas.getContext(&experimental-webgl&); &&
&&catch(e)&{ &&
&&//&If&we&don't&have&a&GL&context,&give&up&now &&
&&if&(!gl)&{ &&
&&&&alert(&Unable&to&initialize&WebGL.&Your&browser&may&not&support&it.&); &&
//&initBuffers &&
//&Initialize&the&buffers&we'll&need.&For&this&demo,&we&just&have &&
//&one&object&--&a&simple&two-dimensional&cube. &&
function&initBuffers()&{ &&
&&//&Create&a&buffer&for&the&cube's&vertices. &&
&&cubeVerticesBuffer&=&gl.createBuffer(); &&
&&//&Select&the&cubeVerticesBuffer&as&the&one&to&apply&vertex &&
&&//&operations&to&from&here&out. &&
&&gl.bindBuffer(gl.ARRAY_BUFFER,&cubeVerticesBuffer); &&
&&//&Now&create&an&array&of&vertices&for&the&cube. &&
&&var&vertices&=&[ &&
&&&&//&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 &&
&&//&Now&pass&the&list&of&vertices&into&WebGL&to&build&the&shape.&We &&
&&//&do&this&by&creating&a&Float32Array&from&the&JavaScript&array, &&
&&//&then&use&it&to&fill&the&current&vertex&buffer. &&
&&gl.bufferData(gl.ARRAY_BUFFER,&new&Float32Array(vertices),&gl.STATIC_DRAW); &&
&&//&Set&up&the&normals&for&the&vertices,&so&that&we&can&compute&lighting. &&
&&cubeVerticesNormalBuffer&=&gl.createBuffer(); &&
&&gl.bindBuffer(gl.ARRAY_BUFFER,&cubeVerticesNormalBuffer); &&
&&var&vertexNormals&=&[ &&
&&&&//&Front &&
&&&&&0.0,&&0.0,&&1.0, &&
&&&&&0.0,&&0.0,&&1.0, &&
&&&&&0.0,&&0.0,&&1.0, &&
&&&&&0.0,&&0.0,&&1.0, &&
&&&&//&Back &&
&&&&&0.0,&&0.0,&-1.0, &&
&&&&&0.0,&&0.0,&-1.0, &&
&&&&&0.0,&&0.0,&-1.0, &&
&&&&&0.0,&&0.0,&-1.0, &&
&&&&//&Top &&
&&&&&0.0,&&1.0,&&0.0, &&
&&&&&0.0,&&1.0,&&0.0, &&
&&&&&0.0,&&1.0,&&0.0, &&
&&&&&0.0,&&1.0,&&0.0, &&
&&&&//&Bottom &&
&&&&&0.0,&-1.0,&&0.0, &&
&&&&&0.0,&-1.0,&&0.0, &&
&&&&&0.0,&-1.0,&&0.0, &&
&&&&&0.0,&-1.0,&&0.0, &&
&&&&//&Right &&
&&&&&1.0,&&0.0,&&0.0, &&
&&&&&1.0,&&0.0,&&0.0, &&
&&&&&1.0,&&0.0,&&0.0, &&
&&&&&1.0,&&0.0,&&0.0, &&
&&&&//&Left &&
&&&&-1.0,&&0.0,&&0.0, &&
&&&&-1.0,&&0.0,&&0.0, &&
&&&&-1.0,&&0.0,&&0.0, &&
&&&&-1.0,&&0.0,&&0.0 &&
&&gl.bufferData(gl.ARRAY_BUFFER,&new&Float32Array(vertexNormals), &&
&&&&&&&&&&&&&&&&gl.STATIC_DRAW); &&
&&//&Map&the&texture&onto&the&cube's&faces. &&
&&cubeVerticesTextureCoordBuffer&=&gl.createBuffer(); &&
&&gl.bindBuffer(gl.ARRAY_BUFFER,&cubeVerticesTextureCoordBuffer); &&
&&var&textureCoordinates&=&[ &&
&&&&//&Front &&
&&&&0.0,&&0.0, &&
&&&&1.0,&&0.0, &&
&&&&1.0,&&1.0, &&
&&&&0.0,&&1.0, &&
&&&&//&Back &&
&&&&0.0,&&0.0, &&
&&&&1.0,&&0.0, &&
&&&&1.0,&&1.0, &&
&&&&0.0,&&1.0, &&
&&&&//&Top &&
&&&&0.0,&&0.0, &&
&&&&1.0,&&0.0, &&
&&&&1.0,&&1.0, &&
&&&&0.0,&&1.0, &&
&&&&//&Bottom &&
&&&&0.0,&&0.0, &&
&&&&1.0,&&0.0, &&
&&&&1.0,&&1.0, &&
&&&&0.0,&&1.0, &&
&&&&//&Right &&
&&&&0.0,&&0.0, &&
&&&&1.0,&&0.0, &&
&&&&1.0,&&1.0, &&
&&&&0.0,&&1.0, &&
&&&&//&Left &&
&&&&0.0,&&0.0, &&
&&&&1.0,&&0.0, &&
&&&&1.0,&&1.0, &&
&&&&0.0,&&1.0 &&
&&gl.bufferData(gl.ARRAY_BUFFER,&new&Float32Array(textureCoordinates), &&
&&&&&&&&&&&&&&&&gl.STATIC_DRAW); &&
&&//&Build&the&element&array&&this&specifies&the&indices &&
&&//&into&the&vertex&array&for&each&face's&vertices. &&
&&cubeVerticesIndexBuffer&=&gl.createBuffer(); &&
&&gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,&cubeVerticesIndexBuffer); &&
&&//&This&array&defines&each&face&as&two&triangles,&using&the &&
&&//&indices&into&the&vertex&array&to&specify&each&triangle's &&
&&//&position. &&
&&var&cubeVertexIndices&=&[ &&
&&&&0,&&1,&&2,&&&&&&0,&&2,&&3,&&&&//&front &&
&&&&4,&&5,&&6,&&&&&&4,&&6,&&7,&&&&//&back &&
&&&&8,&&9,&&10,&&&&&8,&&10,&11,&&&//&top &&
&&&&12,&13,&14,&&&&&12,&14,&15,&&&//&bottom &&
&&&&16,&17,&18,&&&&&16,&18,&19,&&&//&right &&
&&&&20,&21,&22,&&&&&20,&22,&23&&&&//&left &&
&&//&Now&send&the&element&array&to&GL &&
&&gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, &&
&&&&&&new&Uint16Array(cubeVertexIndices),&gl.STATIC_DRAW); &&
//&initTextures &&
//&Initialize&the&textures&we'll&be&using,&then&initiate&a&load&of &&
//&the&texture&images.&The&handleTextureLoaded()&callback&will&finish &&
//&the&&it&gets&called&each&time&a&texture&finishes&loading. &&
//&TODO#1&Start &&
function&createCubeTexture(text)&{ &&
&&&&&&&&&&&&&&&&& &&
&&&&//&create&a&hidden&canvas&to&draw&the&texture &&
&&&&var&canvas&=&document.createElement('canvas'); &&
&&&&canvas.id&&&&&=&&hiddenCanvas&; &&
&&&&canvas.width&&=&512; &&
&&&&canvas.height&=&512; &&
&&&&canvas.style.display&&&=&&none&; &&
&&&&var&body&=&document.getElementsByTagName(&body&)[0]; &&
&&&&body.appendChild(canvas);&&&&&&& &&
&&&&//&draw&texture &&
&&&&var&cubeImage&=&document.getElementById('hiddenCanvas'); &&
&&&&var&ctx&=&cubeImage.getContext('2d'); &&
&&&&ctx.beginPath(); &&
&&&&ctx.rect(0,&0,&ctx.canvas.width,&ctx.canvas.height);&&&&&&&&&&& &&
&&&&ctx.fillStyle&=&'white'; &&
&&&&ctx.fill(); &&
&&&&ctx.fillStyle&=&'black'; &&
&&&&ctx.font&=&&65px&Arial&; &&
&&&&ctx.textAlign&=&'center';&&&&&&&&&&& &&
&&&&ctx.fillText(text,&ctx.canvas.width&/&2,&ctx.canvas.height&/&2); &&
&&&&ctx.restore();&&&&&&& &&
&&&&//&create&new&texture &&
&&&&var&texture&=&gl.createTexture(); &&
&&&&gl.bindTexture(gl.TEXTURE_2D,&texture); &&
&&&&gl.texParameteri(gl.TEXTURE_2D,&gl.TEXTURE_MAG_FILTER,&gl.LINEAR); &&
&&&&gl.texParameteri(gl.TEXTURE_2D,&gl.TEXTURE_MIN_FILTER,&gl.LINEAR_MIPMAP_NEAREST); &&
&&&&gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,&true); &&
&&&&handleTextureLoaded(cubeImage,&texture) &&
&&&&return& &&
//&TODO#1&End &&
function&handleTextureLoaded(image,&texture)&{ &&
&&gl.bindTexture(gl.TEXTURE_2D,&texture); &&
&&gl.texImage2D(gl.TEXTURE_2D,&0,&gl.RGBA,&gl.RGBA,&gl.UNSIGNED_BYTE,&image); &&
&&gl.texParameteri(gl.TEXTURE_2D,&gl.TEXTURE_MAG_FILTER,&gl.LINEAR); &&
&&gl.texParameteri(gl.TEXTURE_2D,&gl.TEXTURE_MIN_FILTER,&gl.LINEAR_MIPMAP_NEAREST); &&
&&gl.generateMipmap(gl.TEXTURE_2D); &&
&&gl.bindTexture(gl.TEXTURE_2D,&null); &&
//&drawScene &&
//&Draw&the&scene. &&
function&drawScene()&{ &&
&&//&Clear&the&canvas&before&we&start&drawing&on&it. &&
&&gl.clear(gl.COLOR_BUFFER_BIT&|&gl.DEPTH_BUFFER_BIT); &&
&&//&Establish&the&perspective&with&which&we&want&to&view&the &&
&&//&scene.&Our&field&of&view&is&45&degrees,&with&a&width/height &&
&&//&ratio&of&640:480,&and&we&only&want&to&see&objects&between&0.1&units &&
&&//&and&100&units&away&from&the&camera. &&
&&perspectiveMatrix&=&makePerspective(45,&640.0/480.0,&0.1,&100.0); &&
&&//&Set&the&drawing&position&to&the&&identity&&point,&which&is &&
&&//&the&center&of&the&scene. &&
&&loadIdentity(); &&
&&//&Now&move&the&drawing&position&a&bit&to&where&we&want&to&start &&
&&//&drawing&the&cube. &&
&&mvTranslate([0.0,&0.0,&-6.0]); &&
&&//&Save&the&current&matrix,&then&rotate&before&we&draw. &&
&&mvPushMatrix(); &&
&&mvRotate(cubeRotation,&[1,&0,&1]); &&
&&//&Draw&the&cube&by&binding&the&array&buffer&to&the&cube's&vertices &&
&&//&array,&setting&attributes,&and&pushing&it&to&GL. &&
&&gl.bindBuffer(gl.ARRAY_BUFFER,&cubeVerticesBuffer); &&
&&gl.vertexAttribPointer(vertexPositionAttribute,&3,&gl.FLOAT,&false,&0,&0); &&
&&//&Set&the&texture&coordinates&attribute&for&the&vertices. &&
&&gl.bindBuffer(gl.ARRAY_BUFFER,&cubeVerticesTextureCoordBuffer); &&
&&gl.vertexAttribPointer(textureCoordAttribute,&2,&gl.FLOAT,&false,&0,&0); &&
&&//&Bind&the&normals&buffer&to&the&shader&attribute. &&
&&gl.bindBuffer(gl.ARRAY_BUFFER,&cubeVerticesNormalBuffer); &&
&&gl.vertexAttribPointer(vertexNormalAttribute,&3,&gl.FLOAT,&false,&0,&0); &&
&&//&Specify&the&texture&to&map&onto&the&faces. &&
&&gl.activeTexture(gl.TEXTURE0); &&
&&gl.bindTexture(gl.TEXTURE_2D,&cubeTexture); &&
&&gl.uniform1i(gl.getUniformLocation(shaderProgram,&&uSampler&),&0); &&
&&//&Draw&the&cube. &&
&&gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,&cubeVerticesIndexBuffer); &&
&&setMatrixUniforms(); &&
&&gl.drawElements(gl.TRIANGLES,&36,&gl.UNSIGNED_SHORT,&0); &&
&&//&Restore&the&original&matrix &&
&&mvPopMatrix(); &&
&&//&Update&the&rotation&for&the&next&draw,&if&it's&time&to&do&so. &&
&&var&currentTime&=&(new&Date).getTime(); &&
&&if&(lastCubeUpdateTime)&{ &&
&&&&var&delta&=&currentTime&-&lastCubeUpdateT &&
&&&&cubeRotation&+=&(30&*&delta)&/&1000.0; &&
&&lastCubeUpdateTime&=&currentTime; &&
//&initShaders &&
//&Initialize&the&shaders,&so&WebGL&knows&how&to&light&our&scene. &&
function&initShaders()&{ &&
&&var&fragmentShader&=&getShader(gl,&&shader-fs&); &&
&&var&vertexShader&=&getShader(gl,&&shader-vs&); &&
&&//&Create&the&shader&program &&
&&shaderProgram&=&gl.createProgram(); &&
&&gl.attachShader(shaderProgram,&vertexShader); &&
&&gl.attachShader(shaderProgram,&fragmentShader); &&
&&gl.linkProgram(shaderProgram); &&
&&//&If&creating&the&shader&program&failed,&alert &&
&&if&(!gl.getProgramParameter(shaderProgram,&gl.LINK_STATUS))&{ &&
&&&&alert(&Unable&to&initialize&the&shader&program.&); &&
&&gl.useProgram(shaderProgram); &&
&&vertexPositionAttribute&=&gl.getAttribLocation(shaderProgram,&&aVertexPosition&); &&
&&gl.enableVertexAttribArray(vertexPositionAttribute); &&
&&textureCoordAttribute&=&gl.getAttribLocation(shaderProgram,&&aTextureCoord&); &&
&&gl.enableVertexAttribArray(textureCoordAttribute); &&
&&vertexNormalAttribute&=&gl.getAttribLocation(shaderProgram,&&aVertexNormal&); &&
&&gl.enableVertexAttribArray(vertexNormalAttribute); &&
//&getShader &&
//&Loads&a&shader&program&by&scouring&the&current&document, &&
//&looking&for&a&script&with&the&specified&ID. &&
function&getShader(gl,&id)&{ &&
&&var&shaderScript&=&document.getElementById(id); &&
&&//&Didn't&find&an&element&with&the&specified&ID;&abort. &&
&&if&(!shaderScript)&{ &&
&&&&return& &&
&&//&Walk&through&the&source&element's&children,&building&the &&
&&//&shader&source&string. &&
&&var&theSource&=&&&; &&
&&var&currentChild&=&shaderScript.firstC &&
&&while(currentChild)&{ &&
&&&&if&(currentChild.nodeType&==&3)&{ &&
&&&&&&theSource&+=&currentChild.textC &&
&&&&currentChildcurrentChild&=&currentChild.nextS &&
&&//&Now&figure&out&what&type&of&shader&script&we&have, &&
&&//&based&on&its&MIME&type. &&
&&if&(shaderScript.type&==&&x-shader/x-fragment&)&{ &&
&&&&shader&=&gl.createShader(gl.FRAGMENT_SHADER); &&
&&}&else&if&(shaderScript.type&==&&x-shader/x-vertex&)&{ &&
&&&&shader&=&gl.createShader(gl.VERTEX_SHADER); &&
&&}&else&{ &&
&&&&return&&&//&Unknown&shader&type &&
&&//&Send&the&source&to&the&shader&object &&
&&gl.shaderSource(shader,&theSource); &&
&&//&Compile&the&shader&program &&
&&gl.compileShader(shader); &&
&&//&See&if&it&compiled&successfully &&
&&if&(!gl.getShaderParameter(shader,&gl.COMPILE_STATUS))&{ &&
&&&&alert(&An&error&occurred&compiling&the&shaders:&&&+&gl.getShaderInfoLog(shader)); &&
&&&&return& &&
&&return& &&
//&Matrix&utility&functions &&
function&loadIdentity()&{ &&
&&mvMatrix&=&Matrix.I(4); &&
function&multMatrix(m)&{ &&
&&mvMatrixmvMatrix&=&mvMatrix.x(m); &&
function&mvTranslate(v)&{ &&
&&multMatrix(Matrix.Translation($V([v[0],&v[1],&v[2]])).ensure4x4()); &&
function&setMatrixUniforms()&{ &&
&&var&pUniform&=&gl.getUniformLocation(shaderProgram,&&uPMatrix&); &&
&&gl.uniformMatrix4fv(pUniform,&false,&new&Float32Array(perspectiveMatrix.flatten())); &&
&&var&mvUniform&=&gl.getUniformLocation(shaderProgram,&&uMVMatrix&); &&
&&gl.uniformMatrix4fv(mvUniform,&false,&new&Float32Array(mvMatrix.flatten())); &&
&&var&normalMatrix&=&mvMatrix.inverse(); &&
&&normalMatrixnormalMatrix&=&normalMatrix.transpose(); &&
&&var&nUniform&=&gl.getUniformLocation(shaderProgram,&&uNormalMatrix&); &&
&&gl.uniformMatrix4fv(nUniform,&false,&new&Float32Array(normalMatrix.flatten())); &&
var&mvMatrixStack&=&[]; &&
function&mvPushMatrix(m)&{ &&
&&if&(m)&{ &&
&&&&mvMatrixStack.push(m.dup()); &&
&&&&mmvMatrix&=&m.dup(); &&
&&}&else&{ &&
&&&&mvMatrixStack.push(mvMatrix.dup()); &&
function&mvPopMatrix()&{ &&
&&if&(!mvMatrixStack.length)&{ &&
&&&&throw(&Can't&pop&from&an&empty&matrix&stack.&); &&
&&mvMatrix&=&mvMatrixStack.pop(); &&
&&return&mvM &&
function&mvRotate(angle,&v)&{ &&
&&var&inRadians&=&angle&*&Math.PI&/&180.0; &&
&&var&m&=&Matrix.Rotation(inRadians,&$V([v[0],&v[1],&v[2]])).ensure4x4(); &&
&&multMatrix(m); &&
下一篇:没有了&&&&利用HTML5、CSS3和WebGL开发HTML5游戏
自营订单满49元(含)免运费
不足金额订单收取运费5元起
邀请好友参加吧
开 本:16开纸 张:胶版纸包 装:平装是否套装:否国际标准书号ISBN:2所属分类:&&&
下载免费当当读书APP
品味海量优质电子书,尊享优雅的阅读体验,只差手机下载一个当当读书APP
本商品暂无详情。
当当价:为商品的销售价,具体的成交价可能因会员使用优惠券、积分等发生变化,最终以订单结算页价格为准。
划线价:划线价格可能是图书封底定价、商品吊牌价、品牌专柜价或由品牌供应商提供的正品零售价(如厂商指导价、建议零售价等)或该商品曾经展示过的销售价等,由于地区、时间的差异化和市场行情波动,商品吊牌价、品牌专柜价等可能会与您购物时展示的不一致,该价格仅供您参考。
折扣:折扣指在划线价(图书定价、商品吊牌价、品牌专柜价、厂商指导价等)某一价格基础上计算出的优惠比例或优惠金额。如有疑问,您可在购买前联系客服咨询。
异常问题:如您发现活动商品销售价或促销信息有异常,请立即联系我们补正,以便您能顺利购物。
当当购物客户端手机端1元秒
当当读书客户端万本电子书免费读【图片】HTML5和WebGL来制作2D游戏教程分享【我学院吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:29贴子:
HTML5和WebGL来制作2D游戏教程分享
Istrolid是一款采用诸多web新技术的HTML5游戏。游戏的作者treeform分别使用webGL、WebSocket、AudioContext和作者自制的响应式HTML框架来渲染图形、创建网络连接、播放音频和设计UI。另外,他还使用了Electron来将游戏打包成Windows和Mac的桌面应用程序。笔者这次给大家分享一下 Istrolid作者的游戏开发心得。2D WebGL在使用openGL和WebGL引擎时,开发者通常会创建多个网格和纹理对象。但是 Istrolid的 作者却有着自己独特的建构方法。他 通过一个网格和纹理对象 来绘画所有的游戏内容。游戏中的飞船有非常简单的多边形构成,有的甚至是由若干个三角形构成的。因此作者认为没有必为每一个要绘制的物体都新建一个网格对象。取而代之的是创建一个动态的网格并在每一帧画面中通过代码来调整这个网格。这样会大大加快绘制的速度。这种方法和通常被开发者们弃用的openGL的immediate模式比较类似。同时,作者不推荐使用 3D ModelView的矩阵。在编写 Istrolid时, 他仅仅将一个视点的矩形传递给了着色器。因此这款游戏是完全基于2D引擎的。纹理对象也很简单,而且和网格对象一样是动态的。在一个区域或者地形上绘制图片时,游戏程序会加载这个纹理对象并将它放到一个实时打包的纹理地图集中。之后程序会根据新的UI坐标系来创建网格对象。作者对着色器的操作也很简单。他将所有的颜色都转换到了HSV颜色空间中以便于进行颜色的调整。Coffee ScriptJavaScript快得难以置信。作者原本利用Panda3d和Python来编写却发现Python并不能满足他对速度的需求。他认为不断发展壮大的JavaScript在满足他对速度的追求的同时还能实现更多的功能。他使用CoffeeScript来编写整个游戏并非常喜爱它的缩进排版和箭头标识符。特别令他印象深刻的一点是箭头标识符可以非常快速的创建内联函数。他利用自己三年前编写的基于HTML的编辑器在服务器上编写代码。这样的好处是他可以通过访问编辑器的URL来在任意一台电脑上开始他的开发工作。他用过Windows、Mac和ChromeOS并非常支持ChromeOS的云理念。WebSocket和服务器作者利用CoffeeScript来编写服务器端程序并用Node.js来运行。他希望这款游戏能够同时支持单人模式和多人模式。当玩家进行单人模式游戏时会开启一个本地服务器。程序通过一个伪WebSocket来连接到本地服务器。这样的好处是可以在一个真实的网络环境中来测试代码,从而简化调试的过程。所有的调试和单步调试都在一个进程中完成。另外,他还可以在这个伪WebSocket中设置网络延时和抖动来模拟复杂的网络环境。在开发即时战略类游戏时,开发者通常会选择锁步(Lock Step)方法。但是 Istrolid得作者并没有这么做。他认为锁步已经过时,不易于编写(尤其是用JavaScript编写时)。而且在这个个人电脑普遍拥有高带宽的时代,锁步的优势已不再明显。他采用delta编码方式,并仅将变动的数据从服务器传给每个玩家的服务器上。AudioContext浏览器的音频播放能力已经改善许多。作者通过过程生成技术来创建背景音乐,并创建一个随着游戏的进行动态响应的鼓。当一个单位被集中或者爆炸时他会提高这个鼓的音量。他将每一个武器开火时的声音的音量设定成一个随机数以保证每一个武器的声音都有差别,尽管这个差别很细微。除非要开发一个音乐游戏否则作者不推荐在这方面花太多时间。HTML UI如果游戏中的UI非常多的话,那么完全靠自己用代码来实现就会非常困难。这时就需要一些些复杂的UI框架来进行辅助。对于HTML5游戏来说,无需使用复杂的工具包即可实现复杂的UI效果。作者还利用HTML5的特性自己设计了一个响应式框架从而简化UI的编写过程。Electorn “Shell”如今将HTML5游戏编译成适合于Windows、Mac或Linux的桌面应用程序非常容易。Istrolid的作者非常推荐那些因为插件拓展、浏览器过时或者驱动故障等问题头疼的开发者尝试一下Electron。同时这也为把你的游戏发布到类似Steam这样需要提供可下载文件的游戏平台创造了可能。
贴吧热议榜
使用签名档&&
保存至快速回贴

我要回帖

更多关于 4399葫芦娃html5礼包 的文章

 

随机推荐