webgl原生实现-球体纹理旋转平移以及镜像功能(有内存泄露问题后续完善)

 

 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="../lib/webgl-utils.js"></script>
        <script src="../lib/webgl-debug.js"></script>
        <script src="../lib/cuon-utils.js"></script>
        <script src="../lib/cuon-matrix.js"></script>
	</head>
	<body>
		
		<canvas id="webgl" width="600" height="600">
	      Please use a browser that supports "canvas"
	    </canvas>
		
		<script type="application/javascript">
		
		       var VSHADER_MONITOR =
				  'attribute vec4 a_Position;\n' +
				   //  'attribute vec4 a_Color;\n' + // Defined constant in main()
				  'attribute vec4 a_Normal;\n' +
				   'uniform mat4 u_ModelMatrix;\n' +
				  'uniform mat4 u_ViewMatrix;\n' +
				  'uniform mat4 u_ProjMatrix;\n' +
				  'uniform mat4 u_NormalMatrix;\n' +   // Transformation matrix of the normal
				  'varying vec3 v_Normal;\n' +
				  'varying vec3 v_Position;\n' +
				  'void main() {\n' +
				  '  gl_Position = u_ProjMatrix * u_ViewMatrix * u_ModelMatrix  * a_Position;\n' +
				     // Calculate the vertex position in the world coordinate
				  '  v_Position = vec3(u_ModelMatrix * a_Position);\n' +
				  '  v_Normal = normalize(vec3(u_NormalMatrix * a_Normal));\n' +
				  '}\n';
			
			 // Fragment shader program
			 var FSHADER_MONITOR =
				  'precision mediump float;\n' +
				  'uniform vec3 u_LightColor;\n' +     // Light color
				  'uniform vec3 u_LightPosition;\n' +  // Position of the light source
				  'uniform vec3 u_AmbientLight;\n' +   // Ambient light color
				  'varying vec3 v_Normal;\n' +
				  'varying vec3 v_Position;\n' +
				  'void main() {\n' +
				     // Normalize the normal because it is interpolated and not 1.0 in length any more
				  '  vec3 normal = normalize(v_Normal);\n' +
				     // Calculate the light direction and make it 1.0 in length
				  '  vec3 lightDirection = normalize(u_LightPosition - v_Position);\n' +
				     // The dot product of the light direction and the normal
				  '  float nDotL = max(dot(lightDirection, normal), 0.0);\n' +
				     // Calculate the final color from diffuse reflection and ambient reflection
				  '  vec4 texColor = vec4(1,1,1,1.0);\n' +
				  '  vec3 diffuse = u_LightColor * texColor.rgb * nDotL;\n' +
				  '  vec3 ambient = u_AmbientLight * texColor.rgb;\n' +
                  '  gl_FragColor = vec4(diffuse + ambient, 1);\n' +
				   //'  gl_FragColor = vec4(visibility,0.0,0.0,1.0);\n' +
				  '}\n'; 
			  
			  
			  var VSHADER_SOURCE_DQ =
				  'attribute vec4 a_Position;\n' +
				  'attribute vec2 a_TexCoord;\n' +
                  'varying vec2 v_TexCoord;\n' +
				   //  'attribute vec4 a_Color;\n' + // Defined constant in main()
				  'attribute vec4 a_Normal;\n' +
				   'uniform mat4 u_ModelMatrix;\n' +
				  'uniform mat4 u_ViewMatrix;\n' +
				  'uniform mat4 u_ProjMatrix;\n' +
				  'uniform mat4 u_NormalMatrix;\n' +   // Transformation matrix of the normal
				  'varying vec3 v_Normal;\n' +
				  'varying vec3 v_Position;\n' +
				  'void main() {\n' +
				  '  v_TexCoord = a_TexCoord;\n' +
				  '  gl_Position = u_ProjMatrix * u_ViewMatrix * u_ModelMatrix  * a_Position;\n' +
				     // Calculate the vertex position in the world coordinate
				  '  v_Position = vec3(u_ModelMatrix * a_Position);\n' +
				  '  v_Normal = normalize(vec3(u_NormalMatrix * a_Normal));\n' +
				  '}\n';
			
			 // Fragment shader program
			 var FSHADER_SOURCE_DQ =
				  'precision mediump float;\n' +
				  'uniform vec3 u_LightColor;\n' +     // Light color
				  'uniform vec3 u_LightPosition;\n' +  // Position of the light source
				  'uniform vec3 u_AmbientLight;\n' +   // Ambient light color
				  'varying vec3 v_Normal;\n' +
				  'varying vec3 v_Position;\n' +
				  'varying vec2 v_TexCoord;\n' +
				  'uniform sampler2D u_Sampler;\n' +
				  'void main() {\n' +
				     // Normalize the normal because it is interpolated and not 1.0 in length any more
				  '  vec3 normal = normalize(v_Normal);\n' +
				     // Calculate the light direction and make it 1.0 in length
				  '  vec3 lightDirection = normalize(u_LightPosition - v_Position);\n' +
				     // The dot product of the light direction and the normal
				  '  float nDotL = max(dot(lightDirection, normal), 0.0);\n' +
				     // Calculate the final color from diffuse reflection and ambient reflection
				  '  vec4 texColor = texture2D(u_Sampler, v_TexCoord);\n' +
				  '  vec3 diffuse = u_LightColor * texColor.rgb * nDotL;\n' +
				  '  vec3 ambient = u_AmbientLight * texColor.rgb;\n' +
                  '  gl_FragColor = vec4(diffuse + ambient, 1);\n' +
				   //'  gl_FragColor = vec4(visibility,0.0,0.0,1.0);\n' +
				  '}\n';
		   let movdis = 0;
		   let derection = 1;
		   var currentAngle = 0.0;
		   var g_last = Date.now();
		   var ANGLE_STEP = 45.0;
   		   	      //获取webgl上下文
	       // Get the rendering context for WebGL
	       var canvas = document.getElementById('webgl');
		   var gl = canvas.getContext('webgl',{stencil: true});
		   function animate(angle) {
			  // Calculate the elapsed time
			  var now = Date.now();
			  var elapsed = now - g_last;
			  g_last = now;
			  // Update the current rotation angle (adjusted by the elapsed time)
			  var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;
			  return newAngle %= 360;
			}
		   window.onload = function(){
		   	     //加载地球图片
	             var image = new Image();  // Create the image object
	               // Register the event handler to be called on loading an image
				 image.onload = function(){ 
	         
			     };
			      // Tell the browser to load an image
			     image.src = 'earth1.png';
			     setTimeout(function(){
			        window.renderCanvas(image)
			     }, 1000)
			     setTimeout(function(){
			     	setInterval(function () {
			          window.renderCanvas(image);
			          currentAngle = animate(currentAngle);
			        }, 100);
			     }, 2000)
		   }
		   function drawMonitor(){
		   	      var shadowProgram_dq = createProgram(gl, VSHADER_MONITOR, FSHADER_MONITOR);
	              gl.useProgram(shadowProgram_dq)
			      gl.program = shadowProgram_dq;
		   	      // Get the storage locations of uniform variables and so on
				  var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
				  var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
				  var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
				  var u_NormalMatrix = gl.getUniformLocation(gl.program, 'u_NormalMatrix');
				  var u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');
				  var u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition');
				  var u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight');
				  // Set the light color (white)
				  gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
				  // Set the light direction (in the world cou_MvpMatrixFromLightordinate)
				  gl.uniform3f(u_LightPosition, 3, 3, 8.0);
				  // Set the ambient light
				  gl.uniform3f(u_AmbientLight, 0.2, 0.2, 0.2);
				  var normalMatrix = new Matrix4(); // Transformation matrix for normals	  
				  var modelMatrix = new Matrix4(); // The model matrix
				  var viewMatrix = new Matrix4();  // The view matrix
				  var projMatrix = new Matrix4();  // The projection matrix
				
				  // Calculate the view matrix and the projection matrix
				  modelMatrix.setTranslate(0, 0, 0);   // Translate 0.75 units along the positive x-axis
				  viewMatrix.setLookAt(5.0, 0.0, 28.0, 0, 0, 0, 0, 1, 0);
				  projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
				  // Pass the model, view, and projection matrix to the uniform variable respectively
				  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
				  gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
				  gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
				  normalMatrix.setInverseOf(modelMatrix);
				  normalMatrix.transpose();
				  // Pass the transformation matrix for normals to u_NormalMatrix
				  gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
				  var positions = [0.0,4.0,4.0,0.0,4.0,-4.0,0.0,-4.0,-4.0,0.0,-4.0,4.0];
				  var indices = [0,2,1,0,3,2];
				  var normals = [1.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0]
				  if (!initArrayBuffer(gl, 'a_Normal', new Float32Array(normals), gl.FLOAT, 3))  return -1;
				  if (!initArrayBuffer(gl, 'a_Position', new Float32Array(positions), gl.FLOAT, 3)) return -1;
				  var indexBuffer = gl.createBuffer();
				  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
			      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
				  gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);  
		   }
		   function renderCanvas(image){
		   	      // Specify the color for clearing <canvas>
			      gl.clearColor(0.0, 0.0, 0.0, 1.0);
			      // Clear <canvas>
			      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );  
			      //清除模板缓存
                  gl.clear(gl.STENCIL_BUFFER_BIT);
				  gl.enable(gl.DEPTH_TEST);
				  //开启剪裁测试
				  gl.enable(gl.STENCIL_TEST);
				  //设置模板测试参数
                  gl.stencilFunc(gl.ALWAYS, 1, 1);
                  //设置模板测试后的操作
                  gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); 
				  if (!gl) {
				    console.log('Failed to get the rendering context for WebGL');
				    return;
				  }
			      //画镜子
			      drawMonitor();
			      //禁用深度测试 开启剪裁测试会画出镜像
			      //关闭深度检测
			      gl.disable(gl.DEPTH_TEST);
			      //设置模板测试参数
                  gl.stencilFunc(gl.EQUAL,1, 1); 
                  //设置模板测试后的操作
                  gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);  
                  //开启卷绕
                  gl.enable(gl.CULL_FACE);
				  gl.frontFace(gl.CW);
				  //开启混合
                  gl.enable(gl.BLEND);
		          //设置混合因子
		          gl.blendFunc(gl.SRC_ALPHA, gl.DST_ALPHA);
		          //绘制阴影贴图 用于给地球贴阴影
		          var shadowProgram_dq = createProgram(gl, VSHADER_SOURCE_DQ, FSHADER_SOURCE_DQ);
	              gl.useProgram(shadowProgram_dq)
			      gl.program = shadowProgram_dq;
			      // Set the vertex coordinates, the color and the normal
	              var n = initVertexBuffers2(gl,2);
	              // Get the storage locations of uniform variables and so on
				  var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
				  var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
				  var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
				  var u_NormalMatrix = gl.getUniformLocation(gl.program, 'u_NormalMatrix');
				  var u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');
				  var u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition');
				  var u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight');
				  // Set the light color (white)
				  gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
				  // Set the light direction (in the world cou_MvpMatrixFromLightordinate)
				  gl.uniform3f(u_LightPosition, 3, 3, 8.0);
				  // Set the ambient light
				  gl.uniform3f(u_AmbientLight, 0.2, 0.2, 0.2);
			      //纹理
				  var texture = gl.createTexture();   // Create a texture object
				  var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');
				  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // Flip the image's y axis
				  // Enable texture unit0
				  gl.activeTexture(gl.TEXTURE0);
				  // Bind the texture object to the target
				  gl.bindTexture(gl.TEXTURE_2D, texture);			
				  // Set the texture parameters
				  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
				  // Set the texture image
				  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
				  // Set the texture unit 0 to the sampler
				  gl.uniform1i(u_Sampler, 0);
				  var normalMatrix = new Matrix4(); // Transformation matrix for normals
				  
				  var modelMatrix = new Matrix4(); // The model matrix
				  var viewMatrix = new Matrix4();  // The view matrix
				  var projMatrix = new Matrix4();  // The projection matrix
				  if(movdis > 38){
                    if(derection == 1){
                    	derection = 0
                    }
				  }else if (movdis < -6){
				  	if(derection == 0){
				  		derection = 1
				  	}
				  }
				  if(derection == 1){
				  	movdis +=1;
				  }else{
				  	movdis +=-1;
				  }
				  // Calculate the view matrix and the projection matrix
				  modelMatrix.setTranslate(-3, 0, -1*movdis);   // Translate 0.75 units along the positive x-axis
				  modelMatrix.rotate(currentAngle,0,0,1);
				  viewMatrix.setLookAt(5.0, 0.0, 28.0, 0, 0, 0, 0, 1, 0);
				  projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
				  // Pass the model, view, and projection matrix to the uniform variable respectively
				  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
				  gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
				  gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
				  normalMatrix.setInverseOf(modelMatrix);
				  normalMatrix.transpose();
				  // Pass the transformation matrix for normals to u_NormalMatrix
				  gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
				  // Draw the cube(Note that the 3rd argument is the gl.UNSIGNED_SHORT)
				  //打开背景剪裁
				  //gl.enable(gl.CULL_FACE);
				  //gl.frontFace(gl.CCW);
	              gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);  
	              //设置定点信息
	              var n = initVertexBuffers(gl,2);
	              modelMatrix.setTranslate(3, 0, -1*movdis);   // Translate 0.75 units along the positive x-axis
	              modelMatrix.rotate(-1*currentAngle,0,0,1);
	              gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
	              normalMatrix.setInverseOf(modelMatrix);
				  normalMatrix.transpose();
				  gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
				  //打开背景剪裁
				  gl.enable(gl.DEPTH_TEST);
				  gl.disable(gl.BLEND);
				  gl.disable(gl.STENCIL_TEST);
				  gl.frontFace(gl.CCW);
				  gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);  
		   }
		   function initVertexBuffers2(gl,size,need) {// Create a sphere
		   	  var positions = [];
		      var indices = [];
			  var SPHERE_DIV = 13;
			
			  var i, ai, si, ci;
			  var j, aj, sj, cj;
			  var p1, p2;
			  var textures = [];
			  // Generate coordinates
			  for (j = 0; j <= SPHERE_DIV; j++) {
			    aj = j * Math.PI / SPHERE_DIV;
			    sj = Math.sin(aj);
			    cj = Math.cos(aj);
			    for (i = 0; i <= SPHERE_DIV; i++) {
			      ai = i * 2 * Math.PI / SPHERE_DIV;
			      si = Math.sin(ai);
			      ci = Math.cos(ai);
			      positions.push(-1*size*si * sj);  // X
			      positions.push(size*cj);       // Y
			      positions.push(size*ci * sj);  // Z
			      //设置纹理坐标
			      let heigh = j/SPHERE_DIV
			      let width = i/SPHERE_DIV
			      textures.push(width);
			      textures.push(heigh);
			    }
			  }
			
			  // Generate indices
			  for (j = 0; j < SPHERE_DIV; j++) {
			    for (i = 0; i < SPHERE_DIV; i++) {
			      p1 = j * (SPHERE_DIV+1) + i;
			      p2 = p1 + (SPHERE_DIV+1);
			      indices.push(p1);
			      indices.push(p2);
			      indices.push(p1 + 1);
			      indices.push(p1 + 1);
			      indices.push(p2);
			      indices.push(p2 + 1);
			    }
			  }
			
			  // Write the vertex property to buffers (coordinates and normals)
			  // Same data can be used for vertex and normal
			  // In order to make it intelligible, another buffer is prepared separately
			  if (!initArrayBuffer(gl, 'a_Position', new Float32Array(positions), gl.FLOAT, 3)) return -1;
			  if(!need){
			  	 if (!initArrayBuffer(gl, 'a_Normal', new Float32Array(positions), gl.FLOAT, 3))  return -1;
			  	 if (!initArrayBuffer(gl, 'a_TexCoord', new Float32Array(textures), gl.FLOAT, 2))  return -1;
			  }
			  // Unbind the buffer object
			  gl.bindBuffer(gl.ARRAY_BUFFER, null);
			
			  // Write the indices to the buffer object
			  var indexBuffer = gl.createBuffer();
			  if (!indexBuffer) {
			    console.log('Failed to create the buffer object');
			    return -1;
			  }
			  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
			  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
			
			  return indices.length;
			}
		   function initVertexBuffers(gl,size,need) {// Create a sphere
		   	  var positions = [];
		      var indices = [];
			  var SPHERE_DIV = 13;
			
			  var i, ai, si, ci;
			  var j, aj, sj, cj;
			  var p1, p2;
			  var textures = [];
			  // Generate coordinates
			  for (j = 0; j <= SPHERE_DIV; j++) {
			    aj = j * Math.PI / SPHERE_DIV;
			    sj = Math.sin(aj);
			    cj = Math.cos(aj);
			    for (i = 0; i <= SPHERE_DIV; i++) {
			      ai = i * 2 * Math.PI / SPHERE_DIV;
			      si = Math.sin(ai);
			      ci = Math.cos(ai);
			      positions.push(size*si * sj);  // X
			      positions.push(size*cj);       // Y
			      positions.push(size*ci * sj);  // Z
			      //设置纹理坐标
			      let heigh = j/SPHERE_DIV
			      let width = i/SPHERE_DIV
			      textures.push(width);
			      textures.push(heigh);
			    }
			  }
			
			  // Generate indices
			  for (j = 0; j < SPHERE_DIV; j++) {
			    for (i = 0; i < SPHERE_DIV; i++) {
			      p1 = j * (SPHERE_DIV+1) + i;
			      p2 = p1 + (SPHERE_DIV+1);
			      indices.push(p1);
			      indices.push(p2);
			      indices.push(p1 + 1);
			      indices.push(p1 + 1);
			      indices.push(p2);
			      indices.push(p2 + 1);
			    }
			  }
			
			  // Write the vertex property to buffers (coordinates and normals)
			  // Same data can be used for vertex and normal
			  // In order to make it intelligible, another buffer is prepared separately
			  if (!initArrayBuffer(gl, 'a_Position', new Float32Array(positions), gl.FLOAT, 3)) return -1;
			  if(!need){
			  	 if (!initArrayBuffer(gl, 'a_Normal', new Float32Array(positions), gl.FLOAT, 3))  return -1;
			  	 if (!initArrayBuffer(gl, 'a_TexCoord', new Float32Array(textures), gl.FLOAT, 2))  return -1;
			  }
			  // Unbind the buffer object
			  gl.bindBuffer(gl.ARRAY_BUFFER, null);
			
			  // Write the indices to the buffer object
			  var indexBuffer = gl.createBuffer();
			  if (!indexBuffer) {
			    console.log('Failed to create the buffer object');
			    return -1;
			  }
			  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
			  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
			
			  return indices.length;
			}
			
			function initArrayBuffer(gl, attribute, data, type, num) {
			  // Create a buffer object
			  var buffer = gl.createBuffer();
			  if (!buffer) {
			    console.log('Failed to create the buffer object');
			    return false;
			  }
			  // Write date into the buffer object
			  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
			  gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
			  // Assign the buffer object to the attribute variable
			  var a_attribute = gl.getAttribLocation(gl.program, attribute);
			  if (a_attribute < 0) {
			    console.log('Failed to get the storage location of ' + attribute);
			    return false;
			  }
			  gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);
			  // Enable the assignment of the buffer object to the attribute variable
			  gl.enableVertexAttribArray(a_attribute);
			
			  gl.bindBuffer(gl.ARRAY_BUFFER, null);
			
			  return true;
			}
			
			function initFramebufferObject(gl) {
			  var framebuffer, texture, depthBuffer;
			
			  // Define the error handling function
			  var error = function() {
			    if (framebuffer) gl.deleteFramebuffer(framebuffer);
			    if (texture) gl.deleteTexture(texture);
			    if (depthBuffer) gl.deleteRenderbuffer(depthBuffer);
			    return null;
			  }
			
			  // Create a framebuffer object (FBO)
			  framebuffer = gl.createFramebuffer();
			  if (!framebuffer) {
			    console.log('Failed to create frame buffer object');
			    return error();
			  }
			
			  // Create a texture object and set its size and parameters
			  texture = gl.createTexture(); // Create a texture object
			  if (!texture) {
			    console.log('Failed to create texture object');
			    return error();
			  }
			  gl.bindTexture(gl.TEXTURE_2D, texture);
			  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
			  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
			
			  // Create a renderbuffer object and Set its size and parameters
			  depthBuffer = gl.createRenderbuffer(); // Create a renderbuffer object
			  if (!depthBuffer) {
			    console.log('Failed to create renderbuffer object');
			    return error();
			  }
			  gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
			  gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT);
			
			  // Attach the texture and the renderbuffer object to the FBO
			  gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
			  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
			  gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
			
			  // Check if FBO is configured correctly
			  var e = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
			  if (gl.FRAMEBUFFER_COMPLETE !== e) {
			    console.log('Frame buffer object is incomplete: ' + e.toString());
			    return error();
			  }
			
			  framebuffer.texture = texture; // keep the required object
			
			  // Unbind the buffer object
			  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
			  gl.bindTexture(gl.TEXTURE_2D, null);
			  gl.bindRenderbuffer(gl.RENDERBUFFER, null);
			
			  return framebuffer;
			}
		</script>
	</body>
</html>
​

地球纹理图片

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值