Позиционирование элементов в 2D пространстве с помощью OpenGL ES - PullRequest
7 голосов
/ 12 июля 2009

В свободное время я люблю поиграть с разработкой игр для 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 пока что. Спасибо!

Ответы [ 3 ]

6 голосов
/ 13 июля 2009

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

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

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

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

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

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

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

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

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

4 голосов
/ 18 июля 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.

1 голос
/ 18 июля 2009

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

...