WEBGL学习【十】运动模型
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>LWEBGL6.2, Animated WebGL Scene with Key Input.</title>
<script src="./lib/webgl-debug.js"></script>
<script src="./lib/glMatrix.js"></script>
<script src="./lib/webgl-utils.js"></script> <meta charset="utf-8"> <script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoordinates; uniform mat4 uMVMatrix;
uniform mat4 uPMatrix; varying vec2 vTextureCoordinates; void main() {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoordinates = aTextureCoordinates;
}
</script> <script id="shader-fs" type="x-shader/x-fragment">
precision mediump float; varying vec2 vTextureCoordinates;
uniform sampler2D uSampler;
void main() {
gl_FragColor = texture2D(uSampler, vTextureCoordinates);
}
</script> <script type="text/javascript">
// globals
var gl;
var pwgl = {};
// Keep track of ongoing image loads to be able to handle lost context
pwgl.ongoingImageLoads = [];
// Keep track of pressed down keys in a list
pwgl.listOfPressedKeys = [];
var canvas; function createGLContext(canvas) {
var names = ["webgl", "experimental-webgl"];
var context = null;
for (var i=0; i < names.length; i++) {
try {
context = canvas.getContext(names[i]);
} catch(e) {}
if (context) {
break;
}
}
if (context) {
context.viewportWidth = canvas.width;
context.viewportHeight = canvas.height;
} else {
alert("Failed to create WebGL context!");
}
return context;
} function loadShaderFromDOM(id) {
var shaderScript = document.getElementById(id); // If we don't find an element with the specified id
// we do an early exit
if (!shaderScript) {
return null;
} // Loop through the children for the found DOM element and
// build up the shader source code as a string
var shaderSource = "";
var currentChild = shaderScript.firstChild;
while (currentChild) {
if (currentChild.nodeType == 3) { // 3 corresponds to TEXT_NODE
shaderSource += currentChild.textContent;
}
currentChild = currentChild.nextSibling;
} var shader;
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 null;
} gl.shaderSource(shader, shaderSource);
gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS) &&
!gl.isContextLost()) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
} function setupShaders() {
var vertexShader = loadShaderFromDOM("shader-vs");
var fragmentShader = loadShaderFromDOM("shader-fs"); var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS) &&
!gl.isContextLost()) {
alert("Failed to link shaders: " + gl.getProgramInfoLog(shaderProgram));
} gl.useProgram(shaderProgram); pwgl.vertexPositionAttributeLoc =
gl.getAttribLocation(shaderProgram, "aVertexPosition");
pwgl.vertexTextureAttributeLoc =
gl.getAttribLocation(shaderProgram, "aTextureCoordinates");
pwgl.uniformMVMatrixLoc =
gl.getUniformLocation(shaderProgram, "uMVMatrix");
pwgl.uniformProjMatrixLoc =
gl.getUniformLocation(shaderProgram, "uPMatrix");
pwgl.uniformSamplerLoc =
gl.getUniformLocation(shaderProgram, "uSampler"); gl.enableVertexAttribArray(pwgl.vertexPositionAttributeLoc);
gl.enableVertexAttribArray(pwgl.vertexTextureAttributeLoc); //创建模型视图投影矩阵
pwgl.modelViewMatrix = mat4.create();
pwgl.projectionMatrix = mat4.create();
pwgl.modelViewMatrixStack = [];
} function pushModelViewMatrix() {
var copyToPush = mat4.create(pwgl.modelViewMatrix);
pwgl.modelViewMatrixStack.push(copyToPush);
} function popModelViewMatrix() {
if (pwgl.modelViewMatrixStack.length == 0) {
throw "Error popModelViewMatrix() - Stack was empty ";
}
pwgl.modelViewMatrix = pwgl.modelViewMatrixStack.pop();
} function setupFloorBuffers() {
pwgl.floorVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pwgl.floorVertexPositionBuffer); var floorVertexPosition = [
// Plane in y=0
5.0, 0.0, 5.0, //v0
5.0, 0.0, -5.0, //v1
-5.0, 0.0, -5.0, //v2
-5.0, 0.0, 5.0]; //v3 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(floorVertexPosition),
gl.STATIC_DRAW); pwgl.FLOOR_VERTEX_POS_BUF_ITEM_SIZE = 3;
pwgl.FLOOR_VERTEX_POS_BUF_NUM_ITEMS = 4; pwgl.floorVertexTextureCoordinateBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pwgl.floorVertexTextureCoordinateBuffer);
var floorVertexTextureCoordinates = [
2.0, 0.0,
2.0, 2.0,
0.0, 2.0,
0.0, 0.0
]; gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array(floorVertexTextureCoordinates),
gl.STATIC_DRAW); pwgl.FLOOR_VERTEX_TEX_COORD_BUF_ITEM_SIZE = 2;
pwgl.FLOOR_VERTEX_TEX_COORD_BUF_NUM_ITEMS = 4; pwgl.floorVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, pwgl.floorVertexIndexBuffer);
var floorVertexIndices = [0, 1, 2, 3]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(floorVertexIndices),
gl.STATIC_DRAW); pwgl.FLOOR_VERTEX_INDEX_BUF_ITEM_SIZE = 1;
pwgl.FLOOR_VERTEX_INDEX_BUF_NUM_ITEMS = 4;
} function setupCubeBuffers() {
pwgl.cubeVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pwgl.cubeVertexPositionBuffer); var cubeVertexPosition = [
// Front face
1.0, 1.0, 1.0, //v0
-1.0, 1.0, 1.0, //v1
-1.0, -1.0, 1.0, //v2
1.0, -1.0, 1.0, //v3 // Back face
1.0, 1.0, -1.0, //v4
-1.0, 1.0, -1.0, //v5
-1.0, -1.0, -1.0, //v6
1.0, -1.0, -1.0, //v7 // Left face
-1.0, 1.0, 1.0, //v8
-1.0, 1.0, -1.0, //v9
-1.0, -1.0, -1.0, //v10
-1.0, -1.0, 1.0, //v11 // Right face
1.0, 1.0, 1.0, //12
1.0, -1.0, 1.0, //13
1.0, -1.0, -1.0, //14
1.0, 1.0, -1.0, //15 // Top face
1.0, 1.0, 1.0, //v16
1.0, 1.0, -1.0, //v17
-1.0, 1.0, -1.0, //v18
-1.0, 1.0, 1.0, //v19 // Bottom face
1.0, -1.0, 1.0, //v20
1.0, -1.0, -1.0, //v21
-1.0, -1.0, -1.0, //v22
-1.0, -1.0, 1.0, //v23
]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeVertexPosition),
gl.STATIC_DRAW); pwgl.CUBE_VERTEX_POS_BUF_ITEM_SIZE = 3;
pwgl.CUBE_VERTEX_POS_BUF_NUM_ITEMS = 24; // Setup buffer with texture coordinates
pwgl.cubeVertexTextureCoordinateBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pwgl.cubeVertexTextureCoordinateBuffer);
var textureCoordinates = [
//Front face
0.0, 0.0, //v0
1.0, 0.0, //v1
1.0, 1.0, //v2
0.0, 1.0, //v3 // Back face
0.0, 1.0, //v4
1.0, 1.0, //v5
1.0, 0.0, //v6
0.0, 0.0, //v7 // Left face
0.0, 1.0, //v8
1.0, 1.0, //v9
1.0, 0.0, //v10
0.0, 0.0, //v11 // Right face
0.0, 1.0, //v12
1.0, 1.0, //v13
1.0, 0.0, //v14
0.0, 0.0, //v15 // Top face
0.0, 1.0, //v16
1.0, 1.0, //v17
1.0, 0.0, //v18
0.0, 0.0, //v19 // Bottom face
0.0, 1.0, //v20
1.0, 1.0, //v21
1.0, 0.0, //v22
0.0, 0.0, //v23
]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates),
gl.STATIC_DRAW);
pwgl.CUBE_VERTEX_TEX_COORD_BUF_ITEM_SIZE = 2;
pwgl.CUBE_VERTEX_TEX_COORD_BUF_NUM_ITEMS = 24; pwgl.cubeVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, pwgl.cubeVertexIndexBuffer);
var cubeVertexIndices = [
0, 1, 2, 0, 2, 3, // Front face
4, 6, 5, 4, 7, 6, // Back face
8, 9, 10, 8, 10, 11, // Left face
12, 13, 14, 12, 14, 15, // Right face
16, 17, 18, 16, 18, 19, // Top face
20, 22, 21, 20, 23, 22 // Bottom face
];
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices),
gl.STATIC_DRAW);
pwgl.CUBE_VERTEX_INDEX_BUF_ITEM_SIZE = 1;
pwgl.CUBE_VERTEX_INDEX_BUF_NUM_ITEMS = 36;
} function textureFinishedLoading(image, 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,
image); gl.generateMipmap(gl.TEXTURE_2D); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);
gl.bindTexture(gl.TEXTURE_2D, null);
} function loadImageForTexture(url, texture) {
var image = new Image();
image.onload = function() {
pwgl.ongoingImageLoads.splice(pwgl.ongoingImageLoads.indexOf(image), 1);
textureFinishedLoading(image, texture);
}
pwgl.ongoingImageLoads.push(image);
image.src = url;
} function setupTextures() {
// Texture for the table
pwgl.woodTexture = gl.createTexture();
loadImageForTexture("./resources/wood_128x128.jpg", pwgl.woodTexture); // Texture for the floor
pwgl.groundTexture = gl.createTexture();
loadImageForTexture("./resources/wood_floor_256.jpg", pwgl.groundTexture); // Texture for the box on the table
pwgl.boxTexture = gl.createTexture();
loadImageForTexture("./resources/wicker_256.jpg", pwgl.boxTexture); //创建一个立方体
pwgl.colorCube = gl.createTexture();
loadImageForTexture("./resources/xiuxiuba.bmp", pwgl.colorCube);
} function setupBuffers() {
setupFloorBuffers();
setupCubeBuffers();
} function uploadModelViewMatrixToShader() {
gl.uniformMatrix4fv(pwgl.uniformMVMatrixLoc, false, pwgl.modelViewMatrix);
} function uploadProjectionMatrixToShader() {
gl.uniformMatrix4fv(pwgl.uniformProjMatrixLoc,
false, pwgl.projectionMatrix);
} function drawFloor() {
// Bind position buffer
gl.bindBuffer(gl.ARRAY_BUFFER, pwgl.floorVertexPositionBuffer);
gl.vertexAttribPointer(pwgl.vertexPositionAttributeLoc,
pwgl.FLOOR_VERTEX_POS_BUF_ITEM_SIZE,
gl.FLOAT, false, 0, 0); // Bind texture coordinate buffer
gl.bindBuffer(gl.ARRAY_BUFFER, pwgl.floorVertexTextureCoordinateBuffer);
gl.vertexAttribPointer(pwgl.vertexTextureAttributeLoc,
pwgl.FLOOR_VERTEX_TEX_COORD_BUF_ITEM_SIZE,
gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, pwgl.groundTexture); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, pwgl.floorVertexIndexBuffer);
gl.drawElements(gl.TRIANGLE_FAN, pwgl.FLOOR_VERTEX_INDEX_BUF_NUM_ITEMS,
gl.UNSIGNED_SHORT, 0);
} function drawCube(texture) {
// Bind position buffer
gl.bindBuffer(gl.ARRAY_BUFFER, pwgl.cubeVertexPositionBuffer);
gl.vertexAttribPointer(pwgl.vertexPositionAttributeLoc,
pwgl.CUBE_VERTEX_POS_BUF_ITEM_SIZE,
gl.FLOAT, false, 0, 0); // bind texture coordinate buffer
gl.bindBuffer(gl.ARRAY_BUFFER, pwgl.cubeVertexTextureCoordinateBuffer);
gl.vertexAttribPointer(pwgl.vertexTextureAttributeLoc,
pwgl.CUBE_VERTEX_TEX_COORD_BUF_ITEM_SIZE,
gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture); // Bind index buffer and draw cube
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, pwgl.cubeVertexIndexBuffer); gl.drawElements(gl.TRIANGLES, pwgl.CUBE_VERTEX_INDEX_BUF_NUM_ITEMS,
gl.UNSIGNED_SHORT, 0);
} function drawTable(){
// Draw a simple table by modifying the modelview matrix
// (translate and scale) and then use the function drawCube()
// to draw a table top and four table legs. pushModelViewMatrix();
mat4.translate(pwgl.modelViewMatrix, [0.0, 1.0, 0.0], pwgl.modelViewMatrix);
mat4.scale(pwgl.modelViewMatrix, [2.0, 0.1, 2.0], pwgl.modelViewMatrix);
uploadModelViewMatrixToShader();
// Draw the actual cube (now scaled to a cuboid) with woodTexture
drawCube(pwgl.woodTexture);
popModelViewMatrix(); // Draw the table legs
for (var i=-1; i<=1; i+=2) {
for (var j= -1; j<=1; j+=2) {
pushModelViewMatrix();
mat4.translate(pwgl.modelViewMatrix, [i*1.9, -0.1, j*1.9],
pwgl.modelViewMatrix);
mat4.scale(pwgl.modelViewMatrix, [0.1, 1.0, 0.1],
pwgl.modelViewMatrix);
uploadModelViewMatrixToShader();
drawCube(pwgl.woodTexture);
popModelViewMatrix();
}
}
} /*pwgl.fps = 0;
pwgl.lastTime = 0;
pwgl.frameCount = 0;*/ function update_fps() {
++pwgl.frameCount; var curTime = Date.now();
if (curTime - pwgl.lastTime > 1000) // 取固定时间间隔为1秒
{
pwgl.fps = pwgl.frameCount;
pwgl.frameCount = 0;
pwgl.lastTime = curTime;
}
return pwgl.fps;
} function draw(currentTime) {
/*if (pwgl.y < 2) {
// First move the box vertically from its original position on top of
// the table (where y = 2.7) to 5 units above the floor (y = 5).
// Let this movement take 3 seconds
pwgl.y = 2.7 + (currentTime - pwgl.animationStartTime)/3000 * (5.0-2.7); //NAN(不是一个数字)
pwgl.y = 2.7+1;
//document.writeln(pwgl.y.toString());
//pwgl.y = Math.random()*0.8;
}
else {
// Then move the box in a circle where one revolution takes 2 seconds
pwgl.angle = (currentTime - pwgl.animationStartTime)/
2000*2*Math.PI % (2*Math.PI); pwgl.x = Math.cos(pwgl.angle) * pwgl.circleRadius;
pwgl.z = Math.sin(pwgl.angle) * pwgl.circleRadius;
//document.writeln(pwgl.x+" "+pwgl.z);
}*/ update_fps(); //重复绘制
pwgl.requestId = requestAnimFrame(draw);
if (currentTime === undefined) {
currentTime = Date.now();
//document.writeln(currentTime+' '+new Date().getTime()); 两种获取时间的方法是等价的
} handlePressedDownKeys();
pwgl.yRot += 0.01; // Update FPS if a second or more has passed since last FPS update
if(currentTime - pwgl.previousFrameTimeStamp >= 0) {
//pwgl.fpsCounter.innerHTML = pwgl.nbrOfFramesForFPS;
//pwgl.fpsCounter.innerHTML = "<a href=''>12212</a>"; pwgl.nbrOfFramesForFPS = 0;
pwgl.previousFrameTimeStamp = currentTime;
}
//pwgl.fpsCounter.innerHTML = "<a href=''>12212</a>";
//计算我的当前的FPS
pwgl.fpsCounter.innerHTML = pwgl.fps; gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.perspective(60, gl.viewportWidth / gl.viewportHeight,
1, 100.0, pwgl.projectionMatrix);
mat4.identity(pwgl.modelViewMatrix);
mat4.lookAt([8, 5, 10],[0, 0, 0], [0, 1,0], pwgl.modelViewMatrix); //让场景动起来
mat4.rotateY(pwgl.modelViewMatrix, pwgl.yRot,pwgl.modelViewMatrix);
/* mat4.translate(pwgl.modelViewMatrix,
[pwgl.x, pwgl.y, pwgl.z], pwgl.modelViewMatrix);*/
uploadModelViewMatrixToShader();
uploadProjectionMatrixToShader();
gl.uniform1i(pwgl.uniformSamplerLoc, 0); drawFloor(); // Draw table
pushModelViewMatrix();
mat4.translate(pwgl.modelViewMatrix, [0.0, 1.1, 0.0], pwgl.modelViewMatrix);
uploadModelViewMatrixToShader();
drawTable();
popModelViewMatrix(); pushModelViewMatrix();
mat4.translate(pwgl.modelViewMatrix,
[0, 2.7, 0], pwgl.modelViewMatrix);
mat4.scale(pwgl.modelViewMatrix, [0.5, 0.5, 0.5], pwgl.modelViewMatrix);
uploadModelViewMatrixToShader();
drawCube(pwgl.colorCube);
popModelViewMatrix(); // Calculate the position for the box that is initially
// on top of the table but will then be moved during animation
pushModelViewMatrix();
if (currentTime === undefined) {
currentTime = Date.now();
}
if (pwgl.animationStartTime === undefined) {
pwgl.animationStartTime = currentTime;
} //让桌子上面的立方体飘起来哈
// Update the position of the box
if (pwgl.y < 5) {
// First move the box vertically from its original position on top of
// the table (where y = 2.7) to 5 units above the floor (y = 5).
// Let this movement take 3 seconds
//pwgl.y = 2.7 + (currentTime - pwgl.animationStartTime)/3000 * (5.0-2.7);
pwgl.y = 2.7+3;
}
else {
// Then move the box in a circle where one revolution takes 2 seconds
pwgl.angle = (currentTime - pwgl.animationStartTime)/
2000*2*Math.PI % (2*Math.PI); pwgl.x = Math.cos(pwgl.angle) * pwgl.circleRadius;
pwgl.z = Math.sin(pwgl.angle) * pwgl.circleRadius;
} /*var num = (currentTime - pwgl.animationStartTime)/3000 * (5.0-2.7);
//document.writeln(pwgl.y);////2.7
//document.writeln("num="+num.toString());
pwgl.y = 2.7 + (currentTime - pwgl.animationStartTime)/3000 * (5.0-2.7);
//document.writeln("pwgl"+pwgl.y.toString());
pwgl.angle = (currentTime - pwgl.animationStartTime)/
2000*2*Math.PI % (2*Math.PI);*/
//document.writeln("pwgl.angle"+pwgl.angle); //移动我的这个盒子
mat4.translate(pwgl.modelViewMatrix,
[pwgl.x, pwgl.y, pwgl.z], pwgl.modelViewMatrix);
mat4.scale(pwgl.modelViewMatrix, [0.5, 0.5, 0.5], pwgl.modelViewMatrix);
uploadModelViewMatrixToShader();
drawCube(pwgl.boxTexture);
popModelViewMatrix(); /* mat4.translate(pwgl.modelViewMatrix,
[0, 2.7, 0], pwgl.modelViewMatrix);
mat4.scale(pwgl.modelViewMatrix, [0.5, 0.5, 0.5], pwgl.modelViewMatrix);
uploadModelViewMatrixToShader();
drawCube(pwgl.boxTexture);
popModelViewMatrix();*/ // Update number of drawn frames to be able to count fps
pwgl.nbrOfFramesForFPS++;
} function handleContextLost(event) {
event.preventDefault();
cancelRequestAnimFrame(pwgl.requestId); // Ignore all ongoing image loads by removing
// their onload handler
for (var i = 0; i < pwgl.ongoingImageLoads.length; i++) {
//丢失的上下文就忽略
pwgl.ongoingImageLoads[i].onload = undefined;
}
pwgl.ongoingImageLoads = [];
} function init() {
// Initialization that is performed during first startup and when the
// event webglcontextrestored is received is included in this function.
setupShaders();
setupBuffers();
setupTextures();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST); // Initialize some varibles for the moving box
pwgl.x = 0.0;
pwgl.y = 2.7;
pwgl.z = 0.0;
pwgl.circleRadius = 4.0;
pwgl.angle = 0; pwgl.fps = 0;
pwgl.lastTime = 0;
pwgl.frameCount = 0; pwgl.yRot = 0;
// Initialize some variables related to the animation
pwgl.animationStartTime = undefined;
pwgl.nbrOfFramesForFPS = 0;
pwgl.previousFrameTimeStamp = Date.now();
} //上下文回复后就重新初始化变量,并且启动动画
function handleContextRestored(event) {
init();
pwgl.requestId = requestAnimFrame(draw,canvas);
} function handleKeyDown(event) {
pwgl.listOfPressedKeys[event.keyCode] = true; // If you want to have a log for keydown you can uncomment the two lines below.
// console.log("keydown - keyCode=%d, charCode=%d",
// event.keyCode, event.charCode);
} function handleKeyUp(event) {
pwgl.listOfPressedKeys[event.keyCode] = false; // If you want to have a log for keyup you can uncomment the two lines below.
// console.log("keyup - keyCode=%d, charCode=%d",
// event.keyCode, event.charCode);
} function handleKeyPress(event) {
// If you want to have a log for keypress you can uncomment the two lines below.
// console.log("keypress - keyCode=%d, charCode=%d",
// event.keyCode, event.charCode);
} function handlePressedDownKeys() {
if (pwgl.listOfPressedKeys[38]) {
// Arrow up, increase radius of circle
pwgl.circleRadius += 0.1;
}
if (pwgl.listOfPressedKeys[40]) {
// Arrow down, decrease radius of circle
pwgl.circleRadius -= 0.1;
if (pwgl.circleRadius < 0) {
pwgl.circleRadius = 0;
}
}
} function handleMouseMove(event) {
// If you want to test mousemove you can uncomment the two lines below.
// console.log("handleMouseMove, clientX=%d, clientY=%d",
// event.clientX, event.clientY);
} function handleMouseDown(event) {
// If you want to test mousedown you can uncomment the two lines below.
// console.log("handleDown, clientX=%d, clientY=%d, button=%d",
// event.clientX, event.clientY, event.button);
} function handleMouseUp(event) {
// If you want to test mouseup you can uncomment the two lines below.
// console.log("handleMouseUp, clientX=%d, clientY=%d, button=%d",
// event.clientX, event.clientY, event.button); } function startup() {
canvas = document.getElementById("myGLCanvas");
canvas = WebGLDebugUtils.makeLostContextSimulatingContext(canvas); canvas.addEventListener('webglcontextlost', handleContextLost, false);
canvas.addEventListener('webglcontextrestored', handleContextRestored, false);
document.addEventListener('keydown', handleKeyDown, false);
document.addEventListener('keyup', handleKeyUp, false);
document.addEventListener('keypress', handleKeyPress, false);
document.addEventListener('mousemove', handleMouseMove, false);
document.addEventListener('mousedown', handleMouseDown, false);
document.addEventListener('mouseup', handleMouseUp, false); gl = createGLContext(canvas);
init(); pwgl.fpsCounter = document.getElementById("fps"); //Uncomment the three lines of code below to be able to test lost context
/*window.addEventListener('mousedown', function() {
canvas.loseContext();
});*/ // Draw the complete scene
draw();
}
</script> </head> <body onload="startup();">
<canvas id="myGLCanvas" width="500" height="500"></canvas>
<div id="fps-counter">
FPS: <span id="fps">--</span>
</div>
</body> </html>
WEBGL学习【十】运动模型的更多相关文章
- WebGL学习之纹理贴图
为了使图形能获得接近于真实物体的材质效果,一般会使用贴图,贴图类型主要包括两种:漫反射贴图和镜面高光贴图.其中漫反射贴图可以同时实现漫反射光和环境光的效果. 实际效果请看demo:纹理贴图 2D纹理 ...
- WebGL学习(1) - 三角形
原文地址:WebGL学习(1) - 三角形 还记得第一次看到canvas的粒子特效的时候,真的把我给惊艳到了,原来在浏览器也能做出这么棒的效果.结合<HTML5 Canvas核心技术>和网 ...
- WebGL学习(2) - 3D场景
原文地址:WebGL学习(2) - 3D场景 经过前面WebGL学习(1) - 三角形的学习,我们已经掌握了webGL的基础知识,也已经能够画出最基本的图形,比如点,线,三角形,矩形等.有了2D绘图的 ...
- WebGL学习(3) - 3D模型
原文地址:WebGL学习(3) - 3D模型 相信很多人是以创建逼真酷炫的三维效果为目标而学习webGL的吧,首先我就是
- 强化学习(十九) AlphaGo Zero强化学习原理
在强化学习(十八) 基于模拟的搜索与蒙特卡罗树搜索(MCTS)中,我们讨论了MCTS的原理和在棋类中的基本应用.这里我们在前一节MCTS的基础上,讨论下DeepMind的AlphaGo Zero强化学 ...
- 强化学习(十六) 深度确定性策略梯度(DDPG)
在强化学习(十五) A3C中,我们讨论了使用多线程的方法来解决Actor-Critic难收敛的问题,今天我们不使用多线程,而是使用和DDQN类似的方法:即经验回放和双网络的方法来改进Actor-Cri ...
- 强化学习(十五) A3C
在强化学习(十四) Actor-Critic中,我们讨论了Actor-Critic的算法流程,但是由于普通的Actor-Critic算法难以收敛,需要一些其他的优化.而Asynchronous Adv ...
- 强化学习(十四) Actor-Critic
在强化学习(十三) 策略梯度(Policy Gradient)中,我们讲到了基于策略(Policy Based)的强化学习方法的基本思路,并讨论了蒙特卡罗策略梯度reinforce算法.但是由于该算法 ...
- 对比深度学习十大框架:TensorFlow 并非最好?
http://www.oschina.net/news/80593/deep-learning-frameworks-a-review-before-finishing-2016 TensorFlow ...
- webgl学习笔记五-纹理
写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...
随机推荐
- mongodb--作为windows服务启动
注意需要以管理员权限运行CMD
- [bzoj2131]免费的馅饼_树状数组
免费的馅饼 bzoj-2131 题目大意: 注释:$1\le n \le 10^5$,$1\le w \le 10^8$. 想法:首先,想到dp 状态:dp[i][j]表示i分钟在位置j的最大收益 优 ...
- [bzoj1500][NOI2005]维修数列_非旋转Treap
维修数列 bzoj-1500 NOI-2005 题目大意:给定n个数,m个操作,支持:在指定位置插入一段数:删除一个数:区间修改:区间翻转.查询:区间和:全局最大子序列. 注释:$1\le n_{ma ...
- HDU 3007
基本小圆覆盖模板题 #include <iostream> #include <algorithm> #include <cmath> using namespac ...
- 19 个必须知道的 VS 快捷键
本文将为大家列出在Visual Studio中常用的快捷键,正确熟练地使用快捷键,将大大提高你的编程工作效率. 项目相关的快捷键 Ctrl + Shift + B = 生成项目 Ctrl + Alt ...
- hdoj 1518 Square 【dfs】
题意:给出n个(不同长度的)棍子,问能不能将他们构成一个正方形. 策略:深搜. hdoj 1455的简化版 代码: #include <stdio.h> #include <stri ...
- Tomcat容器 web.xml具体解释
<init-param> <param-name>debug</param-name> <param-value>0</param-value&g ...
- 实战Java内存泄漏问题分析 -- hazelcast2.0.3使用时内存泄漏 -- 2
hazelcast 提供了3中方法调用startCleanup: 第一种是在ConcuurentMapManager的构造函数中,通过调用node的executorManager中的Scheduled ...
- svn代码回滚命令【转】
本文转载自:http://www.cnblogs.com/jndream/archive/2012/03/20/2407955.html 取消对代码的修改分为两种情况: 第一种情况:改动没有被提交 ...
- [JavaEE] DWR框架实现Ajax
Ajax是时下比较流行的一种web界面设计新思路,其核心思想是从浏览器获取XMLHttp对象与服务器端进行交互. DWR(Direct Web Remoting)就是实现了这种Ajax技术的一种web ...