OpenGL текстура атлас кровотечение - PullRequest
6 голосов
/ 25 октября 2011

Я пытаюсь нарисовать базовую 2-мерную наземную сетку, составленную из меньших плиток, из текстурного атласа (обратите внимание на прозрачную границу в 1 пиксель):

enter image description here

Я рендерингплитки в виде квадратов текстуры с использованием следующего кода:

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glVertexPointer(2, GL_SHORT, 0, &m_coords[0]);
glTexCoordPointer(2, GL_FLOAT, 0, &m_uvs[0]);

glDrawArrays(GL_TRIANGLES, 0, m_coords.size() / 2);

glBindTexture(GL_TEXTURE_2D, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);

Позиции, очевидно, являются целочисленными координатами.Координаты UV для углов рассчитываются следующим образом:

u0 = float(x) / float(texWidth);
v0 = float(y) / float(texHeight);
u1 = float(x+w) / float(texWidth);
v1 = float(y+h) / float(texHeight);

Где w и h - размер плитки без отступов.

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

enter image description here

Из того, что я понимаю, я должен сместить координаты UV споловина текселя, чтобы заставить его работать, но если я изменю расчеты ультрафиолета на:

u0 = float(x+0.5f) / float(texWidth);
v0 = float(y+0.5f) / float(texHeight);
u1 = float(x+w-0.5f) / float(texWidth);
v1 = float(y+h-0.5f) / float(texHeight);

Это все равно не работает.Это правильный способ сделать это?Нужно ли смешивать, чтобы это работало?Если я смещу плитки, чтобы убедиться, что они привязаны к пиксельной сетке, это работает, но это заставляет их привязываться при медленном движении.Как люди обычно решают это?

РЕДАКТИРОВАТЬ

Я должен был сказать, что это на iphone.

Ответы [ 5 ]

5 голосов
/ 26 октября 2011

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

Вот как вы "обманываете"обёртка для сэмплера текстуры по границам.

2 голосов
/ 12 февраля 2012

У меня была похожая проблема с текстурным атласом. Я исправил это, вставив изображение на 1.0 / TEXTURE_ATLAS_PIXELS_PER_SIDE * 1 / 128.0. Число 128 нужно выяснить экспериментально. Для меня положительным моментом является то, что никто не почувствует, что 128-й пиксель отсутствует. Я сделал эту модификацию для координат текстуры, отправляемых на видеокарту, а не в шейдер. Я не пробовал делать это с текселями в шейдере, как у вас. Я читал различную информацию о том, как справляться с текстурным кровотечением, но для текстурного атласа это было самым простым решением для меня. Добавление границ к моим текстурам, которые плотно упакованы и следуют правилу власти двух, заставило бы меня иметь много свободного пространства.

Это то, что у меня сработало на iphone.

0 голосов
/ 23 декабря 2011

Попробуйте использовать GL_NEAREST для GL_TEXURE_MIN / MAX_FILTER и переведите на 0.375f перед рисованием:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.375f, 0.375f, 0.0f);
0 голосов
/ 26 октября 2011

Вы всегда можете переключить свой GL_TEXTURE_MIN/MAG_FILTER на GL_NEAREST:)

0 голосов
/ 25 октября 2011

У меня была точно такая же проблема. Я исправил это с помощью этого.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
...