Как использовать GL_REPEAT, чтобы повторять только выделение текстурного атласа? (OpenGL) - PullRequest
18 голосов
/ 19 марта 2009

Как мне повторить выделение текстурного атласа?

Например, мой спрайт (выделение) находится в пределах координат текстуры:

GLfloat textureCoords[]=
{
    .1f,  .1f,
    .3f,  .1f,
    .1f,  .3f,
    .3f,  .3f
};

Затем я хочу повторить этот спрайт N раз до треугольной полосы (или четырехугольника), определенной:

GLfloat vertices[]=
{
   -100.f, -100.f,
    100.f, -100.f,
   -100.f,  100.f,
    100.f,  100.f
};

Я знаю, что это как-то связано с GL_REPEAT, и textureCoords проходит диапазон [0,1]. Это, однако, не работает: (пытается повторить N = 10)

GLfloat textureCoords[]=
{
    10.1f,  10.1f,
    10.3f,  10.1f,
    10.1f,  10.3f,
    10.3f,  10.3f
};

Мы видим повторение нашего полного текстурного атласа ...

Как бы я поступил правильно?

Ответы [ 5 ]

18 голосов
/ 19 марта 2009

Это невозможно сделать так, как описано в вопросе. Режимы координат текстуры OpenGL применяются только для всей текстуры.

Обычно, чтобы повторить текстуру, вы должны нарисовать многоугольник, который «больше», чем подразумевает ваша текстура. Например, если у вас была квадратная текстура, которую вы хотели бы повторить несколько раз (скажем, шесть) на большей площади, вы бы нарисовали прямоугольник, который в шесть раз шире его высоты. Затем вы бы задали координаты текстуры (0,0) - (6,1), а режим текстуры «повторил». При интерполяции по многоугольнику координата текстуры, которая выходит за пределы 1, из-за включения повторения будет «обтекать» в текстуре, вызывая отображение текстуры шесть раз по прямоугольнику.

Ни один из режимов обтекания текстурой не поддерживает вид операции, описанный в вопросе, т. Е. Все они отображаются в полный диапазон [0,1], а не в произвольное подмножество. когда вы текстурируете, используя только часть текстуры, невозможно указать эту большую текстурную координату так, чтобы OpenGL повторял ее только внутри под прямоугольника.

В основном у вас есть два варианта: либо создать новую текстуру, которая имеет только тот спрайт, который вам нужен из существующей текстуры, либо написать вершинную программу GLSL для правильного отображения координат текстуры.

6 голосов
/ 19 марта 2009

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

Могут быть расширения, чтобы справиться с этим, я не проверял.

РЕДАКТИРОВАТЬ: Обычно, чтобы повторить текстуру, вы должны нарисовать многоугольник, который «больше», чем предполагает ваша текстура. Например, если у вас была квадратная текстура, которую вы хотели бы повторить несколько раз (скажем, шесть) на большей площади, вы бы нарисовали прямоугольник, который в шесть раз шире его высоты. Затем вы бы задали координаты текстуры (0,0) - (6,1), а режим текстуры «повторил». При интерполяции по полигону координата текстуры, выходящая за пределы 1, из-за включенного повторения будет «обтекать» текстуру, вызывая отображение текстуры шесть раз по прямоугольнику.

Это немного грубо, чтобы объяснить без изображений.

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

5 голосов
/ 19 марта 2009

Ни один из режимов обтекания текстурой не поддерживает требуемый тип операции, т. Е. Все они отображаются в полный диапазон [0,1], а не в произвольное подмножество. В основном у вас есть два варианта: либо создать новую текстуру, которая имеет только тот спрайт, который вам нужен, из существующей текстуры, либо написать пиксельную программу GLSL для правильного отображения координат текстуры.

1 голос
/ 09 декабря 2011

Пока это может быть старая тема; вот как я это сделал:

Обходным решением будет создание нескольких сеток, склеенных вместе, содержащих подмножество текстурных UV.

т.д .: У меня есть лазерная текстура, содержащаяся в большем текстурном атласе, при U [0,05-0,1] и V [0,05-0,1].

Я бы тогда построил N сеток, каждая из которых имела бы координаты U [0,05-0,1] и V [0,05-0,1]. (N = длина / текстура. Высота; высота - это размер текстуры, который я хотел бы повторить. Или проще: сколько раз я хочу повторить текстуру.)

Это решение будет более экономичным, чем перезагрузка текстуры после текстуры. Особенно, если вы пакетируете все вызовы рендеринга (как вы должны).

(OpenGL ES 1.0,1.1,2.0 - Мобильное оборудование 2011)

0 голосов
/ 19 марта 2009

Не может быть сделано ...

...