C++ 在64位操作系统中使用glmultipaurements
我最近从32位环境迁移到64位环境,除了一个问题外,进展顺利:C++ 在64位操作系统中使用glmultipaurements,c++,opengl,64-bit,vbo,C++,Opengl,64 Bit,Vbo,我最近从32位环境迁移到64位环境,除了一个问题外,进展顺利:glmultidraurements使用一些数组,在64位操作系统下,如果不进行一些调整,这些数组将无法工作 glMultiDrawElements( GL_LINE_LOOP, fCount_, GL_UNSIGNED_INT, reinterpret_cast< const GLvoid** >( iOffset_ ), mesh().
glmultidraurements
使用一些数组,在64位操作系统下,如果不进行一些调整,这些数组将无法工作
glMultiDrawElements( GL_LINE_LOOP, fCount_, GL_UNSIGNED_INT,
reinterpret_cast< const GLvoid** >( iOffset_ ),
mesh().faces().size() );
我想我看到的是OpenGL读取64位大块的iOffset
导致大量的数字,但是glmultidraurements
不支持任何大于32位的类型(GL\u UNSIGNED\u 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() );
结果完全相同。您遇到了我在中彻底剖析的问题 我建议你按照我在答案最后的建议去做,不要试图把你的数字转换成编译器认为是指针的东西,而是把函数签名转换成带数字的东西 请注意,对于glmultidrawerelement,第一个间接寻址不进入VBO,而是进入客户机内存。因此,要铸造的签名是例如
void myglMultiDrawElementsOffset(GLenum mode,
const GLsizei * count,
GLenum type,
const uintptr_t * indices,
GLsizei primcount);
原因很简单,这并不需要整数偏移量数组(平台上为32位),而是指针数组(平台上为64位),解释为缓冲区偏移量 但您只是将(或指针指向的)整数数组强制转换为(或指针指向的)指针数组,这是行不通的,因为函数现在只是将n个连续的32位值重新解释为n个连续的64位值。当然,它适用于
glpaurements
,因为您只是将一个整数转换为一个指针,这实际上是将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() );
std::向量指针(mesh().faces().size());
对于(尺寸i=0;i@cbamber85:您必须在调用glewInit()
后执行对签名调整函数指针的赋值。注意,您也可以强制转换该函数:((TFPTR\u VertexOffset)&glvertexointer)(…)
谢谢,我应该注意到这一点。请看我的更新,如果函数指针在您的项目中起作用,它必须是我的语法,但我无法使函数指针的行为与我现有的错误代码有任何不同。这将不起作用,因为函数(无论哪个签名)仍然需要一个64位值(指针)数组他给它一个32位值(整数)的数组。@BenVoigt:我再问你一次:你读过我的另一个答案了吗?你知道吗,将不是指向([u]intptr_t)指针的指针转换回指针的结果的数字转换会调用未定义的行为吗?如果你将任意数字转换成指针,编译器可能会说“这不是一个指针值,我不打算强制转换它”。例如,您可能在一个实现上,其中所有指针值(空指针除外)都大于0x1000,因此编译器很容易在@BenVoigt:中决定一个数字。请澄清一下:C99标准在第6.3.2.3.5节中说:整数可以转换为任何指针类型。除先前指定的情况外,结果是实现定义的,可能没有正确对齐,可能没有指向引用类型的实体,可能是陷阱表示。“。此外,6.3.2.3.8说:指向一种类型函数的指针可以转换为指向另一种类型函数的指针,然后再转换回来;结果应与原始指针相同。“–就是这样。什么类型是fCount\uu
和iOffset\u
?啊,与我的想法相反。我实际上可以通过维护一个quintptr
数组(由Qt
提供的一个整数类型,即指针类型的宽度)来实现这两个方面的最佳效果。”然后保持我的<代码> RealTytCase siZixt(这也保证了指针的大小)甚至与框架无关。@cbamber85:如果有标准的C类型,为什么要使用Qt定义的类型:uintpttr_t@ChristianRau:size\u t不保证为指针大小。您要查找的类型为uintpttr_t@datenwolf:它们是等效的,为什么不使用它呢?quintptr
少了一个字符。
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() );