c++ - OpenGL glMultiDrawElements 在索引偏移 vector 上崩溃

标签 c++ opengl vector

我真的很难为这个问题想出一个好的标题,所以如果你能想出一个好的标题,请提出一个新标题。或许我们可以在解决我的问题后这样做......现在开始:

我目前正在移植代码以使用 glMultiDrawElements 而不是多次调用 glDrawElements。为此,我使用了我称之为 sequenceList 的东西,它只是一对 std::pair 的两个 vector ,一个 unsigned int 和一个 int。

  // Sequence of vectors defining < StartIndex per primitive, Number of vertices per primitive >
  using SequenceList = std::pair< std::vector< unsigned int >, std::vector< GLsizei > >;

为了能够对所有变体只使用一个绘制函数(尽管只有一个基元可以使用一个索引列表进行绘制)我已经将函数调用概括为总是使用一个 sequenceList 对象, 但只有一个索引值。这意味着我对所有索引绘制调用使用 glMultiDrawElements(对非索引绘制调用使用 glMultiDrawArrays)。

void GLVBOProbe::draw( unsigned startIndex, int numberOfIndicesToDraw ) const
{
  VertexArray::SequenceList sequences = { { startIndex }, { numberOfIndicesToDraw } ) };
  GLVBOLib::the().draw( name_, sequences );
}

绘制调用然后绑定(bind)数组/法线/纹理和索引(如果需要)缓冲区。对 glMultiDrawElements 的调用看起来像

glMultiDrawElements( info.mode, sequences.second.data(), GL_UNSIGNED_INT, (const GLvoid **)sequences.first.data(), (GLsizei)sequences.second.size() );

在我的测试用例中,我渲染了 75000 个从 0 开始的索引。所以 sequences.second 包含 75000 个值,而 sequences.first 只包含一个值:0。

现在问题来了:这会导致

崩溃
First-chance exception at 0x000000004735E56B in Application.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

我尝试了很多不同的方法来寻找问题,最终找到了一个不会崩溃的变体,这个变体让我很困惑。

如果我将 vector 复制到一个新的局部变量,它就可以工作。由于 vector 的大小为 1,因此仅仅这样做不是问题,但是对于 3000 个索引偏移量,每帧都这样做感觉没那么有趣。

// Non crashing version
std::vector< unsigned int > indicesOffset = sequences.first;
// using sequence and indices
glMultiDrawElements( info.mode, sequences.second.data(), GL_UNSIGNED_INT, (const GLvoid **)indicesOffset.data(), (GLsizei)sequences.second.size() );

我的一个同事说这可能与 vector 的内存对齐有关,说我必须使用 boost 的 boost::aligned_allocator 才能让它工作。

最佳答案

sizeof(GLvoid*) 不保证等于 sizeof(unsigned int)。但是,您可以将 unsigned int 替换为 GLintptr ,保证与指针的大小相同。

关于c++ - OpenGL glMultiDrawElements 在索引偏移 vector 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27442316/

相关文章:

c++ - 当空指针不是所有位为零时如何正确编写 C/C++ 代码

c++ - 在 Qt 应用程序菜单栏的主菜单中添加和本地化菜单项

c++ - 使用 GLSL 进行光线追踪

c++ - opengl c++ 中的边界填充算法

encryption - AES CTR 测试向量

C++ vector.push_back(string) 调用 SQLGetData 后出现段错误

c++ - 将 C++ 源代码反向为 UML 类图

c++ - 检查是否至少有一个 Wayland session 正在运行

c++ - 如何从 3D 点获取屏幕坐标? OpenGL

c++ - vector<char> 元素的打印地址显示垃圾