我希望有人可以帮我指明了一些纹理基准我做的OpenGL ES 2.0的一些进展和iPhone 4优化OpenGL ES 2.0的2D纹理输出和帧率
我有一个包含精灵的数组对象。渲染循环遍历每个纹理的所有精灵,并检索其所有纹理坐标和顶点坐标。它使用退化的顶点和索引将它们添加到一个巨大的交织阵列中,并将它们发送给GPU(我嵌入的代码是底部)。这一切都是按照纹理完成的,所以我将纹理绑定一次,然后创建我的交错数组,然后绘制它。一切都很好,屏幕上的结果正是他们应该做的。
因此,我的基准测试是通过在不同的不透明度下添加25个新的精灵,并在更新上更改它们的顶点,以便在应用程序上旋转并运行OpenGL ES分析器时,它们在屏幕周围弹跳。
继承人,我希望有一些帮助.... 我可以达到约275个32x32精灵与不同的不透明度在60 fps的屏幕上跳动。到400我下降到40帧/秒。当我运行OpenGL ES Performance Detective时,它会告诉我...
应用程序渲染受三角形栅格化的限制 - 将三角形转换为像素的过程。所有正在渲染的三角形的总面积(以像素为单位)太大。要以更快的帧率绘制,请通过减少三角形的数量,其大小或两者的大小来简化场景。
的是我刚刮起了测试在cocos2d使用CCSpriteBatchNode使用相同的纹理和创建800个透明精灵和帧率为60fps的容易。
下面是一些代码,可能是中肯......
Shader.vsh(矩阵在成立伊始一次)
void main()
{
gl_Position = projectionMatrix * modelViewMatrix * position;
texCoordOut = texCoordIn;
colorOut = colorIn;
}
Shader.fsh(colorOut用于calc下不透明度)
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, 2, GL_FLOAT, GL_FALSE, sizeof(TDSEVertex), BUFFER_OFFSET(8));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(TDSEVertex), 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正在创建和发送每个纹理,所以我绑定,然后每帧只绘制两次(因为只有两个纹理)。
很抱歉,如果这是压倒性的,但在这里它的我的第一篇,想彻底。 任何帮助将不胜感激。
PS,我知道我可以使用Cocos2D而不是从头开始编写所有的东西,但是在那儿玩的乐趣(和学习)?!
UPDATE#1 当我我的片段着色器切换到仅是
gl_FragColor = texture2D(texture, texCoordOut);
它到达802个在精灵50fps的(4804三角形包括退化三角形),尽管设置子画面不透明度丢失..任何建议到如何仍然可以在我的着色器中处理不透明度而不以1/4的速度运行?
UPDATE#2 因此,我放弃了GLKit的View和View控制器,并编写了一个从AppDelegate加载的自定义视图。 902不透明的精灵& 60fps的透明度。
与其使用OpenGL ES Performance Detective,我更喜欢使用带有OpenGL ES分析器和OpenGL ES驱动程序工具的仪器。分析器通常会指出更细微的渲染问题,并且驱动程序可以在Tiler(顶点侧)和Renderer(片段侧)为您提供百分比负载,以验证您的瓶颈位置。另外尝试运行Time Profiler对此。这看起来比应该慢,因为我把A4的基准定为1。使用VBOs和简单的阴影,每秒800万个三角形,或以60 FPS在屏幕上约30000个三角形。 – 2012-03-20 20:07:13
感谢回复@BradLarson。尽管有些事情我不太了解... Renderer Utiliz:99%,Tiler Utilz:8%,Device Utilz:99%,我尽可能使用Analyzer和Driver。思考? Analyzer中唯一突出的是多余的调用,但绝大多数来自glView(绑定帧缓冲区等)。 Time Profilier显示83%来自我绑定和更新VBO(在更新中完成)并绘制。你认为使用glView是问题的一部分吗?我认为这是transp层(即时贴上截图和我更新的代码)。谢谢。 – yiannis 2012-03-20 21:23:27
如果您的渲染器利用率确实为99%,而您的铺砖机为8%,那么显然您的填充率受限,而不是几何形状受限。优化三角形和你的VBO不会对你有什么好处,你需要专注于绘制更少的像素或更快地绘制像素。你已经在上面的场景中进行了很多混合,[来自经验](http://stackoverflow.com/q/6051237/19679)如果一堆混合对象堆积在一起,我知道这是非常昂贵的彼此顶部。您可以渲染不透明区域并写入深度缓冲区,然后在混合半透明区域时从中读取。 – 2012-03-21 14:43:29