我想在iPhone上用OpenGL ES畫點精靈。它可能有很多(1000)和64像素寬(也許這是我的問題 - 有沒有限制,或我可以使用太多的內存?)爲什麼glClear()在iPhone上的點精靈速度緩慢?
我正在使用CADisplayLink到時間框架。會發生什麼情況是,當點數過高或點的大小太大時,第一個gl繪圖函數往往會延遲或失速。在我的例子中,glClear()是第一個繪圖函數,它可以從0.02秒到0.2秒的任何地方運行。如果我只是註釋掉glClear,那麼glDrawArrays就變成了慢速函數(否則它運行得非常快)。
這個例子是我已經剝離我的代碼,以隔離問題。它只是在同一個地方畫出一堆點紋,沒有紋理。我使用VBOs來存儲所有精靈數據(位置,顏色,大小)。這個例子看起來似乎有些過火,但我當然有意在稍後修改這些數據。
這是視圖的初始化函數(減去樣板GL設置):
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_LIGHTING);
glDisable(GL_FOG);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendEquationOES(GL_FUNC_ADD_OES);
glClearColor(0.0, 0.0, 0.0, 0.0);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
glEnable(GL_POINT_SPRITE_OES);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
glEnableClientState(GL_COLOR_ARRAY);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_POINT_SMOOTH);
glGenBuffers(1, &vbo); // vbo is an instance variable
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glMatrixMode(GL_PROJECTION);
glOrthof(0.0, [self frame].size.width, 0.0, [self frame].size.height, 1.0f, -1.0f);
glViewport(0, 0, [self frame].size.width, [self frame].size.height);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0f, [self frame].size.height, 0.0f);
glScalef(1.0f, -1.0f, 1.0f);
這是渲染功能:
- (void)render
{
glClear(GL_COLOR_BUFFER_BIT); // This function runs slowly!
int pointCount = 1000;
// fyi...
// typedef struct {
// CGPoint point;
// CFTimeInterval time;
// GLubyte r, g, b, a;
// GLfloat size;
// } MyPoint;
glBufferData(GL_ARRAY_BUFFER, sizeof(MyPoint)*pointCount, NULL, GL_DYNAMIC_DRAW);
MyPoint * vboBuffer = (MyPoint *)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
for (int i = 0; i < pointCount; i++) {
vboBuffer[i].a = (GLubyte)0xFF;
vboBuffer[i].r = (GLubyte)0xFF;
vboBuffer[i].g = (GLubyte)0xFF;
vboBuffer[i].b = (GLubyte)0xFF;
vboBuffer[i].size = 64.0;
vboBuffer[i].point = CGPointMake(200.0, 200.0);
}
glUnmapBufferOES(GL_ARRAY_BUFFER);
glPointSizePointerOES(GL_FLOAT, sizeof(MyPoint), (void *)offsetof(MyPoint, size));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(MyPoint), (void *)offsetof(MyPoint, r));
glVertexPointer(2, GL_FLOAT, sizeof(MyPoint), (void *)offsetof(MyPoint, point));
glDrawArrays(GL_POINTS, 0, pointCount);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
爲什麼glClear功能停滯?它不僅延遲隨機數量 - 取決於點數或大小,它傾向於隨機延遲相同的時間間隔(例如0.015秒,0.030秒,0.045秒等)。我注意到的另外一件奇怪的事是,如果我切換到glBlendMode(GL_ZERO,GL_ONE),它運行得很好(儘管這不會是我之後的視覺效果)。其他glBlendMode值也會改變速度 - 通常情況下會更好。這讓我覺得這不是一個記憶問題,因爲這與VBO無關(對吧?)。
我承認我在OpenGL上有點新,可能會誤解有關VBO或其他東西的基本概念。任何幫助或指導,非常感謝!
我確實嘗試過,但它看起來並不像glClear那麼慢。它似乎是第一個gl繪圖函數。如果我擺脫glClear並繪製一個空白四邊形,它只會減慢glDrawArrays()。 – 2010-07-30 00:50:34