Текстурные координаты 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, ширина] имеют следующий вид

Ссылка

  1. p270 в https://www.khronos.org/registry/gles/specs/3.1/es_spec_3.1.pdf
  2. https://www.opengl.org/sdk/docs/man/html/gl_FragCoord.xhtml
  3. https://www.opengl.org/wiki/Sampler_(GLSL)
Другие вопросы по тегам