Open GL中的纹理采样

时间:2008-10-08 07:50:43

标签: c++ opengl

我需要从纹理中获取特定坐标的颜色。通过获取和查看原始png数据,或者通过对生成的opengl纹理进行采样,我有两种方法可以做到这一点。是否可以对opengl纹理进行采样以获得给定UV或XY坐标的颜色(RGBA)?如果是这样,怎么样?

3 个答案:

答案 0 :(得分:2)

我发现这样做的最有效方法是访问纹理数据(你应该将我们的PNG解码为纹理)并自己在纹素之间进行插值。假设你的texcoords是[0,1],将texwidth u和texheight v相乘,然后用它来找到纹理上的位置。如果它们是整数,只需直接使用像素,否则使用int部分找到边界像素,并根据小数部分在它们之间进行插值。

这里有一些类似HLSL的伪代码。应该相当清楚:

float3 sample(float2 coord, texture tex) {
    float x = tex.w * coord.x; // Get X coord in texture
    int ix = (int) x; // Get X coord as whole number
    float y = tex.h * coord.y;
    int iy = (int) y;

    float3 x1 = getTexel(ix, iy); // Get top-left pixel
    float3 x2 = getTexel(ix+1, iy); // Get top-right pixel
    float3 y1 = getTexel(ix, iy+1); // Get bottom-left pixel
    float3 y2 = getTexel(ix+1, iy+1); // Get bottom-right pixel

    float3 top = interpolate(x1, x2, frac(x)); // Interpolate between top two pixels based on the fractional part of the X coord
    float3 bottom = interpolate(y1, y2, frac(x)); // Interpolate between bottom two pixels

    return interpolate(top, bottom, frac(y)); // Interpolate between top and bottom based on fractional Y coord
}

答案 1 :(得分:2)

离开我的头顶,你的选择是

  1. 使用glGetTexImage()获取整个纹理并检查您感兴趣的纹素。
  2. 绘制您感兴趣的纹素(例如,通过渲染GL_POINTS原语),然后使用glReadPixels抓取从帧缓冲区渲染它的像素。
  3. 保留纹理图像的副本,并将OpenGL从其中移除。
  4. 选项1和2非常低效(尽管你可以通过使用像素缓冲区对象并异步进行复制来加快速度2)。所以我最喜欢的FAR是选项3。

    编辑:如果您有GL_APPLE_client_storage分机(即您使用的是Mac或iPhone),那么选项4就是胜利者。

答案 2 :(得分:0)

正如其他人所建议的那样,从VRAM读取纹理效率非常低,如果你对性能有兴趣,应该像瘟疫一样避免。

据我所知,有两个可行的解决方案:

  1. 保留pixeldata的副本(虽然浪费内存)
  2. 使用着色器
  3. 进行