我有一个包含精灵对象的数组.渲染循环遍历每个纹理的所有精灵,并检索所有纹理坐标和顶点坐标.它将这些添加到一个巨大的交错数组中,使用简并顶点和索引,然后将它们发送到GPU(我的嵌入代码是底部).这是每个纹理完成所以我绑定纹理一次,然后创建我的交错数组,然后绘制它.一切都很好,屏幕上的结果正是它们应该是的.
所以我的基准测试是通过在不同的不透明度下每次触摸添加25个新的精灵并在更新时更改它们的顶点来完成的,这样它们就可以在应用程序上旋转和运行OpenGL ES Analyzer时在屏幕上d跳.
在希望得到一些帮助的地方……
我可以得到大约275个32×32精灵,不同的不透明度在屏幕上以60 fps的速度反d.到400我降到40 fps.当我运行OpenGL ES Performance Detective时,它告诉我……
The app rendering is limited by triangle rasterization – the process of converting triangles into pixels. The total area in pixels of all of the triangles you are rendering is too large. To draw at a faster frame rate,simplify your scene by reducing either the number of triangles,their size,or both.
事情是我刚刚使用CCSpriteBatchNode使用相同的纹理在cocos2D中进行了测试并创建了800个透明精灵,帧速率是一个简单的60fps.
以下是一些可能相关的代码……
Shader.vsh(矩阵在开头设置一次)
voID main(){ gl_position = projectionMatrix * modelVIEwMatrix * position; texCoordOut = texCoordIn; colorOut = colorIn;}
Shader.fsh(colorOut用于计算不透明度)
voID main(){ lowp vec4 fcolor = texture2D(texture,texCoordOut); gl_Fragcolor = vec4(fcolor.xyz,fcolor.w * colorOut.a);}
VBO设置
glGenBuffers(1,&_vertexBuf); glGenBuffers(1,&_indicIEsBuf); glGenVertexArraysOES(1,&_vertexArray); glBindVertexArrayOES(_vertexArray); glBindBuffer(GL_ARRAY_BUFFER,_vertexBuf); glBufferData(GL_ARRAY_BUFFER,sizeof(TDSEVertex)*12000,&vertices[0].x,GL_DYNAMIC_DRAW); glEnabLevertexAttribarray(GLKVertexAttribposition); glVertexAttribPointer(GLKVertexAttribposition,2,GL_float,GL_FALSE,sizeof(TDSEVertex),BUFFER_OFFSET(0)); glEnabLevertexAttribarray(GLKVertexAttribTexCoord0); glVertexAttribPointer(GLKVertexAttribTexCoord0,BUFFER_OFFSET(8)); glEnabLevertexAttribarray(GLKVertexAttribcolor); glVertexAttribPointer(GLKVertexAttribcolor,4,BUFFER_OFFSET(16)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_indicIEsBuf); glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(ushort)*12000,indicIEs,GL_STATIC_DRAW); glBindVertexArrayOES(0);
更新代码
/* Here it cycles through all the Sprites,gets their vert info (includes coords,texture coords,and color) and adds them to this giant array The array is of... typedef struct{ float x,y; float tx,ty; float r,g,b,a; }TDSEVertex; */ glBindBuffer(GL_ARRAY_BUFFER,_vertexBuf); //glBufferSubData(GL_ARRAY_BUFFER,sizeof(vertices[0])*(start),sizeof(TDSEVertex)*(indicesCount),&vertices[start]); glBufferData(GL_ARRAY_BUFFER,sizeof(TDSEVertex)*indicesCount,&vertices[start].x,GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER,0);
渲染代码
GLKTextureInfo* textureInfo = [[TDSETextureManager sharedTextureManager].textures objectForKey:texturename]; glBindTexture(GL_TEXTURE_2D,textureInfo.name); glBindVertexArrayOES(_vertexArray); glDrawElements(GL_TRIANGLE_STRIP,indicesCount,GL_UNSIGNED_SHORT,BUFFER_OFFSET(start)); glBindVertexArrayOES(0);
下面是400个精灵(800个三角形800个退化三角形)的截图,以便在纹理移动时给出不透明度分层的概念……
我应该注意,每个纹理都会创建并发送一个VBO,因此Im绑定然后每帧只绘制两次(因为只有两个纹理).
对不起,如果这是压倒性的,但它是我在这里的第一篇文章,并希望彻底.
任何帮助将非常感激.
PS,我知道我可以只使用Cocos2D而不是从头开始编写所有东西,但那有趣(和学习)呢?!
更新#1
当我将片段着色器切换为仅时
gl_Fragcolor = texture2D(texture,texCoordOut);
它以50fps(4804个三角形,包括退化三角形)获得802精灵,虽然设置精灵不透明度会丢失..有关如何在我的着色器中处理不透明度而不以1/4速度运行的任何建议?
更新#2
所以我放弃了GLKit的VIEw和VIEw控制器,并编写了一个从AppDelegate加载的自定义视图. 902个不透明的精灵&透明度为60fps.
如果您的三角形有限,请尝试从GL_TRIANGLE_STRIP切换到GL_TRIANGLES.您仍然需要指定完全相同数量的索引 – 每个四个索引6个 – 但GPU永远不必发现四边形之间的连接三角形是退化的(即,它永远不必将它们转换为零像素).您需要进行分析,看看您是否最终支付的费用不再隐含地共享边缘.
您还应该缩小顶点的占用空间.我敢想象你可以将x,y,tx和ty指定为16位整数,并将颜色指定为8位整数,而渲染没有任何明显的变化.这会将每个顶点的占用空间从32个字节(8个组件,每个大小为4个字节)减少到12个字节(4个双字节值加上4个单字节值,不需要填充,因为所有内容都已对齐) – 几乎切割那里有63%的内存带宽.
由于您实际上似乎是填充率有限,您也应该考虑源纹理.你可以做的任何东西来修剪它的字节大小将直接帮助texel提取,从而帮助填充率.
看起来你正在使用有意识地关注像素的艺术,所以切换到PVR可能不是一种选择.也就是说,人们有时并没有意识到PVR纹理的全部好处;如果您切换到比如每像素4位模式,那么您可以将图像缩放到两倍宽和两倍高,以减少压缩伪影,并且仍然只需要在每个源像素上支付16位但可能会得到一个比16 bpp RGB纹理更好的亮度范围.
假设您当前正在使用32 bpp纹理,您至少应该使用任何提供的硬件模式来查看普通的16 bpp RGB纹理是否足够(特别是如果每个颜色通道的1位Alpha加5位适合您的艺术,因为与原版相比,它只丢失了9位颜色信息,同时将带宽成本降低了50%).
看起来你每个帧都上传索引.仅在向场景添加额外对象时或者上次上载的缓冲区远大于其需要时才上载.您可以限制传递给glDrawElements的计数,以便在没有重新上载的情况下减少对象.你还应该通过将顶点上传到VBO来检查你是否真正获得了任何东西,然后如果它们只是改变每一帧就重新使用它们.从客户端内存直接提供它们可能会更快.
总结以上是内存溢出为你收集整理的ios – 优化openGL ES 2.0 2D纹理输出和帧速率全部内容,希望文章能够帮你解决ios – 优化openGL ES 2.0 2D纹理输出和帧速率所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)