OpenGL的4.3和OpenGL ES 3.1添加若干替代功能用于指定顶点数组:glVertexAttribFormat,glBindVertexBuffers等,但我们已经有了用于指定顶点数组功能.即glVertexAttribPointer.
为什么要添加与旧版API相同的新API?
新API如何运作?
后者是否会弃用前者?
我正在编写我想在着色器2.0硬件上工作的代码,但我想使用更新的编程约定,例如VAO.
所以,我一直在使用该glVertexAttribPointer功能来代替glVertexPointer,glNormalPointer,glColorPointer等等.
似乎我们已经到了服务器 - 客户端概念不是特别相关的点(编辑:我的意思是它适用于这些缓冲区指针的切换状态).但我想知道旧的En/DisableClientState实际做了什么,以及它与glEnableVertexAttribArray实际做的有什么关系.
而且我也没有5代以前的任何图形硬件,但肯定是我的软件的一些用户可能.我怎样才能防止我的代码无法在Radeon 9700上编译?(虽然我希望如果用户拥有最新的驱动程序,它可能会支持新的东西)
对于OpenGL中的某些函数,必须glVertexAttribPointer()为stride 指定字节偏移量,例如in .起初我会猜到它将是一个像整数一样的正常数值.但经过检查,我意识到它需要被投入void*(更具体地说GLvoid*).我的问题是:它的意图是什么void*?为什么必须将它用于字节偏移?
在我的跨平台OpenGL应用程序中,我想使用顶点缓冲区对象进行绘制.但是我遇到了调用glDrawRangeElements的问题.
glDrawRangeElements(GL_TRIANGLES, start, start + count, count,
GL_UNSIGNED_INT, static_cast<GLvoid *> (start * sizeof(unsigned int)));
Run Code Online (Sandbox Code Playgroud)
编译器(Mac OS X上的CLang)不喜欢最后一个参数"错误:无法从类型'unsigned long'转换为指针类型'GLvoid*'(又名'void*')".OpenGL API将最后一个参数的类型定义为const GLvoid*,并且当此api与顶点数组一起使用时需要一个指针.但是我知道当使用顶点缓冲区对象而不是指针时,应该将一个表示偏移量的整数值传递给缓冲区数据.这就是我想要做的事情,因此我必须施展.如何协调api要求与编译器进行严格的检查?
这有效,但也会导致“不要使用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*. 我想念什么?
我最近从32位环境迁移到64位环境,除了一个问题之外它已经顺利完成了:glMultiDrawElements使用一些在64位操作系统下没有一些调整就无法工作的阵列.
glMultiDrawElements( GL_LINE_LOOP, fCount_, GL_UNSIGNED_INT,
reinterpret_cast< const GLvoid** >( iOffset_ ),
mesh().faces().size() );
Run Code Online (Sandbox Code Playgroud)
我正在使用VBO来处理顶点和顶点索引. fCount_并且iOffset_是数组GLsizei.由于缓冲区是绑定到GL_ELEMENT_ARRAY_BUFFER,iOffset_的元件被用作从VBO开始字节偏移.这在32位操作系统下完美运行.
如果我改变glMultiDrawElements来glDrawElements并把它变成一个循环,它工作在两个平台上罚款:
int offset = 0;
for ( Sy_meshData::Faces::ConstIterator i = mesh().faces().constBegin();
i != mesh().faces().constEnd(); ++i ) {
glDrawElements( GL_LINE_LOOP, i->vertexIndices.size(), GL_UNSIGNED_INT,
reinterpret_cast< const GLvoid* >( sizeof( GLsizei ) * offset ) );
offset += i->vertexIndices.size();
}
Run Code Online (Sandbox Code Playgroud)
我认为我所看到的是OpenGL读取64位块iOffset_导致大量数字,但glMultiDrawElements不支持任何类型超过32位(GL_UNSIGNED_INT),所以我不知道如何纠正它.
有没有其他人有这种情况并解决了它?或者我处理这个完全错误并且在32位操作系统上运气真的很幸运?
换掉我现有的代码:
typedef void ( *testPtr …Run Code Online (Sandbox Code Playgroud) 我不明白 OpenGL 的缓冲区是如何工作的。我通过 OpenGL 红皮书第 8 版学习 OpenGL。例如,我有一个位置数组、一个颜色数组和一个索引数组:
static const GLfloat strip_position[] =
{
-4.0f, 0.0f, -1.0f, 1.0f, //0
-3.5f, -1.0f, -1.0f, 1.0f, //1
-3.0f, 0.0f, -1.0f, 1.0f, //2
-2.5f, -1.0f, -1.0f, 1.0f, //3
-2.0f, 0.0f, -1.0f, 1.0f, //4
-1.5f, -1.0f, -1.0f, 1.0f, //5
-1.0f, 0.0f, -1.0f, 1.0f, //6
-0.5f, -1.0f, -1.0f, 1.0f, //7
0.0f, 0.0f, -1.0f, 1.0f //8
};
static const GLfloat strip_colors[] =
{
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, …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:链接