像素空间中的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,宽度]如下
参考
原来在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);
如果有人对这如何在性能上起作用有评论,我会感兴趣。