c++ - 指向数组的指针,我错过了什么?

标签 c++ arrays opengl pointers

我对 OpenGL 比较陌生,一直在使用它提供的 GLTools 库。其中一个类 GLTriangleBatch 部分处理顶点批处理。该类有一个全局属性指针 pVerts,声明如下:

typedef float M3DVector3f[3];
M3DVector3f *pVerts; 

当一个初始化函数被调用时,上面的指针被委托(delegate)给一个内存块,其中索引的数量是一个作为参数提供给函数的整数(nMaxIndexes):

pVerts = new M3DVector3f[nMaxIndexes];

另一个函数给出了一个由 3 个 M3DVector3fs 组成的数组,这些 M3DVector3fs 包含三角形的顶点。此函数确定将哪些单独的顶点添加到批处理中。

例如,如果要添加的点已经存在于 pVerts 中,则将该点在 pVerts 中的索引添加到另一个数组中,该数组包含将要绘制的所有点的索引。因此 pVerts 只包含独特的点。因此 pVerts 的实际索引永远不会达到 nMaxIndexes。

但是,如果它是一个唯一的顶点,它被添加到 pVerts 中,如下所示:

memcpy(pVerts[nNumVerts], verts[iVertex], sizeof(M3DVector3f));

其中 nNumVerts 是 pVerts 的当前索引,verts[] 是包含要添加的三角形的 3 个 M3DVector3f 的数组,iVertex 是要添加的特定顶点的索引。

现在我使用另一个计算顶点位置的函数来构建一个(粗略的)球体。我在我的程序中构建的球体以 nMaxIndexes = 2028 结束,当球体完成时 nNumVerts = 378。

现在按照所有这些,我假设 pVerts 指向一个范围为 0 到 2027 的索引数组,但只有索引 0 到 377 被数据填充。但是当我在添加所有顶点后直接放置断点时,pVerts 仅指向一个 M3DVector3f。

我需要访问这些单独的点中的每一个,因为我计划将这个球体用作可碰撞边界。我已经添加了一个返回 pVerts 的 getVertices 函数,但是返回的指针只指向一个 M3DVector3f?我错过了什么?

最佳答案

这与其说是 3D 图形或 OpenGL 问题,不如说是对数组在 C 和 C++ 中的工作原理缺乏理解。

C 中的数组是一组由系统内存支持的连续地址空间。通过称为指针算术的机制,内容由基指针和相对于该基指针的偏移量寻址。

pT 类型的指针, 用 C 语法编写 T *p .现在让p指向 n 的一些连续内存类型元素 T , 分配给 new T[n] (C++) 或 malloc(sizeof(t)) .要访问第 i 个元素,您需要该元素的地址并取消引用指向该地址的指针。 C 有一个称为指针算法的机制:p + i计算为指向从 p 开始的一组连续元素中的第 i 个元素的指针.要获取元素的值,您必须使用 * 取消引用接线员:*(p+i) .索引运算符 [] 提供了简写形式实际上p[i]*(p+i) 完全相同.

这是一个鲜为人知的事实,并且会产生有趣的后果。指针算术通勤,即 p + i == i + p并将其应用于索引运算符,人们会期望 p[i] == i[p]事实确实如此。

回到原来的问题:您使用的是 C++,所以我建议您根本不要为手动分配的数组而烦恼。相反,您最好使用标准容器,即 std::vector,可通过 #include <vector> 获得。 (没有尾随 .h !)

而不是 M3DVector3f *pVerts这只是一个指针,而不是一个完全限定的数组(!),你写std::vector<M3DVector3f> Verts这实际上就是你所说的数组(C++ STL 称它为 vector 以区别于普通数组;一开始这听起来可能很奇怪,但是一旦你从更高的数学角度理解了 vector 空间,它实际上就有意义了).而不是 memcpy(...)您应该能够使用赋值运算符 =在 vector 元素上,即 Verts[nNumVerts] = verts[iVertex] .如果编译器报错,重载赋值运算符:

struct M3DVertex3f {        
    float v[3] __attribute__ ((packed)); // this is a static array, so no double pointers!
    M3DVertex3f &operator=(M3DVertex3f const &src);
}

M3DVertex3f &M3DVertex3f::operator=(M3DVertex3f const &src)
{
    for(int i=0;i<3;i++)
         v[i] = src.v[i];       
    return *this;        
}

std::vector<M3DVertex3f> Verts;

关于c++ - 指向数组的指针,我错过了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6417609/

相关文章:

c++ - 如何在 C++ 中创建一个没有路径名的文件夹,只有您要创建的文件夹的名称?

c++ - 为什么 fprintf 在缺少 width 参数时导致内存泄漏和行为不可预测

arrays - ILMath 函数在给定开始、结束和步长的情况下排列值?

opengl - 如何使用我自己的4x4矩阵更新opengl modelview矩阵?

c++ - 为什么这个 OpenGL 旋转也会平移我的对象?

java - Lwjgl 3D 立方体透明度问题

c++ - 在窗口中垂直居中多行文本,纯 winapi 和 c++

C++ 模板 : Why does not this work?

javascript - Typescript 从嵌套在数组中的数组中拼接项目

Java Arrays.sort 将结果重置为零