⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test5.cpp

📁 《分形算法与程序设计VC版》<9_03>:内含基于递归算法的Sierpinski金字塔源代码。双击test5.exe文件
💻 CPP
字号:
#include <windows.h>
#include <gl/glut.h>
#include <math.h>

const double PI=3.1415926;
const float MIN_LEN = 0.1;
const float LEN = 0.7;
const float g_ax = 0, 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 = 0, g_dy = -LEN, g_dz = -LEN;
static int g_d=0;
///灯光的位置
float g_light_position[]={0, -0.3, 1, 1}; 
float g_light_position2[]={0, 0.5, 0, 1}; 

///环境光
float g_light_ambient[]={0.5,0.5,0.5,1};  

///漫反射光
float g_light_diffuse[]={1,1,1,1};        

///镜面反射光
float g_light_specular[]={0.5,0.5,0.5,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;
        }
    } else if (button == GLUT_RIGHT_BUTTON) g_d = !g_d;
    
}

/**
鼠标运动处理函数
*/
void motion(int x, int y)
{
    if(mouse_button_pressed)
    {
        theta -= y-mouse_y;     //根据鼠标器的移动改变旋转的纬度
        if(theta<0) theta += 360;  //限制纬度在0到180度之间
        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();
            //通知系统:窗口需要刷新
    }
}

/**
窗口伸缩回调函数:当窗口大小改变时系统调用此函数
*/
void reshape (int w, int h)
{
    glViewport (0,0,w,h);

    glMatrixMode (GL_PROJECTION);

    glLoadIdentity();
    if (w<=h) glOrtho(-1,1,-(float)h/w,(float)h/w,-1,1);
        //如果高度大于宽度,就让宽度为1,保持aspect ratio
        //与viewport 一致
    else glOrtho(-(float)w/h,(float)w/h,-1,1,-1,1);
        //如果宽度大于高度,就让高度为1,保持aspect ratio
        //与viewport 一致

    glMatrixMode(GL_MODELVIEW);
        //设置modelview matrix
    glLoadIdentity();
}



/**
点类
*/
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);}
        float between(point3d & p2) {return (x-p2.x)*(x-p2.x)+(y-p2.y)*(y-p2.y)+(z-p2.z)*(z-p2.z);}
};


/**
绘制Seripinski锥体
三点坐标为a(x1,y1,z1), b(x2,y2,z2), c(x3,y3,z3), d(x4, y4, z4)
*/

void seripinski(point3d & a, point3d & b, point3d & c, point3d& d)
{
   if (a.between(b) < MIN_LEN ) {
    
   glBegin(GL_TRIANGLE_STRIP);
   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);
   glVertex3f(a.x, a.y, a.z);
   //glNormal3f(a.x, a.y, a.z);
   glVertex3f(b.x, b.y, b.z);
   glVertex3f(d.x, d.y, d.z);
   glVertex3f(b.x, b.y, b.z);
   glVertex3f(c.x, c.y, c.z);
   glEnd();
   return;
   }
   
   //递归绘制四个锥
   seripinski(a.middle(b), b, b.middle(c), b.middle(d));
   seripinski(a, a.middle(b), a.middle(c), a.middle(d));
   seripinski(a.middle(c), b.middle(c), c, c.middle(d));
   seripinski(a.middle(d), b.middle(d), c.middle(d), d);
}

/**
\b 主处理回调函数,每当需要重画时由OpenGL库调用
\b 该函数功能是调用seripinski,绘制seripinski锥体
*/
void main_display_loop(void)
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //刷新背景 

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-1.7, 1.7, -1.7, 1.7, 1.7, -1.7);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslatef(0, 0, -0.5);
  glLightfv(GL_LIGHT0, GL_POSITION, g_light_position);
  glLightfv(GL_LIGHT1, GL_POSITION, g_light_position2);

  glRotatef(phi,0,1,0);       //绕y轴旋转OCS,旋转的角度为phi
  glRotatef(theta,1,0,0);     //绕x轴旋转OCS,旋转的角度为theta

  glEnable(GL_LIGHT0);        //设置第0盏灯
  glEnable(GL_LIGHT1);        //设置第1盏灯

  glLightfv(GL_LIGHT1,GL_AMBIENT, g_light_ambient);    //环境光 
  glLightfv(GL_LIGHT1,GL_DIFFUSE, g_light_diffuse);    //漫反射光
  glLightfv(GL_LIGHT1,GL_SPECULAR, g_light_specular);  //镜面反射光
  /*设置光照系数*/
  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); //镜面衰减系数

  glMaterialfv(GL_BACK,GL_AMBIENT,g_Gold);     //环境光反射系数
  glMaterialfv(GL_BACK,GL_DIFFUSE,g_Gold+4);   //漫反射系数
  glMaterialfv(GL_BACK,GL_SPECULAR,g_Gold+8);  //镜面反射系数
  glMaterialfv(GL_BACK,GL_SHININESS,g_Gold+12); //镜面衰减系数


  seripinski(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_LESS);
  glEnable(GL_LIGHTING);
  glEnable(GL_NORMALIZE);
  glClearColor(0,0,0,1); 
  glClearDepth(1);
  glShadeModel(GL_SMOOTH);
  glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
}

void _stdcall time_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	phi += g_d;
	if (phi > 360) phi -= 360;
        glutPostRedisplay();
}
/// 主函数
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);
  glutReshapeFunc(reshape);
  glutDisplayFunc(main_display_loop);
  SetTimer(NULL, 10, 10, (TIMERPROC)time_proc);
  glutMainLoop();
  KillTimer(NULL, 10);
  return 0;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -