[英]How do I draw thousands of squares with glkit, opengl es2?
我正在尝试在屏幕上绘制20万个正方形。 或基本上是很多正方形。 我相信我只是在打很多抽奖电话,这正在削弱应用程序的性能。 正方形仅在按下按钮时更新,因此不必一定每帧都更新一次。
这是我现在拥有的代码:
- (void)glkViewControllerUpdate:(GLKViewController *)controller
{
//static float transY = 0.0f;
//float y = sinf(transY)/2.0f;
//transY += 0.175f;
GLKMatrix4 modelview = GLKMatrix4MakeTranslation(0, 0, -5.f);
effect.transform.modelviewMatrix = modelview;
//GLfloat ratio = self.view.bounds.size.width/self.view.bounds.size.height;
GLKMatrix4 projection = GLKMatrix4MakeOrtho(0, 768, 1024, 0, 0.1f, 20.0f);
effect.transform.projectionMatrix = projection;
_isOpenGLViewReady = YES;
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
if(_model.updateView && _isOpenGLViewReady)
{
glClear(GL_COLOR_BUFFER_BIT);
[effect prepareToDraw];
int pixelSize = _model.pixelSize;
if(!_model.isReady)
return;
//NSLog(@"UPDATING: %d, %d", _model.rows, _model.columns);
for(int i = 0; i < _model.rows; i++)
{
for(int ii = 0; ii < _model.columns; ii++)
{
ColorModel *color = [_model getColorAtRow:i andColumn:ii];
CGRect rect = CGRectMake(ii * pixelSize, i*pixelSize, pixelSize, pixelSize);
//[self drawRectWithRect:rect withColor:c];
GLubyte squareColors[] = {
color.red, color.green, color.blue, 255,
color.red, color.green, color.blue, 255,
color.red, color.green, color.blue, 255,
color.red, color.green, color.blue, 255
};
// NSLog(@"Drawing color with red: %d", color.red);
int xVal = rect.origin.x;
int yVal = rect.origin.y;
int width = rect.size.width;
int height = rect.size.height;
GLfloat squareVertices[] = {
xVal, yVal, 1,
xVal + width, yVal, 1,
xVal, yVal + height, 1,
xVal + width, yVal + height, 1
};
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, squareVertices);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, squareColors);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(GLKVertexAttribPosition);
glDisableVertexAttribArray(GLKVertexAttribColor);
}
}
_model.updateView = YES;
}
首先,您真的需要绘制20万个正方形吗? 您的视口总共只有786,000像素。 您可能能够减少绘制对象的数量,而不会显着影响场景的整体质量。
也就是说,如果这些是较小的正方形,则可以将其绘制为像素大小足以覆盖正方形区域的点。 这将需要在顶点着色器中将gl_PointSize设置为适当的像素宽度。 然后,您可以生成坐标并将其全部发送为GL_POINTS,以一次进行绘制。 这将消除三角形额外几何图形的开销以及您在此处使用的各个绘图调用。
即使您不使用点,仍然要先计算所需的所有三角形几何体,然后在一次绘制调用中将所有几何体发送出去,这仍然是一个好主意。 这将大大减少您的OpenGL ES API调用开销。
您可能要考虑的另一件事是使用顶点缓冲区对象来存储此几何。 如果几何是静态的,则可以避免在每个绘制的框架上发送它,或者仅更新已更改的部分。 即使您只是每帧更改一次数据,我相信使用VBO进行动态几何处理在现代iOS设备上也具有性能优势。
您不能尝试以某种方式对其进行优化吗? 我对图形类型的东西并不十分熟悉,但是我想如果您要绘制200,000个正方形,那么所有这些形状实际上都可见的可能性似乎很小。 您是否可以为mySquare类添加某种isVisible标签,该标签确定您要绘制的正方形是否实际可见? 然后,显而易见的下一步是修改绘图功能,以便在看不见正方形的情况下不要绘制它。
还是您正在要求某人尝试改进当前的代码,因为如果您的性能与您所说的一样糟糕,那么我认为对上述代码进行少量更改不会解决您的问题。 您将不得不重新考虑自己的绘图方式。
看起来您的代码实际想要执行的操作是拍摄_model.rows
× _model.columns
2D图像并将其按_model.pixelSize
放大_model.pixelSize
。 如果-[ColorModel getColorAtRow:andColumn:]
一次从一个颜色值数组中检索3个字节,那么您可能要考虑将该颜色值数组作为GL_RGB
/ GL_UNSIGNED_BYTE
数据GL_RGB
OpenGL纹理中,并让GPU放大一次显示所有像素。
另外,如果按比例放大ColorModel
的内容是使用OpenGL ES和GLKit的唯一原因,则最好将颜色值包装到CGImage中,并允许UIKit和Core Animation为您绘制图形。 ColorModel
的颜色值多久更新一次?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.