使用OpenGL ES在iPhone上平铺背景
我想在iPhone上制作一个2D平铺背景系统。获取一个tilemap和tileset图像并将其转换为屏幕上的完整地图的东西 我的第一个方法是为每个瓷砖创建一个多边形,只是做了一些混乱。这很好,直到我开始测试400个多边形左右,然后它开始运行非常缓慢。我只是想知道——这种由几个多边形组成的方法难道不是可行的吗?还是我做错了什么?如果需要,我会稍后发布代码,但我的主要问题是“400个小多边形在iPhone上运行缓慢,还是我只是做错了什么?” 我还考虑了另一种方法,即在初始化期间,通过代码从tilemap/tilesets中创建贴图纹理,然后将其粘贴到一个大多边形上。所以,是的……有没有关于我应该如何处理这类事情的反馈使用OpenGL ES在iPhone上平铺背景,iphone,opengl-es,Iphone,Opengl Es,我想在iPhone上制作一个2D平铺背景系统。获取一个tilemap和tileset图像并将其转换为屏幕上的完整地图的东西 我的第一个方法是为每个瓷砖创建一个多边形,只是做了一些混乱。这很好,直到我开始测试400个多边形左右,然后它开始运行非常缓慢。我只是想知道——这种由几个多边形组成的方法难道不是可行的吗?还是我做错了什么?如果需要,我会稍后发布代码,但我的主要问题是“400个小多边形在iPhone上运行缓慢,还是我只是做错了什么?” 我还考虑了另一种方法,即在初始化期间,通过代码从tilem
我知道有人会提到这一点-我考虑过尝试cocos2d,但我有理由不走这条路。使用
glDrawTex
扩展也可能是一种可能性。使用glDrawTex
扩展也可能是一种可能性。斯坦福iTunes大学有一个关于优化iPhone OpenGL的播客
但基本理念是:
我想这就是我目前所能想到的。斯坦福iTunes大学有一个关于优化OpenGL for iPhone的播客 但基本理念是:
我想这就是我目前所能想到的。你的问题几乎可以肯定是你绑定了400次纹理,而不是其他任何东西。你应该把所有的瓷砖放在一个大的纹理图集/精灵表中,而不是重新绑定你的纹理,你应该只绑定一次图集,然后画一小部分。如果你这样做了,你应该能够在没有真正减速的情况下绘制数千块瓷砖 您可以这样绘制精灵:
//Push the matrix so we can keep it as it was previously.
glPushMatrix();
//Store the coordinates/dimensions from a rectangle.
float x = CGRectGetMinX(rect);
float y = CGRectGetMinY(rect);
float w = CGRectGetWidth(rect);
float h = CGRectGetHeight(rect);
float xOffset = x;
float yOffset = y;
if (rotation != 0.0f)
{
//Translate the OpenGL context to the center of the sprite for rotation.
glTranslatef(x+w/2, y+h/2, 0.0f);
//Apply the rotation over the Z axis.
glRotatef(rotation, 0.0f, 0.0f, 1.0f);
//Have an offset for the top left corner.
xOffset = -w/2;
yOffset = -h/2;
}
// Set up an array of values to use as the sprite vertices.
GLfloat vertices[] =
{
xOffset, yOffset,
xOffset, yOffset+h,
xOffset+w, yOffset+h,
xOffset+w, yOffset,
};
// Set up an array of values for the texture coordinates.
GLfloat texcoords[] =
{
CGRectGetMinX(clippingRect), CGRectGetMinY(clippingRect),
CGRectGetMinX(clippingRect), CGRectGetHeight(clippingRect),
CGRectGetWidth(clippingRect), CGRectGetHeight(clippingRect),
CGRectGetWidth(clippingRect), CGRectGetMinY(clippingRect),
};
//If the image is flipped, flip the texture coordinates.
if (flipped)
{
texcoords[0] = CGRectGetWidth(clippingRect);
texcoords[2] = CGRectGetWidth(clippingRect);
texcoords[4] = CGRectGetMinX(clippingRect);
texcoords[6] = CGRectGetMinX(clippingRect);
}
//Render the vertices by pointing to the arrays.
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
// Set the texture parameters to use a linear filter when minifying.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//Allow transparency and blending.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Enable 2D textures.
glEnable(GL_TEXTURE_2D);
//Bind this texture.
if ([Globals getLastTextureBound] != texture)
{
glBindTexture(GL_TEXTURE_2D, texture);
}
//Finally draw the arrays.
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//Restore the model view matrix to prevent contamination.
glPopMatrix();
我使用的两个CGRect只是为了方便起见。可以指定要绘制图像的X、Y、宽度和高度,也可以指定要使用剪报在图像中绘制的位置。使用剪切矩形,(0,0,1,1)是整个图像,而(0,0,0.25,0.25)只绘制左上角。通过更改剪裁矩形,可以将各种不同的瓷砖放置在同一纹理中,然后只需绑定一次。便宜多了。你的问题几乎肯定是你要绑定400次纹理,而不是其他任何东西。你应该把所有的瓷砖放在一个大的纹理图集/精灵表中,而不是重新绑定你的纹理,你应该只绑定一次图集,然后画一小部分。如果你这样做了,你应该能够在没有真正减速的情况下绘制数千块瓷砖 您可以这样绘制精灵:
//Push the matrix so we can keep it as it was previously.
glPushMatrix();
//Store the coordinates/dimensions from a rectangle.
float x = CGRectGetMinX(rect);
float y = CGRectGetMinY(rect);
float w = CGRectGetWidth(rect);
float h = CGRectGetHeight(rect);
float xOffset = x;
float yOffset = y;
if (rotation != 0.0f)
{
//Translate the OpenGL context to the center of the sprite for rotation.
glTranslatef(x+w/2, y+h/2, 0.0f);
//Apply the rotation over the Z axis.
glRotatef(rotation, 0.0f, 0.0f, 1.0f);
//Have an offset for the top left corner.
xOffset = -w/2;
yOffset = -h/2;
}
// Set up an array of values to use as the sprite vertices.
GLfloat vertices[] =
{
xOffset, yOffset,
xOffset, yOffset+h,
xOffset+w, yOffset+h,
xOffset+w, yOffset,
};
// Set up an array of values for the texture coordinates.
GLfloat texcoords[] =
{
CGRectGetMinX(clippingRect), CGRectGetMinY(clippingRect),
CGRectGetMinX(clippingRect), CGRectGetHeight(clippingRect),
CGRectGetWidth(clippingRect), CGRectGetHeight(clippingRect),
CGRectGetWidth(clippingRect), CGRectGetMinY(clippingRect),
};
//If the image is flipped, flip the texture coordinates.
if (flipped)
{
texcoords[0] = CGRectGetWidth(clippingRect);
texcoords[2] = CGRectGetWidth(clippingRect);
texcoords[4] = CGRectGetMinX(clippingRect);
texcoords[6] = CGRectGetMinX(clippingRect);
}
//Render the vertices by pointing to the arrays.
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
// Set the texture parameters to use a linear filter when minifying.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//Allow transparency and blending.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Enable 2D textures.
glEnable(GL_TEXTURE_2D);
//Bind this texture.
if ([Globals getLastTextureBound] != texture)
{
glBindTexture(GL_TEXTURE_2D, texture);
}
//Finally draw the arrays.
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//Restore the model view matrix to prevent contamination.
glPopMatrix();
我使用的两个CGRect只是为了方便起见。可以指定要绘制图像的X、Y、宽度和高度,也可以指定要使用剪报在图像中绘制的位置。使用剪切矩形,(0,0,1,1)是整个图像,而(0,0,0.25,0.25)只绘制左上角。通过更改剪裁矩形,可以将各种不同的瓷砖放置在同一纹理中,然后只需绑定一次。便宜多了。Scott,每个纹理只需设置一次TexParameter。然而,这并不是你减速的原因 您最好建立一个索引列表,并为整个tile集调用一次gldrawArray。顶点数组的目标是允许您在一个步骤中绘制尽可能多的顶点
应避免使用glDrawTex,因为它会迫使您陷入一次一个的低效思维模式。Scott,每个纹理只需进行一次TexParameter设置。然而,这并不是你减速的原因 您最好建立一个索引列表,并为整个tile集调用一次gldrawArray。顶点数组的目标是允许您在一个步骤中绘制尽可能多的顶点 应该避免使用glDrawTex,因为它会迫使你陷入一次一个的低效思维模式。什么