我在OpenGL VBO实现中看到了以下宏:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
//...
glNormalPointer(GL_FLOAT, 32, BUFFER_OFFSET(x));
Run Code Online (Sandbox Code Playgroud)
你能提供一下这个宏的工作原理吗?可以用功能替换吗?更确切地说,递增NULL指针的结果是什么?
对于OpenGL中的某些函数,必须glVertexAttribPointer()为stride 指定字节偏移量,例如in .起初我会猜到它将是一个像整数一样的正常数值.但经过检查,我意识到它需要被投入void*(更具体地说GLvoid*).我的问题是:它的意图是什么void*?为什么必须将它用于字节偏移?
这有效,但也会导致“不要使用reinterpret_cast(type.1)”警告:
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
reinterpret_cast<void*>(sizeof(GLfloat) * 3));
Run Code Online (Sandbox Code Playgroud)
这不能编译:
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
static_cast<void*>(sizeof(GLfloat) * 3));
Run Code Online (Sandbox Code Playgroud)
这不能编译:
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
dynamic_cast<void*>(sizeof(GLfloat) * 3));
Run Code Online (Sandbox Code Playgroud)
这显然是可行的,但在 C++ 中似乎是一个很大的禁忌(“不要使用 C 风格的强制转换 (type.4)”)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
(void*)(sizeof(GLfloat) * 3));
Run Code Online (Sandbox Code Playgroud)
我应该忽略有关的警告reinterpret_cast吗?
这实际上是一个关于C++的问题,而不是关于OpenGL的问题。我正在关注有关 OpenGL 的本教程(我刚刚开始),作者使用 C++(不是 C)。我的问题是glVertexAttribPointer 需要一个偏移参数作为const void*。由于此参数只是告诉 OpenGL 给定的顶点属性第一次出现在使用 复制的顶点数组中的位置glBufferData(),因此我希望它应该是std::ptrdiff_t类型。SO 上的这篇void*文章解释了为什么用作参数类型的原因,但我想知道为什么这种用法在 C++ 中是合法的。例如,提到的教程只是简单地转换为以void*字节为单位的偏移量值,如下面的调用所示:
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float)));
Run Code Online (Sandbox Code Playgroud)
在我看来,这种方法不合法,因为cpprefence文档reinterpret_cast说
任何整型或枚举类型的值都可以转换为指针类型。转换为足够大小的整数并返回到相同指针类型的指针保证具有其原始值,否则无法安全地取消引用结果指针(不保证相反方向的往返转换,相同的指针可能具有多个整数表示)
因此,如果我正确理解这一点,std::ptrdiff_t偏移量的值(这似乎是这里需要的)在转换为void*. 我想念什么?
我试图使用glDrawRangeElements()命令渲染一些旧的级别数据.我的顶点设置正确,我的索引设置正确,但我似乎无法渲染它.我终于在网上查了一下,发现了这里的例子:http://www.songho.ca/opengl/gl_vertexarray.html
从这个例子来看,我认为我做错了.显然,start是索引值,结尾是索引值,而不是indices数组的索引.我假设,例如,如果你想渲染10个三角形,开始将是0,结尾将是29,计数将是30.但我显然是错的?
只有当索引值为0和29实际上是0和29时,这才是正确的.因此,如果索引以400开始并以452结束,则对该相同数组的调用将改为
glDrawRangeElements(GL_TRIANGLES, 400, 452, 29, GL_UNSIGNED_BYTE, indices);
Run Code Online (Sandbox Code Playgroud)
那是对的吗?有没有人认为这有点反直觉?关于顶点数组的任何其他建议?
我需要将int(指定一个字节偏移量)强制转换为const void*。真正适合我的唯一解决方案是c样式强制转换:
int offset = 6*sizeof(GLfloat);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)offset);
Run Code Online (Sandbox Code Playgroud)
我想摆脱c风格的转换,但找不到有效的解决方案。我试过了
static_cast<void*>(&offset)
Run Code Online (Sandbox Code Playgroud)
并进行编译,但这不是正确的解决方案(此方法的整体输出有所不同)。正确的解决方案是什么?
链接至的文档glVertexAttribPointer:链接
上一个问题曾问过如何在整数类型和GLvoid*C ++ 11之间进行转换(基于该问题的标签),但是在这里我对C ++ 20感兴趣。
现在,std::bit_cast可以选择进行类型转换了,我想知道这是否是将整数与OpenGL函数结合使用的“正确”方法,而OpenGL函数由于历史原因需要使用a GLvoid*来表示字节偏移量(例如glDrawRangeElements),或者应改用上一个问题引用的方法。