Coordenadas de textura do OpenGL no espaço do pixel

Eu estou trabalhando em um aplicativo para iPhone que usa OpenGL ES 2 para o seu desenho. Eu sei que tipicamente coordenadas de texturas são definidas no intervalo de 0-1, mas idealmente eu gostaria de mapeá-las de 0-1023 (o tamanho do meu TextureAtlas) por questões de legibilidade. Eu vi código de exemplo que define coordenadas dessa maneira, mas não consegui descobrir quais chamadas anteriores foram feitas que permitiam isso. glMatrixMode(GL_TEXTURE) parece estar envolvido, mas não tenho certeza de como implementá-lo.

Meu objective final seria realizar algo assim, onde a textura que eu estaria usando dentro do atlas está no quadrado superior esquerdo de 48px:

 GLshort texcoords[]={ 48,48, 0,48, 48,0, 0,0, }; glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_SHORT, 0, 0, texcoords); glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON); 

    Isso foi perguntado algumas vezes, mas eu não tenho os links à mão, então uma explicação rápida e aproximada. Digamos que a textura tenha 8 pixels de largura:

      | 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 

    Os dígitos denotam os pixels da textura, as barras as bordas da textura e, no caso de filtragem mais próxima, a borda entre os pixels. Você, no entanto, quer atingir os centros dos pixels. Então você está interessado nas coordenadas da textura

    (0/8 + 1/8) / 2 = 1 / (2 * 8)

    (1/8 + 2/8) / 2 = 3 / (2 * 8)

    (7/8 + 8/8) / 2 = 15 / (2 * 8)

    Ou, mais geralmente, para o pixel i em uma textura N ampla, a coordenada de textura apropriada é

    (2i + 1) / (2N)

    No entanto, se você quiser alinhar perfeitamente sua textura com os pixels da canvas, lembre-se de que o que você especifica como coordenadas não são pixels de um quadrilátero, mas arestas que, dependendo da projeção, podem se alinhar com as bordas do pixel da canvas. coordenadas.

    Eu perco 1 hora para encontrar figura intuitiva, mas surpreendentemente ninguém pintou. Então eu fiz.

    Dada a textura de 4 pixels, coordenada de textura normalizada [0,1], coordenada de textura não normalizada [0, largura), gl_FragCoord [0, largura] são as seguintes

    insira a descrição da imagem aqui

    Referência

    1. p270 em 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)

    Acontece que isso é possível no OpenGl ES 2. Veja como consegui:

    Fragmento Shader:

     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); 

    Se alguém tiver comentários sobre como isso pode funcionar no desempenho, eu estaria interessado.