Как отобразить текстуру без мощности 2 как спрайт в OpenGL (ES) без растяжения? - PullRequest
3 голосов
/ 21 января 2011

Я хочу нарисовать спрайт произвольного размера в виде png, сказать что-то ПОЛНОСТЬЮ БЕЗУМНОЕ, как 56 в ширину и 30 в высоту. Не степень 2 в обоих измерениях. Также я могу захотеть нарисовать другой спрайт шириной 72 x 33. Указывая на это, потому что здесь нет «уловок», мне нужно разобраться с общим случаем.

Итак, у меня есть этот png (с прозрачностью), и я хочу нарисовать его как спрайт без растяжения, интерполяции и т. Д. Я хочу, чтобы он отображал 1: 1 с пикселями на экране. Притворитесь, что эти спрайты являются пиксельной графикой (они могут или не могут быть, но они нарисованы для точного разрешения).

Я понимаю спрайтовое рисование - 2 треугольника как четырехугольник, отрисовывающий мою текстуру с помощью координатных координат текстуры - однако я понимаю это только для степеней 2. И я также не понимаю, как измерить размер моего «четырехугольника» и настроить моя матрица GL такая, что я могу сделать спрайт точно такого же размера в пикселях, что и мой спрайт

Я использую OpenGL ES, поэтому использование новых расширений для использования текстур не в степени 2 недопустимо.

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

1 Ответ

5 голосов
/ 21 января 2011

Чтобы получить идеальную по пикселям систему координат, вы можете настроить свои матрицы следующим образом:

glViewport(0, window_width, 0, window_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, window_width, 0, window_height, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Это обеспечивает отображение координат OpenGL в пикселях 1: 1 и устанавливает исходную точку внизу.левый угол.

Что касается вашей текстуры, если вы не хотите полагаться на расширение не-степени-двух, вы должны дополнить его степенью двойки.Хотя спецификация OpenGL ES не говорит о том, что она должна быть квадратной (насколько я знаю), я видел странные вещи, происходящие на Android с размерами текстур, такими как 512 x 128, поэтому, возможно, лучше придерживаться квадрат текстуры двух степеней.

Следует отметить, что координаты текстуры в OpenGL всегда находятся в диапазоне от 0 до 1, независимо от размера пикселя вашей текстуры.Так, если ваш спрайт имеет ширину 48 пикселей, и вы добавили его к текстуре 64 x 64, тогда он будет охватывать координаты х от 0 до 0,75:

1 +--------+
  |        |
  |        |
  +-----+  |
  |\_O_/|  |
  |  O  |  |
  | / \ |  |
0 +-----+--+
  0   0.75 1   <- texture coordinates
  0     48 64  <- pixels

Так что вам нужно настроить эти текстурыкоординаты для углов вашего четырехугольника.Поскольку у нас идеальная проекция пикселей, квад также должен иметь ширину ровно 48 пикселей.

В заключение, чтобы нарисовать ваш спрайт в позиции x, y (в пикселях слева внизу), сделайте что-то вроде этого:

float texcoord_x = (float)sprite_width / texture_width;
float texcoord_y = (float)sprite_height / texture_height;

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture_id);

glBegin(GL_QUADS);
// bottom left
glTexCoord2f(0, 0);
glVertex2i(x, y);
// bottom right
glTexCoord2f(texcoord_x, 0);
glVertex2i(x + sprite_width, y);
// top right
glTexCoord2f(texcoord_x, texcoord_y);
glVertex2i(x + sprite_width, y + sprite_height);
// top left
glTexCoord2f(0, texcoord_y);
glVertex2i(x, y + sprite_height);
glEnd();

Я знаю, что OpenGL ES не имеет glVertex2i и так далее, поэтому вам придется поместить эти координаты в буфер.И это не позволяет четырехугольникам, поэтому вам придется разделить его на треугольники.Но это основная идея.

...