代码纯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="1024" height="1024">
Please use a browser that supports "canvas"
</canvas>
<div>helloworld</div>
<script type="application/javascript">
var OFFSCREEN_WIDTH = 1024, OFFSCREEN_HEIGHT = 1024;
//初始化星空
//随机产生 200 个星星 大小是 10 到 20 20个间距
let pointBase = 1
let size = 2
let duansize = 2
var points = []
for(let i = 0 ; i < 50 ; i++){
let point = []
let div = Math.random();
let div1 = Math.random();
let div3 = Math.random();
let divf = div > 0.7?1:-1;
let divf2 = div1 > 0.6?1:-1;
let divf3 = div3 > 0.5?1:-1;
point[0] = divf*div;
point[1] = divf2*div1;
point[2] = divf3*div3-2.9;
point[3] = size + duansize*div;
points = points.concat(point);
}
// Shadow.js (c) 2012 matsuda and tanaka
// Vertex shader program for generating a shadow map
var SHADOW_VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'uniform mat4 u_MvpMatrix;\n' +
'void main() {\n' +
' gl_Position = u_MvpMatrix * a_Position;\n' +
'}\n';
// Fragment shader program for generating a shadow map
var SHADOW_FSHADER_SOURCE =
'precision mediump float;\n' +
'void main() {\n' +
// ' if((gl_FragCoord.z) > 0.9) {\n' + // Radius is 0.5
' gl_FragColor = vec4(gl_FragCoord.z, 0.0, 0.0, 1.0);\n' + // Write the z-value in R
// ' } else { gl_FragColor = vec4(0.0, gl_FragCoord.z/gl_FragCoord.w, 0.0, 1.0); }\n' +
'}\n';
// 星星 顶点着色器
var VSHADER_SOURCE_XX =
'attribute vec4 a_Position;\n' +
'attribute float a_PointSize;\n' +
'uniform mat4 u_ModelMatrix;\n' +
'uniform mat4 u_ViewMatrix;\n' +
'uniform mat4 u_ProjMatrix;\n' +
'varying float v_Dist;\n' +
'void main() {\n' +
' gl_Position = u_ProjMatrix * u_ViewMatrix * u_ModelMatrix * a_Position;\n' +
' gl_PointSize = a_PointSize;\n' +
' v_Dist = gl_Position.w;\n' +
'}\n';
// 星星 片元着色器
var FSHADER_SOURCE_XX =
'precision mediump float;\n' +
'uniform vec3 u_FogColor;\n' + // Color of Fog
'uniform vec2 u_FogDist;\n' + // Distance of Fog (starting point, end point)
'varying float v_Dist;\n' +
'void main() {\n' + // Center coordinate is (0.5, 0.5)
' float d = distance(gl_PointCoord, vec2(0.5, 0.5));\n' +
' if(d < 0.5) {\n' + // Radius is 0.5
// Calculation of fog factor (factor becomes smaller as it goes further away from eye point)
' float fogFactor = (u_FogDist.y - v_Dist) / (u_FogDist.y - u_FogDist.x);\n' +
// Stronger fog as it gets further: u_FogColor * (1 - fogFactor) + v_Color * fogFactor
' vec4 v_Color = vec4(1.0, 1.0, 0.0, 1.0);\n' +
' vec3 color = mix(u_FogColor, vec3(v_Color), clamp(fogFactor, 0.0, 1.0));\n' +
' gl_FragColor = vec4(color, v_Color.a);\n' +
' } else { discard; }\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_MvpMatrix;\n' +
'uniform mat4 u_ModelMatrix;\n' + // Model matrix
'uniform mat4 u_NormalMatrix;\n' + // Transformation matrix of the normal
'varying vec4 v_Color;\n' +
'varying vec3 v_Normal;\n' +
'varying vec3 v_Position;\n' +
'uniform mat4 u_MvpMatrixFromLight;\n' +
'varying vec4 v_PositionFromLight;\n' +
'void main() {\n' +
' v_TexCoord = a_TexCoord;\n' +
' vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\n' + // Sphere color
' gl_Position = u_MvpMatrix * 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' +
' v_Color = color;\n' +
' v_PositionFromLight = u_MvpMatrixFromLight * a_Position;\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 vec4 v_Color;\n' +
'varying vec2 v_TexCoord;\n' +
'uniform sampler2D u_Sampler;\n' +
'uniform sampler2D u_ShadowMap;\n' +
'varying vec4 v_PositionFromLight;\n' +
'void main() {\n' +
' vec3 shadowCoord = (v_PositionFromLight.xyz/v_PositionFromLight.w)/2.0 + 0.5;\n' +
' vec4 rgbaDepth = texture2D(u_ShadowMap, shadowCoord.xy);\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' +
' float depth = rgbaDepth.r;\n' + // Retrieve the z-value from R
' float visibility = (shadowCoord.z > depth + 0.002 ) ? 0.3 : 1.0;\n' +
' gl_FragColor = vec4((diffuse + ambient)* visibility, v_Color.a);\n' +
//' gl_FragColor = vec4(visibility,0.0,0.0,1.0);\n' +
'}\n';
let ANGLE = 0;
let ZANGLE = 0;
//获取webgl上下文
// Get the rendering context for WebGL
var canvas = document.getElementById('webgl');
var gl = getWebGLContext(canvas);
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 = '../resources/earth1.png';
//加载月球图片
var imageMoon = new Image();
imageMoon.onload = function(){
};
imageMoon.src = '../resources/moon.png';
setTimeout(function(){
setInterval(function () {
ANGLE += 0.2
ZANGLE += 2
window.renderCanvas(image,imageMoon, ANGLE, ZANGLE)
}, 100);
}, 2000)
}
function renderCanvas(image,imageMoon, ZANGLE, ANGLE){
gl.enable(gl.DEPTH_TEST);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
//释放缓冲区
// gl.deleteBuffer()
// gl.deleteTexture()
// 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);
var fbo = initFramebufferObject(gl);
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
//绘制阴影贴图 用于给地球贴阴影
var shadowProgram = createProgram(gl, SHADOW_VSHADER_SOURCE, SHADOW_FSHADER_SOURCE);
gl.useProgram(shadowProgram);
gl.program = shadowProgram;
//开始绘制地球贴图
gl.activeTexture(gl.TEXTURE1); // Set a texture object to the texture unit
gl.bindTexture(gl.TEXTURE_2D, fbo.texture);
var n = initVertexBuffers(gl,0.2,true);
//地球的矩阵
// Get the storage locations of uniform variables and so on
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
var modelMatrix = new Matrix4(); // Model matrix
var Tx = -0.6; // Translation distance
modelMatrix.setRotate(ANGLE, 0, 0, 1); // Set rotation matrix
modelMatrix.translate(Tx, 0, 0);
modelMatrix.rotate(ZANGLE, 0, 0, 1);// Multiply modelMatrix by the calculated translation matrix
var mvpMatrix = new Matrix4(); // Model view projection matrix
var normalMatrix = new Matrix4(); // Transformation matrix for normals
// Calculate the view projection matrix
mvpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
mvpMatrix.lookAt(-5.0, 7.0, 8.0, 0, 0, 0, 0, 0, 1);
mvpMatrix.multiply(modelMatrix);
// Pass the model view projection matrix to u_MvpMatrix
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
// Draw the cube(Note that the 3rd argument is the gl.UNSIGNED_SHORT)
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);
//绘制月球贴图阴影
// Set the vertex coordinates, the color and the normal
var n = initVertexBuffers(gl,0.08,true);
var modelMatrix = new Matrix4(); // Model matrix
var Tx = -0.6; // Translation distance
modelMatrix.setRotate(ANGLE, 0, 0, 1); // Set rotation matrix
modelMatrix.translate(Tx, 0, 0);
modelMatrix.rotate(ANGLE, 0, 1, 0);
modelMatrix.translate(0.29, 0, 0);
modelMatrix.rotate(ZANGLE, 0, 0, 1);// Multiply modelMatrix by the calculated translation matrix
var mvpMatrix = new Matrix4(); // Model view projection matrix
// Calculate the view projection matrix
mvpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
mvpMatrix.lookAt(-5.0, 7.0, 8.0, 0, 0, 0, 0, 0, 1);
mvpMatrix.multiply(modelMatrix);
// Pass the model view projection matrix to u_MvpMatrix
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);
//纹理贴图已经画入到texture中
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
//渲染星空
var shitiProgram = createProgram(gl, VSHADER_SOURCE_XX, FSHADER_SOURCE_XX);
gl.useProgram(shitiProgram)
gl.program = shitiProgram;
// Create a buffer object
var vertexSizeBuffer = gl.createBuffer();
if (!vertexSizeBuffer) {
console.log('Failed to create the buffer object');
return -1;
}
// Bind the buffer object to target
gl.bindBuffer(gl.ARRAY_BUFFER, vertexSizeBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(points), gl.STATIC_DRAW);
//缓冲区数据和着色器 变量绑定和启用
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return -1;
}
var FSIZE = Float32Array.BYTES_PER_ELEMENT;
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 4, 0);
gl.enableVertexAttribArray(a_Position); // Enable the assignment of the buffer object
// Get the storage location of a_PointSize
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
if(a_PointSize < 0) {
console.log('Failed to get the storage location of a_PointSize');
return -1;
}
gl.vertexAttribPointer(a_PointSize, 1, gl.FLOAT, false, FSIZE * 4, FSIZE * 3);
gl.enableVertexAttribArray(a_PointSize); // Enable buffer allocation
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 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(0, 0, 3, 0, 0, -100, 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);
// Color of Fog
var fogColor = new Float32Array([0.137, 0.231, 1.0]);
// Distance of fog [where fog starts, where fog completely covers object]
var fogDist = new Float32Array([1, 10]);
var u_FogColor = gl.getUniformLocation(gl.program, 'u_FogColor');
var u_FogDist = gl.getUniformLocation(gl.program, 'u_FogDist');
// Pass fog color, distances, and eye point to uniform variable
gl.uniform3fv(u_FogColor, fogColor); // ColorssetPerspective
gl.uniform2fv(u_FogDist, fogDist); // Starting point and end point
//绘制
//初始化黑色星空
// 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);
// Draw the rectangle
gl.drawArrays(gl.POINTS, 0, 50);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
//启动地球着色器
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 = initVertexBuffers(gl,0.2);
// Get the storage locations of uniform variables and so on
var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
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');
//阴影矩阵TODO
var u_MvpMatrixFromLight = gl.getUniformLocation(gl.program, 'u_MvpMatrixFromLight');
// Set the light color (white)
gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
// Set the light direction (in the world coordinate)
gl.uniform3f(u_LightPosition, -5.0, 7.0, 8.0);
// Set the ambient light
gl.uniform3f(u_AmbientLight, 0.1, 0.1, 0.1);
var modelMatrix = new Matrix4(); // Model matrix
var Tx = -0.6; // Translation distance
modelMatrix.setRotate(ANGLE, 0, 0, 1); // Set rotation matrix
modelMatrix.translate(Tx, 0, 0);
modelMatrix.rotate(ZANGLE, 0, 0, 1);// Multiply modelMatrix by the calculated translation matrix
var mvpMatrix = new Matrix4(); // Model view projection matrix
var normalMatrix = new Matrix4(); // Transformation matrix for normals
//TODO
var mvpMatrixFromLight = new Matrix4();
// Pass the model matrix to u_ModelMatrix
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
// Calculate the view projection matrix
mvpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
mvpMatrix.lookAt(3, 3, 5, 0, 0, 0, 0, 0, 1);
mvpMatrix.multiply(modelMatrix);
// Pass the model view projection matrix to u_MvpMatrix
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
//TODO
mvpMatrixFromLight.setPerspective(30, canvas.width/canvas.height, 1, 100);;
mvpMatrixFromLight.lookAt(-5.0, 7.0, 8.0, 0, 0, 0, 0, 0, 1);
mvpMatrixFromLight.multiply(modelMatrix);
//设置阴影矩阵
gl.uniformMatrix4fv(u_MvpMatrixFromLight, false, mvpMatrixFromLight.elements);
// Calculate the matrix to transform the normal based on the model matrix
normalMatrix.setInverseOf(modelMatrix);
normalMatrix.transpose();
// Pass the transformation matrix for normals to u_NormalMatrix
gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
//纹理
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);
//设置阴影纹理渲染TODO
var u_ShadowMap = gl.getUniformLocation(gl.program, 'u_ShadowMap');
// gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
// // Enable texture unit0
// gl.activeTexture(gl.TEXTURE1);
// // Bind the texture object to the target
// gl.bindTexture(gl.TEXTURE_2D, fbo.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);
gl.uniform1i(u_ShadowMap, 1);
// Draw the cube(Note that the 3rd argument is the gl.UNSIGNED_SHORT)
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
//开始画月球了!!!
// Set the vertex coordinates, the color and the normal
var n = initVertexBuffers(gl,0.08);
// Get the storage locations of uniform variables and so on
var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
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');
//阴影矩阵TODO
var u_MvpMatrixFromLight = gl.getUniformLocation(gl.program, 'u_MvpMatrixFromLight');
// Set the light color (white)
gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
// Set the light direction (in the world coordinate)
gl.uniform3f(u_LightPosition, -5.0, 7.0, 8.0);
// Set the ambient light
gl.uniform3f(u_AmbientLight, 0.1, 0.1, 0.1);
var modelMatrix = new Matrix4(); // Model matrix
var Tx = -0.6; // Translation distance
modelMatrix.setRotate(ANGLE, 0, 0, 1); // Set rotation matrix
modelMatrix.translate(Tx, 0, 0);
modelMatrix.rotate(ANGLE, 0, 1, 0);
modelMatrix.translate(0.29, 0, 0);
modelMatrix.rotate(ZANGLE, 0, 0, 1);// Multiply modelMatrix by the calculated translation matrix
var mvpMatrix = new Matrix4(); // Model view projection matrix
var normalMatrix = new Matrix4(); // Transformation matrix for normals
//TODO
var mvpMatrixFromLight = new Matrix4();
// Pass the model matrix to u_ModelMatrix
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
// Calculate the view projection matrix
mvpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
mvpMatrix.lookAt(3, 3, 5, 0, 0, 0, 0, 0, 1);
mvpMatrix.multiply(modelMatrix);
// Pass the model view projection matrix to u_MvpMatrix
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
//TODO
mvpMatrixFromLight.setPerspective(30, canvas.width/canvas.height, 1, 100);
mvpMatrixFromLight.lookAt(-5.0, 7.0, 8.0, 0, 0, 0, 0, 0, 1);
mvpMatrixFromLight.multiply(modelMatrix);
//设置阴影矩阵
gl.uniformMatrix4fv(u_MvpMatrixFromLight, false, mvpMatrixFromLight.elements);
// Calculate the matrix to transform the normal based on the model matrix
normalMatrix.setInverseOf(modelMatrix);
normalMatrix.transpose();
// Pass the transformation matrix for normals to u_NormalMatrix
gl.uniformMatrix4fv(u_NormalMatrix, false, normalMatrix.elements);
//纹理
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, imageMoon);
// Set the texture unit 0 to the sampler
gl.uniform1i(u_Sampler, 0);
//设置阴影纹理渲染TODO
// var u_ShadowMap = gl.getUniformLocation(gl.program, 'u_ShadowMap');
// gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
// // Enable texture unit0
// gl.activeTexture(gl.TEXTURE1);
// // Bind the texture object to the target
// gl.bindTexture(gl.TEXTURE_2D, fbo.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);
//gl.uniform1i(u_ShadowMap, 1);
// Draw the cube(Note that the 3rd argument is the gl.UNSIGNED_SHORT)
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);
}
function initVertexBuffers(gl,size,need) { // Create a sphere
var SPHERE_DIV = 13;
var i, ai, si, ci;
var j, aj, sj, cj;
var p1, p2;
var positions = [];
var indices = [];
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>
月球图片
地球图片