Skip to main content
 首页 » 编程设计

c++之如何在不违反 C++ 核心准则的情况下将整数转换为 void*

2024年11月01日10lori

这有效,但也会导致“不要使用 reinterpret_cast (type.1)”警告:

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, 
  reinterpret_cast<void*>(sizeof(GLfloat) * 3)); 

这不编译:
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, 
  static_cast<void*>(sizeof(GLfloat) * 3)); 

这不编译:
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, 
  dynamic_cast<void*>(sizeof(GLfloat) * 3)); 

这显然有效,但在 C++ 中似乎是一个很大的禁忌(“不要使用 C 风格的强制转换(type.4)”)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, 
  (void*)(sizeof(GLfloat) * 3)); 

我应该忽略关于 reinterpret_cast 的警告吗?

请您参考如下方法:

当您进行低级编程时,您有时会不得不做 C++ 核心指南规定不应该做的事情。因此,只需执行它们,要么接受“警告”,要么关闭该特定指南(可能基于每个文件)。

话虽如此,需要这种特殊的低级捏造完全是因为 OpenGL 在其顶点规范 API 中的愚蠢。该值应该是某种整数字节偏移量,而不是转换为另一方将转换回偏移量的指针的偏移量。

所以最好完全避免使用糟糕的 API。使用 separate attribute format specification 而不是旧式 glVertexAttribPointer 。它几乎在各个方面都优越。它会将您的代码从:

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, 
  reinterpret_cast<void*>(sizeof(GLfloat) * 3)); 


glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3); //Offset specified as integer. 
glVertexAttribBinding(1, 0); //You seem to be using multiple attributes with a stride, so they should use the same buffer binding. 
 
//Some later point when you're ready to provide a buffer. 
 
glBindVertexBuffer(0, buffer_obj, 0, sizeof(GLfloat) * 8); //Stride goes into the buffer binding. 

看,根本没有类型转换。

不幸的是, glDrawElements 函数系列没有替代方案,因此您仍然会收到此警告。