glDrawArrays () медленно на iPad? - PullRequest
1 голос
/ 05 мая 2010

Мне было интересно, как ускорить работу приложения на 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.

Другие решения приветствуются! Я опробую их и выложу результаты здесь

Ответы [ 2 ]

2 голосов
/ 11 мая 2010

У меня была ветвь в моем фрагментном шейдере. Я думал, что это не сильно напрягало, но это так! В любом случае, это была вся проблема, я удалил ветку, и теперь мой FPS почти удвоился.

2 голосов
/ 05 мая 2010

Если вы используете очень большие текстуры, попробуйте создать текстуры mipmap. Стоимость составляет в основном 1/3 оригинальной текстуры памяти. Я думаю, что они могут быть созданы с помощью этого вызова при настройке текстур.

glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);

Некоторые расчеты: если у вас есть 3 текстуры 2048x2048 (максимальный размер) с частотой 15 Гц, у вас будет пропускная способность текселей (если они полностью показаны, т.е. уменьшены до разрешения экрана) 2048x2048x3x15 = 188,743,680 / сек, что примерно соответствует значению, которое мы см. glbenchmark.com , чтобы узнать скорость одиночного заполнения (173 мтекселя / с). Но если вы используете текстуры mipmap, пропускная способность текселей должна быть ближе к разрешению размера экрана (1024x768), которое должно быть примерно 1/4 от предыдущей пропускной способности.

...