Координаты текстуры OpenGL ES слегка отключены - PullRequest
11 голосов
/ 17 мая 2011

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

Вот идея того, что я описываю. В этом случае я бы хотел выбрать зелено-белую область 6х5, но то, что представляет OpenGL, включает в себя легкий розовый оттенок для верхнего и левого пикселей. Offset Illustration

Как будет выглядеть вывод:

Resulting Output Texture

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

псевдокод:

float uFactor = regionWidth / textureWidth;   // For the example: 0.6f
float vFactor = regionHeight / textureHeight; // For the example: 0.5f

data[0].t[0] = 0.0f * uFactor;
data[0].t[1] = 0.0f * vFactor;
data[1].t[0] = 1.0f * uFactor;
data[1].t[1] = 0.0f * vFactor;
data[2].t[0] = 0.0f * uFactor;
data[2].t[1] = 1.0f * vFactor;
data[3].t[0] = 1.0f * uFactor;
data[3].t[1] = 1.0f * vFactor;

glPushMatrix();

// translate/scale/bind operations

glTexCoordPointer(2, GL_FLOAT, 0, data[0].t);

Ответы [ 2 ]

18 голосов
/ 19 мая 2011

Имейте в виду, что OpenGL пробует текстуры в центрах текселей. Таким образом, при использовании линейной фильтрации (например, GL_LINEAR или GL_LINEAR_MIPMAP_LINEAR) точный цвет текселя возвращается только в случае выборки в центре текселя. Таким образом, когда вы хотите использовать только субрегион текстуры, вам нужно отступить координаты текстуры на половину текселя (или 0.5/width и 0.5/height). В противном случае фильтрация смешает границу текстуры с соседними текселями за пределами предполагаемой области. Это вызывает вашу слегка розоватую окантовку. Если вы используете всю текстуру, этот эффект компенсируется режимом обтекания GL_CLAMP_TO_EDGE, но при использовании субрегиона GL не знает, где находится его край, и что фильтрация не должна пересекать его.

Таким образом, когда вы получили субрегион текстуры в диапазоне [s1,s2]x[t1,t2] (0 <= s,t <= 1), реальный действительный интервал texCoord должен быть [s1+x,s2-x]x[t1+y,t2-y] с x равным 0.5/width и y being 0.5/height ( ширина и высота всей текстуры, соответствующей [0,1]x[0,1]).

Поэтому попробуйте

data[0].t[0] = 0.0f * uFactor + 0.5/textureWidth;
data[0].t[1] = 0.0f * vFactor + 0.5/textureHeight;
data[1].t[0] = 1.0f * uFactor - 0.5/textureWidth;
data[1].t[1] = 0.0f * vFactor + 0.5/textureHeight;
data[2].t[0] = 0.0f * uFactor + 0.5/textureWidth;
data[2].t[1] = 1.0f * vFactor - 0.5/textureHeight;
data[3].t[0] = 1.0f * uFactor - 0.5/textureWidth;
data[3].t[1] = 1.0f * vFactor - 0.5/textureHeight;
4 голосов
/ 17 мая 2011

Вероятно, это связано с переносом.Попробуйте это при создании исходного изображения:

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP )
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...