Как использовать битовые операции в GLSL 1.3 с OpenGL 2.1 - PullRequest
4 голосов
/ 09 июля 2011

Я пытаюсь написать шейдер, который использует много битовых операций. На самом деле они поддерживаются начиная с glsl 1.30, но я использую только OpenGL 2.1.

Можно ли использовать битовые операции с моей версией OpenGL?

Ответы [ 2 ]

3 голосов
/ 09 июля 2011

Все совместимое с SM3 (~ OpenGL 2.1) аппаратное обеспечение поддерживает ограниченную целочисленную функциональность. Обычно это делается путем эмуляции целых чисел с плавающей точкой, и не включает битовые операции.

Для битовых операций вам потребуется либо GLSL 1.3, либо EXT_gpu_shader4 .

Если причина, по которой у вас есть только OpenGL 2.1, заключается в том, что ваш драйвер несколько устарел, возможно, вам повезет, если у вас все еще есть EXT_gpu_shader4 (хотя обновление драйверов может быть хорошей идеей в этом случае).

Если причина в том, что ваша видеокарта просто не поддерживает ничего лучше, вам не повезло.

Если у вас есть EXT_gpu_shader4 (проверьте строку расширения), вы можете добавить:

#extension EXT_gpu_shader4 : require

на ваши шейдеры GLSL 1.2, и это должно работать.

0 голосов
/ 19 мая 2014

Это должно помочь вам начать работу.

lowp ivec4 imod4_2(lowp ivec4 x)
{
  return x - (2 * (x/2));
}

lowp ivec4 parselowbits(lowp int x)
{
  // Implement (x % y) where y is known to be the constant 2
  // by first dividing x by (8, 4, 2, 1) and then doing a mod
  // by (2, 2, 2, 2) to generate an int vector.

  lowp ivec4 numerator = ivec4(x);
  lowp ivec4 denominator = ivec4(8, 4, 2, 1);
  lowp ivec4 modNumerator = numerator / denominator;
  lowp ivec4 modResult = imod4_2(modNumerator);

  return modResult;
}

lowp ivec4 parsehighbits(lowp int x)
{
  // Implement (x % y) where y is known to be the constant 2
  // by first dividing by (8*16, 4*16, 2*16, 1*16) and then doing a mod
  // by (2, 2, 2, 2) to generate an int vector.

  lowp ivec4 numerator = ivec4(x);
  lowp ivec4 denominator = ivec4(8*16, 4*16, 2*16, 1*16);
  lowp ivec4 modNumerator = numerator / denominator;
  lowp ivec4 modResult = imod4_2(modNumerator);

  return modResult;
}

Вышеуказанные функции работают на верхнем и нижнем полубайтах (4 бита) компонента, такого как .r .g входного вектора. Вам, конечно, нужно будет прочитать значения и умножить их на 255, чтобы денормализовать. Тогда реализовать AND просто:

lowp ivec4 and4(lowp ivec4 a, lowp ivec4 b)
{
 lowp ivec4 a_and_b = a * b;
 return a_and_b;
}
...