JavaScript WebGL framebuffer object - SegmentFault 思否

文章推薦指數: 80 %
投票人數:10人

When How I built a wind map with WebGL , framebuffer was used in it, so I checked the data and tried it out. 注册登录问答专栏课程招聘活动发现✓使用“Bing”搜本站使用“Google”搜本站使用“百度”搜本站站内搜索注册登录首页专栏javascript文章详情1JavaScriptWebGLframebufferobjectXXHolic发布于2月1日中文IntroductionWhenHowIbuiltawindmapwithWebGL,framebufferwasusedinit,soIcheckedthedataandtrieditout.OriginMyGitHubframebufferobjectWebGLhastheabilitytousetherenderingresultasatexture,whichisthe(framebufferobject).Bydefault,thefinalWebGLdrawingresultisstoredinthecolorbuffer,andtheframebufferobjectcanbeusedinsteadofthecolorbuffer,asshowninthefollowingfigure,theobjectsdrawnintheframebufferarenotdirectlydisplayedontheCanvas,soThistechniqueisalsoknownas(offscreendrawing).ExampleToverifytheabovefunctionality,theexampledrawsanimageintheframebuffer,andthendrawsitagainasatexturefordisplay.Basedonusingthepictureexample,therearemainlythefollowingchanges:dataframebufferobjectdrawdataDrawingintheframebufferisthesameasnormaldrawing,butitisnotdisplayed,sotheremustbecorrespondingdrawingareasize,vertexcoordinatesandtexturecoordinates.offscreenWidth:200,//离屏绘制的宽度 offscreenHeight:150,//离屏绘制的高度 //部分代码省略 //针对帧缓冲区绘制的顶点和纹理坐标 this.offScreenBuffer=this.initBuffersForFramebuffer(gl); //部分代码省略 initBuffersForFramebuffer:function(gl){ constvertices=newFloat32Array([ 0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5, ]);//矩形 constindices=newUint16Array([0,1,2,0,2,3]); consttexCoords=newFloat32Array([ 1.0, 1.0,//右上角 0.0, 1.0,//左上角 0.0, 0.0,//左下角 1.0, 0.0,//右下角 ]); constobj={}; obj.verticesBuffer=this.createBuffer(gl,gl.ARRAY_BUFFER,vertices); obj.indexBuffer=this.createBuffer(gl,gl.ELEMENT_ARRAY_BUFFER,indices); obj.texCoordsBuffer=this.createBuffer(gl,gl.ARRAY_BUFFER,texCoords); returnobj; }, createBuffer:function(gl,type,data){ constbuffer=gl.createBuffer(); gl.bindBuffer(type,buffer); gl.bufferData(type,data,gl.STATIC_DRAW); gl.bindBuffer(type,null); returnbuffer; } //部分代码省略Bothvertexshadersandfragmentshaderscanbenewlydefined,andasetissharedhereforconvenience.framebufferobjectTodrawintheframebuffer,youneedtocreatethecorrespondingframebufferobject.//帧缓冲区对象 this.framebufferObj=this.createFramebufferObject(gl); //部分代码省略 createFramebufferObject:function(gl){ letframebuffer=gl.createFramebuffer(); lettexture=gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D,texture); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, this.offscreenWidth, this.offscreenHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null ); //反转图片Y轴方向 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true); //纹理坐标水平填充s gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE); //纹理坐标垂直填充t gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE); //纹理放大处理 gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR); //纹理缩小处理 gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR); framebuffer.texture=texture;//保存纹理对象 //关联缓冲区对象 gl.bindFramebuffer(gl.FRAMEBUFFER,framebuffer); gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0 ); //检查配置是否正确 vare=gl.checkFramebufferStatus(gl.FRAMEBUFFER); if(gl.FRAMEBUFFER_COMPLETE!==e){ console.log("Framebufferobjectisincomplete:"+e.toString()); return; } gl.bindFramebuffer(gl.FRAMEBUFFER,null); gl.bindTexture(gl.TEXTURE_2D,null); returnframebuffer; } //部分代码省略createFramebufferfunctiontocreateaframebufferobject,thefunctiontodeletetheobjectisdeleteFramebuffer.Afterthecreation,youneedtoassignatextureobjecttothecolorassociationobjectoftheframebuffer.Thetextureobjectcreatedbytheexamplehasseveralcharacteristics:1.Thewidthandheightofthetextureareconsistentwiththewidthandheightofthedrawingarea;2.WhenusingtexImage2D,thelastparameterisnull,Thatis,ablankareaforstoringtextureobjectsisreserved;3Thecreatedtextureobjectisplacedontheframebufferobject,whichisthislineofcodeframebuffer.texture=texture.bindFramebufferThefunctionbindstheframebuffertothetarget,andthenusestobindthepreviouslycreatedtextureobjecttotheframebuffer'scolor-linkedobjectgl.COLOR_ATTACHMENT0.checkFramebufferStatusCheckthattheframebufferobjectisconfiguredcorrectly.drawThemaindifferencewhendrawingisthatthereisaswitchingprocess://部分代码省略 draw:function(){ constgl=this.gl; constframeBuffer=this.framebufferObj; this.canvasObj.clear(); constprogram=this.shaderProgram; gl.useProgram(program.program); //这个就让绘制的目标变成了帧缓冲区 gl.bindFramebuffer(gl.FRAMEBUFFER,frameBuffer); gl.viewport(0,0,this.offscreenWidth,this.offscreenHeight); this.drawOffFrame(program,this.imgTexture); //解除帧缓冲区绑定,绘制的目标变成了颜色缓冲区 gl.bindFramebuffer(gl.FRAMEBUFFER,null); gl.viewport(0,0,gl.canvas.width,gl.canvas.height); this.drawScreen(program,frameBuffer.texture); }, //部分代码省略FirstusebindFramebuffermakethedrawingtargetbecometheframebuffer,andyouneedtospecifythecorrespondingviewport.Aftertheframebufferisdrawn,itisunboundandrestoredtothenormaldefaultcolorbuffer.Itisalsonecessarytospecifythecorrespondingviewport,andmoreparticularly,thetextureofthebufferobjectisused.Thisindicationisobtainedfromtheframebuffer.Plottheresult.observeandthinkTherelevantexamplesfoundontheInternetfeelmorecomplicated,andtherearesomeobservationsandthoughtsbelowintheprocessoftryingtosimplify.framebuffer.textureanexistingattributeoranartificialaddition?Thereisthislogicwhencreatingtheframebufferobject:framebuffer.texture=texture,thendoestheframebufferobjectitselfhavethetextureattribute?Theprintlogfoundthatthisattributewasnotpresentwhenitwasjustcreated,soitispresumedthatitshouldbeaddedartificially.framebuffer.texturehavecontent?Whentheframebufferobjectisinitialized,thestoredtextureisblank,butfromthefinalresult,aftertheframebufferisdrawn,thetexturehascontent,soframebuffer.textureattributehavecontent?Inthedrawinglogic,thestatementsrelatedtotexturesare:gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D,texture); gl.uniform1i(program.uSampler,0); gl.drawElements(gl.TRIANGLES,6,gl.UNSIGNED_SHORT,0);Itisspeculatedthatthegl.drawElementsmethodisstoredinthecolor-relatedobjectoftheframebuffer.Thecolor-relatedobjectoftheframebufferisassociatedwiththeblanktextureobjectcreatedduringinitialization.framebuffer.texturepointstothesameblanktextureobject,sofinallythereiscontent.Whydoesn'tthefinaldisplayfilltheentirecanvas?Whenthedisplayablecontentisfinallydrawn,itcanbefoundthattheverticescorrespondtotheentirecanvas,andthetexturecoordinatescorrespondtotheentirecompletetexture,butwhyistheentirecanvasnotcovered?Thetextureusedinthefinaldrawingofthedisplayablecontentcomesfromthedrawingresultoftheframebuffer,andtheverticesoftheframebuffercorrespondtohalfoftheentirebufferarea.Ifthedrawingresultoftheentireframebufferisregardedasatexture,drawthevisibleareaaccordingtothefinaldrawing.Ifthescaleisscaled,thenthefinaldrawingisnotfull,whichistheexpectedcorrectresult.Thisisa161f912bd416e4examplecanvas,justadjustthebufferverticestocorrespondtotheentirebuffersize.ReferencesWebGLProgrammingGuideFramebufferExampleWebGLFramebuffersWebGLdisplayframebuffer?javascripthtml5canvaswebgl阅读1.3k发布于2月1日赞1收藏1分享本作品系原创,采用《署名-非商业性使用-禁止演绎4.0国际》许可协议XXHolic[链接]325声望1.1k粉丝关注作者0条评论得票最新提交评论XXHolic[链接]325声望1.1k粉丝关注作者文章目录跟随宣传栏▲11



請為這篇文章評分?