var canvas = document.getElementById('webgl');var gl =getWebGLContext(canvas);
获取Plane、Triangle顶点缓冲区,颜色缓冲区,索引缓冲区
var triangle =initVertexBuffersForTriangle(gl);//三角形var plane =initVertexBuffersForPlane(gl);//平面//不推荐这么写...当然我也不知道怎么写更好//将顶点数组、颜色数组、索引数组 转为顶点缓冲区,颜色缓冲区,索引缓冲区functioninitVertexBuffersForTriangle(gl){// Create a triangle// v2// / | // / |// / |// v0----v1// Vertex coordinatesvar vertices =newFloat32Array([-0.8,3.5,0.0,0.8,3.5,0.0,0.0,3.5,1.8]);// Colorsvar colors =newFloat32Array([1.0,0.5,0.0,1.0,0.5,0.0,1.0,0.0,0.0]);// Indices of the verticesvar indices =newUint8Array([0,1,2]);var o =newObject();// Utilize Object object to return multiple buffer objects together// Write vertex information to buffer object
o.vertexBuffer =initArrayBufferForLaterUse(gl, vertices,3, gl.FLOAT);
o.colorBuffer =initArrayBufferForLaterUse(gl, colors,3, gl.FLOAT);
o.indexBuffer =initElementArrayBufferForLaterUse(gl, indices, gl.UNSIGNED_BYTE);if(!o.vertexBuffer ||!o.colorBuffer ||!o.indexBuffer)returnnull;
o.numIndices = indices.length;// Unbind the buffer object
gl.bindBuffer(gl.ARRAY_BUFFER,null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,null);return o;}//这个是加载PlanefunctioninitVertexBuffersForPlane(gl){// Create a plane// v1------v0// | | // | |// | |// v2------v3// Vertex coordinatesvar vertices =newFloat32Array([3.0,-1.7,2.5,-3.0,-1.7,2.5,-3.0,-1.7,-2.5,3.0,-1.7,-2.5// v0-v1-v2-v3]);// Colorsvar colors =newFloat32Array([1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]);// Indices of the verticesvar indices =newUint8Array([0,1,2,0,2,3]);var o =newObject();// Utilize Object object to return multiple buffer objects together// Write vertex information to buffer object
o.vertexBuffer =initArrayBufferForLaterUse(gl, vertices,3, gl.FLOAT);
o.colorBuffer =initArrayBufferForLaterUse(gl, colors,3, gl.FLOAT);
o.indexBuffer =initElementArrayBufferForLaterUse(gl, indices, gl.UNSIGNED_BYTE);if(!o.vertexBuffer ||!o.colorBuffer ||!o.indexBuffer)returnnull;
o.numIndices = indices.length;// Unbind the buffer object
gl.bindBuffer(gl.ARRAY_BUFFER,null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,null);return o;}functioninitArrayBufferForLaterUse(gl, data, num, type){// Create a buffer objectvar buffer = gl.createBuffer();if(!buffer){
console.log('Failed to create the buffer object');returnnull;}
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
buffer.num = num;
buffer.type = type;return buffer;}functioninitElementArrayBufferForLaterUse(gl, data, type){var buffer = gl.createBuffer();if(!buffer){
console.log('Failed to create the buffer object');returnnull;}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, gl.STATIC_DRAW);
buffer.type = type;return buffer;}
先获取fbo,后面用
fbo还有一种方式绑定
var fbo =initFramebufferObject(gl);//texture depthBuffer 返回fbofunctioninitFramebufferObject(gl){var texture = gl.createTexture();// 纹理创建 后面拿来用的
gl.bindTexture(gl.TEXTURE_2D, texture);// Bind the object to target
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);var depthBuffer = gl.createRenderbuffer();// 创建渲染缓冲区 用来渲染的
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);// Bind the object to target
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16,OFFSCREEN_WIDTH,OFFSCREEN_HEIGHT);//都是深度吗?var framebuffer = gl.createFramebuffer();//帧缓冲区 有个有点展示的意思
framebuffer.texture = texture;// Store the texture object
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);//帧缓冲区 对应渲染缓冲区var e = gl.checkFramebufferStatus(gl.FRAMEBUFFER);//判断是否正确配置return framebuffer;}
变量的声明
varOFFSCREEN_WIDTH=2048,OFFSCREEN_HEIGHT=2048;varLIGHT_X=0,LIGHT_Y=7,LIGHT_Z=2;// Position of the light sourcevar currentAngle =0.0;// Current rotation angle (degrees)var mvpMatrixFromLight_t =newMatrix4();// A model view projection matrix from light source (for triangle)var mvpMatrixFromLight_p =newMatrix4();// A model view projection matrix from light source (for plane)
shadowProgram.a_Position = gl.getAttribLocation(shadowProgram,'a_Position');
shadowProgram.u_MvpMatrix = gl.getUniformLocation(shadowProgram,'u_MvpMatrix');
gl.activeTexture(gl.TEXTURE0);// Set a texture object to the texture unit
gl.bindTexture(gl.TEXTURE_2D, fbo.texture);//为啥要在这里绑定呢var viewProjMatrixFromLight =newMatrix4();// Prepare a view projection matrix for generating a shadow map
viewProjMatrixFromLight.setPerspective(70.0,OFFSCREEN_WIDTH/OFFSCREEN_HEIGHT,1.0,100.0);
viewProjMatrixFromLight.lookAt(LIGHT_X,LIGHT_Y,LIGHT_Z,0.0,0.0,0.0,0.0,1.0,0.0);
drawcall
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);// Change the drawing destination to FBO
gl.viewport(0,0,OFFSCREEN_HEIGHT,OFFSCREEN_HEIGHT);// Set view port for FBO
gl.clear(gl.COLOR_BUFFER_BIT| gl.DEPTH_BUFFER_BIT);// Clear FBO
gl.useProgram(shadowProgram);// Set shaders for generating a shadow mapdrawTriangle(gl, shadowProgram, triangle, currentAngle, viewProjMatrixFromLight);//mvpMatrixFromLight_t.set(g_mvpMatrix); // Used laterdrawPlane(gl, shadowProgram, plane, viewProjMatrixFromLight);
mvpMatrixFromLight_p.set(g_mvpMatrix);// Used later
gl.bindFramebuffer(gl.FRAMEBUFFER,null);// Change the drawing destination to color buffer
gl.viewport(0,0, canvas.width, canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT| gl.DEPTH_BUFFER_BIT);// Clear color and depth buffer
gl.useProgram(normalProgram);// Set the shader for regular drawing
gl.uniform1i(normalProgram.u_ShadowMap,0);// Pass 0 because gl.TEXTURE0 is enabled�る//gl.uniformMatrix4fv(normalProgram.u_MvpMatrixFromLight, false, mvpMatrixFromLight_t.elements);drawTriangle(gl, normalProgram, triangle, currentAngle, viewProjMatrix);
gl.uniformMatrix4fv(normalProgram.u_MvpMatrixFromLight,false, mvpMatrixFromLight_p.elements);drawPlane(gl, normalProgram, plane, viewProjMatrix);
drawcall的一些方法
// Coordinate transformation matrixvar g_modelMatrix =newMatrix4();var g_mvpMatrix =newMatrix4();functiondrawTriangle(gl, program, triangle, angle, viewProjMatrix){// Set rotate angle to model matrix and draw triangle
g_modelMatrix.setRotate(angle,0,1,0);draw(gl, program, triangle, viewProjMatrix);}functiondrawPlane(gl, program, plane, viewProjMatrix){// Set rotate angle to model matrix and draw plane
g_modelMatrix.setRotate(-45,0,1,1);draw(gl, program, plane, viewProjMatrix);}functiondraw(gl, program, o, viewProjMatrix){initAttributeVariable(gl, program.a_Position, o.vertexBuffer);if(program.a_Color != undefined)// If a_Color is defined to attributeinitAttributeVariable(gl, program.a_Color, o.colorBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, o.indexBuffer);// Calculate the model view project matrix and pass it to u_MvpMatrix
g_mvpMatrix.set(viewProjMatrix);
g_mvpMatrix.multiply(g_modelMatrix);
gl.uniformMatrix4fv(program.u_MvpMatrix,false, g_mvpMatrix.elements);
gl.drawElements(gl.TRIANGLES, o.numIndices, gl.UNSIGNED_BYTE,0);}// Assign the buffer objects and enable the assignmentfunctioninitAttributeVariable(gl, a_attribute, buffer){
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.vertexAttribPointer(a_attribute, buffer.num, buffer.type,false,0,0);
gl.enableVertexAttribArray(a_attribute);}