0

我正在使用twgl.js库在webgl中编写一个柱状图应用程序。我已经成功地实现了它。但它很容易使浏览器崩溃。

我在这里添加了plunker@https://plnkr.co/edit/hK9YXyT0Cj9BEUowYiKVSubH?p=info.

渲染部分大多位于renderer.js中。

请从您的本地计算机浏览jpeg,并在启用GPU内存后使用SHIFT+ESC监视chrome GPU内存。图像加载后,它将计算图像中该区域的直方图,并自动缩小/缩小,内存随着每次缩放而增加。

问题是它只使用一个图像使GPU崩溃。为了更快地解决这个问题,我添加了一个setInterval,它每100ms被调用一次,以重新渲染图像并计算直方图。

代码:

`

var prepareHistogram=函数(img){//arrays.texcoord=[0.2,0.2,1.0,0.2,0.2,1.0,1.0,1.0];gl.arrays=数组;gl.arrays.position.data=[-1,-1,1,-1,-1,1,1];gl.arrays.position.numComponents=2;gl.arrays.texcoord.numComponents=2;//gl.arrays.texcoord=[0.2,0.2,1.0,0.2,0.2,1.0,1.0];quadBufferInfo=twgl.createBufferInformFromArrays(gl,gl.arrays);//quadBufferInfo=twgl.primitives.createXYQuadBuffer信息(gl);quadBufferInfo.indices=空;var newFbi=twgl.createFramebufferInfo(gl);twgl.bindFramebufferInfo(gl,newFbi);gl.useProgram(newProgramInfo.program);twgl.setBuffersAndAttributes(gl,newProgramInfo,quadBufferInfo);twgl.setUniforms(新程序信息{u_texture:纹理,u_resolution:[img.width,img.height]});twgl.drawBufferInfo(gl,gl.TRIANGLES,quadBufferInform);/*twgl.bindFramebufferInfo(gl,null);twgl.drawBufferInfo(gl,gl.TRIANGLES,quadBufferInform);回报*/numIds=img.width*img.height;pixelIds=dummyPixelIds.子数组(0,numIds);var pixelIdBufferInfo=twgl.createBufferInformFromArrays(gl{像素Id:{尺寸:2,数据:像素ID,num组件:1}});//制作一个256x1 RGBA浮点纹理并附加到帧缓冲区var sumFbi=twgl.createFramebufferInfo(gl[{类型:gl.FLOAT,最小值:gl.最小值,杂志:gl.NEAREST,包装:gl.CLAMP_TO_EDGE,}, ], 256, 1);if(gl.checkFramebufferStatus(gl.FRAMEBUFFER)!==全局框架缓冲_完整){警告(“无法渲染到浮点纹理”);}//每种颜色的渲染总和//我们将为源图像中的每个像素渲染一个gl.POINT//该点将根据源图像的颜色进行定位//我们只需要渲染vec4(1,1,1,1)。此混合函数将//意思是每次我们渲染到特定点时,该点将得到//增加了1。gl.blendFunc(gl.ONE,gl.ONE);全局启用(全局混合);gl.useProgram(histProgramInfo.program);twgl.setBuffersAndAttributes(gl、histProgramInfo、pixelIdBufferInfo);twgl.bindFramebufferInfo(gl,sumFbi);//分别渲染每个通道,因为我们只能定位每个点//一次一个频道。gl.colorMask(真、真、真和假);twgl.setUniforms(histProgramInfo,{u_texture:newFbi.附件[0],u_resolution:[img.width,img.height]});twgl.drawBufferInfo(gl,gl.POINTS,pixelIdBufferInfo);gl.colorMask(真、真、真和真);gl.blendFunc(gl.ONE,gl.ZERO);全局禁用(全局混合);//render-compute最小值//我们将256x1像素和纹理渲染为单个1x1像素纹理//制作一个连接到帧缓冲区的229x1像素RGBA、FLOAT纹理var maxFbi=twgl.createFramebufferInfo(gl[{类型:gl.FLOAT,最小值:gl.最小值,杂志:gl.NEAREST,包装:gl.CLAMP_TO_EDGE,}, ], 229, 1);twgl.bindFramebufferInfo(gl,maxFbi);gl.useProgram(maxProgramInfo.program);twgl.setBuffersAndAttributes(gl,maxProgramInfo,quadBufferInfo);twgl.setUniforms(maxProgramInfo{u_texture:sumFbi.附件[0],像素计数:像素计数});twgl.drawBufferInfo(gl,gl.TRIANGLES,quadBufferInform);//渲染直方图。//twgl.bindFramebufferInfo(gl,null);var newFbi2=twgl.createFramebufferInfo(gl);twgl.bindFramebufferInfo(gl,newFbi2);gl.useProgram(showProgramInfo.program);twgl.setBuffersAndAttributes(gl,showProgramInfo,quadBufferInfo);twgl.setUniforms(showProgramInfo{u_resolution:[img.width,img.height],u_res:[img.width,img.height],u_maxTexture:maxFbi.附件[0],inputImage:newFbi.附件[0]});twgl.drawBufferInfo(gl,gl.TRIANGLES,quadBufferInform);twgl.bindFramebufferInfo(gl,null);gl.useProgram(showProgramInfo2.program);twgl.setUniforms(显示ProgramInfo2{u_texture:newFbi2.附件[0],u_resolution:[gl.canvas.width,gl.canvas.height]});//arrays.texcoord.numComponents=2;//arrays.position.data=[ar.x1、ar.y1、ar.x2、ary1、ar.x1,ar.y2、ar.x2、ar.jy2];//gl.arrays=数组;//quadBufferInfo=twgl.primitives.createXYQuadBuffer信息(gl);//gl.arrays=数组;gl.arrays.position.data=[ar.x1,ar.y1,ar.x2,ar.j1,ar.j2,ar.j2];//gl.arrays.texcoord=[0.0,0.0,1.0,0.0、0.0、1.0、1.0、1.0];/*gl.arrays.texcoord=[0.0,0.0,1.0,0.0、0.0、1.0、1.0、1.0];gl.arrays.texcoord.numComponents=2;gl.arrays.position.numComponents=2*/quadBufferInfo=twgl.createBufferInformFromArrays(gl,gl.arrays);quadBufferInfo.indices=空;twgl.setBuffersAndAttributes(gl,showProgramInfo2,quadBufferInfo);twgl.drawBufferInfo(gl,gl.TRIANGLES,quadBufferInform);

}
`

