Текстурные координаты OpenGL в пространстве пикселей
Я работаю над приложением для iPhone, которое использует OpenGL ES 2 для рисования. Я знаю, что обычно текстурные координаты определяются в диапазоне 0-1, но в идеале я бы хотел отобразить их в 0-1023 (размер моего TextureAtlas) для удобства чтения. Я видел пример кода, который определяет координаты таким образом, но не смог выяснить, какие предыдущие вызовы были сделаны для этого. glMatrixMode(GL_TEXTURE)
кажется, что это может быть связано, но я не совсем уверен, как это реализовать.
Моей конечной целью было бы добиться чего-то подобного, где текстура, которую я бы использовал в атласе, находится в верхнем левом квадрате 48 пикселей:
GLshort texcoords[]={
48,48,
0,48,
48,0,
0,0,
};
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_SHORT, 0, 0, texcoords);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);
3 ответа
Оказывается, это возможно в OpenGl ES 2. Вот как я это сделал:
Фрагмент шейдера:
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D textureSample;
uniform float texScale;
void main()
{
vec2 mult=(2.0*v_texCoord - 1.0)/(2.0*texScale);
gl_FragColor = texture2D(textureSample,mult);
}
Obj-C:
GLshort texCoords[]={
512,512,
0,512,
512,0,
0,0,
};
GLfloat textureWidth = 512.0; //texture size, assumed square, power of 2
texCoordLoc = glGetAttribLocation ( program, "a_texCoord");
GLuint textureScale = glGetUniformLocation ( program, "texScale");
glUniform1f(textureScale, textureWidth);
glVertexAttribPointer ( texCoordLoc, 2, GL_SHORT, GL_FALSE, 0, texCoords);
Если у кого-то есть комментарии о том, как это может работать с точки зрения производительности, мне было бы интересно.
Об этом спрашивали несколько раз, но у меня нет ссылок под рукой, поэтому быстрое и грубое объяснение. Допустим, текстура имеет ширину 8 пикселей:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
^ ^ ^ ^ ^ ^ ^ ^ ^
0.0 | | | | | | | 1.0
| | | | | | | | |
0/8 1/8 2/8 3/8 4/8 5/8 6/8 7/8 8/8
Цифрами обозначены пиксели текстуры, столбцы - края текстуры, а в случае ближайшей фильтрации - граница между пикселями. Однако вы хотите поразить центры пикселей. Итак, вы заинтересованы в координатах текстуры
(0/8 + 1/8) / 2 = 1 / (2 * 8)
(1/8 + 2/8) / 2 = 3 / (2 * 8)
...
(7/8 + 8/8) / 2 = 15 / (2 * 8)
Или, в более общем случае, для пикселя i в текстуре шириной N правильная координата текстуры
(2i + 1)/(2N)
Однако, если вы хотите идеально выровнять текстуру по пикселям экрана, помните, что то, что вы указываете в качестве координат, - это не пиксели квадрата, а кромки, которые в зависимости от проекции могут совпадать с краями пикселов экрана, а не по центрам, поэтому может потребоваться другая текстура координаты.
Я трачу 1 час, чтобы найти интуитивную фигуру, но на удивление никто не рисовал. Так я и сделал.
При заданной 4-пиксельной текстуре, нормализованная координата текстуры [0,1], ненормализованная координата текстуры [0, ширина), gl_FragCoord [0, ширина] имеют следующий вид
Ссылка