OpenGL - GLenum如何是无符号的32位整数?

时间:2013-12-29 20:13:23

标签: opengl enums opengl-4

首先,OpenGL中有8种类型的缓冲区对象:

  • GL_ARRAY_BUFFER
  • GL_ELEMENT_ARRAY_BUFFER
  • GL_COPY_READ_BUFFER
  • ...

它们是枚举,或者更具体地说是GLenum。其中GLenum是一个无符号的32位整数,其值最多可达~4,743,222,432。

缓冲区对象的大部分用法都涉及将它们绑定到某个目标,例如:

glBindBuffer(GL_ARRAY_BUFFER,Buffers [size]);

[void glBindBuffer(GLenum target,GLuint buffer)]文档

我的问题是 - 如果它的枚举它的唯一值必须分别为0,1,2,3,4..7那么为什么要一直使用并使其成为32位整数,如果它只有值到7?请原谅我对CS和OpenGL的了解,这似乎是不道德的。

2 个答案:

答案 0 :(得分:6)

枚举不仅仅用于缓冲区 - 但是在任何地方都需要符号常量。目前,已分配了几千个枚举值(查看您的GL.h和最新的glext.h。请注意,供应商会分配其官方枚举范围,以便他们可以实现特定于供应商的扩展而不会干扰其他人 - 所以32Bit枚举空间并不是一个坏主意。此外,在现代CPU架构中,使用低于32Bit的效率将不会更高,因此这在性能方面不是问题。

<强>更新 正如Andon M. Coleman指出的那样,目前只有16Bit的枚举范围被分配。在OpenGL Enumerant Allocation Policies链接可能很有用,它也有以下注释:

  

历史上,某些单供应商扩展的枚举值是以块为单位分配的,从块[102000,102999]开始向上进行。此范围中的值不能表示为16位无符号整数。这对某些实现施加了显着且不必要的性能损失。已经分配给供应商的这些块将保持分配,除非并且直到供应商自愿释放整个块,但不会分配此范围内的其他块。

其中大多数似乎已被删除,支持16位值,但32位值已被使用。在当前的glext.h中,仍然可以找到0xffff以上的一些(过时的)枚举,如

#ifndef GL_PGI_misc_hints
#define GL_PGI_misc_hints 1
#define GL_PREFER_DOUBLEBUFFER_HINT_PGI   0x1A1F8
#define GL_CONSERVE_MEMORY_HINT_PGI       0x1A1FD
#define GL_RECLAIM_MEMORY_HINT_PGI        0x1A1FE
...

答案 1 :(得分:0)

为什么你会使用短片呢?你有什么情况可以节省超过8k ram(如果近千个GLenums的报告是正确的),使用short或uint8_t而不是GLuint用于枚举和const声明?考虑到潜在硬件不兼容的问题以及您可能会介绍的潜在跨平台错误,即使在最初的2mb Voodoo3d图形硬件环境中尝试保存8k ram之类的东西也是奇怪的,更不用说SGL超级计算机了。 -farms OpenGL是为。

创建的

此外,现代的x86和GPU硬件一次在32位或64位上对齐,你实际上会停止CPU / GPU的操作,因为寄存器的24或56位必须被清零然后读/写一旦它被复制,它就可以在标准int上运行。从OpenGL开始,计算资源往往比内存更有价值,而你可能会在程序的生命周期中进行数十亿的状态更改。 #39;如果用uint8_t替换每个32位的GLuint枚举,则可以节省大约10kb(千字节)的ram max。我现在很努力,不要过于愤世嫉俗,呵呵。

例如,像uint18_t之类的东西的一个有效原因是大数据缓冲区/算法,其中数据适合该位深度。堆栈上的1024英寸对1024个uint8_t变量是8k,我们要分割超过8k的头发吗?现在考虑4000 * 2500 * 32位的4k原始位图图像,我们说几百兆,如果我们使用64位RGBA缓冲区代替标准8位RGBA8缓冲区,它将是8倍大小,如果我们使用32位RGBA编码,则大小或四倍。乘以打开的纹理数量或保存的图片,并为所有额外的内存交换一些cpu操作是有意义的,特别是在这种类型的工作环境中。

这就是使用非标准整数类型有意义的地方。如果你试图在const声明或引用之类的东西上保存一些内存,那么除非你使用的是64k机器或其他东西(比如老式的蜂鸣器,运行OpenGL就好运气)系统反击你只是在浪费每个人的时间。