📄 test6.cpp
字号:
#include <windows.h>
#include <gl/glut.h>
#include <math.h>
const double PI=3.1415926;
const float MIN_LEN = 0.01;
const float LEN = 0.6;
const float g_ax = -LEN, g_ay = LEN, g_az = 0;
const float g_bx = -LEN, g_by = -LEN, g_bz = LEN;
const float g_cx = LEN, g_cy = -LEN, g_cz = -LEN;
const float g_dx = LEN, g_dy = LEN, g_dz = LEN;
///灯光的位置
float g_light_position[]={0, 0, 4, 1};
///环境光
float g_light_ambient[]={0.1,0.1,0.1,1};
///漫反射光
float g_light_diffuse[]={1,1,1,1};
///镜面反射光
float g_light_specular[]={1,1,1,1};
///材料
float g_Gold[] = {
0.247250, 0.199500, 0.074500, 1.000000,
0.751640, 0.606480, 0.226480, 1.000000,
0.628281, 0.555802, 0.366065, 1.000000,
51.200001
};
/// 窗口宽度
int g_width=400;
/// 窗口高度
int g_height=300;
///鼠标器左键是否按下
bool mouse_button_pressed=false;
///记录鼠标器位置
int mouse_x;
///记录鼠标器位置
int mouse_y;
///旋转的纬度
float theta=0;
///旋转的经度
float phi=0;
/**
鼠标按钮回调函数
*/
void mouse(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON)
{
if(state == GLUT_DOWN)
//如果鼠标器左键按下,mouse_button_pressed置位
//并记录光标位置
{
mouse_button_pressed = true;
mouse_x = x;
mouse_y = y;
}
else
{
mouse_button_pressed = false;
}
}
}
/**
鼠标运动处理函数
*/
void motion(int x, int y)
{
if(mouse_button_pressed)
{
theta -= y-mouse_y; //根据鼠标器的移动改变旋转的纬度
if(theta<0) theta += 360; //限制纬度在0到360度之间
if(theta> 360) theta -= 360;
phi += x-mouse_x; //根据鼠标器的移动改变旋转的经度
if(phi<0) phi+=360; //限制经度在0到360度之间
if(phi>360) phi-=360;
mouse_x = x; //更新记录的鼠标器位置
mouse_y = y;
glutPostRedisplay();
//通知系统:窗口需要刷新
}
}
/**
点类
*/
class point3d {
public:
float x;
float y;
float z;
public:
point3d(float _x, float _y, float _z) {x=_x;y=_y;z=_z;}
point3d(point3d & p) {x=p.x; y=p.y; z=p.z;}
point3d middle(point3d & p2) {return point3d((x+p2.x)/2, (y+p2.y)/2, (z+p2.z)/2);}
point3d one_third(point3d & p2) { return point3d((p2.x-x)/3+x, (p2.y-y)/3+y, (p2.z-z)/3+z);}
float between(point3d & p2) {return (x-p2.x)*(x-p2.x)+(y-p2.y)*(y-p2.y)+(z-p2.z)*(z-p2.z);}
};
/**
绘制Sierpinski地毯
四个顶点坐标为a(x1,y1,z1), b(x2,y2,z2), c(x3,y3,z3),d(x4,y4,z4)
*/
void Menger(point3d & a, point3d & b, point3d & c, point3d& d)
{
if (a.between(b) < MIN_LEN ) {
glBegin(GL_QUADS);
glVertex3f(a.x, a.y, a.z);
glVertex3f(b.x, b.y, b.z);
glVertex3f(c.x, c.y, c.z);
glVertex3f(d.x, d.y, d.z);
glEnd();
return;
}
/* 算出所有点的坐标
a d2 d1 d
a1 _a _d c2
a2 _b _c c1
b b1 b2 c
*/
point3d a1 = a.one_third(b), a2=b.one_third(a);
point3d b1 = b.one_third(c), b2=c.one_third(b);
point3d c1 = c.one_third(d), c2=d.one_third(c);
point3d d1 = d.one_third(a), d2=a.one_third(d);
point3d _a = a1.one_third(c2), _b = a2.one_third(c1);
point3d _c = b2.one_third(d1), _d = d1.one_third(b2);
//递归绘制8个小块
Menger(a, a1, _a, d2);
Menger(a1, a2, _b, _a);
Menger(a2, b, b1, _b);
Menger(_b, b1, b2, _c);
Menger(_c, b2, c, c1);
Menger(_d, _c, c1, c2);
Menger(d1, _d, c2, d);
Menger(d2, _a, _d, d1);
}
/**
\b 主处理回调函数,每当需要重画时由OpenGL库调用
\b 该函数功能是调用Menger,绘制Menger锥体
*/
void main_display_loop(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //刷新背景
glMatrixMode (GL_PROJECTION); //设置矩阵模式为投影矩阵
glLoadIdentity(); //初始化投影矩阵
glFrustum(-1,1,-1,1,-1,1); //设置平行投影的投影矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, g_light_position);
glRotatef(phi,0,1,0); //绕y轴旋转OCS,旋转的角度为phi
glRotatef(theta,1,0,0); //绕x轴旋转OCS,旋转的角度为theta
glEnable(GL_LIGHT0); //设置第0盏灯
/*设置光照系数*/
glLightfv(GL_LIGHT0,GL_AMBIENT, g_light_ambient); //环境光
glLightfv(GL_LIGHT0,GL_DIFFUSE, g_light_diffuse); //漫反射光
glLightfv(GL_LIGHT0,GL_SPECULAR, g_light_specular); //镜面反射光
/*设置材料反光系数*/
glMaterialfv(GL_FRONT,GL_AMBIENT,g_Gold); //环境光反射系数
glMaterialfv(GL_FRONT,GL_DIFFUSE,g_Gold+4); //漫反射系数
glMaterialfv(GL_FRONT,GL_SPECULAR,g_Gold+8); //镜面反射系数
glMaterialfv(GL_FRONT,GL_SHININESS,g_Gold+12); //镜面衰减系数
Menger(point3d(g_ax, g_ay, g_az), point3d(g_bx, g_by, g_bz), point3d(g_cx, g_cy, g_cz), point3d(g_dx, g_dy, g_dz));
glFlush(); //更新窗口
glutSwapBuffers();
}
/**
OPENGL 特性初始化函数
*/
init()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glEnable(GL_LIGHTING);
glClearColor(0,0,0,1);
glClearDepth(1);
glShadeModel(GL_SMOOTH);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
}
/// 主函数
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGBA);
glutInitWindowSize(g_width, g_height);
glutCreateWindow("OpenGL");
init();
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutDisplayFunc(main_display_loop);
glutMainLoop();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -