在64位操作系统中使用glMultiDrawElements

cma*_*t85 4 c++ opengl 64-bit vbo

我最近从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位操作系统下完美运行.

如果我改变glMultiDrawElementsglDrawElements并把它变成一个循环,它工作在两个平台上罚款:

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 )( GLenum mode, const GLsizei* count, GLenum type,
                           const GLuint* indices, GLsizei primcount );
testPtr ptr = (testPtr)glMultiDrawElements;
ptr( GL_LINE_LOOP, fCount_, GL_UNSIGNED_INT, iOffset_, mesh().faces().size() );
Run Code Online (Sandbox Code Playgroud)

结果完全相同.

Chr*_*ica 5

简单的原因是,glMultiDrawElements不期望整数偏移数组(平台上为32位),而是指针数组(平台上为64位),被解释为缓冲区偏移.

但是你只是将(或指针)整数的数组转换为(或指针)指针的数组,这将无法工作,因为该函数现在只需将n个连续的32位值重新解释为n个连续的64位值.当然它的作用是glDrawElements因为你只是将一个整数转换为单个指针,它实际上将你的32位值转换为64位值.

你需要做的不是转换你的指针/数组,而是这个偏移数组中的每个单独的值:

std::vector<void*> pointers(mesh().faces().size());
for(size_t i=0; i<pointers.size(); ++i)
    pointers[i] = static_cast<void*>(iOffset_[i]);
glMultiDrawElements( GL_LINE_LOOP, fCount_, GL_UNSIGNED_INT, 
                     &pointers.front(), mesh().faces().size() );
Run Code Online (Sandbox Code Playgroud)

或者更好,只是从一开始就将偏移量存储为指针而不是整数.