哈~ 搞掂!
#include<gl/glut.h>
#include<math.h>
#include<stdlib.h>
//窗口大小
int width = 600;
int height = 600;
//a point data type
typedef GLfloat point3[3];
point3 v[] = {{0.0, 0.0, 1.0}, {0.0, 0.942809, -0.333333}, {-0.816497, -0.471405, -0.333333}, {0.816497, -0.471405, -0.333333}};
static int k = 5;
void triangle(point3 a, point3 b, point3 c)
{
glNormal3fv(a);
glVertex3fv(a);
glNormal3fv(b);
glVertex3fv(b);
glNormal3fv(c);
glVertex3fv(c);
}
void normalize(point3 v1, point3 v2, point3 &v3)
{
float len = sqrt((v1[0]+v2[0])*(v1[0]+v2[0])+(v1[1]+v2[1])*(v1[1]+v2[1])+(v1[2]+v2[2])*(v1[2]+v2[2]));
v3[0] = (v1[0]+v2[0])/len;
v3[1] = (v1[1]+v2[1])/len;
v3[2] = (v1[2]+v2[2])/len;
}
void divide_triangle(point3 a, point3 b, point3 c, int k)
{
point3 ab, ac, bc;
normalize(a, b, ab);
normalize(a, c, ac);
normalize(b, c, bc);
if (k > 0)
{
divide_triangle(a, ac, ab, k-1);
divide_triangle(c, bc, ac, k-1);
divide_triangle(b, ab, bc, k-1);
divide_triangle(ab, ac, bc, k-1);
}
else {
triangle(a, b, c);
}
}
void tetra()
{
divide_triangle(v[0], v[1], v[2], k);
divide_triangle(v[3], v[2], v[1], k);
divide_triangle(v[0], v[3], v[1], k);
divide_triangle(v[0], v[2], v[3], k);
}
void display(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);//注意事项:要在glClear之前设置color!
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 清除屏幕及深度缓存
glViewport(0,0,(GLsizei)width,(GLsizei)height);
glMatrixMode(GL_PROJECTION);//投影矩阵
glLoadIdentity();
gluPerspective(45, width/height, 1, 1000);
glMatrixMode(GL_MODELVIEW);//模型矩阵
glLoadIdentity();
gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
glRotatef(30, 1, 0, 0);//绕x轴旋转
glRotatef(150, 0, 1, 0);
glEnable(GL_DEPTH_TEST);
/*glEnableClientState(GL_VERTEX_ARRAY);
colorcube();
glVertexPointer(4, GL_FLOAT, 0, points);
glEnableClientState(GL_COLOR_ARRAY);//启用颜色数组
glColorPointer(4, GL_FLOAT, 0, quad_color);
glDrawArrays(GL_TRIANGLES, 0, 36);
*/
glBegin(GL_TRIANGLES);
glColor3f(0.0f, 1.0f, 0.0f);//设置顶点颜色
//tetra(v[0], v[1], v[2], v[3], 6);
tetra();
glEnd();
glFlush();//当窗口模式为双缓存时,此函数的功能就是把后台缓存的内容交换到前台显示。当然,只有单缓存时,使用它的功能跟用glFlush()一样。而使用双缓存是为了把完整图画一次性显示在窗口上,或者是为了实现动画。
}
void init()
{
/*
GLfloat gAmbient[] = {0.6, 0,6, 0,6, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, gAmbient);
*/
GLfloat light_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 0.3, 0.3, 0.8, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
GLfloat mat_ambient[] = { 0.0, 0.8, 0.8, 1.0 };
GLfloat mat_diffuse[] = { 0.0, 0.5, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 100.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//glEnable(GL_COLOR_MATERIAL);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
}
void reshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho(-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);//初始化GLUT
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);//设置图形显示模式。GLUT_DEPTH:使用深度缓存;GLUT_DOUBLE:使用双缓存;
glutInitWindowPosition(100, 100);//设置窗口显示位置
glutInitWindowSize(600,600);//设置窗口大小
glutCreateWindow("Lighting Sphere");//创建带标题的窗口
init();// 之前一直没有光照效果是因为错把这个函数放在createwindow之前调用了
glutDisplayFunc(display);//为当前窗口设置显示回调函数
glutReshapeFunc(reshape);
glutMainLoop();//进入GLUT事件处理循环
return 0;
}