C++ vector 元素在不同时间访问时是不同的

标签 c++ opengl vector sdl

我正在使用 Eclipse CDT 在 Ubuntu 9.04 上使用 SDL 和 OpenGL 开发 3D 游戏。我有一个类可以将每种类型的网格数据保存在 vector 中。比如Vertex, Normal, UVcoord(纹理坐标),还有面的 vector 。每张脸都有 3 个 int vector ,它们保存着其他数据的索引。到目前为止,我的游戏在以不错的速率进行渲染方面一直运行良好。但话又说回来,出于测试目的,我在两个对象中只有不到一百个顶点。

访问此数据的循环如下所示:

void RenderFace(oFace face)
{
    /*
    * More Stuff
    */

    oVertice gvert;
    oUVcoord tvert;
    oNormal nvert;

    for (unsigned int fvIndex = 0; fvIndex < face.GeoVerts.size(); fvIndex++)
    {
        gvert = obj.TheMesh.GetVertice(face.GeoVerts[fvIndex] - 1);
        tvert = obj.TheMesh.GetUVcoord(face.UV_Verts[fvIndex] - 1);
        nvert = obj.TheMesh.GetNormal(face.NrmVerts[fvIndex] - 1);

        glNormal3f(nvert.X, nvert.Y, nvert.Z);
        glTexCoord2f(tvert.U, tvert.V);
        glVertex3f(scale * gvert.X, scale * gvert.Y, scale * gvert.Z);
    }

    /*
    *  More Stuff
    */
} 

有一个调用 renderFace() 函数的循环,其中包括上面的 for 循环。负一是因为 Wavefront .obj 文件是 1 索引(而不是 c++ 0 索引)。不管怎样,我发现一旦你有大约 3 万张面孔,所有那些对 glVertex3f() 等的调用都会将游戏速度降低到大约 10 FPS。那是我不能允许的。所以我了解了顶点数组,它需要指向数组的指针。按照 NeHe 教程的示例,我继续使用我的 oVertice 类和其他类。它只有 floats x、y、z 或 u、v。所以我将上面的相同函数添加到我的 OnLoad() 函数来构建数组,这些数组只是“oVertice*"和类似的。

代码如下:

bool oEntity::OnLoad(std::string FileName)
{
    if (!obj.OnLoad(FileName))
    {
        return false;
    }

    unsigned int flsize = obj.TheMesh.GetFaceListSize();

    obj.TheMesh.VertListPointer = new oVertice[flsize];
    obj.TheMesh.UVlistPointer = new oUVcoord[flsize];
    obj.TheMesh.NormListPointer = new oNormal[flsize];

    oFace face = obj.TheMesh.GetFace(0);
    oVertice gvert;
    oUVcoord tvert;
    oNormal nvert;
    unsigned int counter = 0;
    unsigned int temp = 0;

    for (unsigned int flIndex = 0; flIndex < obj.TheMesh.GetFaceListSize(); flIndex++)
    {
        face = obj.TheMesh.GetFace(flIndex);

        for (unsigned int fvIndex = 0; fvIndex < face.GeoVerts.size(); fvIndex++)
        {
            temp = face.GeoVerts[fvIndex];
            gvert = obj.TheMesh.GetVertice(face.GeoVerts[fvIndex] - 1);

            temp = face.UV_Verts[fvIndex];
            tvert = obj.TheMesh.GetUVcoord(face.UV_Verts[fvIndex] - 1);

            temp = face.NrmVerts[fvIndex];
            nvert = obj.TheMesh.GetNormal(face.NrmVerts[fvIndex] - 1);

            obj.TheMesh.VertListPointer[counter].X = gvert.X;
            obj.TheMesh.VertListPointer[counter].Y = gvert.Y;
            obj.TheMesh.VertListPointer[counter].Z = gvert.Z;

            obj.TheMesh.UVlistPointer[counter].U = tvert.U;
            obj.TheMesh.UVlistPointer[counter].V = tvert.V;

            obj.TheMesh.NormListPointer[counter].X = nvert.X;
            obj.TheMesh.NormListPointer[counter].Y = nvert.Y;
            obj.TheMesh.NormListPointer[counter].Z = nvert.Z;

            counter++;
        }
    }

    return true;
}

unsigned int temp 变量用于调试目的。显然我没有 oFace 的默认构造函数,它没有任何东西可以用来初始化。无论如何,正如您所看到的,它几乎是完全相同的例程。只是我没有调用 gl 函数,而是将数据添加到三个数组。

这是关键:

我正在加载一个典型的三角形立方体。

当我从 RenderFace() 函数访问 UV_Verts vector 的元素 16(0 索引)时,我得到 12。

但是当我从 OnLoad() 函数访问同一 UV_Verts vector 的元素 16(0 索引)时,我得到类似 3045472189 的信息

我很困惑。

有谁知道是什么原因造成的?如果是,如何解决?

最佳答案

一个可能的原因可能是您正在创建大小为 flsize 的数组:

obj.TheMesh.VertListPointer = new oVertice[flsize];
obj.TheMesh.UVlistPointer = new oUVcoord[flsize];
obj.TheMesh.NormListPointer = new oNormal[flsize];

但使用索引最大为 flsize * face.GeoVerts.size

的数组
for (...; flIndex < obj.TheMesh.GetFaceListSize(); ...) { // flsize = GetFaceListSize
  for (...; fvIndex < face.GeoVerts.size(); ...) {
    ...
    obj.TheMesh.UVlistPointer[counter].U = ...;
    ...
    counter++;
  }
}

所以你的数组创建代码实际上应该更像

obj.TheMesh.VertListPointer = new oVertice[flsize * face.GeoVerts.size()];
obj.TheMesh.UVlistPointer = new oUVcoord[flsize * face.GeoVerts.size()];
obj.TheMesh.NormListPointer = new oNormal[flsize * face.GeoVerts.size()];

关于C++ vector 元素在不同时间访问时是不同的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1123574/

相关文章:

c++ - 具有固定功能管道的一维纹理查找表

c++ - 如何创建一个 2MB 的数组或 vector 并用随机整数填充它

c++ - 参数化回调函数

c++ - 为什么在使用解除引用的指针时 EXPECT_CALL 测试意外通过?

c# - 将带有参数的 c# 回调方法传递给 c++ dll 会导致 System.ExecutionEngineException

c++ - 将 std::vector<char> 转换为 char* 会导致有缺陷的字符

c++ - C++中 vector 对象的地址是什么?

C++:基本数组交换

c++ - 从带有 opengl 代码的 C++ 转换为带有 GUI 的 QT 应用程序?

c++ - VBO什么都不画