Мне было интересно, как ускорить работу приложения на iPad с помощью OpenGLES 2.0. На данный момент каждый нарисованный объект рисует сам с помощью вызова glDrawArrays (). Режим смешивания включен, он нам действительно нужен. Без отключения blendmode, как бы мы улучшили производительность для этого приложения?
Например, если мы теперь рисуем 3 текстуры (1024x1024, 256x512, 256x512) по всему экрану, приложение получает только 15FPS, что, на мой взгляд, очень медленно? Мы делаем что-то ужасно неправильно? Наш код рисования (для каждого рисованного) выглядит следующим образом:
- (void) draw {
GLuint textureAvailable = 0;
if(texture != nil){
textureAvailable = 1;
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture.name);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, vertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, 1, 0, colorsWithMultipliedAlpha);
glEnableVertexAttribArray(ATTRIB_COLOR);
glVertexAttribPointer(ATTRIB_TEXTUREMAP, 2, GL_FLOAT, 1, 0, textureMapping);
glEnableVertexAttribArray(ATTRIB_TEXTUREMAP);
//Note that we are NOT using position.z here because that is only used to determine drawing order
int *jnUniforms = JNOpenGLConstants::getInstance().uniforms;
glUniform4f(jnUniforms[UNIFORM_TRANSLATE], position.x, position.y, 0.0, 0.0);
glUniform4f(jnUniforms[UNIFORM_SCALE], scale.x, scale.y, 1.0, 1.0);
glUniform1f(jnUniforms[UNIFORM_ROTATION], rotation);
glUniform1i(jnUniforms[UNIFORM_TEXTURE_SAMPLE], 0);
glUniform2f(jnUniforms[UNIFORM_TEXTURE_REPEAT], textureRepeat.x, textureRepeat.y);
glUniform1i(jnUniforms[UNIFORM_TEXTURE_AVAILABLE], textureAvailable);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
Возможные оптимизации, я думаю, не сработают:
- Рисование геометрии партиями
- Я рисую только 3 элемента, а FPS равен 15, я не думаю, что пакетная геометрия будет работать здесь, потому что это такое небольшое количество вызовов для рисования, что не имеет значения, если мы убьем 2 / 3 из этих вызовов.
- Текстурный Атлас
- Снова, только рисуя 3 текстуры. Что мне действительно интересно, если бы это имело (много) значение, если бы мы конвертировали их в PVR? Я не рассматривал это, но должен признать, что в данный момент мы загружаем большие PNG. Есть ли способ узнать, так ли это на самом деле, или проще проверить это?
Но, пожалуйста, скажите мне, если я ошибаюсь, я рад услышать любые идеи.
Предлагаемые решения
Mipmapped текстуры
Загрузка mipmapped текстур, делая это так:
- (id) initWithUIImage: (UIImage * const) image {
glGenTextures(1, &name);
//JNLogString(@"Recieved name(%d), binding texture", name);
glBindTexture(GL_TEXTURE_2D, name);
//Set the needed parameters for the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//Load the image data into the texture
glGenerateMipmap(GL_TEXTURE_2D);
return self;
}
Это, похоже, ничего не делает для нашего FPS, я думаю, это потому, что наши текстуры уже примерно соответствуют размеру, который они отображают на экране, в большинстве случаев даже 1: 1.
Другие решения приветствуются! Я опробую их и выложу результаты здесь