Размещение элементов в 2D-пространстве с помощью OpenGL ES

В свободное время я люблю поиграть с разработкой игр на iPhone с помощью OpenGL ES. Я собираю небольшую демонстрацию 2D-скроллера для развлечения, и я относительно новичок в OpenGL, и мне хотелось услышать мнение более опытных разработчиков по этому поводу.

Итак, вот мой вопрос: имеет ли смысл указывать вершины каждого 2D-элемента в пространстве модели, а затем переводить каждый элемент в его окончательное пространство просмотра каждый раз, когда отрисовывается кадр?

Например, скажем, у меня есть набор блоков (квадратов), которые составляют землю в моем боковом скроллере. Каждый квадрат определяется как:

const GLfloat squareVertices[] = {
        -1.0, 1.0, -6.0,            // Top left
        -1.0, -1.0, -6.0,           // Bottom left
        1.0, -1.0, -6.0,            // Bottom right
        1.0, 1.0, -6.0              // Top right
    }

Скажем, у меня есть 10 таких квадратов, которые мне нужно скомпоновать в качестве фона для следующего кадра. Должен ли я сделать что-то подобное для каждого квадрата, видимого в текущей сцене?

glPushMatrix();
{
    glTranslatef(currentSquareX, currentSquareY, 0.0);
    glVertexPointer(3, GL_FLOAT, 0, squareVertices);
    glEnableClientState(GL_VERTEX_ARRAY);

    // Do the drawing
}
glPopMatrix();

Мне кажется, что выполнение этого для каждого 2D-элемента в сцене, для каждого кадра становится немного напряженным, и я могу представить, что более умные люди, которые используют OpenGL гораздо чаще, чем я, могут иметь лучший способ сделать это.

При всем сказанном я ожидаю услышать, что мне следует профилировать код и посмотреть, где могут быть узкие места: этим людям я говорю: я еще не написал ни одного этого кода, я просто в процессе обдумывать это, чтобы, когда я все-таки собираюсь писать, все шло гладко.

Что касается профилирования и оптимизации, я действительно не пытаюсь преждевременно оптимизировать здесь, я просто пытаюсь понять, как можно настроить 2D-сцену и отрендерить ее. Как я уже сказал, я относительно новичок в OpenGL и просто пытаюсь понять, как все это делается. Если у кого-то есть предложения по тому, как это сделать лучше, я хотел бы услышать ваши мысли.

Имейте в виду, что меня не интересует 3D, пока только 2D. Спасибо!


person Rob    schedule 12.07.2009    source источник


Ответы (3)


Вас беспокоят накладные расходы, необходимые для преобразования модели (в данном случае квадрата) из координат модели в мировые координаты, когда у вас много моделей. Это кажется очевидной оптимизацией для статических моделей.

Если вы построите вершины своего квадрата в мировых координатах, то, конечно, это будет быстрее, поскольку каждый квадрат позволит избежать дополнительных затрат на эти три функции (glPushMatrix, glPopMatrix и glTranslatef), поскольку нет необходимости переводить из модели в мир. координаты во время рендеринга. Я понятия не имею, насколько это будет быстрее, я подозреваю, что это не будет огромной оптимизацией, и вы потеряете модульность сохранения квадратов в координатах модели: что, если в будущем вы решите, что хотите, чтобы эти квадраты можно было перемещать ? Это будет намного сложнее, если вы сохраните их вершины в мировых координатах.

Короче говоря, это компромисс:

Мировые координаты

  • Больше памяти - каждому квадрату нужен свой набор вершин.
  • Меньше вычислений - нет необходимости выполнять glPushMatrix, glPopMatrix или glTranslatef для каждого квадрата во время рендеринга.
  • Менее гибкий - отсутствует поддержка (или усложняет) динамическое перемещение этих квадратов.

Координаты модели

  • Меньше памяти - квадраты могут использовать одни и те же данные вершин
  • Больше вычислений - каждый квадрат должен выполнять три дополнительных функции во время рендеринга.
  • Более гибкий - квадраты можно легко перемещать, манипулируя вызовом glTranslatef.

Я думаю, единственный способ узнать, какое решение является правильным, - это делать и профилировать. Я знаю, что вы сказали, что еще не написали этого, но я подозреваю, что независимо от того, находятся ли ваши квадраты в координатах модели или мира, это не будет иметь большого значения - а если это так, я не могу представить архитектуру, которую вы могли бы создайте там, где было бы сложно переключить ваши квадраты с модельных на мировые координаты или наоборот.

Удачи вам и ваших приключений в разработке игр для iPhone!

person Andrew Garrison    schedule 12.07.2009
comment
Спасибо, это отличный ответ. Я подозревал, что придется пойти на компромисс, как вы описали. Я думаю, что сначала я попробую координаты модели, в ожидании некоторых тестов. - person Rob; 13.07.2009

Если вы используете только квадраты с выравниванием по экрану, возможно, будет проще использовать OES Расширение Draw Texture. Затем вы можете использовать одну текстуру для хранения всех ваших игровых «спрайтов». Сначала укажите прямоугольник обрезки, задав GL_TEXTURE_CROP_RECT_OES TexParameter. Это граница спрайта внутри большей текстуры. Для рендеринга вызовите glDrawTexiOES, передав желаемое положение и размер в координатах области просмотра.

int rect[4] = {0, 0, 16, 16};
glBindTexture(GL_TEXTURE_2D, sprites);
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, rect);
glDrawTexiOES(x, y, z, width, height);

Это расширение доступно не на всех устройствах, но отлично работает на iPhone.

person hyperlogic    schedule 18.07.2009
comment
Очень круто! Придется попробовать, я работаю над iPhone - звучит очень интересно. - person Rob; 18.07.2009

Вы также можете подумать об использовании статического изображения и просто его прокрутки вместо рисования каждого отдельного блока пола, перевода его положения и т. Д.

person Community    schedule 18.07.2009