OpenGL glMultiDrawElements在索引偏移量向量上崩溃

时间:2014-12-12 11:07:09

标签: c++ opengl vector

我很难为这个问题找到一个好头衔,所以如果你想出一个好问题,请提出一个新问题。也许我们可以在解决问题之后做到这一点......现在就来了:

我目前正在移植代码以使用glMultiDrawElements而不是几次调用glDrawElements。为此,我使用了一些我称之为sequenceList的东西,它只是一对std ::两个向量,一个是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 );
}

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

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

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

现在问题:这与

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

我试图以多种不同的方式找到问题,并且终于能够找到一个不会崩溃的变体,并且变体让我感到困惑。

如果我将矢量复制到新的局部变量,它就可以工作。由于向量的大小为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() );

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

问题似乎是我在64位平台上,而glMultiDrawArrays期望指向int s ,而不是实际的int

此处描述了更多内容。

https://www.opengl.org/discussion_boards/showthread.php/182391-How-to-use-glMultiDrawElements-and-glDrawElements

对此的解决方案是使用GLintptr作为类型,它描述数组中的字节偏移。因此,数组中的每个位置也必须使其指针大小与其自身相乘。