//创建球体模型的顶点坐标
bool OGLESFiveSpheres::CreateGeometry()
{
unsigned int i;
/*
g_ui32RimNo 多少个同心圆
g_uiRimSize 每个同心圆上的点数
*/
/*
Creates the sphere vertices and texture coordinates
*/
m_ui32VertexNo = (g_ui32RimNo - 2) * g_uiRimSize + 2;
m_pVertex = new SVertex[m_ui32VertexNo];
if(!m_pVertex)
{
PVRShellSet(prefExitMessage, "Error: Out of memory.");
return false;
}
// Bottom vertex
m_pVertex[0].fPos.x = 0;
m_pVertex[0].fPos.y = -0.5f * g_ui32SphereScale;
m_pVertex[0].fPos.z = 0;
m_pVertex[0].fU = 0.5f;
m_pVertex[0].fV = 0.5f;
// 7 rims of 16 vertices each
float fYAngleInc = PVRT_PI / (float) (g_ui32RimNo - 1);
float fYAngle = fYAngleInc;
int i32Index = 1;
for(i = 0; i < (g_ui32RimNo - 2); ++i)
{
float fPosY = (float) cos(fYAngle) * -0.5f;
fYAngle += fYAngleInc;
for(int j = 0; j < g_uiRimSize; ++j)
{
float fAngle = (float)j * 2.0f * PVRT_PI / (float)g_uiRimSize;
float fSize = (float) cos(asin(fPosY*2)) * 0.50f;
m_pVertex[GetVertexIndex(i+1,j)].fPos.x = (float)PVRTFCOS(fAngle) * (fSize*g_ui32SphereScale);
m_pVertex[GetVertexIndex(i+1,j)].fPos.y = fPosY * g_ui32SphereScale;
m_pVertex[GetVertexIndex(i+1,j)].fPos.z = (float)PVRTFSIN(fAngle) * (fSize*g_ui32SphereScale);
m_pVertex[GetVertexIndex(i+1,j)].fU = m_pVertex[GetVertexIndex(i+1,j)].fPos.x + 0.5f;
m_pVertex[GetVertexIndex(i+1,j)].fV = m_pVertex[GetVertexIndex(i+1,j)].fPos.z + 0.5f;
++i32Index;
}
}
// Top vertex
m_pVertex[i32Index].fPos.x = 0;
m_pVertex[i32Index].fPos.y = 0.5f * g_ui32SphereScale;
m_pVertex[i32Index].fPos.z = 0;
m_pVertex[i32Index].fU = 0.5f;
m_pVertex[i32Index].fV = 0.5f;
/*
Creates the sphere normals.
*/
for(i = 0; i < (g_ui32RimNo - 2) * g_uiRimSize + 2; ++i)
{
PVRTVec3 vNormal;
vNormal.x = m_pVertex[i].fPos.x;
vNormal.y = m_pVertex[i].fPos.y;
vNormal.z = m_pVertex[i].fPos.z;
vNormal.normalize();
m_pVertex[i].fNormal.x = vNormal.x;
m_pVertex[i].fNormal.y = vNormal.y;
m_pVertex[i].fNormal.z = vNormal.z;
}
return true;
}
bool OGLESFiveSpheres::CreateGeometry()
{
unsigned int i;
/*
g_ui32RimNo 多少个同心圆
g_uiRimSize 每个同心圆上的点数
*/
/*
Creates the sphere vertices and texture coordinates
*/
m_ui32VertexNo = (g_ui32RimNo - 2) * g_uiRimSize + 2;
m_pVertex = new SVertex[m_ui32VertexNo];
if(!m_pVertex)
{
PVRShellSet(prefExitMessage, "Error: Out of memory.");
return false;
}
// Bottom vertex
m_pVertex[0].fPos.x = 0;
m_pVertex[0].fPos.y = -0.5f * g_ui32SphereScale;
m_pVertex[0].fPos.z = 0;
m_pVertex[0].fU = 0.5f;
m_pVertex[0].fV = 0.5f;
// 7 rims of 16 vertices each
float fYAngleInc = PVRT_PI / (float) (g_ui32RimNo - 1);
float fYAngle = fYAngleInc;
int i32Index = 1;
for(i = 0; i < (g_ui32RimNo - 2); ++i)
{
float fPosY = (float) cos(fYAngle) * -0.5f;
fYAngle += fYAngleInc;
for(int j = 0; j < g_uiRimSize; ++j)
{
float fAngle = (float)j * 2.0f * PVRT_PI / (float)g_uiRimSize;
float fSize = (float) cos(asin(fPosY*2)) * 0.50f;
m_pVertex[GetVertexIndex(i+1,j)].fPos.x = (float)PVRTFCOS(fAngle) * (fSize*g_ui32SphereScale);
m_pVertex[GetVertexIndex(i+1,j)].fPos.y = fPosY * g_ui32SphereScale;
m_pVertex[GetVertexIndex(i+1,j)].fPos.z = (float)PVRTFSIN(fAngle) * (fSize*g_ui32SphereScale);
m_pVertex[GetVertexIndex(i+1,j)].fU = m_pVertex[GetVertexIndex(i+1,j)].fPos.x + 0.5f;
m_pVertex[GetVertexIndex(i+1,j)].fV = m_pVertex[GetVertexIndex(i+1,j)].fPos.z + 0.5f;
++i32Index;
}
}
// Top vertex
m_pVertex[i32Index].fPos.x = 0;
m_pVertex[i32Index].fPos.y = 0.5f * g_ui32SphereScale;
m_pVertex[i32Index].fPos.z = 0;
m_pVertex[i32Index].fU = 0.5f;
m_pVertex[i32Index].fV = 0.5f;
/*
Creates the sphere normals.
*/
for(i = 0; i < (g_ui32RimNo - 2) * g_uiRimSize + 2; ++i)
{
PVRTVec3 vNormal;
vNormal.x = m_pVertex[i].fPos.x;
vNormal.y = m_pVertex[i].fPos.y;
vNormal.z = m_pVertex[i].fPos.z;
vNormal.normalize();
m_pVertex[i].fNormal.x = vNormal.x;
m_pVertex[i].fNormal.y = vNormal.y;
m_pVertex[i].fNormal.z = vNormal.z;
}
return true;
}
说明:假如球体有180个同心圆(g_ui32RimNo = 180)当然包含最上面一个点和最下面一个点,南极北极。
那么每个同心圆之间的角度差都是1°。即角度增量为:
float fYAngleInc = PVRT_PI / (float) (g_ui32RimNo - 1); //B角
同一个同心圆上面所有点的Y坐标都是一致的。
float fPosY = (float) cos(fYAngle) * -0.5f;
角度Q的计算:
float fAngle = (float)j * 2.0f * PVRT_PI / (float)g_uiRimSize; //图中有点错误,Q画成了与X负轴夹角,应该是正轴夹角。
同心圆半径R1的计算:
float fSize = (float) cos(asin(fPosY*2)) * 0.50f;
fPosY*2 = (float) cos(fYAngle) * -0.5f * 2 = (float) cos(fYAngle) = sin(π/2 - fYAngle)
其实R1也可以这样计算: (float) sin(fYAngle) * 0.50f;
X坐标计算:
R1 * cosQ
Z坐标计算:
R1 * sinQ