(怎么样)标量可以转换为另一个标量而不用GLSL转换?

use*_*655 2 opengl casting glsl

(怎么样)标量可以转换为另一个标量而不用GLSL转换?

假设这两种类型具有相同的位数,则该问题中使用的"强制转换"的定义是在不改变数据本身的情况下改变对完全相同数据的解释.即(浮动)B00101111 == B00101111

在这个问题中使用的"转换"的定义是改变数据的解释以及将所述数据重新格式化为原始值的某些数学近似,即(float)1 == 1.0

GLSL 4.30.6规范的5.4.3暗示标量float-to-int和int-to-float构造函数仅执行转换: "当构造函数用于将任何浮点类型转换为整数类型时,小数部分浮点值被删除." - pg.87

棺材中的另一个钉子是5.1节上的这条线,pg.85: "没有类型转换操作符;而是使用构造函数."

目标是使用Buffer-Texture/Texture-Buffer和texelFetch(...)来获取float vec4s(128bit)并填充结构,例如:

struct MyStruct
{
int foo; //32bit
float bar; //32bit
int baz; //32bit
short blah; //16bit
short hmm; //16bit
} // 128bit total
Run Code Online (Sandbox Code Playgroud)

...但是很难确定如何将vec4分解为二进制子块并重新构建它们以设置所述结构值.

以下是理论上的工作吗?

MyStruct myUuberChunk = MyStruct(myVec4);
Run Code Online (Sandbox Code Playgroud)

使用float vec4s(或int vec4s)背后的理由是正确的,是为了带宽性能而将所有值都放在一个128位的读取中(大多数卡有四个32位内存总线).

Nic*_*las 6

以下是理论上的工作吗?

没有.

GLSL不允许您直接重新解释结构.虽然GLSL(3.30+)确实保证整数和浮点数是32位,但你不能只采用vec4并假装它是别的东西.

但是,OpenGL 3.3+允许您重新解释单个标量值.首先,您的代码应该使用整数缓冲区纹理,而不是浮点纹理.这只是为了防止texel提取逻辑在非元化值,NaN或其他浮点怪异的情况下做一些不愉快的事情.

因此,你应该使用a usamplerBuffer并取回a uvec4.

要获得实际值,您必须进行一些重新解释,由适当的库函数提供:

struct Data
{
  int first;
  float value;
  int second;
  int half1;
  int half2;
};

Data UnpackStruct(uvec4 packed)
{
  Data ret;
  ret.first = int(packed[0]); //Sign bit is preserved, per GLSL standard.
  ret.value = uintBitsToFloat(packed[1]);
  ret.second = int(packed[2]);
  ret.half1 = (packed[3] >> 16) & 0x0000FFFF;
  ret.half2 = packed[3] & 0x0000FFFF;
  return ret;
}
Run Code Online (Sandbox Code Playgroud)