Выборка текстур в Open GL - PullRequest
       9

Выборка текстур в Open GL

1 голос
/ 08 октября 2008

Мне нужно получить цвет по определенной координате из текстуры. Есть два способа сделать это: получить и просмотреть необработанные данные png или сэмплировать мою сгенерированную текстуру opengl Можно ли сэмплировать текстуру opengl, чтобы получить цвет (RGBA) с заданными координатами UV или XY? Если да, то как?

Ответы [ 3 ]

2 голосов
/ 08 октября 2008

Вне моей головы, ваши варианты

  1. Получите всю текстуру, используя glGetTexImage (), и проверьте интересующий вас текст.
  2. Нарисуйте интересующий вас тексель (например, рендерингом примитива GL_POINTS), затем захватите пиксель, в котором вы его отрендерили, из кадрового буфера, используя glReadPixels.
  3. Держите копию изображения текстуры под рукой и не используйте OpenGL.

Опции 1 и 2 ужасно неэффективны (хотя вы могли бы немного ускорить 2, используя объекты pixel-buffer-буфера и делая копию асинхронно). Так что мой любимый по FAR вариант 3.

Редактировать: Если у вас есть расширение GL_APPLE_client_storage (т. Е. Вы на Mac или iPhone), то это вариант 4, который в конечном итоге победит.

2 голосов
/ 08 октября 2008

Самый эффективный способ, который я нашел, - это получить доступ к данным текстуры (вам все равно нужно декодировать наш PNG, чтобы превратить в текстуру) и самостоятельно интерполировать тексели. Предполагая, что ваши texcoords равны [0,1], умножьте texwidth u и texheight v и затем используйте это, чтобы найти положение на текстуре. Если они являются целыми числами, просто используйте пиксель напрямую, в противном случае используйте части int, чтобы найти ограничивающие пиксели и интерполировать их на основе дробных частей.

Вот некоторый HLSL-подобный psuedocode для него. Должно быть достаточно ясно:

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
}
0 голосов
/ 08 октября 2008

Как и предполагали другие, чтение текстуры из VRAM ужасно неэффективно, и его следует избегать, как чумы, если вы даже отдаленно заинтересованы в производительности.

Насколько мне известно, два выполнимых решения:

  1. Держите копию пиксельных данных под рукой (впрочем, впустую тратит память)
  2. Сделайте это с помощью шейдера
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...