Coordenadas de textura OpenGL en espacio de píxeles

Estoy trabajando en una aplicación de iPhone que usa OpenGL ES 2 para su dibujo. Sé que típicamente las coordenadas de textura están definidas en el rango de 0-1, pero idealmente me gustaría asignarlas de 0 a 1023 (el tamaño de mi TextureAtlas) por motivos de legibilidad. He visto un código de muestra que define las coordenadas de esta manera, pero no he podido averiguar qué llamadas anteriores se hicieron para eso. glMatrixMode(GL_TEXTURE) parece que podría estar involucrado, pero no estoy muy seguro de cómo implementarlo.

Mi objective final sería lograr algo como esto, donde la textura que usaría dentro del atlas se encuentra en la esquina superior izquierda de 48 píxeles:

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

Esto se ha pedido algunas veces, pero no tengo los enlaces a mano, por lo que una explicación rápida y aproximada. Digamos que la textura tiene 8 píxeles de ancho:

  | 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 

Los dígitos denotan los píxeles de la textura, las barras los bordes de la textura y, en el caso de filtrar más cerca, el límite entre los píxeles. Sin embargo, desea golpear los centros de los píxeles. Entonces, estás interesado en las coordenadas de la 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)

O más generalmente para pixel i en una textura N amplia, la coordenada de textura adecuada es

(2i + 1) / (2N)

Sin embargo, si desea alinear perfectamente su textura con los píxeles de la pantalla, recuerde que lo que especifica como coordenadas no son píxeles de un cuádruple, sino bordes que, según la proyección, pueden alinearse con los bordes de los píxeles de la pantalla, no con los centros. coordenadas

Pierdo 1 hora para encontrar una figura intuitiva, pero sorprendentemente nadie pintó. Así que lo hice.

Dada la textura de 4 píxeles, la coordenada de textura normalizada [0,1], la coordenada de textura no normalizada [0, ancho), gl_FragCoord [0, ancho] son ​​las siguientes

enter image description here

Referencia

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

Resulta que esto es posible en OpenGl ES 2. Así es como lo logré:

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

Si alguien tiene comentarios sobre cómo esto podría funcionar en cuanto a rendimiento, me interesaría.