给定下面的代码。取自http://pastie.org/pastes/764327/text
void CreateSphere(int PointRows, int PointsPerRow)
{
NumVertices = (PointRows-2)*PointsPerRow + 2;
Vertices = new SVertex[NumVertices];
IndexVect.clear(); //to be sure it is empty
float x,y,z;
int i,j;
double r;
for (i = 1; i < (PointRows-1); i++)
{
for (j = 0; j < PointsPerRow; j++)
{
y = 1.0 - float(i) / float(PointRows-1)*2.0;
r = sin (acos(y)); //radius of the row
x = r * sin(float(j) / float(PointsPerRow)*PI*2.0);
z = r * cos(float(j) / float(PointsPerRow)*PI*2.0);
Vertices[(i-1)*PointsPerRow+j].x = x;
Vertices[(i-1)*PointsPerRow+j].y = y;
Vertices[(i-1)*PointsPerRow+j].z = z;
Vertices[(i-1)*PointsPerRow+j].r = (float)(i) / float(PointRows);
Vertices[(i-1)*PointsPerRow+j].g = 0.7;
Vertices[(i-1)*PointsPerRow+j].b = (float)(j) / float(PointsPerRow);
}
}
//The highest and deepest vertices:
Vertices[(PointRows-2)*PointsPerRow].x = 0.0;
Vertices[(PointRows-2)*PointsPerRow].y = 1.0;
Vertices[(PointRows-2)*PointsPerRow].z = 0.0;
Vertices[(PointRows-2)*PointsPerRow].r = 1.0;
Vertices[(PointRows-2)*PointsPerRow].g = 0.7;
Vertices[(PointRows-2)*PointsPerRow].b = 1.0;
Vertices[(PointRows-2)*PointsPerRow+1].x = 0.0;
Vertices[(PointRows-2)*PointsPerRow+1].y = -1.0;
Vertices[(PointRows-2)*PointsPerRow+1].z = 0.0;
Vertices[(PointRows-2)*PointsPerRow+1].r = 1.0;
Vertices[(PointRows-2)*PointsPerRow+1].g = 0.7;
Vertices[(PointRows-2)*PointsPerRow+1].b = 1.0;
for (i = 1; i < (PointRows-2); i++)
{
for (j = 0; j < (PointsPerRow-1); j++)
{
IndexVect.push_back((i-1)*PointsPerRow+j);
IndexVect.push_back((i-1)*PointsPerRow+j+1);
IndexVect.push_back((i)*PointsPerRow+j);
IndexVect.push_back((i-1)*PointsPerRow+j+1);
IndexVect.push_back((i)*PointsPerRow+j+1);
IndexVect.push_back((i)*PointsPerRow+j);
}
IndexVect.push_back((i-1)*PointsPerRow+PointsPerRow-1);
IndexVect.push_back((i-1)*PointsPerRow);
IndexVect.push_back((i)*PointsPerRow+j);
IndexVect.push_back((i)*PointsPerRow);
IndexVect.push_back((i-1)*PointsPerRow);
IndexVect.push_back((i)*PointsPerRow+j);
}
//The triangles to the highest and deepest vertices:
for (j = 0; j< (PointsPerRow-1); j++)
{
IndexVect.push_back(j);
IndexVect.push_back(j+1);
IndexVect.push_back((PointRows-2)*PointsPerRow);
}
IndexVect.push_back(j);
IndexVect.push_back(0);
IndexVect.push_back((PointRows-2)*PointsPerRow);
for (j = 0; j< (PointsPerRow-1); j++)
{
IndexVect.push_back((PointRows-3)*PointsPerRow+j);
IndexVect.push_back((PointRows-3)*PointsPerRow+j+1);
IndexVect.push_back((PointRows-2)*PointsPerRow+1);
}
IndexVect.push_back((PointRows-3)*PointsPerRow+j);
IndexVect.push_back((PointRows-3)*PointsPerRow);
IndexVect.push_back((PointRows-2)*PointsPerRow+1);
Indices = new GLuint[IndexVect.size()]; //allocate the required memory
for (i = 0; i < IndexVect.size(); i++)
{
Indices[i] = IndexVect[i];
}
NumIndices = IndexVect.size();
IndexVect.clear(); //no longer needed, takes only memory
}
您将如何使用结果顶点计算法线......?
然后我希望使用 glEnableClientState(GL_NORMAL_ARRAY) 和 glNormalPointer(GL_FLOAT,0, Normals) 以及 glDrawElements 将结果索引与法线一起绘制。
我试过了,但它看起来不对。灯光出现在球体的左侧,而不是下方。
道歉。我在这里没有给出完整的图片。基本上,我试图通过在数据中输入噪声来生成随机形状。
如果我在第一个嵌套循环的末尾使用以下代码:
Normals[(i-1)*PointsPerRow+j].x = x;
Normals[(i-1)*PointsPerRow+j].y = y;
Normals[(i-1)*PointsPerRow+j].z = z;
我能够为球体生成正确的法线,一切看起来都很好。
但是,如果我这样做:
x=x+(noise3(x,y,z));
y=y+(noise3(x,y,z));
z=z+(noise3(x,y,z));
然后尝试使用:
Normals[(i-1)*PointsPerRow+j].x = x;
Normals[(i-1)*PointsPerRow+j].y = y;
Normals[(i-1)*PointsPerRow+j].z = z;
某些面孔的法线看起来是错误的。一旦创建了完整的形状,我想遍历结果索引,然后计算每个点的法线,如果这有任何意义的话....?
好的,这就是我得到的。它似乎不起作用。它可能完全错误,所以放轻松。
for (j = 0; j < NumIndices-2; j=j+3)
{
Ax = Vertices[Indices[j]].x; Bx = Vertices[Indices[j+1]].x; Cx = Vertices[Indices[j+2]].x;
Ay = Vertices[Indices[j]].y; By = Vertices[Indices[j+1]].y; Cy = Vertices[Indices[j+2]].y;
Az = Vertices[Indices[j]].z; Bz = Vertices[Indices[j+1]].z; Cz = Vertices[Indices[j+2]].z;
dms::Vector3 p1(Ax,Ay,Az);
dms::Vector3 p2(Bx,By,Bz);
dms::Vector3 p3(Cx,Cy,Cz);
dms::Vector3 V1= (p2 - p1);
dms::Vector3 V2 = (p3 - p1);
dms::Vector3 normal = V1.cross(V2);
Normals[j].x = normal[0];
Normals[j].y = normal[1];
Normals[j].z = normal[2];;
Normals[j+1].x = normal[0];
Normals[j+1].y = normal[1];
Normals[j+1].z = normal[2];;
Normals[j+2].x = normal[0];
Normals[j+2].y = normal[1];
Normals[j+2].z = normal[2];;
}
编辑 - -
通过重新安排计算 2 个向量的部分,我能够获得更好的结果。我更改了以下内容:
dms::Vector3 V1= (p2 - p1);
dms::Vector3 V2 = (p3 - p1);
到:
dms::Vector3 V1= (p2 - p1);
dms::Vector3 V2 = (p1 - p3);
但是看起来还是不太对劲,球体的前面有一条黑色的条带,球体的顶部看起来很奇怪。
非常感谢 Kaganar 的出色回答,我将努力解决我剩下的问题。也非常感谢巴特!