像素空间中的OpenGL纹理坐标

Sam*_*Sam 15 iphone cocoa-touch opengl-es objective-c

我正在开发一款使用OpenGL ES 2进行绘图的iPhone应用程序.我知道通常纹理坐标是在0-1范围内定义的,但理想情况下我想将它们从0-1023(我的TextureAtlas的大小)映射出来以便于阅读.我已经看到了以这种方式定义坐标的示例代码,但是无法确定以前允许这样做的调用.glMatrixMode(GL_TEXTURE)好像它可能涉及,但我不太确定如何实现它.

我的最终目标是完成这样的事情,我在地图册中使用的纹理位于左上角48px的正方形中:

GLshort texcoords[]={
  48,48,
  0,48,
  48,0,
  0,0,
};
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_SHORT, 0, 0, texcoords);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);
Run Code Online (Sandbox Code Playgroud)

dat*_*olf 44

这已被问了好几次,但我手边没有链接,所以快速而粗略的解释.假设纹理宽度为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
Run Code Online (Sandbox Code Playgroud)

数字表示纹理的像素,条纹表示纹理的边缘,并且在最近的情况下过滤像素之间的边界.但是你想要点击像素的中心.所以你对纹理坐标感兴趣

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

但是,如果您想要将纹理与屏幕像素完美对齐,请记住您指定为坐标的不是四边形像素,而是边缘,根据投影可能与屏幕像素边缘对齐,而不是中心,因此可能需要其他纹理坐标.

  • @datenwolf OpenGL ES 2.0中没有纹理矩形或texelFetch. (5认同)

小智 8

我浪费了1个小时来找到直观的身材,但令人惊讶的是没有人画画.所以我做了.

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

在此输入图像描述

参考

  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)

  • 好像这张图中有一个拼写错误,“Norm tex coord”应该是“0.125 到 0.875” (7认同)

Sam*_*Sam 4

事实证明,这在 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);
}
Run Code Online (Sandbox Code Playgroud)

对象-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);
Run Code Online (Sandbox Code Playgroud)

如果有人对这如何在性能方面发挥作用有评论,我会很感兴趣。

  • 好吧,您不需要每帧都调用 glGetAttribLocation/glGetUniformLocation。将结果保存在变量中。但我认为性能差异可以忽略不计。 (2认同)