1答案1

重置为默认值
1

该代码通过调用twgl.createFramebufferInfo(创建帧缓冲信息)因此代码最终耗尽了内存。

如果可能,您应该在初始化时分配纹理。换句话说,呼叫twgl.createFrameBufferInfo(创建帧缓冲信息)在初始化时,如果需要不同的大小,请稍后调用twgl.resize帧缓冲区信息改变尺寸。

否则,由您来解除分配它们

函数freeFramebufferInfoResources(gl,fbi){for(联邦调查局附件的固定附件){if(WebGLTexture的附件实例){gl.deleteTexture(附件);}其他{gl.deleteRenderbuffer(附件);}}gl.deleteFramebuffer(fbi.framebuffer);}

至于twgl为什么不包含这个函数,这是因为twgl只是WebGL的一个助手。它创建的数据旨在用于您的应用程序需要使用的任何数据。它不知道您是否正在跨帧缓冲区共享附件(常见),因此无法为您管理资源。这取决于你。

1
  • 好的,我也试过了,现在不是巨大的记忆力损失,而是减少了。我认为createBuffers也应该走出去。但是:我收到类似GL_INVALID_FRAMEBUFFER_OPERATION:绘制帧缓冲区不完整的警告
    – 图形123
    2019年5月14日13:05

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.