于(0,0,0) 绘制一个半径R=1 的球体函数:
sphere_entry
void sphere_entry(int du, int dv){
float gu = 3.1415926535 / du , gv = 2.0*3.1415926535 / (dv-1);
float x, y, z ,r ;
glPushMatrix();
#define MAKE_R(z2) sqrt(1.0 - (z2))
#define MAKE_Z(z_step) cos((z_step) *gu)
#define MAKE_Y(x_step,r) (r)*sin((x_step)* gv)
#define MAKE_X(x_step,r) (r)*cos((x_step)* gv)
// 球体
glBegin(GL_QUADS);
for (int z_step = 0 ; z_step < du; ++z_step) {
for (int x_step = 0; x_step < dv; ++x_step) {
z = MAKE_Z(z_step);
r = MAKE_R(z*z);
x = MAKE_X(x_step, r);
y = MAKE_Y(x_step, r);
glVertex3f(x, y, z);
z = MAKE_Z(z_step+1);
r = MAKE_R(z*z);
x = MAKE_X(x_step, r);
y = MAKE_Y(x_step, r);
glVertex3f(x, y, z);
z = MAKE_Z(z_step + 1);
r = MAKE_R(z*z);
x = MAKE_X(x_step + 1,r);
y = MAKE_Y(x_step+1, r);
glVertex3f(x, y, z);
z = MAKE_Z(z_step);
r = MAKE_R(z*z);
x = MAKE_X(x_step + 1,r);
y = MAKE_Y(x_step + 1, r);
glVertex3f(x, y, z);
}
}
glEnd();
#undef MAKE_Y
#undef MAKE_Z
#undef MAKE_X
#undef MAKE_R
glPopMatrix();
}
所有代码:
main.cpp
#include "pch.h"
#include
#include
#include
#ifdef _WIN32
#define FREEGLUT_STATIC
#include
#endif
#include "sphere.h"
float angle;
void changed_size(int w, int h) {
// 修改视窗size
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, double(w) / double(h), 1.0f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 5.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
}
// 初始化渲染环境
void setup_rc() {
// 蓝色背景
glClearColor(0.f, 0.f, .3f, 1.f);
angle = 0.0f;
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// 渲染
void render(void) {
// 清除颜色缓冲、深度缓冲、模板缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
glRotatef(angle, 0.0f, 1.0f, 1.0f);
glColor3f(.6f, .05f, .95f);
sphere_entry(32,32);
angle += .02f;
angle = angle > 360.0f ? 0.0f : angle;
// 交换缓冲区
glutSwapBuffers();
}
int main(int argc, char**argv) {
gltSetWorkingDirectory(*argv);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL App");
glutReshapeFunc(changed_size);
glutDisplayFunc(render);
glutIdleFunc(render);
GLenum err = glewInit();
if (GLEW_OK != err) {
std::cerr << "GLEW Error : " << glewGetErrorString(err) << std::endl;
return 1;
}
setup_rc();
glutMainLoop();
return 0;
}