在我看来,关于如何制作 icospheres 的教程非常丰富,但关于使用极坐标近似刻面的方法的教程却不多。
这里有一个来自 Richard S. Wright Jr. 的 OpenGL Superbible 4th Edition 书中经过轻微编辑的代码示例。
由于它是固定功能管道的非常简单的用法(没有 glDrawElements 等),我发现它对教育目的很有用。
堆栈被绘制为一系列三角形条带。显然不是最佳性能,但它确实有效!
// For best results, put this in a display list
// Draw a sphere at the origin
void RenderSphere(const float fRadius, const int iStacks, const int iSlices)
{
const auto PI = (float)M_PI;
const auto PIx2 = (float)(M_PI * 2.0);
GLfloat drho = PI / (GLfloat)iStacks;
GLfloat dtheta = PIx2 / (GLfloat)iSlices;
GLfloat ds = 1.0f / (GLfloat)iSlices;
GLfloat dt = 1.0f / (GLfloat)iStacks;
GLfloat t = 1.0f;
GLfloat s = 0.0f;
for (int i = 0; i < iStacks; i++)
{
const GLfloat rho = (GLfloat)i * drho;
const GLfloat srho = (GLfloat)(std::sinf(rho));
const GLfloat crho = (GLfloat)(std::cosf(rho));
const GLfloat srhodrho = (GLfloat)(std::sinf(rho + drho));
const GLfloat crhodrho = (GLfloat)(std::cosf(rho + drho));
// Many sources of OpenGL sphere drawing code uses a triangle fan
// for the caps of the sphere. This however introduces texturing
// artifacts at the poles on some OpenGL implementations
glBegin(GL_TRIANGLE_STRIP);
s = 0.0f;
for (int j = 0; j <= iSlices; j++)
{
const GLfloat theta = (j == iSlices) ? 0.0f : j * dtheta;
const GLfloat stheta = (GLfloat)(-std::sinf(theta));
const GLfloat ctheta = (GLfloat)(std::cosf(theta));
GLfloat x = stheta * srho;
GLfloat y = ctheta * srho;
GLfloat z = crho;
glTexCoord2f(s, t);
glNormal3f(x, y, z);
glVertex3f(x * fRadius, y * fRadius, z * fRadius);
x = stheta * srhodrho;
y = ctheta * srhodrho;
z = crhodrho;
glTexCoord2f(s, t - dt);
s += ds;
glNormal3f(x, y, z);
glVertex3f(x * fRadius, y * fRadius, z * fRadius);
}
glEnd();
t -= dt;
}
}
不幸的是,我找不到该源代码的原始在线存储库的链接,它非常古老。如果您知道在哪里可以找到它,请随时发布!