像素空间中的OpenGL纹理坐标

我正在开发一个使用OpenGL ES 2进行绘图的iPhone应用程序。 我知道通常纹理坐标是在0-1范围内定义的,但是为了便于阅读,理想情况下我想从0-1023(我的TextureAtlas的大小)映射它们。 我已经看到了以这种方式定义坐标的示例代码,但是还没有能够列出之前做过的调用。 glMatrixMode(GL_TEXTURE)似乎可能涉及到,但我不太清楚如何实现它。

我的最终目标是完成这样的事情,在图集里我将使用的纹理是在左上angular的48px square:

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

这已经被问了几次了,但是我手边没有链接,所以做了一个快速而粗略的解释。 假设纹理宽度为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)

或者更一般地,对于N宽纹理中的像素i,适当的纹理坐标是

(2i + 1)/(2N)

但是,如果要将纹理与屏幕像素完美alignment,请记住,您指定的坐标不是四边形的像素,而是边缘,这取决于投影可能与屏幕像素边缘alignment,而不是中心,因此可能需要其他纹理坐标。

我浪费了1个小时find直观的人物,但令人惊讶的是没有人画。 所以我做了。

给定4像素纹理,归一化纹理坐标[0,1],非标准化纹理坐标[0,宽度],gl_FragCoord [0,宽度]如下

在这里输入图像描述

参考

  1. https://www.khronos.org/registry/gles/specs/3.1/es_spec_3.1.pdf中的; p270
  2. https://www.opengl.org/sdk/docs/man/html/gl_FragCoord.xhtml
  3. https://www.opengl.org/wiki/Sampler_(GLSL);

原来在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); 

如果有人对这如何在性能上起作用有评论,我会感兴趣。