我在OpenGL VBO实现中看到了以下宏:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
//...
glNormalPointer(GL_FLOAT, 32, BUFFER_OFFSET(x));
Run Code Online (Sandbox Code Playgroud)
你能提供一下这个宏的工作原理吗?可以用功能替换吗?更确切地说,递增NULL指针的结果是什么?
OpenGL的4.3和OpenGL ES 3.1添加若干替代功能用于指定顶点数组:glVertexAttribFormat,glBindVertexBuffers等,但我们已经有了用于指定顶点数组功能.即glVertexAttribPointer.
为什么要添加与旧版API相同的新API?
新API如何运作?
在我的跨平台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要求与编译器进行严格的检查?
规范glVertexAttribPointer如下:
void glVertexAttribPointer( GLuint index,
GLint size,
GLenum type,
GLboolean normalized,
GLsizei stride,
const GLvoid * pointer);
Run Code Online (Sandbox Code Playgroud)
鉴于最后一个参数只是一个4字节的整数偏移量,为什么OpenGL期望它作为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吗?