我正在使用Eclipse CDT在Ubuntu 9.04上使用SDL和OpenGL开发3D游戏。我有一个类可以将网格数据保存在每种类型的向量中。例如Vertex,Normal,UVcoord(纹理坐标),以及面向量。每个面都有3个int向量,用于保存其他数据的索引。到目前为止,我的游戏在渲染速度方面表现得非常好。但是我再次在两个对象中只有不到一百个顶点用于测试目的。
访问此数据的循环如下所示:
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函数。
这是踢球者:
我正在加载一个由三角形组成的典型立方体。
当我从UV_Verts
函数访问RenderFace()
向量的元素16(0索引)时,我得到12。
但是当我从UV_Verts
函数访问相同OnLoad()
向量的元素16(0索引)时,我得到类似于3045472189的内容
我很困惑。
有谁知道造成这种情况的原因是什么?如果是这样,如何解决它?
答案 0 :(得分:3)
一个可能的原因可能是您正在创建大小为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()];